From: Rupesh Majhi <zoone.rupert@gmail.com>
To: "Andy Shevchenko" <andy@kernel.org>,
"Bill Wendling" <morbo@google.com>,
"David Lechner" <dlechner@baylibre.com>,
"Eddie James" <eajames@linux.ibm.com>,
"Joel Stanley" <joel@jms.id.au>,
"Jonathan Cameron" <jic23@kernel.org>,
"Justin Stitt" <justinstitt@google.com>,
"Nathan Chancellor" <nathan@kernel.org>,
"Nick Desaulniers" <nick.desaulniers+lkml@gmail.com>,
"Nuno Sá" <nuno.sa@analog.com>
Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org,
llvm@lists.linux.dev, Rupesh Majhi <zoone.rupert@gmail.com>
Subject: [PATCH v6 4/6] iio: pressure: dps310: add triggered buffer support
Date: Mon, 24 Aug 2026 23:12:01 +0300 [thread overview]
Message-ID: <20260824201203.396651-5-zoone.rupert@gmail.com> (raw)
In-Reply-To: <20260824201203.396651-1-zoone.rupert@gmail.com>
Add a triggered buffer in order to capture continuously on both channels
instead of one sysfs read at a time.
Raw register value is not useful on its own, pressure has to go through
the compensation polynomial and needs a temperature reading. Report raw
in Pa with 1/1000 scale to keep full resolution in the buffer without
changing what the existing processed attribute reports.
Raw and processed reads return -EBUSY while buffer is on, so does any
reconfiguration.
Assisted-by: Claude:claude-opus-5
Signed-off-by: Rupesh Majhi <zoone.rupert@gmail.com>
---
drivers/iio/pressure/Kconfig | 2 +
drivers/iio/pressure/dps310.c | 169 ++++++++++++++++++++++++++++++++--
2 files changed, 165 insertions(+), 6 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 269a71ea3e7a..f122acd72b0c 100644
--- a/drivers/iio/pressure/dps310.c
+++ b/drivers/iio/pressure/dps310.c
@@ -21,8 +21,11 @@
#include <linux/regmap.h>
#include <linux/unaligned.h>
+#include <linux/iio/buffer.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
#define DPS310_DEV_NAME "dps310"
@@ -93,19 +96,60 @@ struct dps310_data {
bool timeout_recovery_failed;
};
+enum dps310_scan_index {
+ DPS310_SCAN_TEMP,
+ DPS310_SCAN_PRESSURE,
+};
+
+struct dps310_scan {
+ s32 channels[2];
+ aligned_s64 ts;
+};
+
static const struct iio_chan_spec dps310_channels[] = {
{
.type = IIO_TEMP,
.info_mask_separate = BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) |
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
BIT(IIO_CHAN_INFO_PROCESSED),
+ .scan_index = DPS310_SCAN_TEMP,
+ .scan_type = {
+ .sign = 's',
+ .realbits = 32,
+ .storagebits = 32,
+ .endianness = IIO_CPU,
+ },
},
{
.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.
+ *
+ * Do not copy this pattern into other drivers. A raw 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 */
@@ -589,6 +633,11 @@ static int dps310_write_raw(struct iio_dev *iio,
{
struct dps310_data *data = iio_priv(iio);
+ /* Reconfiguring mid-capture would change the values being captured */
+ IIO_DEV_ACQUIRE_DIRECT_MODE(iio, claim);
+ if (IIO_DEV_ACQUIRE_FAILED(claim))
+ return -EBUSY;
+
ACQUIRE(mutex_intr, lock)(&data->lock);
if (ACQUIRE_ERR(mutex_intr, &lock))
return -EINTR;
@@ -730,6 +779,13 @@ static int dps310_read_pressure(struct dps310_data *data, int *val, int *val2,
return IIO_VAL_INT;
+ case IIO_CHAN_INFO_RAW:
+ rc = dps310_read_pressure_value(data, val);
+ if (rc)
+ return rc;
+
+ return IIO_VAL_INT;
+
case IIO_CHAN_INFO_PROCESSED:
rc = dps310_read_pressure_value(data, val);
if (rc)
@@ -738,6 +794,12 @@ static int dps310_read_pressure(struct dps310_data *data, int *val, int *val2,
*val2 = 1000; /* Convert Pa to KPa per IIO ABI */
return IIO_VAL_FRACTIONAL;
+ case IIO_CHAN_INFO_SCALE:
+ /* The raw value is in Pa, the ABI wants kPa */
+ *val = 1;
+ *val2 = 1000;
+ return IIO_VAL_FRACTIONAL;
+
case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
rc = dps310_get_pres_precision(data, val);
if (rc)
@@ -819,12 +881,10 @@ static int dps310_read_temp(struct dps310_data *data, int *val, int *val2,
}
}
-static int dps310_read_raw(struct iio_dev *iio,
- struct iio_chan_spec const *chan,
- int *val, int *val2, long mask)
+static int dps310_read_channel(struct dps310_data *data,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
{
- struct dps310_data *data = iio_priv(iio);
-
switch (chan->type) {
case IIO_PRESSURE:
return dps310_read_pressure(data, val, val2, mask);
@@ -837,6 +897,92 @@ static int dps310_read_raw(struct iio_dev *iio,
}
}
+static int dps310_read_raw(struct iio_dev *iio,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
+{
+ struct dps310_data *data = iio_priv(iio);
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ case IIO_CHAN_INFO_PROCESSED: {
+ /*
+ * Sampling here consumes the same measurement the capture path
+ * reads, so refuse while the buffer is enabled.
+ */
+ IIO_DEV_ACQUIRE_DIRECT_MODE(iio, claim);
+ if (IIO_DEV_ACQUIRE_FAILED(claim))
+ return -EBUSY;
+
+ return dps310_read_channel(data, chan, val, val2, mask);
+ }
+ default:
+ return dps310_read_channel(data, chan, val, val2, mask);
+ }
+}
+
+static int dps310_fill_scan(struct dps310_data *data,
+ const unsigned long *scan_mask,
+ struct dps310_scan *scan)
+ __must_hold(&data->lock)
+{
+ int rc;
+ int i = 0;
+
+ /*
+ * The pressure compensation needs a temperature reading, so temperature
+ * is sampled even when only the pressure channel is enabled.
+ */
+ rc = dps310_read_temp_raw_locked(data);
+ if (rc)
+ return rc;
+
+ if (test_bit(DPS310_SCAN_TEMP, scan_mask)) {
+ /* Millidegrees Celsius */
+ rc = dps310_calculate_temp(data, &scan->channels[i]);
+ if (rc)
+ return rc;
+
+ i++;
+ }
+
+ if (test_bit(DPS310_SCAN_PRESSURE, scan_mask)) {
+ rc = dps310_read_pres_raw_locked(data);
+ if (rc)
+ return rc;
+
+ /* Pascals, see the comment on the channel definition */
+ rc = dps310_calculate_pressure(data, &scan->channels[i]);
+ if (rc)
+ return rc;
+ }
+
+ return 0;
+}
+
+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);
+ struct dps310_scan scan = { };
+ int rc;
+
+ mutex_lock(&data->lock);
+ rc = dps310_fill_scan(data, iio->active_scan_mask, &scan);
+ mutex_unlock(&data->lock);
+ if (rc)
+ goto err;
+
+ iio_push_to_buffers_with_ts(iio, &scan, sizeof(scan),
+ iio_get_time_ns(iio));
+
+err:
+ iio_trigger_notify_done(iio->trig);
+
+ return IRQ_HANDLED;
+}
+
static void dps310_reset(void *action_data)
{
struct dps310_data *data = action_data;
@@ -893,6 +1039,17 @@ 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.
+ * The trigger is not aligned with the measurements either way, so the
+ * timestamp is taken in the handler rather than by a top half.
+ */
+ rc = devm_iio_triggered_buffer_setup(dev, iio, NULL,
+ dps310_trigger_handler, NULL);
+ if (rc)
+ return rc;
+
rc = devm_iio_device_register(dev, iio);
if (rc)
return rc;
--
2.43.0
next prev parent reply other threads:[~2026-08-24 20:14 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-24 20:11 [PATCH v6 0/6] iio: pressure: dps310: FIFO and triggered buffer support Rupesh Majhi
2026-08-24 20:11 ` [PATCH v6 1/6] iio: pressure: dps310: fix CFG_REG bit definitions Rupesh Majhi
2026-08-24 20:11 ` [PATCH v6 2/6] iio: pressure: dps310: use a local device pointer in probe Rupesh Majhi
2026-08-24 20:12 ` [PATCH v6 3/6] iio: pressure: dps310: rework the raw read paths Rupesh Majhi
2026-08-25 8:59 ` Andy Shevchenko
2026-08-24 20:12 ` Rupesh Majhi [this message]
2026-08-25 9:06 ` [PATCH v6 4/6] iio: pressure: dps310: add triggered buffer support Andy Shevchenko
2026-08-31 0:41 ` Jonathan Cameron
2026-08-31 7:03 ` Andy Shevchenko
2026-09-06 10:06 ` Rupesh Majhi
2026-08-31 1:14 ` Jonathan Cameron
2026-08-24 20:12 ` [PATCH v6 5/6] iio: pressure: dps310: add hardware FIFO support Rupesh Majhi
2026-08-25 9:39 ` Andy Shevchenko
2026-09-06 10:07 ` Rupesh Majhi
2026-08-31 1:14 ` Jonathan Cameron
2026-09-06 9:45 ` Rupesh Majhi
2026-09-10 2:36 ` Jonathan Cameron
2026-08-24 20:12 ` [PATCH v6 6/6] iio: pressure: dps310: check the lock markings with context analysis Rupesh Majhi
2026-08-31 1:14 ` 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=20260824201203.396651-5-zoone.rupert@gmail.com \
--to=zoone.rupert@gmail.com \
--cc=andy@kernel.org \
--cc=dlechner@baylibre.com \
--cc=eajames@linux.ibm.com \
--cc=jic23@kernel.org \
--cc=joel@jms.id.au \
--cc=justinstitt@google.com \
--cc=linux-iio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=llvm@lists.linux.dev \
--cc=morbo@google.com \
--cc=nathan@kernel.org \
--cc=nick.desaulniers+lkml@gmail.com \
--cc=nuno.sa@analog.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 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.