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: 24+ 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 ` Radu Sabau
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:10 ` Radu Sabau
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:10 ` Radu Sabau
2026-05-25 10:45 ` sashiko-bot
2026-05-27 18:07 ` Jonathan Cameron
2026-05-29 10:06 ` Sabau, Radu bogdan
2026-05-25 10:10 ` [PATCH v13 3/6] iio: adc: ad4691: add triggered buffer support Radu Sabau via B4 Relay
2026-05-25 10:10 ` Radu Sabau
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 10:10 ` Radu Sabau
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 10:10 ` Radu Sabau
2026-05-25 13:06 ` sashiko-bot [this message]
2026-05-27 18:16 ` Jonathan Cameron
2026-05-25 10:10 ` [PATCH v13 6/6] docs: iio: adc: ad4691: add driver documentation Radu Sabau via B4 Relay
2026-05-25 10:10 ` Radu Sabau
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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.