From 954c06ddabb0d02bedd7a99a59fcc09173087eee Mon Sep 17 00:00:00 2001 From: Guillaume Stols Date: Tue, 10 Dec 2024 10:46:41 +0000 Subject: [PATCH 1/7] iio: adc: ad7606: Fix hardcoded offset in the ADC channels When introducing num_adc_channels, I overlooked some new functions created in a meanwhile that had also the hardcoded offset. This commit adds the new logic to these functions. Fixes: ef67f16e365c ("iio: adc: ad7606: Introduce num_adc_channels") Signed-off-by: Guillaume Stols Link: https://patch.msgid.link/20241210-ad7606_add_iio_backend_software_mode-v2-1-6619c3e50d81@baylibre.com Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad7606.c | 48 +++++++++++++++++++++++----------------- drivers/iio/adc/ad7606.h | 2 +- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/drivers/iio/adc/ad7606.c b/drivers/iio/adc/ad7606.c index e35d55d03d86..d8e3c7a43678 100644 --- a/drivers/iio/adc/ad7606.c +++ b/drivers/iio/adc/ad7606.c @@ -175,17 +175,17 @@ static const struct iio_chan_spec ad7616_channels[] = { AD7606_CHANNEL(15, 16), }; -static int ad7606c_18bit_chan_scale_setup(struct ad7606_state *st, +static int ad7606c_18bit_chan_scale_setup(struct iio_dev *indio_dev, struct iio_chan_spec *chan, int ch); -static int ad7606c_16bit_chan_scale_setup(struct ad7606_state *st, +static int ad7606c_16bit_chan_scale_setup(struct iio_dev *indio_dev, struct iio_chan_spec *chan, int ch); -static int ad7606_16bit_chan_scale_setup(struct ad7606_state *st, +static int ad7606_16bit_chan_scale_setup(struct iio_dev *indio_dev, struct iio_chan_spec *chan, int ch); -static int ad7607_chan_scale_setup(struct ad7606_state *st, +static int ad7607_chan_scale_setup(struct iio_dev *indio_dev, struct iio_chan_spec *chan, int ch); -static int ad7608_chan_scale_setup(struct ad7606_state *st, +static int ad7608_chan_scale_setup(struct iio_dev *indio_dev, struct iio_chan_spec *chan, int ch); -static int ad7609_chan_scale_setup(struct ad7606_state *st, +static int ad7609_chan_scale_setup(struct iio_dev *indio_dev, struct iio_chan_spec *chan, int ch); const struct ad7606_chip_info ad7605_4_info = { @@ -323,9 +323,10 @@ int ad7606_reset(struct ad7606_state *st) } EXPORT_SYMBOL_NS_GPL(ad7606_reset, "IIO_AD7606"); -static int ad7606_16bit_chan_scale_setup(struct ad7606_state *st, +static int ad7606_16bit_chan_scale_setup(struct iio_dev *indio_dev, struct iio_chan_spec *chan, int ch) { + struct ad7606_state *st = iio_priv(indio_dev); struct ad7606_chan_scale *cs = &st->chan_scales[ch]; if (!st->sw_mode_en) { @@ -345,10 +346,12 @@ static int ad7606_16bit_chan_scale_setup(struct ad7606_state *st, return 0; } -static int ad7606_get_chan_config(struct ad7606_state *st, int ch, +static int ad7606_get_chan_config(struct iio_dev *indio_dev, int ch, bool *bipolar, bool *differential) { - unsigned int num_channels = st->chip_info->num_channels - 1; + struct ad7606_state *st = iio_priv(indio_dev); + unsigned int num_channels = st->chip_info->num_adc_channels; + unsigned int offset = indio_dev->num_channels - st->chip_info->num_adc_channels; struct device *dev = st->dev; int ret; @@ -364,7 +367,7 @@ static int ad7606_get_chan_config(struct ad7606_state *st, int ch, continue; /* channel number (here) is from 1 to num_channels */ - if (reg == 0 || reg > num_channels) { + if (reg < offset || reg > num_channels) { dev_warn(dev, "Invalid channel number (ignoring): %d\n", reg); continue; @@ -399,9 +402,10 @@ static int ad7606_get_chan_config(struct ad7606_state *st, int ch, return 0; } -static int ad7606c_18bit_chan_scale_setup(struct ad7606_state *st, +static int ad7606c_18bit_chan_scale_setup(struct iio_dev *indio_dev, struct iio_chan_spec *chan, int ch) { + struct ad7606_state *st = iio_priv(indio_dev); struct ad7606_chan_scale *cs = &st->chan_scales[ch]; bool bipolar, differential; int ret; @@ -413,7 +417,7 @@ static int ad7606c_18bit_chan_scale_setup(struct ad7606_state *st, return 0; } - ret = ad7606_get_chan_config(st, ch, &bipolar, &differential); + ret = ad7606_get_chan_config(indio_dev, ch, &bipolar, &differential); if (ret) return ret; @@ -455,9 +459,10 @@ static int ad7606c_18bit_chan_scale_setup(struct ad7606_state *st, return 0; } -static int ad7606c_16bit_chan_scale_setup(struct ad7606_state *st, +static int ad7606c_16bit_chan_scale_setup(struct iio_dev *indio_dev, struct iio_chan_spec *chan, int ch) { + struct ad7606_state *st = iio_priv(indio_dev); struct ad7606_chan_scale *cs = &st->chan_scales[ch]; bool bipolar, differential; int ret; @@ -469,7 +474,7 @@ static int ad7606c_16bit_chan_scale_setup(struct ad7606_state *st, return 0; } - ret = ad7606_get_chan_config(st, ch, &bipolar, &differential); + ret = ad7606_get_chan_config(indio_dev, ch, &bipolar, &differential); if (ret) return ret; @@ -512,9 +517,10 @@ static int ad7606c_16bit_chan_scale_setup(struct ad7606_state *st, return 0; } -static int ad7607_chan_scale_setup(struct ad7606_state *st, +static int ad7607_chan_scale_setup(struct iio_dev *indio_dev, struct iio_chan_spec *chan, int ch) { + struct ad7606_state *st = iio_priv(indio_dev); struct ad7606_chan_scale *cs = &st->chan_scales[ch]; cs->range = 0; @@ -523,9 +529,10 @@ static int ad7607_chan_scale_setup(struct ad7606_state *st, return 0; } -static int ad7608_chan_scale_setup(struct ad7606_state *st, +static int ad7608_chan_scale_setup(struct iio_dev *indio_dev, struct iio_chan_spec *chan, int ch) { + struct ad7606_state *st = iio_priv(indio_dev); struct ad7606_chan_scale *cs = &st->chan_scales[ch]; cs->range = 0; @@ -534,9 +541,10 @@ static int ad7608_chan_scale_setup(struct ad7606_state *st, return 0; } -static int ad7609_chan_scale_setup(struct ad7606_state *st, +static int ad7609_chan_scale_setup(struct iio_dev *indio_dev, struct iio_chan_spec *chan, int ch) { + struct ad7606_state *st = iio_priv(indio_dev); struct ad7606_chan_scale *cs = &st->chan_scales[ch]; cs->range = 0; @@ -1146,8 +1154,8 @@ static int ad7606_sw_mode_setup(struct iio_dev *indio_dev) static int ad7606_chan_scales_setup(struct iio_dev *indio_dev) { - unsigned int num_channels = indio_dev->num_channels - 1; struct ad7606_state *st = iio_priv(indio_dev); + unsigned int offset = indio_dev->num_channels - st->chip_info->num_adc_channels; struct iio_chan_spec *chans; size_t size; int ch, ret; @@ -1161,8 +1169,8 @@ static int ad7606_chan_scales_setup(struct iio_dev *indio_dev) memcpy(chans, indio_dev->channels, size); indio_dev->channels = chans; - for (ch = 0; ch < num_channels; ch++) { - ret = st->chip_info->scale_setup_cb(st, &chans[ch + 1], ch); + for (ch = 0; ch < st->chip_info->num_adc_channels; ch++) { + ret = st->chip_info->scale_setup_cb(indio_dev, &chans[ch + offset], ch); if (ret) return ret; } diff --git a/drivers/iio/adc/ad7606.h b/drivers/iio/adc/ad7606.h index 998814a92b82..8778ffe515b3 100644 --- a/drivers/iio/adc/ad7606.h +++ b/drivers/iio/adc/ad7606.h @@ -69,7 +69,7 @@ struct ad7606_state; -typedef int (*ad7606_scale_setup_cb_t)(struct ad7606_state *st, +typedef int (*ad7606_scale_setup_cb_t)(struct iio_dev *indio_dev, struct iio_chan_spec *chan, int ch); /** From 0c45633c3210730ca938772f3f450df6fff82b11 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Fri, 22 Nov 2024 17:36:52 +0000 Subject: [PATCH 2/7] iio: hid-sensor-prox: Fix invalid read_raw for attention The attention channel is a IIO_CHAN_INFO_PROCESSED, not a IIO_CHAN_INFO_RAW. Modify prox_read_raw() to support it. Fixes: 596ef5cf654b ("iio: hid-sensor-prox: Add support for more channels") Signed-off-by: Ricardo Ribalda Acked-by: Srinivas Pandruvada Link: https://patch.msgid.link/20241122-fix-processed-v2-1-b9f606d3b519@chromium.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/hid-sensor-prox.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/iio/light/hid-sensor-prox.c b/drivers/iio/light/hid-sensor-prox.c index c83acbd78275..7ab64f5c623c 100644 --- a/drivers/iio/light/hid-sensor-prox.c +++ b/drivers/iio/light/hid-sensor-prox.c @@ -94,6 +94,7 @@ static int prox_read_raw(struct iio_dev *indio_dev, *val2 = 0; switch (mask) { case IIO_CHAN_INFO_RAW: + case IIO_CHAN_INFO_PROCESSED: if (chan->scan_index >= prox_state->num_channels) return -EINVAL; address = prox_state->channel2usage[chan->scan_index]; From c969c1e56264ecb14a3f92ae53d096f1bbee7f3b Mon Sep 17 00:00:00 2001 From: Axel Haslam Date: Wed, 6 Nov 2024 11:38:24 +0100 Subject: [PATCH 3/7] dt-bindings: iio: dac: ad5791: ldac gpio is active low On the example, the ldac gpio is flagged as active high, when in reality its an active low gpio. Fix the example by using the active low flag for the ldac gpio. Fixes: baaa92d284d5 ("dt-bindings: iio: dac: ad5791: Add optional reset, clr and ldac gpios") Signed-off-by: Axel Haslam Acked-by: Conor Dooley Link: https://patch.msgid.link/20241106103824.579292-1-ahaslam@baylibre.com Signed-off-by: Jonathan Cameron --- Documentation/devicetree/bindings/iio/dac/adi,ad5791.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/iio/dac/adi,ad5791.yaml b/Documentation/devicetree/bindings/iio/dac/adi,ad5791.yaml index 79cb4b78a88a..2bd89e0aa46b 100644 --- a/Documentation/devicetree/bindings/iio/dac/adi,ad5791.yaml +++ b/Documentation/devicetree/bindings/iio/dac/adi,ad5791.yaml @@ -91,7 +91,7 @@ examples: vrefn-supply = <&dac_vrefn>; reset-gpios = <&gpio_bd 16 GPIO_ACTIVE_LOW>; clear-gpios = <&gpio_bd 17 GPIO_ACTIVE_LOW>; - ldac-gpios = <&gpio_bd 18 GPIO_ACTIVE_HIGH>; + ldac-gpios = <&gpio_bd 18 GPIO_ACTIVE_LOW>; }; }; ... From ab09c6cfe01b317f515bcd944668697241a54b9d Mon Sep 17 00:00:00 2001 From: Javier Carrasco Date: Sat, 14 Dec 2024 23:55:50 +0100 Subject: [PATCH 4/7] iio: light: as73211: fix channel handling in only-color triggered buffer The channel index is off by one unit if AS73211_SCAN_MASK_ALL is not set (optimized path for color channel readings), and it must be shifted instead of leaving an empty channel for the temperature when it is off. Once the channel index is fixed, the uninitialized channel must be set to zero to avoid pushing uninitialized data. Add available_scan_masks for all channels and only-color channels to let the IIO core demux and repack the enabled channels. Cc: stable@vger.kernel.org Fixes: 403e5586b52e ("iio: light: as73211: New driver") Tested-by: Christian Eggers Signed-off-by: Javier Carrasco Link: https://patch.msgid.link/20241214-iio_memset_scan_holes-v4-1-260b395b8ed5@gmail.com Signed-off-by: Jonathan Cameron --- drivers/iio/light/as73211.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/drivers/iio/light/as73211.c b/drivers/iio/light/as73211.c index be0068081ebb..11fbdcdd26d6 100644 --- a/drivers/iio/light/as73211.c +++ b/drivers/iio/light/as73211.c @@ -177,6 +177,12 @@ struct as73211_data { BIT(AS73211_SCAN_INDEX_TEMP) | \ AS73211_SCAN_MASK_COLOR) +static const unsigned long as73211_scan_masks[] = { + AS73211_SCAN_MASK_COLOR, + AS73211_SCAN_MASK_ALL, + 0 +}; + static const struct iio_chan_spec as73211_channels[] = { { .type = IIO_TEMP, @@ -672,9 +678,12 @@ static irqreturn_t as73211_trigger_handler(int irq __always_unused, void *p) /* AS73211 starts reading at address 2 */ ret = i2c_master_recv(data->client, - (char *)&scan.chan[1], 3 * sizeof(scan.chan[1])); + (char *)&scan.chan[0], 3 * sizeof(scan.chan[0])); if (ret < 0) goto done; + + /* Avoid pushing uninitialized data */ + scan.chan[3] = 0; } if (data_result) { @@ -682,9 +691,15 @@ static irqreturn_t as73211_trigger_handler(int irq __always_unused, void *p) * Saturate all channels (in case of overflows). Temperature channel * is not affected by overflows. */ - scan.chan[1] = cpu_to_le16(U16_MAX); - scan.chan[2] = cpu_to_le16(U16_MAX); - scan.chan[3] = cpu_to_le16(U16_MAX); + if (*indio_dev->active_scan_mask == AS73211_SCAN_MASK_ALL) { + scan.chan[1] = cpu_to_le16(U16_MAX); + scan.chan[2] = cpu_to_le16(U16_MAX); + scan.chan[3] = cpu_to_le16(U16_MAX); + } else { + scan.chan[0] = cpu_to_le16(U16_MAX); + scan.chan[1] = cpu_to_le16(U16_MAX); + scan.chan[2] = cpu_to_le16(U16_MAX); + } } iio_push_to_buffers_with_timestamp(indio_dev, &scan, iio_get_time_ns(indio_dev)); @@ -758,6 +773,7 @@ static int as73211_probe(struct i2c_client *client) indio_dev->channels = data->spec_dev->channels; indio_dev->num_channels = data->spec_dev->num_channels; indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->available_scan_masks = as73211_scan_masks; ret = i2c_smbus_read_byte_data(data->client, AS73211_REG_OSR); if (ret < 0) From 20eb1fae4145bc45717aa8a6d05fcd6a64ed856a Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 8 Jan 2025 12:37:22 +0300 Subject: [PATCH 5/7] iio: chemical: bme680: Fix uninitialized variable in __bme680_read_raw() The bme680_read_temp() function takes a pointer to s16 but we're passing an int pointer to it. This will not work on big endian systems and it also means that the other 16 bits are uninitialized. Pass an s16 type variable. Fixes: f51171ce2236 ("iio: chemical: bme680: Add SCALE and RAW channels") Signed-off-by: Dan Carpenter Acked-by: Vasileios Amoiridis Link: https://patch.msgid.link/4addb68c-853a-49fc-8d40-739e78db5fa1@stanley.mountain Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/chemical/bme680_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/iio/chemical/bme680_core.c b/drivers/iio/chemical/bme680_core.c index d12270409c8a..a2949daf9467 100644 --- a/drivers/iio/chemical/bme680_core.c +++ b/drivers/iio/chemical/bme680_core.c @@ -874,11 +874,11 @@ static int bme680_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_RAW: switch (chan->type) { case IIO_TEMP: - ret = bme680_read_temp(data, (s16 *)&chan_val); + ret = bme680_read_temp(data, &temp_chan_val); if (ret) return ret; - *val = chan_val; + *val = temp_chan_val; return IIO_VAL_INT; case IIO_PRESSURE: ret = bme680_read_press(data, &chan_val); From 1e758b613212b6964518a67939535910b5aee831 Mon Sep 17 00:00:00 2001 From: Angelo Dureghello Date: Wed, 8 Jan 2025 18:29:15 +0100 Subject: [PATCH 6/7] iio: dac: ad3552r-common: fix ad3541/2r ranges Fix ad3541/2r voltage ranges to be as per ad3542r datasheet, rev. C, table 38 (page 57). The wrong ad354xr ranges was generating erroneous Vpp output. In more details: - fix wrong number of ranges, they are 5 ranges, not 6, - remove non-existent 0-3V range, - adjust order, since ad3552r_find_range() get a wrong index, producing a wrong Vpp as output. Retested all the ranges on real hardware, EVALAD3542RFMCZ: adi,output-range-microvolt (fdt): <(000000) (2500000)>; ok (Rfbx1, switch 10) <(000000) (5000000)>; ok (Rfbx1, switch 10) <(000000) (10000000)>; ok (Rfbx1, switch 10) <(-5000000) (5000000)>; ok (Rfbx2, switch +/- 5) <(-2500000) (7500000)>; ok (Rfbx2, switch -2.5/7.5) Fixes: 8f2b54824b28 ("drivers:iio:dac: Add AD3552R driver support") Signed-off-by: Angelo Dureghello Reviewed-by: David Lechner Link: https://patch.msgid.link/20250108-wip-bl-ad3552r-axi-v0-iio-testing-carlos-v2-1-2dac02f04638@baylibre.com Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ad3552r-common.c | 5 ++--- drivers/iio/dac/ad3552r.h | 8 +++----- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/iio/dac/ad3552r-common.c b/drivers/iio/dac/ad3552r-common.c index 0f495df2e5ce..03e0864f5084 100644 --- a/drivers/iio/dac/ad3552r-common.c +++ b/drivers/iio/dac/ad3552r-common.c @@ -22,11 +22,10 @@ EXPORT_SYMBOL_NS_GPL(ad3552r_ch_ranges, "IIO_AD3552R"); const s32 ad3542r_ch_ranges[AD3542R_MAX_RANGES][2] = { [AD3542R_CH_OUTPUT_RANGE_0__2P5V] = { 0, 2500 }, - [AD3542R_CH_OUTPUT_RANGE_0__3V] = { 0, 3000 }, [AD3542R_CH_OUTPUT_RANGE_0__5V] = { 0, 5000 }, [AD3542R_CH_OUTPUT_RANGE_0__10V] = { 0, 10000 }, - [AD3542R_CH_OUTPUT_RANGE_NEG_2P5__7P5V] = { -2500, 7500 }, - [AD3542R_CH_OUTPUT_RANGE_NEG_5__5V] = { -5000, 5000 } + [AD3542R_CH_OUTPUT_RANGE_NEG_5__5V] = { -5000, 5000 }, + [AD3542R_CH_OUTPUT_RANGE_NEG_2P5__7P5V] = { -2500, 7500 } }; EXPORT_SYMBOL_NS_GPL(ad3542r_ch_ranges, "IIO_AD3552R"); diff --git a/drivers/iio/dac/ad3552r.h b/drivers/iio/dac/ad3552r.h index fd5a3dfd1d1c..4b5581039ae9 100644 --- a/drivers/iio/dac/ad3552r.h +++ b/drivers/iio/dac/ad3552r.h @@ -131,7 +131,7 @@ #define AD3552R_CH1_ACTIVE BIT(1) #define AD3552R_MAX_RANGES 5 -#define AD3542R_MAX_RANGES 6 +#define AD3542R_MAX_RANGES 5 #define AD3552R_QUAD_SPI 2 extern const s32 ad3552r_ch_ranges[AD3552R_MAX_RANGES][2]; @@ -189,16 +189,14 @@ enum ad3552r_ch_vref_select { enum ad3542r_ch_output_range { /* Range from 0 V to 2.5 V. Requires Rfb1x connection */ AD3542R_CH_OUTPUT_RANGE_0__2P5V, - /* Range from 0 V to 3 V. Requires Rfb1x connection */ - AD3542R_CH_OUTPUT_RANGE_0__3V, /* Range from 0 V to 5 V. Requires Rfb1x connection */ AD3542R_CH_OUTPUT_RANGE_0__5V, /* Range from 0 V to 10 V. Requires Rfb2x connection */ AD3542R_CH_OUTPUT_RANGE_0__10V, - /* Range from -2.5 V to 7.5 V. Requires Rfb2x connection */ - AD3542R_CH_OUTPUT_RANGE_NEG_2P5__7P5V, /* Range from -5 V to 5 V. Requires Rfb2x connection */ AD3542R_CH_OUTPUT_RANGE_NEG_5__5V, + /* Range from -2.5 V to 7.5 V. Requires Rfb2x connection */ + AD3542R_CH_OUTPUT_RANGE_NEG_2P5__7P5V, }; enum ad3552r_ch_output_range { From 012b8276f08a67b9f2e2fd0f35363ae4a75e5267 Mon Sep 17 00:00:00 2001 From: Angelo Dureghello Date: Wed, 8 Jan 2025 18:29:16 +0100 Subject: [PATCH 7/7] iio: dac: ad3552r-hs: clear reset status flag Clear reset status flag, to keep error status register clean after reset (ad3552r manual, rev B table 38). Reset error flag was left to 1, so debugging registers, the "Error Status Register" was dirty (0x01). It is important to clear this bit, so if there is any reset event over normal working mode, it is possible to detect it. Fixes: 0b4d9fe58be8 ("iio: dac: ad3552r: add high-speed platform driver") Signed-off-by: Angelo Dureghello Reviewed-by: David Lechner Link: https://patch.msgid.link/20250108-wip-bl-ad3552r-axi-v0-iio-testing-carlos-v2-2-2dac02f04638@baylibre.com Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ad3552r-hs.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/iio/dac/ad3552r-hs.c b/drivers/iio/dac/ad3552r-hs.c index 216c634f3eaf..8974df625670 100644 --- a/drivers/iio/dac/ad3552r-hs.c +++ b/drivers/iio/dac/ad3552r-hs.c @@ -329,6 +329,12 @@ static int ad3552r_hs_setup(struct ad3552r_hs_state *st) dev_info(st->dev, "Chip ID error. Expected 0x%x, Read 0x%x\n", AD3552R_ID, id); + /* Clear reset error flag, see ad3552r manual, rev B table 38. */ + ret = st->data->bus_reg_write(st->back, AD3552R_REG_ADDR_ERR_STATUS, + AD3552R_MASK_RESET_STATUS, 1); + if (ret) + return ret; + ret = st->data->bus_reg_write(st->back, AD3552R_REG_ADDR_SH_REFERENCE_CONFIG, 0, 1);