mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Jonathan Cameron <jic23@kernel.org>
To: Rupesh Majhi <zoone.rupert@gmail.com>
Cc: "Andy Shevchenko" <andy@kernel.org>,
	"David Lechner" <dlechner@baylibre.com>,
	"Eddie James" <eajames@linux.ibm.com>,
	"Joel Stanley" <joel@jms.id.au>, "Nuno Sá" <nuno.sa@analog.com>,
	linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v5 2/3] iio: pressure: dps310: add triggered buffer support
Date: Sun, 23 Aug 2026 00:19:14 +0100	[thread overview]
Message-ID: <20260823001914.224aba09@jic23-huawei> (raw)
In-Reply-To: <20260817170725.1074078-3-zoone.rupert@gmail.com>

On Mon, 17 Aug 2026 20:07:24 +0300
Rupesh Majhi <zoone.rupert@gmail.com> wrote:

> Add triggered buffer support so pressure and temperature can be captured
> into a buffer instead of only through one-shot sysfs reads. The device
> measures continuously in background mode, so a capture is just a read of
> the latest results and no buffer setup ops are needed.
> 
> Pressure has to be computed from the raw register value with the
> compensation polynomial in section 4.9.1 of the datasheet, which also
> needs a temperature reading. To keep full resolution in the buffer
> without disagreeing with the unit the existing processed attribute
> reports, add raw and scale attributes for pressure, raw in Pa and scale
> 1/1000 to convert to kPa. The channel definition carries a comment
> explaining why it is done this way here and why it should not be copied
> into other drivers.
> 
> Temperature is already a full resolution value in its base unit of
> millidegrees Celsius, so it stays a processed channel.
> 
> Either channel can be enabled on its own. Temperature is always sampled
> because the pressure compensation needs it, but only the enabled channels
> are pushed to the buffer.
> 
> The raw read helpers are split into variants that expect the lock to be
> held, so the trigger handler takes the lock once per scan instead of once
> per value. That also lets dps310_calculate_pressure() drop its
> mutex_trylock() dance, as the temperature refresh now always happens
> under the caller's lock instead of only when the lock happened to be
> free.
> 
> Sysfs sample reads and reconfiguration return -EBUSY while the buffer is
> enabled, since they share the capture path's values and configuration.
> 
> Signed-off-by: Rupesh Majhi <zoone.rupert@gmail.com>
> ---
>  drivers/iio/pressure/Kconfig  |   2 +
>  drivers/iio/pressure/dps310.c | 305 ++++++++++++++++++++++++++--------
>  2 files changed, 242 insertions(+), 65 deletions(-)
> 
> diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig
> index 838a8340c4c0..cef8b90b9ae7 100644
> --- a/drivers/iio/pressure/Kconfig
> +++ b/drivers/iio/pressure/Kconfig
> @@ -112,6 +112,8 @@ config DPS310
>  	tristate "Infineon DPS310 pressure and temperature sensor"
>  	depends on I2C
>  	select REGMAP_I2C
> +	select IIO_BUFFER
> +	select IIO_TRIGGERED_BUFFER
>  	help
>  	  Support for the Infineon DPS310 digital barometric pressure sensor.
>  	  It can be accessed over I2C bus.
> diff --git a/drivers/iio/pressure/dps310.c b/drivers/iio/pressure/dps310.c
> index 68382960382f..0d6e65766469 100644
> --- a/drivers/iio/pressure/dps310.c
> +++ b/drivers/iio/pressure/dps310.c


