iio: humidity: hts221: update probe and logging implementations
Subsystems (2)
cover iio: humidity: hts221: update probe and logging implementations
HTS221 is an older driver. This series groups a few small modernizations based on current development practices.
- Report available values via read_avail()
- Add a blank line after variable declarations (style)
- Allow unknown whoami for DT fallback instead of erroring out
- Use dev_err_probe() in probe paths
- Reject calibration data that would cause division by zero
No HTS221 hardware was available. Verified with checkpatch --strict and builds of hts221, hts221_i2c and hts221_spi. Probe and calibration error paths were exercised against i2c-stub with register contents pre-loaded via i2cset.
Adi Nata (5):
iio: humidity: hts221: report available values via read_avail()
iio: humidity: hts221: Add a blank line after variable declarations
iio: humidity: hts221: Allow unknown whoami for DT fallback
iio: humidity: hts221: use dev_err_probe() in probe paths
iio: humidity: hts221: fix division by zero in calibration parsing
drivers/iio/humidity/hts221_buffer.c | 1 + drivers/iio/humidity/hts221_core.c | 171 ++++++++++++--------------- drivers/iio/humidity/hts221_i2c.c | 8 +- drivers/iio/humidity/hts221_spi.c | 8 +- 4 files changed, 85 insertions(+), 103 deletions(-)
Signature · 1 line
2.47.3
PATCH 1/5 iio: humidity: hts221: report available values via read_avail()
Replace the custom oversampling_ratio_available sysfs attributes with the standard IIO read_avail() callback. This lets the IIO core create and format *_available attributes and exposes the lists to in-kernel consumers.
--- drivers/iio/humidity/hts221_core.c | 106 +++++++++++------------------ 1 file changed, 40 insertions(+), 66 deletions(-)
drivers/iio/humidity/hts221_core.c +40 -66
@@ -10,7 +10,6 @@#include <linux/kernel.h> #include <linux/module.h> #include <linux/device.h> -#include <linux/iio/sysfs.h> #include <linux/delay.h> #include <linux/pm.h> #include <linux/regmap.h>
@@ -49,7 +48,7 @@ struct hts221_odr {struct hts221_avg {u8 addr;u8 mask; -u16 avg_avl[HTS221_AVG_DEPTH ]; +int avg_avl[HTS221_AVG_DEPTH ]; };static const struct hts221_odr hts221_odr_table[] = {
@@ -58,6 +57,8 @@ static const struct hts221_odr hts221_odr_table[] = { { 13, 0x03 }, /* 12.5Hz */ }; +static const int hts221_odr_avail[] = { 1, 7, 13 }; + static const struct hts221_avg hts221_avg_list[] = { { .addr = 0x10,
@@ -97,7 +98,11 @@ static const struct iio_chan_spec hts221_channels[] = {BIT (IIO_CHAN_INFO_OFFSET ) |BIT (IIO_CHAN_INFO_SCALE ) | BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), + .info_mask_separate_available = + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), + .info_mask_shared_by_all_available = + BIT(IIO_CHAN_INFO_SAMP_FREQ), .scan_index = 0, .scan_type = { .sign = 's',
@@ -113,7 +118,11 @@ static const struct iio_chan_spec hts221_channels[] = {BIT (IIO_CHAN_INFO_OFFSET ) |BIT (IIO_CHAN_INFO_SCALE ) | BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), + .info_mask_separate_available = + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), + .info_mask_shared_by_all_available = + BIT(IIO_CHAN_INFO_SAMP_FREQ), .scan_index = 1, .scan_type = { .sign = 's',
@@ -192,53 +201,35 @@ static int hts221_update_avg(struct hts221_hw *hw,return 0 ; } -static ssize_t hts221_sysfs_sampling_freq (struct device *dev, -struct device_attribute *attr, -char *buf) -{ -int i; -ssize_t len =0 ; - -for (i =0 ; i <ARRAY_SIZE (hts221_odr_table); i++) - len +=scnprintf (buf + len,PAGE_SIZE - len,"%d " , - hts221_odr_table[i].hz); - buf[len -1 ] ='\n' ; - -return len; -} - -static ssize_t -hts221_sysfs_rh_oversampling_avail (struct device *dev, -struct device_attribute *attr, -char *buf) -{ -const struct hts221_avg *avg = &hts221_avg_list[HTS221_SENSOR_H ]; -ssize_t len =0 ; -int i; - -for (i =0 ; i <ARRAY_SIZE (avg->avg_avl); i++) - len +=scnprintf (buf + len,PAGE_SIZE - len,"%d " , - avg->avg_avl[i]); - buf[len -1 ] ='\n' ; - -return len; -} - -static ssize_t -hts221_sysfs_temp_oversampling_avail (struct device *dev, -struct device_attribute *attr, -char *buf) +static int hts221_read_avail (struct iio_dev *indio_dev, +struct iio_chan_spec const *chan, +const int **vals,int *type,int *length, +long mask) { -const struct hts221_avg *avg = &hts221_avg_list[HTS221_SENSOR_T ]; -ssize_t len =0 ; -int i; - -for (i =0 ; i <ARRAY_SIZE (avg->avg_avl); i++) - len +=scnprintf (buf + len,PAGE_SIZE - len,"%d " , - avg->avg_avl[i]); - buf[len -1 ] ='\n' ; - -return len; +switch (mask) { +case IIO_CHAN_INFO_OVERSAMPLING_RATIO : +switch (chan->type) { +case IIO_HUMIDITYRELATIVE : + *vals = hts221_avg_list[HTS221_SENSOR_H ].avg_avl; + *length =ARRAY_SIZE (hts221_avg_list[HTS221_SENSOR_H ].avg_avl); +break ; +case IIO_TEMP : + *vals = hts221_avg_list[HTS221_SENSOR_T ].avg_avl; + *length =ARRAY_SIZE (hts221_avg_list[HTS221_SENSOR_T ].avg_avl); +break ; +default : +return -EINVAL ; + } + *type =IIO_VAL_INT ; +return IIO_AVAIL_LIST ; +case IIO_CHAN_INFO_SAMP_FREQ : + *vals = hts221_odr_avail; + *type =IIO_VAL_INT ; + *length =ARRAY_SIZE (hts221_odr_avail); +return IIO_AVAIL_LIST ; +default : +return -EINVAL ; + } }int hts221_set_enable (struct hts221_hw *hw,bool enable)
@@ -521,27 +512,10 @@ static int hts221_validate_trigger(struct iio_dev *iio_dev,return hw->trig == trig ?0 : -EINVAL ; } -static IIO_DEVICE_ATTR(in_humidity_oversampling_ratio_available, S_IRUGO, - hts221_sysfs_rh_oversampling_avail, NULL, 0); -static IIO_DEVICE_ATTR(in_temp_oversampling_ratio_available, S_IRUGO, - hts221_sysfs_temp_oversampling_avail, NULL, 0); -static IIO_DEV_ATTR_SAMP_FREQ_AVAIL (hts221_sysfs_sampling_freq); - -static struct attribute *hts221_attributes[] = { - &iio_dev_attr_sampling_frequency_available.dev_attr.attr, - &iio_dev_attr_in_humidity_oversampling_ratio_available.dev_attr.attr, - &iio_dev_attr_in_temp_oversampling_ratio_available.dev_attr.attr, -NULL , -}; - -static const struct attribute_group hts221_attribute_group = { - .attrs = hts221_attributes, -}; -static const struct iio_info hts221_info = { - .attrs = &hts221_attribute_group, .read_raw = hts221_read_raw, .write_raw = hts221_write_raw, + .read_avail = hts221_read_avail, .validate_trigger = hts221_validate_trigger, };
Signature · 1 line
2.47.3
Jonathan Cameron
maintainerRe: [PATCH 1/5] iio: humidity: hts221: report available values via read_avail()
Quoted 4 lines · On Sat, 8 Aug 2026 17:00:22 +0800 Adi Nata…
Replace the custom
oversampling_ratio_availablesysfs attributes with the standard IIOread_avail()callback. This lets the IIO core create and format*_availableattributes and exposes the lists to in-kernel consumers.
Sashiko points out that there is an ABI change in here as oddly the driver uses in_humidity_oversampling_ratio_available rather than in_humidityrelative_oversampling_ratio_available
Which makes this an ABI fix. Therefore this should have a fixes tag and be moved to the start of the set. Please check that logic though as maybe I'm missing something.
J
Quoted 171 lines
Signed-off-by Adi Nata <[email protected]>--- drivers/iio/humidity/hts221_core.c | 106 +++++++++++------------------ 1 file changed, 40 insertions(+), 66 deletions(-)drivers/iio/humidity/hts221_core.c +40
-66@@ -10,7 +10,6 @@#include <linux/kernel.h> #include <linux/module.h> #include <linux/device.h> -#include <linux/iio/sysfs.h> #include <linux/delay.h> #include <linux/pm.h> #include <linux/regmap.h> @@ -49,7 +48,7 @@ struct hts221_odr {struct hts221_avg {u8 addr;u8 mask; -u16 avg_avl[HTS221_AVG_DEPTH ]; +int avg_avl[HTS221_AVG_DEPTH ]; };static const struct hts221_odr hts221_odr_table[] = {@@ -58,6 +57,8 @@ static const struct hts221_odr hts221_odr_table[] = { { 13, 0x03 }, /* 12.5Hz */ }; +static const int hts221_odr_avail[] = { 1, 7, 13 }; + static const struct hts221_avg hts221_avg_list[] = { { .addr = 0x10,@@ -97,7 +98,11 @@ static const struct iio_chan_spec hts221_channels[] = {BIT (IIO_CHAN_INFO_OFFSET ) |BIT (IIO_CHAN_INFO_SCALE ) | BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), + .info_mask_separate_available = + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), + .info_mask_shared_by_all_available = + BIT(IIO_CHAN_INFO_SAMP_FREQ), .scan_index = 0, .scan_type = { .sign = 's',@@ -113,7 +118,11 @@ static const struct iio_chan_spec hts221_channels[] = {BIT (IIO_CHAN_INFO_OFFSET ) |BIT (IIO_CHAN_INFO_SCALE ) | BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), + .info_mask_separate_available = + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), + .info_mask_shared_by_all_available = + BIT(IIO_CHAN_INFO_SAMP_FREQ), .scan_index = 1, .scan_type = { .sign = 's',@@ -192,53 +201,35 @@ static int hts221_update_avg(struct hts221_hw *hw,return 0 ; } -static ssize_t hts221_sysfs_sampling_freq (struct device *dev, -struct device_attribute *attr, -char *buf) -{ -int i; -ssize_t len =0 ; - -for (i =0 ; i <ARRAY_SIZE (hts221_odr_table); i++) - len +=scnprintf (buf + len,PAGE_SIZE - len,"%d " , - hts221_odr_table[i].hz); - buf[len -1 ] ='\n' ; - -return len; -} - -static ssize_t -hts221_sysfs_rh_oversampling_avail (struct device *dev, -struct device_attribute *attr, -char *buf) -{ -const struct hts221_avg *avg = &hts221_avg_list[HTS221_SENSOR_H ]; -ssize_t len =0 ; -int i; - -for (i =0 ; i <ARRAY_SIZE (avg->avg_avl); i++) - len +=scnprintf (buf + len,PAGE_SIZE - len,"%d " , - avg->avg_avl[i]); - buf[len -1 ] ='\n' ; - -return len; -} - -static ssize_t -hts221_sysfs_temp_oversampling_avail (struct device *dev, -struct device_attribute *attr, -char *buf) +static int hts221_read_avail (struct iio_dev *indio_dev, +struct iio_chan_spec const *chan, +const int **vals,int *type,int *length, +long mask) { -const struct hts221_avg *avg = &hts221_avg_list[HTS221_SENSOR_T ]; -ssize_t len =0 ; -int i; - -for (i =0 ; i <ARRAY_SIZE (avg->avg_avl); i++) - len +=scnprintf (buf + len,PAGE_SIZE - len,"%d " , - avg->avg_avl[i]); - buf[len -1 ] ='\n' ; - -return len; +switch (mask) { +case IIO_CHAN_INFO_OVERSAMPLING_RATIO : +switch (chan->type) { +case IIO_HUMIDITYRELATIVE : + *vals = hts221_avg_list[HTS221_SENSOR_H ].avg_avl; + *length =ARRAY_SIZE (hts221_avg_list[HTS221_SENSOR_H ].avg_avl); +break ; +case IIO_TEMP : + *vals = hts221_avg_list[HTS221_SENSOR_T ].avg_avl; + *length =ARRAY_SIZE (hts221_avg_list[HTS221_SENSOR_T ].avg_avl); +break ; +default : +return -EINVAL ; + } + *type =IIO_VAL_INT ; +return IIO_AVAIL_LIST ; +case IIO_CHAN_INFO_SAMP_FREQ : + *vals = hts221_odr_avail; + *type =IIO_VAL_INT ; + *length =ARRAY_SIZE (hts221_odr_avail); +return IIO_AVAIL_LIST ; +default : +return -EINVAL ; + } }int hts221_set_enable (struct hts221_hw *hw,bool enable)@@ -521,27 +512,10 @@ static int hts221_validate_trigger(struct iio_dev *iio_dev,return hw->trig == trig ?0 : -EINVAL ; } -static IIO_DEVICE_ATTR(in_humidity_oversampling_ratio_available, S_IRUGO, - hts221_sysfs_rh_oversampling_avail, NULL, 0); -static IIO_DEVICE_ATTR(in_temp_oversampling_ratio_available, S_IRUGO, - hts221_sysfs_temp_oversampling_avail, NULL, 0); -static IIO_DEV_ATTR_SAMP_FREQ_AVAIL (hts221_sysfs_sampling_freq); - -static struct attribute *hts221_attributes[] = { - &iio_dev_attr_sampling_frequency_available.dev_attr.attr, - &iio_dev_attr_in_humidity_oversampling_ratio_available.dev_attr.attr, - &iio_dev_attr_in_temp_oversampling_ratio_available.dev_attr.attr, -NULL , -}; - -static const struct attribute_group hts221_attribute_group = { - .attrs = hts221_attributes, -}; -static const struct iio_info hts221_info = { - .attrs = &hts221_attribute_group, .read_raw = hts221_read_raw, .write_raw = hts221_write_raw, + .read_avail = hts221_read_avail, .validate_trigger = hts221_validate_trigger, };
Re: [PATCH 1/5] iio: humidity: hts221: report available values via read_avail()
Hi Jonathan,
Thanks for the feedback. I have checked with what Sachiko is saying is correct. The custom attribute was in_humidity_oversampling_ratio_available while the current on is in_humidityrelative_oversampling_ratio_available because in industrial_core.c only has [IIO_HUMIDITYRELATIVE] = "humidityrelative".
For this humidity case in particular, would it be better to keep the legacy implementation while adding the new read_avail()?
The other case declaration will remain changed.
Quoted 13 lines
Quoted 4 lines
Replace the custom
oversampling_ratio_availablesysfs attributes with the standard IIOread_avail()callback. This lets the IIO core create and format*_availableattributes and exposes the lists to in-kernel consumers.Sashiko points out that there is an ABI change in here as oddly the driver uses
in_humidity_oversampling_ratio_availablerather thanin_humidityrelative_oversampling_ratio_availableWhich makes this an ABI fix. Therefore this should have a fixes tag and be moved to the start of the set. Please check that logic though as maybe I'm missing something.
Jonathan Cameron
maintainerRe: [PATCH 1/5] iio: humidity: hts221: report available values via read_avail()
Quoted 9 lines · On Wed, 12 Aug 2026 08:22:48 +0800 Adinata Tan <[email protected]> wrote:
Hi Jonathan,
Thanks for the feedback. I have checked with what Sachiko is saying is correct. The custom attribute was
in_humidity_oversampling_ratio_availablewhile the current on isin_humidityrelative_oversampling_ratio_availablebecause inindustrial_core.conly has [IIO_HUMIDITYRELATIVE] = "humidityrelative".For this humidity case in particular, would it be better to keep the legacy implementation while adding the new
read_avail()?
To me it seems vanishingly unlikely there is any code out there jumping through the hoops to read the wrong ABI element to figure out a possible value to write to in_humidityrelative_oversampling_ratio
So I think this is in the category of ABI that we can change as long as no one notices. For IIO I will also generally take ABI fixes on basis we actually want to know if anyone is using the broken ABI (and they very rarely are!)
Quoted 16 lines
The other case declaration will remain changed.
Quoted 13 lines
Quoted 4 lines
Replace the custom
oversampling_ratio_availablesysfs attributes with the standard IIOread_avail()callback. This lets the IIO core create and format*_availableattributes and exposes the lists to in-kernel consumers.Sashiko points out that there is an ABI change in here as oddly the driver uses
in_humidity_oversampling_ratio_availablerather thanin_humidityrelative_oversampling_ratio_availableWhich makes this an ABI fix. Therefore this should have a fixes tag and be moved to the start of the set. Please check that logic though as maybe I'm missing something.
Re: [PATCH 1/5] iio: humidity: hts221: report available values via read_avail()
Hi Jonathan,
Thanks for the input. In this case, we can proceed with the current implementation?
Quoted 11 lines
Quoted 2 lines
For this humidity case in particular, would it be better to keep the legacy implementation while adding the new
read_avail()?To me it seems vanishingly unlikely there is any code out there jumping through the hoops to read the wrong ABI element to figure out a possible value to write to
in_humidityrelative_oversampling_ratioSo I think this is in the category of ABI that we can change as long as no one notices. For IIO I will also generally take ABI fixes on basis we actually want to know if anyone is using the broken ABI (and they very rarely are!)
Jonathan Cameron
maintainerRe: [PATCH 1/5] iio: humidity: hts221: report available values via read_avail()
Quoted 3 lines · On Wed, 12 Aug 2026 19:40:05 +0800 Adinata Tan <[email protected]> wrote:
Hi Jonathan,
Thanks for the input. In this case, we can proceed with the current implementation?
Busy week so sorry for slow reply.
Yes, that's fine and what I assume you did for v2!
Jonathan
Quoted 12 lines
Quoted 12 lines
Quoted 3 lines
For this humidity case in particular, would it be better to keep the legacy implementation while adding the new
read_avail()?To me it seems vanishingly unlikely there is any code out there jumping through the hoops to read the wrong ABI element to figure out a possible value to write to
in_humidityrelative_oversampling_ratioSo I think this is in the category of ABI that we can change as long as no one notices. For IIO I will also generally take ABI fixes on basis we actually want to know if anyone is using the broken ABI (and they very rarely are!)
Re: [PATCH 1/5] iio: humidity: hts221: report available values via read_avail()
In reply to Jonathan CameronHi Jonathan,
Thanks for the feedback. I have checked with what Sachiko is saying is correct. The custom attribute was in_humidity_oversampling_ratio_available while the current on is in_humidityrelative_oversampling_ratio_available because in industrial_core.c only has [IIO_HUMIDITYRELATIVE] = "humidityrelative".
For this humidity case in particular, would it be better to keep the legacy implementation while adding the new read_avail()?
The other case declaration will remain changed.
Quoted 5 lines
Quoted 4 lines
Replace the custom
oversampling_ratio_availablesysfs attributes with the standard IIOread_avail()callback. This lets the IIO core create and format*_availableattributes and exposes the lists to in-kernel consumers.
Quoted 8 lines
Sashiko points out that there is an ABI change in here as oddly the driver uses
in_humidity_oversampling_ratio_availablerather thanin_humidityrelative_oversampling_ratio_availableWhich makes this an ABI fix. Therefore this should have a fixes tag and be moved to the start of the set. Please check that logic though as maybe I'm missing something.
Regards,
Adi Nata
Quoted 191 lines · Jonathan Cameron
Quoted 4 lines · On Sat, 8 Aug 2026 17:00:22 +0800 Adi Nata…
Replace the custom
oversampling_ratio_availablesysfs attributes with the standard IIOread_avail()callback. This lets the IIO core create and format*_availableattributes and exposes the lists to in-kernel consumers.Sashiko points out that there is an ABI change in here as oddly the driver uses
in_humidity_oversampling_ratio_availablerather thanin_humidityrelative_oversampling_ratio_availableWhich makes this an ABI fix. Therefore this should have a fixes tag and be moved to the start of the set. Please check that logic though as maybe I'm missing something.
J
Quoted 171 lines
Signed-off-by Adi Nata <[email protected]>--- drivers/iio/humidity/hts221_core.c | 106 +++++++++++------------------ 1 file changed, 40 insertions(+), 66 deletions(-)drivers/iio/humidity/hts221_core.c +40
-66@@ -10,7 +10,6 @@#include <linux/kernel.h> #include <linux/module.h> #include <linux/device.h> -#include <linux/iio/sysfs.h> #include <linux/delay.h> #include <linux/pm.h> #include <linux/regmap.h> @@ -49,7 +48,7 @@ struct hts221_odr {struct hts221_avg {u8 addr;u8 mask; -u16 avg_avl[HTS221_AVG_DEPTH ]; +int avg_avl[HTS221_AVG_DEPTH ]; };static const struct hts221_odr hts221_odr_table[] = {@@ -58,6 +57,8 @@ static const struct hts221_odr hts221_odr_table[] = { { 13, 0x03 }, /* 12.5Hz */ }; +static const int hts221_odr_avail[] = { 1, 7, 13 }; + static const struct hts221_avg hts221_avg_list[] = { { .addr = 0x10,@@ -97,7 +98,11 @@ static const struct iio_chan_spec hts221_channels[] = {BIT (IIO_CHAN_INFO_OFFSET ) |BIT (IIO_CHAN_INFO_SCALE ) | BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), + .info_mask_separate_available = + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), + .info_mask_shared_by_all_available = + BIT(IIO_CHAN_INFO_SAMP_FREQ), .scan_index = 0, .scan_type = { .sign = 's',@@ -113,7 +118,11 @@ static const struct iio_chan_spec hts221_channels[] = {BIT (IIO_CHAN_INFO_OFFSET ) |BIT (IIO_CHAN_INFO_SCALE ) | BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), + .info_mask_separate_available = + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), + .info_mask_shared_by_all_available = + BIT(IIO_CHAN_INFO_SAMP_FREQ), .scan_index = 1, .scan_type = { .sign = 's',@@ -192,53 +201,35 @@ static int hts221_update_avg(struct hts221_hw *hw,return 0 ; } -static ssize_t hts221_sysfs_sampling_freq (struct device *dev, -struct device_attribute *attr, -char *buf) -{ -int i; -ssize_t len =0 ; - -for (i =0 ; i <ARRAY_SIZE (hts221_odr_table); i++) - len +=scnprintf (buf + len,PAGE_SIZE - len,"%d " , - hts221_odr_table[i].hz); - buf[len -1 ] ='\n' ; - -return len; -} - -static ssize_t -hts221_sysfs_rh_oversampling_avail (struct device *dev, -struct device_attribute *attr, -char *buf) -{ -const struct hts221_avg *avg = &hts221_avg_list[HTS221_SENSOR_H ]; -ssize_t len =0 ; -int i; - -for (i =0 ; i <ARRAY_SIZE (avg->avg_avl); i++) - len +=scnprintf (buf + len,PAGE_SIZE - len,"%d " , - avg->avg_avl[i]); - buf[len -1 ] ='\n' ; - -return len; -} - -static ssize_t -hts221_sysfs_temp_oversampling_avail (struct device *dev, -struct device_attribute *attr, -char *buf) +static int hts221_read_avail (struct iio_dev *indio_dev, +struct iio_chan_spec const *chan, +const int **vals,int *type,int *length, +long mask) { -const struct hts221_avg *avg = &hts221_avg_list[HTS221_SENSOR_T ]; -ssize_t len =0 ; -int i; - -for (i =0 ; i <ARRAY_SIZE (avg->avg_avl); i++) - len +=scnprintf (buf + len,PAGE_SIZE - len,"%d " , - avg->avg_avl[i]); - buf[len -1 ] ='\n' ; - -return len; +switch (mask) { +case IIO_CHAN_INFO_OVERSAMPLING_RATIO : +switch (chan->type) { +case IIO_HUMIDITYRELATIVE : + *vals = hts221_avg_list[HTS221_SENSOR_H ].avg_avl; + *length =ARRAY_SIZE (hts221_avg_list[HTS221_SENSOR_H ].avg_avl); +break ; +case IIO_TEMP : + *vals = hts221_avg_list[HTS221_SENSOR_T ].avg_avl; + *length =ARRAY_SIZE (hts221_avg_list[HTS221_SENSOR_T ].avg_avl); +break ; +default : +return -EINVAL ; + } + *type =IIO_VAL_INT ; +return IIO_AVAIL_LIST ; +case IIO_CHAN_INFO_SAMP_FREQ : + *vals = hts221_odr_avail; + *type =IIO_VAL_INT ; + *length =ARRAY_SIZE (hts221_odr_avail); +return IIO_AVAIL_LIST ; +default : +return -EINVAL ; + } }int hts221_set_enable (struct hts221_hw *hw,bool enable)@@ -521,27 +512,10 @@ static int hts221_validate_trigger(struct iio_dev *iio_dev,return hw->trig == trig ?0 : -EINVAL ; } -static IIO_DEVICE_ATTR(in_humidity_oversampling_ratio_available, S_IRUGO, - hts221_sysfs_rh_oversampling_avail, NULL, 0); -static IIO_DEVICE_ATTR(in_temp_oversampling_ratio_available, S_IRUGO, - hts221_sysfs_temp_oversampling_avail, NULL, 0); -static IIO_DEV_ATTR_SAMP_FREQ_AVAIL (hts221_sysfs_sampling_freq); - -static struct attribute *hts221_attributes[] = { - &iio_dev_attr_sampling_frequency_available.dev_attr.attr, - &iio_dev_attr_in_humidity_oversampling_ratio_available.dev_attr.attr, - &iio_dev_attr_in_temp_oversampling_ratio_available.dev_attr.attr, -NULL , -}; - -static const struct attribute_group hts221_attribute_group = { - .attrs = hts221_attributes, -}; -static const struct iio_info hts221_info = { - .attrs = &hts221_attribute_group, .read_raw = hts221_read_raw, .write_raw = hts221_write_raw, + .read_avail = hts221_read_avail, .validate_trigger = hts221_validate_trigger, };
PATCH 2/5 iio: humidity: hts221: Add a blank line after variable declarations
In reply to Adi NataImprove code readability per checkpatch warning
--- drivers/iio/humidity/hts221_buffer.c | 1 + 1 file changed, 1 insertion(+)
drivers/iio/humidity/hts221_buffer.c +1 -0
@@ -194,6 +194,7 @@ static irqreturn_t hts221_buffer_handler_thread(int irq, void *p)int hts221_allocate_buffers (struct iio_dev *iio_dev) {struct hts221_hw *hw =iio_priv (iio_dev); +return devm_iio_triggered_buffer_setup (hw->dev, iio_dev,NULL , hts221_buffer_handler_thread, &hts221_buffer_ops);
Signature · 1 line
2.47.3
Re: [PATCH 2/5] iio: humidity: hts221: Add a blank line after variable declarations
Quoted 1 line · Adi Nata
Improve code readability per checkpatch warning
You still need to respect the English grammar and punctuation. Here is missing period.
Signature · 2 lines
With Best Regards, Andy Shevchenko
PATCH 3/5 iio: humidity: hts221: Allow unknown whoami for DT fallback
In reply to Adi NataThe WHOAMI check currently returns -ENODEV when the chip ID is not 0xbc. That rejects Device Tree fallback compatibles.
Keep failing if the WHOAMI register cannot be read. On an unexpected ID, log it and continue so OF fallback matching can work.
Use dev_err_probe() for the read-failure path.
--- drivers/iio/humidity/hts221_core.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-)
drivers/iio/humidity/hts221_core.c +6 -9
@@ -139,16 +139,13 @@ static int hts221_check_whoami(struct hts221_hw *hw)int err, data; err =regmap_read (hw->regmap,HTS221_REG_WHOAMI_ADDR , &data); -if (err <0 ) { -dev_err (hw->dev,"failed to read whoami register\n" ); -return err; - } +if (err <0 ) +return dev_err_probe (hw->dev, err, +"failed to read whoami register\n" ); -if (data !=HTS221_REG_WHOAMI_VAL ) { -dev_err (hw->dev,"wrong whoami {%02x vs %02x}\n" , - data,HTS221_REG_WHOAMI_VAL ); -return -ENODEV ; - } +if (data !=HTS221_REG_WHOAMI_VAL ) +dev_info (hw->dev, +"unexpected whoami 0x%02x, continuing\n" , data);return 0 ; }
Signature · 1 line
2.47.3
Re: [PATCH 3/5] iio: humidity: hts221: Allow unknown whoami for DT fallback
Quoted 7 lines · Adi Nata
The WHOAMI check currently returns
-ENODEVwhen the chip ID is not0xbc. That rejects Device Tree fallback compatibles.Keep failing if the WHOAMI register cannot be read. On an unexpected ID, log it and continue so OF fallback matching can work.
Use
dev_err_probe()for the read-failure path.
...
Quoted 3 lines
static int
hts221_check_whoami(struct hts221_hw *hw)int err, data;
With
struct device *dev = hw->dev;
drivers/iio/humidity/hts221_core.c static int hts221_check_whoami(struct hts221_hw *hw) · line 144
Quoted 8 lines
drivers/iio/humidity/hts221_core.c +3
-4err =regmap_read (hw->regmap,HTS221_REG_WHOAMI_ADDR , &data); -if (err <0 ) { -dev_err (hw->dev,"failed to read whoami register\n" ); -return err; - } +if (err <0 ) +return dev_err_probe (hw->dev, err, +"failed to read whoami register\n" );
return dev_err_probe(dev, err, "failed to read whoami register\n");
(a bit longer, but still fine to have on a single line).
drivers/iio/humidity/hts221_core.c static int hts221_check_whoami(struct hts221_hw *hw) · line 148
Quoted 8 lines
drivers/iio/humidity/hts221_core.c +3
-5-if (data !=HTS221_REG_WHOAMI_VAL ) { -dev_err (hw->dev,"wrong whoami {%02x vs %02x}\n" , - data,HTS221_REG_WHOAMI_VAL ); -return -ENODEV ; - } +if (data !=HTS221_REG_WHOAMI_VAL ) +dev_info (hw->dev, +"unexpected whoami 0x%02x, continuing\n" , data);
dev_info(dev, "unexpected whoami 0x%02x, continuing\n", data);
Signature · 2 lines
With Best Regards, Andy Shevchenko
PATCH 4/5 iio: humidity: hts221: use dev_err_probe() in probe paths
In reply to Adi NataConvert remaining probe-time error logs to dev_err_probe() so the errno is included and deferred probe failures stay quiet.
--- drivers/iio/humidity/hts221_core.c | 30 ++++++++++++------------------ drivers/iio/humidity/hts221_i2c.c | 8 +++----- drivers/iio/humidity/hts221_spi.c | 8 +++----- 3 files changed, 18 insertions(+), 28 deletions(-)
drivers/iio/humidity/hts221_core.c +12 -18
@@ -579,33 +579,27 @@ int hts221_probe(struct device *dev, int irq, const char *name,/* configure humidity sensor */ err =hts221_parse_rh_caldata (hw); -if (err <0 ) { -dev_err (hw->dev,"failed to get rh calibration data\n" ); -return err; - } +if (err <0 ) +return dev_err_probe (hw->dev, err, +"failed to get rh calibration data\n" ); data = hts221_avg_list[HTS221_SENSOR_H ].avg_avl[3 ]; err =hts221_update_avg (hw,HTS221_SENSOR_H , data); -if (err <0 ) { -dev_err (hw->dev,"failed to set rh oversampling ratio\n" ); -return err; - } +if (err <0 ) +return dev_err_probe (hw->dev, err, +"failed to set rh oversampling ratio\n" );/* configure temperature sensor */ err =hts221_parse_temp_caldata (hw); -if (err <0 ) { -dev_err (hw->dev, -"failed to get temperature calibration data\n" ); -return err; - } +if (err <0 ) +return dev_err_probe (hw->dev, err, +"failed to get temperature calibration data\n" ); data = hts221_avg_list[HTS221_SENSOR_T ].avg_avl[3 ]; err =hts221_update_avg (hw,HTS221_SENSOR_T , data); -if (err <0 ) { -dev_err (hw->dev, -"failed to set temperature oversampling ratio\n" ); -return err; - } +if (err <0 ) +return dev_err_probe (hw->dev, err, +"failed to set temperature oversampling ratio\n" );if (hw->irq >0 ) { err =hts221_allocate_buffers (iio_dev);
drivers/iio/humidity/hts221_i2c.c +3 -5
@@ -29,11 +29,9 @@ static int hts221_i2c_probe(struct i2c_client *client)struct regmap *regmap; regmap =devm_regmap_init_i2c (client, &hts221_i2c_regmap_config); -if (IS_ERR (regmap)) { -dev_err (&client->dev,"Failed to register i2c regmap %ld\n" , -PTR_ERR (regmap)); -return PTR_ERR (regmap); - } +if (IS_ERR (regmap)) +return dev_err_probe (&client->dev,PTR_ERR (regmap), +"Failed to register i2c regmap\n" );return hts221_probe (&client->dev, client->irq, client->name, regmap);
drivers/iio/humidity/hts221_spi.c +3 -5
@@ -30,11 +30,9 @@ static int hts221_spi_probe(struct spi_device *spi)struct regmap *regmap; regmap =devm_regmap_init_spi (spi, &hts221_spi_regmap_config); -if (IS_ERR (regmap)) { -dev_err (&spi->dev,"Failed to register spi regmap %ld\n" , -PTR_ERR (regmap)); -return PTR_ERR (regmap); - } +if (IS_ERR (regmap)) +return dev_err_probe (&spi->dev,PTR_ERR (regmap), +"Failed to register spi regmap\n" );return hts221_probe (&spi->dev, spi->irq, spi->modalias, regmap);
Signature · 1 line
2.47.3
Re: [PATCH 4/5] iio: humidity: hts221: use dev_err_probe() in probe paths
Quoted 2 lines · Adi Nata
Convert remaining probe-time error logs to
dev_err_probe()so the errno is included and deferred probe failures stay quiet.
...
drivers/iio/humidity/hts221_core.c int hts221_probe(struct device *dev, int irq, const char *name, · line 584
Quoted 11 lines
drivers/iio/humidity/hts221_core.c +3
-4@@ -579,33 +579,27 @@ int hts221_probe(struct device *dev, int irq, const char *name,/* configure humidity sensor */ err =hts221_parse_rh_caldata (hw); -if (err <0 ) { -dev_err (hw->dev,"failed to get rh calibration data\n" ); -return err; - } +if (err <0 ) +return dev_err_probe (hw->dev, err, +"failed to get rh calibration data\n" );
Why hw->dev and not simply dev?!
Also in all cases.
Signature · 2 lines
With Best Regards, Andy Shevchenko
Re: [PATCH 4/5] iio: humidity: hts221: use dev_err_probe() in probe paths
Hi Andy,
Thank you for your feedback. That is suitable. I will update accordingly on the next version patch.
Regards,
Adi Nata
Quoted 2 lines
Why
hw->devand not simply dev?!
Also in all cases.
PATCH 5/5 iio: humidity: hts221: fix division by zero in calibration parsing
In reply to Adi Natahts221_parse_rh_caldata() and hts221_parse_temp_caldata() divide by (cal_x1 - cal_x0) without checking that the two calibration points differ can cause division by zero.
Reject zero divisor with -EINVAL, logging the offending calibration values. A device with such calibration data cannot produce meaningful scale or offset values anyway.
--- drivers/iio/humidity/hts221_core.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
drivers/iio/humidity/hts221_core.c +20 -0
@@ -276,10 +276,20 @@ static int hts221_parse_temp_caldata(struct hts221_hw *hw)return err; cal_x1 =le16_to_cpu (val); +if (cal_x1 == cal_x0) +return dev_err_probe (hw->dev, -EINVAL , +"invalid temperature calibration points (x0 %d, x1 %d)\n" , + cal_x0, cal_x1); + slope = &hw->sensors[HTS221_SENSOR_T ].slope; b_gen = &hw->sensors[HTS221_SENSOR_T ].b_gen; *slope = ((cal_y1 - cal_y0) *8000 ) / (cal_x1 - cal_x0); +if (!*slope) +return dev_err_probe (hw->dev, -EINVAL , +"invalid temperature calibration slope (y0 %d, y1 %d)\n" , + cal_y0, cal_y1); + *b_gen = (((s32 )cal_x1 * cal_y0 - (s32 )cal_x0 * cal_y1) *1000 ) / (cal_x1 - cal_x0); *b_gen *=8 ;
@@ -315,10 +325,20 @@ static int hts221_parse_rh_caldata(struct hts221_hw *hw)return err; cal_x1 =le16_to_cpu (val); +if (cal_x1 == cal_x0) +return dev_err_probe (hw->dev, -EINVAL , +"invalid rh calibration points (x0 %d, x1 %d)\n" , + cal_x0, cal_x1); + slope = &hw->sensors[HTS221_SENSOR_H ].slope; b_gen = &hw->sensors[HTS221_SENSOR_H ].b_gen; *slope = ((cal_y1 - cal_y0) *8000 ) / (cal_x1 - cal_x0); +if (!*slope) +return dev_err_probe (hw->dev, -EINVAL , +"invalid rh calibration slope (y0 %d, y1 %d)\n" , + cal_y0, cal_y1); + *b_gen = (((s32 )cal_x1 * cal_y0 - (s32 )cal_x0 * cal_y1) *1000 ) / (cal_x1 - cal_x0); *b_gen *=8 ;
Signature · 1 line
2.47.3