public inbox for devicetree@vger.kernel.org
 help / color / mirror / Atom feed
From: Jonathan Cameron <jic23@kernel.org>
To: Jonathan Santos <Jonathan.Santos@analog.com>
Cc: <linux-iio@vger.kernel.org>, <devicetree@vger.kernel.org>,
	<linux-kernel@vger.kernel.org>, <lars@metafoo.de>,
	<Michael.Hennerich@analog.com>, <marcelo.schmitt@analog.com>,
	<robh@kernel.org>, <krzk+dt@kernel.org>, <conor+dt@kernel.org>,
	<jonath4nns@gmail.com>, <marcelo.schmitt1@gmail.com>,
	<dlechner@baylibre.com>, Pop Paul <paul.pop@analog.com>
Subject: Re: [PATCH RESEND v3 16/17] iio: adc: ad7768-1: add filter type and oversampling ratio attributes
Date: Sun, 16 Feb 2025 16:31:53 +0000	[thread overview]
Message-ID: <20250216163153.55a1ae97@jic23-huawei> (raw)
In-Reply-To: <2c3ce1701545e435238605342397e45657a0fb2a.1739368121.git.Jonathan.Santos@analog.com>

On Wed, 12 Feb 2025 15:18:59 -0300
Jonathan Santos <Jonathan.Santos@analog.com> wrote:

> Separate filter type and decimation rate from the sampling frequency
> attribute. The new filter type attribute enables sinc3, sinc3+rej60
> and wideband filters, which were previously unavailable.
> 
> Previously, combining decimation and MCLK divider in the sampling
> frequency obscured performance trade-offs. Lower MCLK divider
> settings increase power usage, while lower decimation rates reduce
> precision by decreasing averaging. By creating an oversampling
> attribute, which controls the decimation, users gain finer control
> over performance.
> 
> The addition of those attributes allows a wider range of sampling
> frequencies and more access to the device features.
> 
> Co-developed-by: Pop Paul <paul.pop@analog.com>
> Signed-off-by: Pop Paul <paul.pop@analog.com>
> Signed-off-by: Jonathan Santos <Jonathan.Santos@analog.com>
As below. We should aim to 'pre bake' the value arrays for
get_available() to avoid the potential race conditions of a consumer
seeing a partly updated set a parameters change.

Better to see a consistent but stale one.

Jonathan

> ---
> v3 Changes:
> * removed unsed variables.
> * included sinc3+rej60 filter type.
> * oversampling_ratio moved to info_mask_shared_by_type.
> * reordered functions to avoid foward declaration.
> * simplified regmap writes.
> * Removed locking.
> * replaced some helper functions for direct regmap_update_bits
>   calls.
> * Addressed other nits.
> 
> v2 Changes:
> * Decimation_rate attribute replaced for oversampling_ratio.
> ---
>  drivers/iio/adc/ad7768-1.c | 359 ++++++++++++++++++++++++++++++-------
>  1 file changed, 290 insertions(+), 69 deletions(-)
> 
> diff --git a/drivers/iio/adc/ad7768-1.c b/drivers/iio/adc/ad7768-1.c
> index 8aea38c154fe..18f1ea0bf66d 100644
> --- a/drivers/iio/adc/ad7768-1.c
> +++ b/drivers/iio/adc/ad7768-1.c

> +
> +/* Decimation Rate range for each filter type */
> +static const int ad7768_dec_rate_range[][3] = {
> +	[AD7768_FILTER_SINC5] = { 8, 8, 1024 },
> +	[AD7768_FILTER_SINC3] = { 32, 32, 163840 },
> +	[AD7768_FILTER_WIDEBAND] = { 32, 32, 1024 },
> +	[AD7768_FILTER_SINC3_REJ60] = { 32, 32, 163840 },
> +};
> +
> +/*
> + * The AD7768-1 supports three primary filter types:
> + * Sinc5, Sinc3, and Wideband.
> + * However, the filter register values can also encode
wrap at 80 chars.
> + * additional parameters such as decimation rates and
> + * 60Hz rejection. This utility function separates the
> + * filter type from these parameters.
> + */

>  
> -	return 0;
> +static int ad7768_get_fil_type_attr(struct iio_dev *dev,
> +				    const struct iio_chan_spec *chan)
> +{
> +	struct ad7768_state *st = iio_priv(dev);
> +	int ret;
> +	unsigned int mode;
> +
> +	ret = regmap_read(st->regmap, AD7768_REG_DIGITAL_FILTER, &mode);
> +	if (ret)
> +		return ret;
> +
> +	mode = FIELD_GET(AD7768_DIG_FIL_FIL_MSK, mode);
> +
> +	/*
> +	 * From the register value, get the corresponding
> +	 * filter type.

Very short line wrap.  Stick to 80 chars.

> +	 */
> +	return ad7768_filter_regval_to_type[mode];
>  }

