* [PATCH 0/2] iio: adc: ad9467: fixes for ad9434
@ 2025-12-01 11:59 Tomas Melin
2025-12-01 11:59 ` [PATCH 1/2] iio: adc: ad9467: fix ad9434 vref mask Tomas Melin
2025-12-01 11:59 ` [PATCH 2/2] iio: adc: ad9467: support write/read offset Tomas Melin
0 siblings, 2 replies; 9+ messages in thread
From: Tomas Melin @ 2025-12-01 11:59 UTC (permalink / raw)
To: Lars-Peter Clausen, Michael Hennerich, Nuno Sa, Jonathan Cameron,
David Lechner, Andy Shevchenko, Alexandru Ardelean
Cc: Michael Hennerich, Jonathan Cameron, linux-iio, linux-kernel,
Tomas Melin
Add support for setting offset range for the ad9434 and fixup
vref mask handling.
Signed-off-by: Tomas Melin <tomas.melin@vaisala.com>
---
Tomas Melin (2):
iio: adc: ad9467: fix ad9434 vref mask
iio: adc: ad9467: support write/read offset
drivers/iio/adc/ad9467.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 58 insertions(+), 2 deletions(-)
---
base-commit: 9b9e43704d2b05514aeeaea36311addba2c72408
change-id: 20251201-ad9434-fixes-6dfdc86fb881
Best regards,
--
Tomas Melin <tomas.melin@vaisala.com>
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH 1/2] iio: adc: ad9467: fix ad9434 vref mask 2025-12-01 11:59 [PATCH 0/2] iio: adc: ad9467: fixes for ad9434 Tomas Melin @ 2025-12-01 11:59 ` Tomas Melin 2025-12-01 13:49 ` Andy Shevchenko 2025-12-01 11:59 ` [PATCH 2/2] iio: adc: ad9467: support write/read offset Tomas Melin 1 sibling, 1 reply; 9+ messages in thread From: Tomas Melin @ 2025-12-01 11:59 UTC (permalink / raw) To: Lars-Peter Clausen, Michael Hennerich, Nuno Sa, Jonathan Cameron, David Lechner, Andy Shevchenko, Alexandru Ardelean Cc: Michael Hennerich, Jonathan Cameron, linux-iio, linux-kernel, Tomas Melin The mask setting is 5 bits wide for the ad9434 (ref. data sheet register 0x18 FLEX_VREF). Apparently the settings from ad9265 were copied by mistake when support for the device was added to the driver. Fixes: 4606d0f4b05f ("iio: adc: ad9467: add support for AD9434 high-speed ADC") Signed-off-by: Tomas Melin <tomas.melin@vaisala.com> --- drivers/iio/adc/ad9467.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/adc/ad9467.c b/drivers/iio/adc/ad9467.c index f7a9f46ea0dc405e25f312197df4b2131871b4bc..2910b6c5b576d101a25c0b5f0fb9024f0b4da63d 100644 --- a/drivers/iio/adc/ad9467.c +++ b/drivers/iio/adc/ad9467.c @@ -95,7 +95,7 @@ #define CHIPID_AD9434 0x6A #define AD9434_DEF_OUTPUT_MODE 0x00 -#define AD9434_REG_VREF_MASK 0xC0 +#define AD9434_REG_VREF_MASK 0x1F /* * Analog Devices AD9467 16-Bit, 200/250 MSPS ADC -- 2.47.3 ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/2] iio: adc: ad9467: fix ad9434 vref mask 2025-12-01 11:59 ` [PATCH 1/2] iio: adc: ad9467: fix ad9434 vref mask Tomas Melin @ 2025-12-01 13:49 ` Andy Shevchenko 0 siblings, 0 replies; 9+ messages in thread From: Andy Shevchenko @ 2025-12-01 13:49 UTC (permalink / raw) To: Tomas Melin Cc: Lars-Peter Clausen, Michael Hennerich, Nuno Sa, Jonathan Cameron, David Lechner, Andy Shevchenko, Alexandru Ardelean, Jonathan Cameron, linux-iio, linux-kernel On Mon, Dec 1, 2025 at 2:00 PM Tomas Melin <tomas.melin@vaisala.com> wrote: > > The mask setting is 5 bits wide for the ad9434 > (ref. data sheet register 0x18 FLEX_VREF). Apparently the settings > from ad9265 were copied by mistake when support for the device was added > to the driver. ... > -#define AD9434_REG_VREF_MASK 0xC0 > +#define AD9434_REG_VREF_MASK 0x1F Can you switch to use GENMASK() while at it? -- With Best Regards, Andy Shevchenko ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/2] iio: adc: ad9467: support write/read offset 2025-12-01 11:59 [PATCH 0/2] iio: adc: ad9467: fixes for ad9434 Tomas Melin 2025-12-01 11:59 ` [PATCH 1/2] iio: adc: ad9467: fix ad9434 vref mask Tomas Melin @ 2025-12-01 11:59 ` Tomas Melin 2025-12-01 13:59 ` Andy Shevchenko 2025-12-01 17:40 ` David Lechner 1 sibling, 2 replies; 9+ messages in thread From: Tomas Melin @ 2025-12-01 11:59 UTC (permalink / raw) To: Lars-Peter Clausen, Michael Hennerich, Nuno Sa, Jonathan Cameron, David Lechner, Andy Shevchenko, Alexandru Ardelean Cc: Michael Hennerich, Jonathan Cameron, linux-iio, linux-kernel, Tomas Melin Support configuring output offset value. Among the devices currently supported by this driver, this setting is specific to ad9434. Signed-off-by: Tomas Melin <tomas.melin@vaisala.com> --- drivers/iio/adc/ad9467.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/drivers/iio/adc/ad9467.c b/drivers/iio/adc/ad9467.c index 2910b6c5b576d101a25c0b5f0fb9024f0b4da63d..41b29e9e765b4296358bb277d63993889ce46290 100644 --- a/drivers/iio/adc/ad9467.c +++ b/drivers/iio/adc/ad9467.c @@ -145,6 +145,7 @@ struct ad9467_chip_info { unsigned int num_lanes; unsigned int dco_en; unsigned int test_points; + const int *offset_range; /* data clock output */ bool has_dco; bool has_dco_invert; @@ -234,6 +235,10 @@ static int ad9467_reg_access(struct iio_dev *indio_dev, unsigned int reg, return 0; } +static const int ad9434_offset_range[] = { + -128, 1, 127, +}; + static const unsigned int ad9265_scale_table[][2] = { {1250, 0x00}, {1500, 0x40}, {1750, 0x80}, {2000, 0xC0}, }; @@ -281,6 +286,23 @@ static void __ad9467_get_scale(struct ad9467_state *st, int index, *val2 = tmp % 1000000; } +#define AD9434_CHAN(_chan, avai_mask, _si, _bits, _sign) \ +{ \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = _chan, \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ + BIT(IIO_CHAN_INFO_OFFSET), \ + .info_mask_shared_by_type_available = avai_mask, \ + .scan_index = _si, \ + .scan_type = { \ + .sign = _sign, \ + .realbits = _bits, \ + .storagebits = 16, \ + }, \ +} + #define AD9467_CHAN(_chan, avai_mask, _si, _bits, _sign) \ { \ .type = IIO_VOLTAGE, \ @@ -298,7 +320,8 @@ static void __ad9467_get_scale(struct ad9467_state *st, int index, } static const struct iio_chan_spec ad9434_channels[] = { - AD9467_CHAN(0, BIT(IIO_CHAN_INFO_SCALE), 0, 12, 's'), + AD9434_CHAN(0, BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_OFFSET), + 0, 12, 's'), }; static const struct iio_chan_spec ad9467_channels[] = { @@ -367,6 +390,7 @@ static const struct ad9467_chip_info ad9434_chip_tbl = { .default_output_mode = AD9434_DEF_OUTPUT_MODE, .vref_mask = AD9434_REG_VREF_MASK, .num_lanes = 6, + .offset_range = ad9434_offset_range, }; static const struct ad9467_chip_info ad9265_chip_tbl = { @@ -499,6 +523,29 @@ static int ad9467_set_scale(struct ad9467_state *st, int val, int val2) return -EINVAL; } +static int ad9467_get_offset(struct ad9467_state *st, int *val) +{ + *val = ad9467_spi_read(st, AN877_ADC_REG_OFFSET); + if (*val < 0) + return *val; + + return IIO_VAL_INT; +} + +static int ad9467_set_offset(struct ad9467_state *st, int val) +{ + int ret; + + if (val < st->info->offset_range[0] || val > st->info->offset_range[2]) + return -EINVAL; + + ret = ad9467_spi_write(st, AN877_ADC_REG_OFFSET, val); + if (ret < 0) + return ret; + return ad9467_spi_write(st, AN877_ADC_REG_TRANSFER, + AN877_ADC_TRANSFER_SYNC); +} + static int ad9467_outputmode_set(struct ad9467_state *st, unsigned int mode) { int ret; @@ -802,6 +849,8 @@ static int ad9467_read_raw(struct iio_dev *indio_dev, struct ad9467_state *st = iio_priv(indio_dev); switch (m) { + case IIO_CHAN_INFO_OFFSET: + return ad9467_get_offset(st, val); case IIO_CHAN_INFO_SCALE: return ad9467_get_scale(st, val, val2); case IIO_CHAN_INFO_SAMP_FREQ: @@ -836,6 +885,8 @@ static int ad9467_write_raw(struct iio_dev *indio_dev, int ret; switch (mask) { + case IIO_CHAN_INFO_OFFSET: + return ad9467_set_offset(st, val); case IIO_CHAN_INFO_SCALE: return ad9467_set_scale(st, val, val2); case IIO_CHAN_INFO_SAMP_FREQ: @@ -874,6 +925,11 @@ static int ad9467_read_avail(struct iio_dev *indio_dev, const struct ad9467_chip_info *info = st->info; switch (mask) { + case IIO_CHAN_INFO_OFFSET: + *type = IIO_VAL_INT; + *vals = info->offset_range; + *length = 3; + return IIO_AVAIL_RANGE; case IIO_CHAN_INFO_SCALE: *vals = (const int *)st->scales; *type = IIO_VAL_INT_PLUS_MICRO; -- 2.47.3 ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] iio: adc: ad9467: support write/read offset 2025-12-01 11:59 ` [PATCH 2/2] iio: adc: ad9467: support write/read offset Tomas Melin @ 2025-12-01 13:59 ` Andy Shevchenko 2025-12-02 10:03 ` Tomas Melin 2025-12-01 17:40 ` David Lechner 1 sibling, 1 reply; 9+ messages in thread From: Andy Shevchenko @ 2025-12-01 13:59 UTC (permalink / raw) To: Tomas Melin Cc: Lars-Peter Clausen, Michael Hennerich, Nuno Sa, Jonathan Cameron, David Lechner, Andy Shevchenko, Alexandru Ardelean, Jonathan Cameron, linux-iio, linux-kernel On Mon, Dec 1, 2025 at 2:00 PM Tomas Melin <tomas.melin@vaisala.com> wrote: > > Support configuring output offset value. Among the devices > currently supported by this driver, this setting is specific to > ad9434. ... > +#define AD9434_CHAN(_chan, avai_mask, _si, _bits, _sign) \ > +{ \ > + .type = IIO_VOLTAGE, \ > + .indexed = 1, \ > + .channel = _chan, \ > + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ > + BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ > + BIT(IIO_CHAN_INFO_OFFSET), \ > + .info_mask_shared_by_type_available = avai_mask, \ Okay, this macro uses parameterized avai_mask (which should be spelled correctly and probably in parentheses, but it's not the point) and it's being called only once. Why can't we just embed it for now? > + .scan_index = _si, \ > + .scan_type = { \ > + .sign = _sign, \ > + .realbits = _bits, \ > + .storagebits = 16, \ > + }, \ > +} Also, looking at the existing macro below, I think you should have a common, parameterised macro and then 3 different on top of it for this case, and for the existing two. Does it make sense? > #define AD9467_CHAN(_chan, avai_mask, _si, _bits, _sign) \ ... > static const struct iio_chan_spec ad9434_channels[] = { > - AD9467_CHAN(0, BIT(IIO_CHAN_INFO_SCALE), 0, 12, 's'), > + AD9434_CHAN(0, BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_OFFSET), > + 0, 12, 's'), > }; Also the first and third parameters are identical in all cases, can we for now just make them using a single parameter? ... > +static int ad9467_get_offset(struct ad9467_state *st, int *val) > +{ > + *val = ad9467_spi_read(st, AN877_ADC_REG_OFFSET); > + if (*val < 0) > + return *val; The standard pattern is to avoid polluting the output in case of known errors. Hence int ret; ret = ad9467_spi_read(st, AN877_ADC_REG_OFFSET); if (ret < 0) return ret; *val = ret; > + return IIO_VAL_INT; > +} ... > + if (val < st->info->offset_range[0] || val > st->info->offset_range[2]) > + return -EINVAL; Wondering if at some point we can switch to in_range(). And we perhaps need a new generic macro to supply start/end instead of start/size. -- With Best Regards, Andy Shevchenko ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] iio: adc: ad9467: support write/read offset 2025-12-01 13:59 ` Andy Shevchenko @ 2025-12-02 10:03 ` Tomas Melin 2025-12-02 14:36 ` Andy Shevchenko 0 siblings, 1 reply; 9+ messages in thread From: Tomas Melin @ 2025-12-02 10:03 UTC (permalink / raw) To: Andy Shevchenko Cc: Lars-Peter Clausen, Michael Hennerich, Nuno Sa, Jonathan Cameron, David Lechner, Andy Shevchenko, Alexandru Ardelean, Jonathan Cameron, linux-iio, linux-kernel Hi Andy, On 01/12/2025 15:59, Andy Shevchenko wrote: > On Mon, Dec 1, 2025 at 2:00 PM Tomas Melin <tomas.melin@vaisala.com> wrote: >> >> Support configuring output offset value. Among the devices >> currently supported by this driver, this setting is specific to >> ad9434. > > ... > >> +#define AD9434_CHAN(_chan, avai_mask, _si, _bits, _sign) \ >> +{ \ >> + .type = IIO_VOLTAGE, \ >> + .indexed = 1, \ >> + .channel = _chan, \ >> + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ >> + BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ >> + BIT(IIO_CHAN_INFO_OFFSET), \ >> + .info_mask_shared_by_type_available = avai_mask, \ > > Okay, this macro uses parameterized avai_mask (which should be spelled > correctly and probably in parentheses, but it's not the point) and > it's being called only once. Why can't we just embed it for now? Sure, I'm ok with embedding if that is preferred. > > >> + .scan_index = _si, \ >> + .scan_type = { \ >> + .sign = _sign, \ >> + .realbits = _bits, \ >> + .storagebits = 16, \ >> + }, \ >> +} > > Also, looking at the existing macro below, I think you should have a > common, parameterised macro and then 3 different on top of it for this > case, and for the existing two. > > Does it make sense? Keeping this and embedding the ad9434 declaration. > >> #define AD9467_CHAN(_chan, avai_mask, _si, _bits, _sign) \ > > ... > >> static const struct iio_chan_spec ad9434_channels[] = { >> - AD9467_CHAN(0, BIT(IIO_CHAN_INFO_SCALE), 0, 12, 's'), >> + AD9434_CHAN(0, BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_OFFSET), >> + 0, 12, 's'), >> }; > > Also the first and third parameters are identical in all cases, can we > for now just make them using a single parameter? > > ... > >> +static int ad9467_get_offset(struct ad9467_state *st, int *val) >> +{ >> + *val = ad9467_spi_read(st, AN877_ADC_REG_OFFSET); >> + if (*val < 0) >> + return *val; > > The standard pattern is to avoid polluting the output in case of known > errors. Hence > > int ret; > > ret = ad9467_spi_read(st, AN877_ADC_REG_OFFSET); > if (ret < 0) > return ret; > > *val = ret; ok, will change to this format. > >> + return IIO_VAL_INT; >> +} > > > ... > >> + if (val < st->info->offset_range[0] || val > st->info->offset_range[2]) >> + return -EINVAL; > > Wondering if at some point we can switch to in_range(). And we perhaps > need a new generic macro to supply start/end instead of start/size. Atleast drop-in usage of in_range() does not seems feasible? Thanks, Tomas > ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] iio: adc: ad9467: support write/read offset 2025-12-02 10:03 ` Tomas Melin @ 2025-12-02 14:36 ` Andy Shevchenko 0 siblings, 0 replies; 9+ messages in thread From: Andy Shevchenko @ 2025-12-02 14:36 UTC (permalink / raw) To: Tomas Melin Cc: Andy Shevchenko, Lars-Peter Clausen, Michael Hennerich, Nuno Sa, Jonathan Cameron, David Lechner, Andy Shevchenko, Alexandru Ardelean, Jonathan Cameron, linux-iio, linux-kernel On Tue, Dec 02, 2025 at 12:03:21PM +0200, Tomas Melin wrote: > On 01/12/2025 15:59, Andy Shevchenko wrote: > > On Mon, Dec 1, 2025 at 2:00 PM Tomas Melin <tomas.melin@vaisala.com> wrote: ... > >> +#define AD9434_CHAN(_chan, avai_mask, _si, _bits, _sign) \ > >> +{ \ > >> + .type = IIO_VOLTAGE, \ > >> + .indexed = 1, \ > >> + .channel = _chan, \ > >> + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ > >> + BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ > >> + BIT(IIO_CHAN_INFO_OFFSET), \ > >> + .info_mask_shared_by_type_available = avai_mask, \ > > > > Okay, this macro uses parameterized avai_mask (which should be spelled > > correctly and probably in parentheses, but it's not the point) and > > it's being called only once. Why can't we just embed it for now? > > Sure, I'm ok with embedding if that is preferred. I meant to embed the one of the _chan/_si parameter, not the entire macro. And with comment about index vs. channel, it seems one of them is not needed at all. > >> + .scan_index = _si, \ > >> + .scan_type = { \ > >> + .sign = _sign, \ > >> + .realbits = _bits, \ > >> + .storagebits = 16, \ > >> + }, \ > >> +} > > > > Also, looking at the existing macro below, I think you should have a > > common, parameterised macro and then 3 different on top of it for this > > case, and for the existing two. > > > > Does it make sense? > Keeping this and embedding the ad9434 declaration. Answered to v2. I think the macro approach is better due to consistency. > >> #define AD9467_CHAN(_chan, avai_mask, _si, _bits, _sign) \ ... > >> static const struct iio_chan_spec ad9434_channels[] = { > >> - AD9467_CHAN(0, BIT(IIO_CHAN_INFO_SCALE), 0, 12, 's'), > >> + AD9434_CHAN(0, BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_OFFSET), > >> + 0, 12, 's'), > >> }; > > > > Also the first and third parameters are identical in all cases, can we > > for now just make them using a single parameter? ... > >> + if (val < st->info->offset_range[0] || val > st->info->offset_range[2]) > >> + return -EINVAL; > > > > Wondering if at some point we can switch to in_range(). And we perhaps > > need a new generic macro to supply start/end instead of start/size. > Atleast drop-in usage of in_range() does not seems feasible? I know, that's why it starts with "wondering" and continues with "perhaps". -- With Best Regards, Andy Shevchenko ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] iio: adc: ad9467: support write/read offset 2025-12-01 11:59 ` [PATCH 2/2] iio: adc: ad9467: support write/read offset Tomas Melin 2025-12-01 13:59 ` Andy Shevchenko @ 2025-12-01 17:40 ` David Lechner 2025-12-02 10:20 ` Tomas Melin 1 sibling, 1 reply; 9+ messages in thread From: David Lechner @ 2025-12-01 17:40 UTC (permalink / raw) To: Tomas Melin, Lars-Peter Clausen, Michael Hennerich, Nuno Sa, Jonathan Cameron, Andy Shevchenko, Alexandru Ardelean Cc: Jonathan Cameron, linux-iio, linux-kernel On 12/1/25 5:59 AM, Tomas Melin wrote: > Support configuring output offset value. Among the devices > currently supported by this driver, this setting is specific to > ad9434. What is the purpose of adjusting the offset. If it is to compensate e.g. for manufacturing variations, the CALIBBIAS might be a better choice. In any case, the commit message should explain a bit better the intended use. > > Signed-off-by: Tomas Melin <tomas.melin@vaisala.com> > --- > drivers/iio/adc/ad9467.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 57 insertions(+), 1 deletion(-) > > diff --git a/drivers/iio/adc/ad9467.c b/drivers/iio/adc/ad9467.c > index 2910b6c5b576d101a25c0b5f0fb9024f0b4da63d..41b29e9e765b4296358bb277d63993889ce46290 100644 > --- a/drivers/iio/adc/ad9467.c > +++ b/drivers/iio/adc/ad9467.c > @@ -145,6 +145,7 @@ struct ad9467_chip_info { > unsigned int num_lanes; > unsigned int dco_en; > unsigned int test_points; > + const int *offset_range; > /* data clock output */ > bool has_dco; > bool has_dco_invert; > @@ -234,6 +235,10 @@ static int ad9467_reg_access(struct iio_dev *indio_dev, unsigned int reg, > return 0; > } > > +static const int ad9434_offset_range[] = { > + -128, 1, 127, > +}; > + > static const unsigned int ad9265_scale_table[][2] = { > {1250, 0x00}, {1500, 0x40}, {1750, 0x80}, {2000, 0xC0}, > }; > @@ -281,6 +286,23 @@ static void __ad9467_get_scale(struct ad9467_state *st, int index, > *val2 = tmp % 1000000; > } > > +#define AD9434_CHAN(_chan, avai_mask, _si, _bits, _sign) \ > +{ \ > + .type = IIO_VOLTAGE, \ > + .indexed = 1, \ > + .channel = _chan, \ > + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ > + BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ > + BIT(IIO_CHAN_INFO_OFFSET), \ > + .info_mask_shared_by_type_available = avai_mask, \ > + .scan_index = _si, \ > + .scan_type = { \ > + .sign = _sign, \ > + .realbits = _bits, \ > + .storagebits = 16, \ > + }, \ > +} > + > #define AD9467_CHAN(_chan, avai_mask, _si, _bits, _sign) \ > { \ > .type = IIO_VOLTAGE, \ > @@ -298,7 +320,8 @@ static void __ad9467_get_scale(struct ad9467_state *st, int index, > } > > static const struct iio_chan_spec ad9434_channels[] = { > - AD9467_CHAN(0, BIT(IIO_CHAN_INFO_SCALE), 0, 12, 's'), > + AD9434_CHAN(0, BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_OFFSET), > + 0, 12, 's'), > }; > > static const struct iio_chan_spec ad9467_channels[] = { > @@ -367,6 +390,7 @@ static const struct ad9467_chip_info ad9434_chip_tbl = { > .default_output_mode = AD9434_DEF_OUTPUT_MODE, > .vref_mask = AD9434_REG_VREF_MASK, > .num_lanes = 6, > + .offset_range = ad9434_offset_range, > }; > > static const struct ad9467_chip_info ad9265_chip_tbl = { > @@ -499,6 +523,29 @@ static int ad9467_set_scale(struct ad9467_state *st, int val, int val2) > return -EINVAL; > } > > +static int ad9467_get_offset(struct ad9467_state *st, int *val) > +{ > + *val = ad9467_spi_read(st, AN877_ADC_REG_OFFSET); > + if (*val < 0) > + return *val; Since processed value is (raw + offset) * scale, this means that the offset will be applied twice, once in hardware and once in software. I don't think that is the intended case here? > + > + return IIO_VAL_INT; > +} > + > +static int ad9467_set_offset(struct ad9467_state *st, int val) > +{ > + int ret; > + > + if (val < st->info->offset_range[0] || val > st->info->offset_range[2]) > + return -EINVAL; > + > + ret = ad9467_spi_write(st, AN877_ADC_REG_OFFSET, val); > + if (ret < 0) > + return ret; This could use a comment explaining why we need to do the sync after adjusting the offset. > + return ad9467_spi_write(st, AN877_ADC_REG_TRANSFER, > + AN877_ADC_TRANSFER_SYNC); > +} > + > static int ad9467_outputmode_set(struct ad9467_state *st, unsigned int mode) > { > int ret; > @@ -802,6 +849,8 @@ static int ad9467_read_raw(struct iio_dev *indio_dev, > struct ad9467_state *st = iio_priv(indio_dev); > > switch (m) { > + case IIO_CHAN_INFO_OFFSET: > + return ad9467_get_offset(st, val); > case IIO_CHAN_INFO_SCALE: > return ad9467_get_scale(st, val, val2); > case IIO_CHAN_INFO_SAMP_FREQ: > @@ -836,6 +885,8 @@ static int ad9467_write_raw(struct iio_dev *indio_dev, > int ret; > > switch (mask) { > + case IIO_CHAN_INFO_OFFSET: > + return ad9467_set_offset(st, val); > case IIO_CHAN_INFO_SCALE: > return ad9467_set_scale(st, val, val2); > case IIO_CHAN_INFO_SAMP_FREQ: > @@ -874,6 +925,11 @@ static int ad9467_read_avail(struct iio_dev *indio_dev, > const struct ad9467_chip_info *info = st->info; > > switch (mask) { > + case IIO_CHAN_INFO_OFFSET: > + *type = IIO_VAL_INT; > + *vals = info->offset_range; > + *length = 3; We don't need to specify length when using IIO_AVAIL_RANGE. > + return IIO_AVAIL_RANGE; > case IIO_CHAN_INFO_SCALE: > *vals = (const int *)st->scales; > *type = IIO_VAL_INT_PLUS_MICRO; > ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] iio: adc: ad9467: support write/read offset 2025-12-01 17:40 ` David Lechner @ 2025-12-02 10:20 ` Tomas Melin 0 siblings, 0 replies; 9+ messages in thread From: Tomas Melin @ 2025-12-02 10:20 UTC (permalink / raw) To: David Lechner, Lars-Peter Clausen, Michael Hennerich, Nuno Sa, Jonathan Cameron, Andy Shevchenko, Alexandru Ardelean Cc: Jonathan Cameron, linux-iio, linux-kernel Hi David, On 01/12/2025 19:40, David Lechner wrote: > On 12/1/25 5:59 AM, Tomas Melin wrote: >> Support configuring output offset value. Among the devices >> currently supported by this driver, this setting is specific to >> ad9434. > > What is the purpose of adjusting the offset. If it is to compensate > e.g. for manufacturing variations, the CALIBBIAS might be a better > choice. In any case, the commit message should explain a bit better > the intended use. This is indeed more of a calibration. It should compensate for difference between expected and actual output. I agree that the CALIBBIAS seems to be a better fit. > >> >> Signed-off-by: Tomas Melin <tomas.melin@vaisala.com> >> --- >> drivers/iio/adc/ad9467.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++- >> 1 file changed, 57 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/iio/adc/ad9467.c b/drivers/iio/adc/ad9467.c >> index 2910b6c5b576d101a25c0b5f0fb9024f0b4da63d..41b29e9e765b4296358bb277d63993889ce46290 100644 >> --- a/drivers/iio/adc/ad9467.c >> +++ b/drivers/iio/adc/ad9467.c >> @@ -145,6 +145,7 @@ struct ad9467_chip_info { >> unsigned int num_lanes; >> unsigned int dco_en; >> unsigned int test_points; >> + const int *offset_range; >> /* data clock output */ >> bool has_dco; >> bool has_dco_invert; >> @@ -234,6 +235,10 @@ static int ad9467_reg_access(struct iio_dev *indio_dev, unsigned int reg, >> return 0; >> } >> >> +static const int ad9434_offset_range[] = { >> + -128, 1, 127, >> +}; >> + >> static const unsigned int ad9265_scale_table[][2] = { >> {1250, 0x00}, {1500, 0x40}, {1750, 0x80}, {2000, 0xC0}, >> }; >> @@ -281,6 +286,23 @@ static void __ad9467_get_scale(struct ad9467_state *st, int index, >> *val2 = tmp % 1000000; >> } >> >> +#define AD9434_CHAN(_chan, avai_mask, _si, _bits, _sign) \ >> +{ \ >> + .type = IIO_VOLTAGE, \ >> + .indexed = 1, \ >> + .channel = _chan, \ >> + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ >> + BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ >> + BIT(IIO_CHAN_INFO_OFFSET), \ >> + .info_mask_shared_by_type_available = avai_mask, \ >> + .scan_index = _si, \ >> + .scan_type = { \ >> + .sign = _sign, \ >> + .realbits = _bits, \ >> + .storagebits = 16, \ >> + }, \ >> +} >> + >> #define AD9467_CHAN(_chan, avai_mask, _si, _bits, _sign) \ >> { \ >> .type = IIO_VOLTAGE, \ >> @@ -298,7 +320,8 @@ static void __ad9467_get_scale(struct ad9467_state *st, int index, >> } >> >> static const struct iio_chan_spec ad9434_channels[] = { >> - AD9467_CHAN(0, BIT(IIO_CHAN_INFO_SCALE), 0, 12, 's'), >> + AD9434_CHAN(0, BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_OFFSET), >> + 0, 12, 's'), >> }; >> >> static const struct iio_chan_spec ad9467_channels[] = { >> @@ -367,6 +390,7 @@ static const struct ad9467_chip_info ad9434_chip_tbl = { >> .default_output_mode = AD9434_DEF_OUTPUT_MODE, >> .vref_mask = AD9434_REG_VREF_MASK, >> .num_lanes = 6, >> + .offset_range = ad9434_offset_range, >> }; >> >> static const struct ad9467_chip_info ad9265_chip_tbl = { >> @@ -499,6 +523,29 @@ static int ad9467_set_scale(struct ad9467_state *st, int val, int val2) >> return -EINVAL; >> } >> >> +static int ad9467_get_offset(struct ad9467_state *st, int *val) >> +{ >> + *val = ad9467_spi_read(st, AN877_ADC_REG_OFFSET); >> + if (*val < 0) >> + return *val; > > > Since processed value is (raw + offset) * scale, this means that > the offset will be applied twice, once in hardware and once in > software. I don't think that is the intended case here? offset has not been used in "official" way here. But I think this should be sorted out if moving to CALIBBIAS? > >> + >> + return IIO_VAL_INT; >> +} >> + >> +static int ad9467_set_offset(struct ad9467_state *st, int val) >> +{ >> + int ret; >> + >> + if (val < st->info->offset_range[0] || val > st->info->offset_range[2]) >> + return -EINVAL; >> + >> + ret = ad9467_spi_write(st, AN877_ADC_REG_OFFSET, val); >> + if (ret < 0) >> + return ret; > > This could use a comment explaining why we need to do the sync after > adjusting the offset. Certain registers in the map needs the sync to take effect. I can add comment.> >> + return ad9467_spi_write(st, AN877_ADC_REG_TRANSFER, >> + AN877_ADC_TRANSFER_SYNC); >> +} >> + >> static int ad9467_outputmode_set(struct ad9467_state *st, unsigned int mode) >> { >> int ret; >> @@ -802,6 +849,8 @@ static int ad9467_read_raw(struct iio_dev *indio_dev, >> struct ad9467_state *st = iio_priv(indio_dev); >> >> switch (m) { >> + case IIO_CHAN_INFO_OFFSET: >> + return ad9467_get_offset(st, val); >> case IIO_CHAN_INFO_SCALE: >> return ad9467_get_scale(st, val, val2); >> case IIO_CHAN_INFO_SAMP_FREQ: >> @@ -836,6 +885,8 @@ static int ad9467_write_raw(struct iio_dev *indio_dev, >> int ret; >> >> switch (mask) { >> + case IIO_CHAN_INFO_OFFSET: >> + return ad9467_set_offset(st, val); >> case IIO_CHAN_INFO_SCALE: >> return ad9467_set_scale(st, val, val2); >> case IIO_CHAN_INFO_SAMP_FREQ: >> @@ -874,6 +925,11 @@ static int ad9467_read_avail(struct iio_dev *indio_dev, >> const struct ad9467_chip_info *info = st->info; >> >> switch (mask) { >> + case IIO_CHAN_INFO_OFFSET: >> + *type = IIO_VAL_INT; >> + *vals = info->offset_range; >> + *length = 3; > > We don't need to specify length when using IIO_AVAIL_RANGE. > >> + return IIO_AVAIL_RANGE; >> case IIO_CHAN_INFO_SCALE: >> *vals = (const int *)st->scales; >> *type = IIO_VAL_INT_PLUS_MICRO; >> > ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2025-12-02 14:36 UTC | newest] Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2025-12-01 11:59 [PATCH 0/2] iio: adc: ad9467: fixes for ad9434 Tomas Melin 2025-12-01 11:59 ` [PATCH 1/2] iio: adc: ad9467: fix ad9434 vref mask Tomas Melin 2025-12-01 13:49 ` Andy Shevchenko 2025-12-01 11:59 ` [PATCH 2/2] iio: adc: ad9467: support write/read offset Tomas Melin 2025-12-01 13:59 ` Andy Shevchenko 2025-12-02 10:03 ` Tomas Melin 2025-12-02 14:36 ` Andy Shevchenko 2025-12-01 17:40 ` David Lechner 2025-12-02 10:20 ` Tomas Melin
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®