>  	{
>  		.type = IIO_PRESSURE,
> +		/*
> +		 * Pressure is only meaningful once the raw register value has
> +		 * been run through the compensation polynomial in section 4.9.1
> +		 * of the datasheet, which needs a temperature reading as well.
> +		 * So what is reported as _raw here is already compensated, in
> +		 * Pa, and _scale converts it to the kPa the ABI asks for. The
> +		 * _processed attribute reports the same value and predates
> +		 * buffer support, so it has to stay.
> +		 *
> +		 * Please do not copy this pattern into other drivers. A raw

Drop the Please! 
		 * Do not copy ...

> +		 * attribute that is not the raw register value is only
> +		 * tolerable here because the alternative is either losing
> +		 * resolution in the buffer or breaking existing users of
> +		 * _processed.
> +		 */
>  		.info_mask_separate = BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) |
>  			BIT(IIO_CHAN_INFO_SAMP_FREQ) |
> -			BIT(IIO_CHAN_INFO_PROCESSED),
> +			BIT(IIO_CHAN_INFO_PROCESSED) |
> +			BIT(IIO_CHAN_INFO_RAW) |
> +			BIT(IIO_CHAN_INFO_SCALE),
> +		.scan_index = DPS310_SCAN_PRESSURE,
> +		.scan_type = {
> +			.sign = 's',
> +			.realbits = 32,
> +			.storagebits = 32,
> +			.endianness = IIO_CPU,
> +		},
>  	},
> +	IIO_CHAN_SOFT_TIMESTAMP(2),
>  };
>  
>  /* To be called after checking the COEF_RDY bit in MEAS_CFG */
> @@ -463,7 +503,8 @@ static int dps310_ready(struct dps310_data *data, int ready_bit, int timeout)
>  	return 0;
>  }
>  
> -static int dps310_read_pres_raw(struct dps310_data *data)
> +/* Called with lock held */

Use the sparse markings to make it clear and testable - thus not needing the
comment. __must_hold(&data->lock) 



> +static int dps310_read_pres_raw_locked(struct dps310_data *data)
>  {
>  	int rc;
>  	int rate;
> @@ -471,30 +512,25 @@ static int dps310_read_pres_raw(struct dps310_data *data)
>  	s32 raw;
>  	u8 val[3];
>  
> -	if (mutex_lock_interruptible(&data->lock))
> -		return -EINTR;
> -
>  	rc = dps310_get_pres_samp_freq(data, &rate);
>  	if (rc)
> -		goto done;
> +		return rc;
>  
>  	timeout = DPS310_POLL_TIMEOUT_US(rate);
>  
>  	/* Poll for sensor readiness; base the timeout upon the sample rate. */
>  	rc = dps310_ready(data, DPS310_PRS_RDY, timeout);
>  	if (rc)
> -		goto done;
> +		return rc;
>  
>  	rc = regmap_bulk_read(data->regmap, DPS310_PRS_BASE, val, sizeof(val));
>  	if (rc < 0)
> -		goto done;
> +		return rc;
>  
>  	raw = (val[0] << 16) | (val[1] << 8) | val[2];

Can we take the opportunity to make this get_unaligned_be24() which 
I think ends up as the same thing?

>  	data->pressure_raw = sign_extend32(raw, 23);
>  
> -done:
> -	mutex_unlock(&data->lock);
> -	return rc;
> +	return 0;
>  }
>  
>  /* Called with lock held */
> @@ -514,31 +550,45 @@ static int dps310_read_temp_ready(struct dps310_data *data)
>  	return 0;
>  }
>  
> -static int dps310_read_temp_raw(struct dps310_data *data)
> +/* Called with lock held */

As above.  Same for all the other cases where you have a comment
saying a lock must be held.

> +static int dps310_read_temp_raw_locked(struct dps310_data *data)

...


> +/*
> + * Sample the pressure and compensate it. Shared by the raw and processed
> + * attributes, which report the same value in different units, and takes the
> + * lock once for the whole sequence.
> + */
> +static int dps310_read_pressure_value(struct dps310_data *data, int *val)
> +{
> +	int rc;
> +
> +	ACQUIRE(mutex_intr, lock)(&data->lock);
> +	if (ACQUIRE_ERR(mutex_intr, &lock))
> +		return -EINTR;
> +
> +	rc = dps310_read_pres_raw_locked(data);
> +	if (rc)
> +		return rc;
> +
> +	dps310_refresh_temp_locked(data);
> +
> +	return dps310_calculate_pressure(data, val);

A lot of this seems to be rework that you could pull out ahead of
the stuff that adds buffered support.  That might be worth doing
to create two simpler and easier to review patches.

> +}
> +
> +static irqreturn_t dps310_trigger_handler(int irq, void *p)
> +{
> +	struct iio_poll_func *pf = p;
> +	struct iio_dev *iio = pf->indio_dev;
> +	struct dps310_data *data = iio_priv(iio);
> +	/*
> +	 * Either channel can be enabled on its own, so the offset of the second
> +	 * value depends on the scan mask and the layout cannot be described
> +	 * with a structure. Sized for both 32-bit channels plus the timestamp.
> +	 */
> +	u8 buffer[16] __aligned(8) = { };
> +	int rc = 0;
> +
> +	scoped_guard(mutex, &data->lock)
It isn't necessary to use guard/scoped_guard() for all locks in a driver
if they actually hurt readability.  I think that is the case here.

	mutex_lock(&data->lock);
	rc = dps310...
	mutex_unlock(&data->lock);
	ir (rc)
		goto err;

	iio_push_to_buffers_with_ts();

err:
	iio_trigger_notify_done();
	
	return IRQ_HANDLED;

Is (to my eyes) easier to read.


> +		rc = dps310_fill_scan(iio, buffer);
> +
> +	if (!rc)
> +		iio_push_to_buffers_with_ts(iio, buffer, sizeof(buffer),
> +					    pf->timestamp);
> +
> +	iio_trigger_notify_done(iio->trig);
> +
> +	return IRQ_HANDLED;
> +}
> +
>  static void dps310_reset(void *action_data)
>  {
>  	struct dps310_data *data = action_data;
> @@ -877,6 +1042,16 @@ static int dps310_probe(struct i2c_client *client)
>  	if (rc)
>  		return rc;
>  
> +	/*
> +	 * The device measures continuously in background mode, so a capture is
> +	 * just a read of the latest results and no buffer setup ops are needed.
> +	 */
> +	rc = devm_iio_triggered_buffer_setup(&client->dev, iio,
> +					     iio_pollfunc_store_time,

Given you are driving this from a trigger that isn't aligned with actual data acquisition
there is no point in using iio_pollfunc_store_time().  You can just grab a timestamp
directly in dps310_trigger_handler.  That has the added advantage of making this
compatible with triggers that use iio_poll_trigger_nested().

> +					     dps310_trigger_handler, NULL);
> +	if (rc)
> +		return rc;
> +
>  	rc = devm_iio_device_register(&client->dev, iio);
>  	if (rc)
>  		return rc;


  reply	other threads:[~2026-08-22 23:19 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-17 17:07 [PATCH v5 0/3] iio: pressure: dps310: FIFO and " Rupesh Majhi
2026-08-17 17:07 ` [PATCH v5 1/3] iio: pressure: dps310: fix CFG_REG bit definitions Rupesh Majhi
2026-08-17 17:07 ` [PATCH v5 2/3] iio: pressure: dps310: add triggered buffer support Rupesh Majhi
2026-08-22 23:19   ` Jonathan Cameron [this message]
2026-08-24 19:52     ` Rupesh Majhi
2026-08-17 17:07 ` [PATCH v5 3/3] iio: pressure: dps310: add hardware FIFO support Rupesh Majhi
2026-08-22 23:33   ` Jonathan Cameron
2026-08-24 20:08     ` Rupesh Majhi
2026-08-17 18:47 ` [PATCH v5 0/3] iio: pressure: dps310: FIFO and triggered buffer support Andy Shevchenko
2026-08-17 22:09   ` Rupert Zoone

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=20260823001914.224aba09@jic23-huawei \
    --to=jic23@kernel.org \
    --cc=andy@kernel.org \
    --cc=dlechner@baylibre.com \
    --cc=eajames@linux.ibm.com \
    --cc=joel@jms.id.au \
    --cc=linux-iio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=nuno.sa@analog.com \
    --cc=zoone.rupert@gmail.com \
    /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

all inboxes | Powered by JetHome®