>  
> @@ -619,16 +798,25 @@ static int ad7768_read_avail(struct iio_dev *indio_dev,
>  			     long info)
>  {
>  	struct ad7768_state *st = iio_priv(indio_dev);
> -	int i;
> +	int i, freq_filtered, len = 0;
>  
>  	switch (info) {
> +	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
> +		*vals = (int *)ad7768_dec_rate_range[st->filter_type];
> +		*type = IIO_VAL_INT;
> +		return IIO_AVAIL_RANGE;
>  	case IIO_CHAN_INFO_SAMP_FREQ:
> -		for (i = 0; i < ARRAY_SIZE(ad7768_clk_config); i++)
> -			st->samp_freq_avail[i] = DIV_ROUND_CLOSEST(st->mclk_freq,
> -								   ad7768_clk_config[i].clk_div);
> +		freq_filtered = DIV_ROUND_CLOSEST(st->mclk_freq, st->oversampling_ratio);

Ah. So now it is dynamic.  This hits the previously mentioned race.
A consumer can be holding a copy of this and acting on it whilst holding no
locks on this device - thus it can see a mixture of values as this update
occurs. To avoid that you need to precompute the combinations +
store the lot in arrays.  Then this code should simply be selecting the arrays.
A consumer holding a stale one will get a consistent (if wrong) set.

The < 50 check makes this more complex than normal but they are still static
choices I think as long as the input clock doesn't change.

> +		for (i = 0; i < ARRAY_SIZE(ad7768_mclk_div_rates); i++) {
> +			st->samp_freq_avail[len] = DIV_ROUND_CLOSEST(freq_filtered,
> +								     ad7768_mclk_div_rates[i]);
> +			/* Sampling frequency cannot be lower than the minimum of 50 SPS */
> +			if (st->samp_freq_avail[len] >= 50)
> +				len++;
> +		}
>  
>  		*vals = (int *)st->samp_freq_avail;
> -		*length = ARRAY_SIZE(ad7768_clk_config);
> +		*length = len;
>  		*type = IIO_VAL_INT;
>  		return IIO_AVAIL_LIST;
>  	default:
> @@ -636,20 +824,45 @@ static int ad7768_read_avail(struct iio_dev *indio_dev,
>  	}
>  }
>  
> -static int ad7768_write_raw(struct iio_dev *indio_dev,
> -			    struct iio_chan_spec const *chan,
> -			    int val, int val2, long info)
> +static int __ad7768_write_raw(struct iio_dev *indio_dev,
> +			      struct iio_chan_spec const *chan,
> +			      int val, int val2, long info)
>  {
>  	struct ad7768_state *st = iio_priv(indio_dev);
> +	int ret;
>  
>  	switch (info) {
>  	case IIO_CHAN_INFO_SAMP_FREQ:
>  		return ad7768_set_freq(st, val);
> +
> +	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
> +		ret = ad7768_configure_dig_fil(indio_dev, st->filter_type, val);
> +		if (ret)
> +			return ret;
> +
> +		/* Update sampling frequency */
> +		return ad7768_set_freq(st, st->samp_freq);
>  	default:
>  		return -EINVAL;
>  	}
>  }
>  
> +static int ad7768_write_raw(struct iio_dev *indio_dev,
> +			    struct iio_chan_spec const *chan,
> +			    int val, int val2, long info)
> +{
> +	int ret;
> +
> +	ret = iio_device_claim_direct_mode(indio_dev);
Previously we didn't claim this to set the sampling frequency.
That change looks like a potential ABI issue.  I'm fine with it
if we should always have this protected.

If you are just using it to avoid racing between setting sampling
frequency and oversampling ratio then don't use that, use a local
lock where the scope can be clearly described.

> +	if (ret)
> +		return ret;
> +
> +	ret = __ad7768_write_raw(indio_dev, chan, val, val2, info);
> +	iio_device_release_direct_mode(indio_dev);
> +
> +	return ret;
> +}

  reply	other threads:[~2025-02-16 16:32 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-02-12 18:15 [PATCH RESEND v3 00/17] iio: adc: ad7768-1: Add features, improvements, and fixes Jonathan Santos
2025-02-12 18:15 ` [PATCH RESEND v3 01/17] iio: adc: ad7768-1: Fix conversion result sign Jonathan Santos
2025-02-12 18:16 ` [PATCH RESEND v3 02/17] iio: adc: ad7768-1: set MOSI idle state to prevent accidental reset Jonathan Santos
2025-02-16 15:59   ` Jonathan Cameron
2025-02-12 18:16 ` [PATCH RESEND v3 03/17] dt-bindings: iio: adc: ad7768-1: add trigger-sources property Jonathan Santos
2025-02-13 20:24   ` Conor Dooley
2025-02-27 21:30     ` Jonathan Santos
2025-03-21 14:39       ` Rob Herring
2025-02-12 18:16 ` [PATCH RESEND v3 04/17] dt-bindings: iio: adc: ad7768-1: Document GPIO controller Jonathan Santos
2025-02-12 18:16 ` [PATCH RESEND v3 05/17] dt-bindings: iio: adc: ad7768-1: document regulator provider property Jonathan Santos
2025-02-13 20:25   ` Conor Dooley
2025-02-20 21:22   ` David Lechner
2025-02-12 18:16 ` [PATCH RESEND v3 06/17] Documentation: ABI: add wideband filter type to sysfs-bus-iio Jonathan Santos
2025-02-20 21:28   ` David Lechner
2025-02-22 11:51     ` Jonathan Cameron
2025-02-12 18:17 ` [PATCH RESEND v3 07/17] iio: adc: ad7768-1: remove unnecessary locking Jonathan Santos
2025-02-20 21:30   ` David Lechner
2025-02-12 18:17 ` [PATCH RESEND v3 08/17] iio: adc: ad7768-1: convert driver to use regmap Jonathan Santos
2025-02-16 16:06   ` Jonathan Cameron
2025-02-20 21:41   ` David Lechner
2025-02-12 18:17 ` [PATCH RESEND v3 09/17] iio: adc: ad7768-1: Add reset gpio Jonathan Santos
2025-02-12 18:17 ` [PATCH RESEND v3 10/17] iio: adc: ad7768-1: Move buffer allocation to a separate function Jonathan Santos
2025-02-20 21:43   ` David Lechner
2025-02-12 18:17 ` [PATCH RESEND v3 11/17] iio: adc: ad7768-1: add regulator to control VCM output Jonathan Santos
2025-02-13 22:57   ` kernel test robot
2025-02-16 16:11   ` Jonathan Cameron
2025-02-20 22:20   ` David Lechner
2025-02-12 18:18 ` [PATCH RESEND v3 12/17] iio: adc: ad7768-1: Add GPIO controller support Jonathan Santos
2025-02-16 16:14   ` Jonathan Cameron
2025-02-19 20:34   ` Linus Walleij
2025-02-20 22:27     ` David Lechner
2025-02-27 21:36       ` Jonathan Santos
2025-02-27 21:54         ` David Lechner
2025-02-28  8:52       ` Linus Walleij
2025-02-28 15:55         ` David Lechner
2025-03-04  8:03   ` Linus Walleij
2025-02-12 18:18 ` [PATCH RESEND v3 13/17] iio: adc: ad7768-1: add multiple scan types to support 16-bits mode Jonathan Santos
2025-02-20 22:38   ` David Lechner
2025-02-12 18:18 ` [PATCH RESEND v3 14/17] iio: adc: ad7768-1: add support for Synchronization over SPI Jonathan Santos
2025-02-12 18:18 ` [PATCH RESEND v3 15/17] iio: adc: ad7768-1: replace manual attribute declaration Jonathan Santos
2025-02-16 16:21   ` Jonathan Cameron
2025-02-12 18:18 ` [PATCH RESEND v3 16/17] iio: adc: ad7768-1: add filter type and oversampling ratio attributes Jonathan Santos
2025-02-16 16:31   ` Jonathan Cameron [this message]
2025-02-20 13:28     ` Jonathan Santos
2025-02-12 18:19 ` [PATCH RESEND v3 17/17] iio: adc: ad7768-1: add low pass -3dB cutoff attribute Jonathan Santos
2025-02-16 16:33   ` Jonathan Cameron

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=20250216163153.55a1ae97@jic23-huawei \
    --to=jic23@kernel.org \
    --cc=Jonathan.Santos@analog.com \
    --cc=Michael.Hennerich@analog.com \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=dlechner@baylibre.com \
    --cc=jonath4nns@gmail.com \
    --cc=krzk+dt@kernel.org \
    --cc=lars@metafoo.de \
    --cc=linux-iio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=marcelo.schmitt1@gmail.com \
    --cc=marcelo.schmitt@analog.com \
    --cc=paul.pop@analog.com \
    --cc=robh@kernel.org \
    /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