From: sashiko-bot@kernel.org
To: "Radu Sabau via B4 Relay" <devnull+radu.sabau.analog.com@kernel.org>
Cc: devicetree@vger.kernel.org, conor+dt@kernel.org, robh@kernel.org
Subject: Re: [PATCH v13 5/6] iio: adc: ad4691: add oversampling support
Date: Mon, 25 May 2026 13:06:47 +0000 [thread overview]
Message-ID: <20260525130648.049841F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260525-ad4692-multichannel-sar-adc-driver-v13-5-1b7626d3b35c@analog.com>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] The oversampling ratio (OSR) is only applied to channel 0, leaving all other channels unconfigured.
- [Medium] Decreasing the oversampling ratio can incorrectly fail with -EINVAL, effectively trapping the device in a high OSR state.
- [Medium] Mismatch between the commit message intent (per-channel OSR) and the actual implementation (device-wide shared OSR).
--
commit cb227edc48341e4c564eb44a5dcf61a6d76e273a
Author: Radu Sabau <radu.sabau@analog.com>
iio: adc: ad4691: add oversampling support
Add per-channel oversampling ratio (OSR) support for CNV burst mode.
The accumulator depth register (ACC_DEPTH_IN) is programmed with the
selected OSR at buffer enable time and before each single-shot read.
> Add per-channel oversampling ratio (OSR) support for CNV burst mode.
> The accumulator depth register (ACC_DEPTH_IN) is programmed with the
> selected OSR at buffer enable time and before each single-shot read.
>
> Supported OSR values: 1, 2, 4, 8, 16, 32.
>
> Introduce AD4691_MANUAL_CHANNEL() for manual mode channels, which do
> not expose the oversampling_ratio attribute since OSR is not applicable
> in that mode. A separate manual_channels array is added to
> struct ad4691_channel_info and selected at probe time.
>
> in_voltageN_sampling_frequency represents the effective output rate for
> channel N, defined as osc_freq / osr[N]. The chip has one internal
> oscillator shared by all channels; each channel independently
> accumulates osr[N] oscillator cycles before producing a result.
[Severity: Medium]
Is the intent to support per-channel oversampling ratios as described here?
The commit message refers to osr[N], but the implementation introduces a
single global state variable st->osr, exposes the sysfs attributes as
info_mask_shared_by_all in the channel macros, and applies this shared
variable device-wide.
> diff --git a/drivers/iio/adc/ad4691.c b/drivers/iio/adc/ad4691.c
> index 6563488ab8b89..64238f8428417 100644
> --- a/drivers/iio/adc/ad4691.c
> +++ b/drivers/iio/adc/ad4691.c
[ ... ]
> @@ -642,7 +856,7 @@ static int ad4691_single_shot_read(struct iio_dev *indio_dev,
> struct iio_chan_spec const *chan, int *val)
> {
> struct ad4691_state *st = iio_priv(indio_dev);
> - unsigned int reg_val, osc_idx, period_us;
> + unsigned int reg_val, period_us;
> int ret;
>
> guard(mutex)(&st->lock);
> @@ -662,7 +876,11 @@ static int ad4691_single_shot_read(struct iio_dev *indio_dev,
> if (ret)
> return ret;
>
> - ret = regmap_read(st->regmap, AD4691_OSC_FREQ_REG, ®_val);
> + ret = regmap_write(st->regmap, AD4691_ACC_DEPTH_IN(0), st->osr);
[Severity: High]
Does this apply the oversampling ratio only to channel 0?
Since AD4691_ACC_DEPTH_IN(n) targets a distinct register address per channel,
hardcoding 0 here means for single-shot reads on channels other than 0,
the OSR is never configured, yet the driver waits the full oversampled
duration and expects accumulated data.
> + if (ret)
> + return ret;
> +
> + ret = ad4691_write_osc_freq(st);
> if (ret)
> return ret;
[ ... ]
> @@ -730,6 +965,33 @@ static int ad4691_write_raw(struct iio_dev *indio_dev,
> switch (mask) {
> case IIO_CHAN_INFO_SAMP_FREQ:
> return ad4691_set_sampling_freq(st, val);
> + case IIO_CHAN_INFO_OVERSAMPLING_RATIO: {
> + unsigned int old_effective, found, osr_idx;
> +
> + osr_idx = ad4691_osr_index(val);
> + if (ad4691_oversampling_ratios[osr_idx] != val)
> + return -EINVAL;
> +
> + /*
> + * Hold st->lock while computing the new oscillator frequency
> + * and updating both target_osc_freq_Hz and osr atomically:
> + * read_raw for SAMP_FREQ reads both fields under the lock and
> + * must see a consistent pair (new osc ↔ new osr).
> + *
> + * Snap target_osc_freq_Hz to the largest table entry that is
> + * both <= old_effective * new_osr and evenly divisible by
> + * new_osr, preserving an integer read-back of
> + * in_voltage_sampling_frequency after the OSR change.
> + */
> + guard(mutex)(&st->lock);
> + old_effective = st->target_osc_freq_Hz / st->osr;
> + found = ad4691_find_osc_freq(st, old_effective * (unsigned int)val, val);
> + if (!found)
> + return -EINVAL;
[Severity: Medium]
Could this reject valid oversampling ratio changes with -EINVAL, effectively
trapping the device in a high OSR state?
If the device is currently at a high OSR (e.g., 32), the old_effective rate
is very low. Attempting to decrease the OSR directly to 1 yields a low
needed oscillator frequency (old_effective * new_osr).
Since ad4691_find_osc_freq() only returns frequencies less than or equal to
this needed oscillator rate, and the minimum supported frequency is
25,000 Hz, the search will fail and return 0 if the needed rate is less
than 25,000. This would force users to use a non-intuitive step-down
workaround to lower the OSR.
> + st->target_osc_freq_Hz = found;
> + st->osr = val;
> + return 0;
> + }
> default:
> return -EINVAL;
> }
[ ... ]
> @@ -943,6 +1209,10 @@ static int ad4691_cnv_burst_buffer_preenable(struct iio_dev *indio_dev)
> if (ret)
> goto err_unoptimize;
>
> + ret = regmap_write(st->regmap, AD4691_ACC_DEPTH_IN(0), st->osr);
[Severity: High]
Does this hardcoded channel 0 write leave the remaining active channels
unconfigured?
Since this doesn't iterate over the active scan mask, channels 1-15 will
always operate with the default OSR of 1 during buffered reads, causing
incorrect hardware accumulation.
> + if (ret)
> + goto err_unoptimize;
> +
> ret = ad4691_enter_conversion_mode(st);
> if (ret)
> goto err_unoptimize;
[ ... ]
> @@ -1122,6 +1392,10 @@ static int ad4691_cnv_burst_offload_buffer_postenable(struct iio_dev *indio_dev)
> if (ret)
> return ret;
>
> + ret = regmap_write(st->regmap, AD4691_ACC_DEPTH_IN(0), st->osr);
[Severity: High]
As with ad4691_cnv_burst_buffer_preenable() above, this also hardcodes
channel 0. Should this iterate over the active scan mask instead?
> + if (ret)
> + return ret;
> +
> ret = ad4691_enter_conversion_mode(st);
> if (ret)
> return ret;
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260525-ad4692-multichannel-sar-adc-driver-v13-0-1b7626d3b35c@analog.com?part=5
next prev parent reply other threads:[~2026-05-25 13:06 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-25 10:10 [PATCH v13 0/6] iio: adc: ad4691: add driver for AD4691 multichannel SAR ADC family Radu Sabau via B4 Relay
2026-05-25 10:10 ` [PATCH v13 1/6] dt-bindings: iio: adc: add AD4691 family Radu Sabau via B4 Relay
2026-05-25 10:16 ` sashiko-bot
2026-05-25 10:10 ` [PATCH v13 2/6] iio: adc: ad4691: add initial driver for " Radu Sabau via B4 Relay
2026-05-25 10:45 ` sashiko-bot
2026-05-25 10:10 ` [PATCH v13 3/6] iio: adc: ad4691: add triggered buffer support Radu Sabau via B4 Relay
2026-05-25 11:29 ` sashiko-bot
2026-05-25 12:02 ` Sabau, Radu bogdan
2026-05-25 12:31 ` Sabau, Radu bogdan
2026-05-25 10:10 ` [PATCH v13 4/6] iio: adc: ad4691: add SPI offload support Radu Sabau via B4 Relay
2026-05-25 12:26 ` sashiko-bot
2026-05-25 10:10 ` [PATCH v13 5/6] iio: adc: ad4691: add oversampling support Radu Sabau via B4 Relay
2026-05-25 13:06 ` sashiko-bot [this message]
2026-05-25 10:10 ` [PATCH v13 6/6] docs: iio: adc: ad4691: add driver documentation Radu Sabau via B4 Relay
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260525130648.049841F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=devnull+radu.sabau.analog.com@kernel.org \
--cc=robh@kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox