* [PATCH 0/2] iio: pressure: dps310: data-ready trigger @ 2026-11-10 15:42 Rupesh Majhi 2026-11-10 15:42 ` [PATCH 1/2] dt-bindings: iio: pressure: infineon,dps310: Add interrupts Rupesh Majhi 2026-11-10 15:42 ` [PATCH 2/2] iio: pressure: dps310: add a data-ready trigger Rupesh Majhi 0 siblings, 2 replies; 6+ messages in thread From: Rupesh Majhi @ 2026-11-10 15:42 UTC (permalink / raw) To: Andy Shevchenko, Conor Dooley, David Lechner, Eddie James, Jonathan Cameron, Krzysztof Kozlowski, Nuno Sá, Rob Herring Cc: devicetree, linux-iio, linux-kernel, Rupesh Majhi, Paulius Zaleckas DPS310 can raise an interrupt on SDO for each new result. Document it and use it for a data-ready trigger, so triggered captures follow the measurements and are stamped with the interrupt time. Tested on a DPS310 breakout (0x77) on a BeagleBone Black with SDO to a GPIO, level-low and falling-edge: one scan per pressure result at 1 and 8 Hz, gaps steady to 0.15 ms where the handler timestamp moved 1-2 ms. Without an interrupt nothing changes. Not tested: active high, which needs SDO strapped low (0x76), and ZTS8032. If the chip stalls, the case the timeout reset is for, the trigger stops firing until the buffer is disabled and a read resets the chip. Cc: Paulius Zaleckas <paulius.zaleckas@gmail.com> Rupesh Majhi (2): dt-bindings: iio: pressure: infineon,dps310: Add interrupts iio: pressure: dps310: add a data-ready trigger .../iio/pressure/infineon,dps310.yaml | 10 ++ drivers/iio/pressure/dps310.c | 129 +++++++++++++++++- 2 files changed, 135 insertions(+), 4 deletions(-) base-commit: b70566610b48ba49dec636019da4d696db64b085 -- 2.43.0 ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/2] dt-bindings: iio: pressure: infineon,dps310: Add interrupts 2026-11-10 15:42 [PATCH 0/2] iio: pressure: dps310: data-ready trigger Rupesh Majhi @ 2026-11-10 15:42 ` Rupesh Majhi 2026-11-10 15:42 ` [PATCH 2/2] iio: pressure: dps310: add a data-ready trigger Rupesh Majhi 1 sibling, 0 replies; 6+ messages in thread From: Rupesh Majhi @ 2026-11-10 15:42 UTC (permalink / raw) To: Andy Shevchenko, Conor Dooley, David Lechner, Eddie James, Jonathan Cameron, Krzysztof Kozlowski, Nuno Sá, Rob Herring Cc: devicetree, linux-iio, linux-kernel, Rupesh Majhi, Paulius Zaleckas DPS310 signals new results and a full FIFO on its SDO pin. In I2C mode the same pin sets the address LSB, and interrupt polarity must be the opposite of how SDO is strapped. Signed-off-by: Rupesh Majhi <zoone.rupert@gmail.com> --- Cc: Paulius Zaleckas <paulius.zaleckas@gmail.com> .../bindings/iio/pressure/infineon,dps310.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Documentation/devicetree/bindings/iio/pressure/infineon,dps310.yaml b/Documentation/devicetree/bindings/iio/pressure/infineon,dps310.yaml index 416117dfd927..cded6e0af147 100644 --- a/Documentation/devicetree/bindings/iio/pressure/infineon,dps310.yaml +++ b/Documentation/devicetree/bindings/iio/pressure/infineon,dps310.yaml @@ -23,6 +23,12 @@ properties: reg: maxItems: 1 + interrupts: + maxItems: 1 + description: + New result or full FIFO, on SDO pin. SDO also selects I2C address, so + interrupt is active high at 0x76 (SDO low) and active low at 0x77. + "#io-channel-cells": const: 0 @@ -42,6 +48,8 @@ additionalProperties: false examples: - | + #include <dt-bindings/interrupt-controller/irq.h> + i2c { #address-cells = <1>; #size-cells = <0>; @@ -49,6 +57,8 @@ examples: dps: pressure-sensor@76 { compatible = "infineon,dps310"; reg = <0x76>; + interrupt-parent = <&gpio0>; + interrupts = <17 IRQ_TYPE_LEVEL_HIGH>; #io-channel-cells = <0>; vdd-supply = <&vref1>; vddio-supply = <&vref2>; -- 2.43.0 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/2] iio: pressure: dps310: add a data-ready trigger 2026-11-10 15:42 [PATCH 0/2] iio: pressure: dps310: data-ready trigger Rupesh Majhi 2026-11-10 15:42 ` [PATCH 1/2] dt-bindings: iio: pressure: infineon,dps310: Add interrupts Rupesh Majhi @ 2026-11-10 15:42 ` Rupesh Majhi 2026-11-10 16:48 ` Andy Shevchenko 2026-11-11 2:15 ` sashiko-bot 1 sibling, 2 replies; 6+ messages in thread From: Rupesh Majhi @ 2026-11-10 15:42 UTC (permalink / raw) To: Andy Shevchenko, Conor Dooley, David Lechner, Eddie James, Jonathan Cameron, Krzysztof Kozlowski, Nuno Sá, Rob Herring Cc: devicetree, linux-iio, linux-kernel, Rupesh Majhi, Paulius Zaleckas With an interrupt wired to SDO, the chip can signal each new pressure result. Expose it as a trigger, so captures follow the measurements and scans carry the time the result was ready, not when the handler ran. Polarity follows the interrupt type. Status latches while the interrupt is disabled, so it is cleared before enabling. The trigger is not the default, so FIFO mode without a trigger is unchanged. Signed-off-by: Rupesh Majhi <zoone.rupert@gmail.com> --- Cc: Paulius Zaleckas <paulius.zaleckas@gmail.com> drivers/iio/pressure/dps310.c | 129 ++++++++++++++++++++++++++++++++-- 1 file changed, 125 insertions(+), 4 deletions(-) diff --git a/drivers/iio/pressure/dps310.c b/drivers/iio/pressure/dps310.c index 5cee23986f30..76738360e528 100644 --- a/drivers/iio/pressure/dps310.c +++ b/drivers/iio/pressure/dps310.c @@ -17,6 +17,8 @@ #include <linux/cleanup.h> #include <linux/devm-helpers.h> #include <linux/i2c.h> +#include <linux/interrupt.h> +#include <linux/irq.h> #include <linux/limits.h> #include <linux/math64.h> #include <linux/module.h> @@ -31,6 +33,7 @@ #include <linux/iio/buffer.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> +#include <linux/iio/trigger.h> #include <linux/iio/trigger_consumer.h> #include <linux/iio/triggered_buffer.h> @@ -62,10 +65,13 @@ #define DPS310_COEF_RDY BIT(7) #define DPS310_CFG_REG 0x09 #define DPS310_INT_HL BIT(7) +#define DPS310_INT_PRS BIT(4) #define DPS310_TMP_SHIFT_EN BIT(3) #define DPS310_PRS_SHIFT_EN BIT(2) #define DPS310_FIFO_EN BIT(1) #define DPS310_SPI_EN BIT(0) +#define DPS310_INT_STS 0x0a +#define DPS310_INT_STS_PRS BIT(0) #define DPS310_RESET 0x0c #define DPS310_FIFO_FLUSH BIT(7) #define DPS310_RESET_MAGIC 0x09 @@ -144,6 +150,9 @@ struct dps310_data { bool timeout_recovery_failed; bool fifo_temp_valid; + struct iio_trigger *trig; + s64 irq_timestamp; + /* Used only while the FIFO is enabled */ struct iio_dev *iio; struct delayed_work fifo_work; @@ -706,6 +715,7 @@ static bool dps310_is_volatile_reg(struct device *dev, unsigned int reg) case DPS310_TMP_B1: case DPS310_TMP_B2: case DPS310_MEAS_CFG: + case DPS310_INT_STS: case 0x32: /* No documentation available on this register */ return true; default: @@ -713,6 +723,12 @@ static bool dps310_is_volatile_reg(struct device *dev, unsigned int reg) } } +/* Cleared on read */ +static bool dps310_is_precious_reg(struct device *dev, unsigned int reg) +{ + return reg == DPS310_INT_STS; +} + static int dps310_write_raw(struct iio_dev *iio, struct iio_chan_spec const *chan, int val, int val2, long mask) @@ -1048,7 +1064,7 @@ static int dps310_fifo_set_enable(struct dps310_data *data, bool enable) enable); } -/* No interrupt pin is wired in tree, so drain on a timer */ +/* The FIFO only interrupts when full and then stops, so drain on a timer */ static unsigned int dps310_fifo_interval(struct dps310_data *data, int prs_rate, int tmp_rate) { @@ -1375,6 +1391,7 @@ static irqreturn_t dps310_trigger_handler(int irq, void *p) s32 channels[2]; aligned_s64 timestamp; } scan = { }; + s64 timestamp; int rc; mutex_lock(&data->lock); @@ -1383,7 +1400,12 @@ static irqreturn_t dps310_trigger_handler(int irq, void *p) if (rc) goto err; - iio_push_to_buffers_with_ts(iio, &scan, sizeof(scan), iio_get_time_ns(iio)); + if (iio_trigger_using_own(iio)) + timestamp = data->irq_timestamp; + else + timestamp = iio_get_time_ns(iio); + + iio_push_to_buffers_with_ts(iio, &scan, sizeof(scan), timestamp); err: iio_trigger_notify_done(iio->trig); @@ -1391,6 +1413,97 @@ static irqreturn_t dps310_trigger_handler(int irq, void *p) return IRQ_HANDLED; } +static irqreturn_t dps310_irq_handler(int irq, void *private) +{ + struct dps310_data *data = private; + + data->irq_timestamp = iio_get_time_ns(data->iio); + + return IRQ_WAKE_THREAD; +} + +static irqreturn_t dps310_irq_thread(int irq, void *private) +{ + struct dps310_data *data = private; + unsigned int status; + + if (regmap_read(data->regmap, DPS310_INT_STS, &status)) + return IRQ_NONE; + + if (!(status & DPS310_INT_STS_PRS)) + return IRQ_NONE; + + iio_trigger_poll_nested(data->trig); + + return IRQ_HANDLED; +} + +static int dps310_trigger_set_state(struct iio_trigger *trig, bool state) +{ + struct dps310_data *data = iio_trigger_get_drvdata(trig); + unsigned int status; + int rc; + + guard(mutex)(&data->lock); + + /* Status latched while disabled would fire a stale interrupt */ + if (state) { + rc = regmap_read(data->regmap, DPS310_INT_STS, &status); + if (rc) + return rc; + } + + return regmap_assign_bits(data->regmap, DPS310_CFG_REG, DPS310_INT_PRS, + state); +} + +static const struct iio_trigger_ops dps310_trigger_ops = { + .set_trigger_state = dps310_trigger_set_state, +}; + +static int dps310_trigger_probe(struct dps310_data *data) +{ + struct device *dev = &data->client->dev; + struct iio_dev *iio = data->iio; + int irq = data->client->irq; + bool active_high; + int rc; + + switch (irq_get_trigger_type(irq)) { + case IRQ_TYPE_LEVEL_HIGH: + case IRQ_TYPE_EDGE_RISING: + active_high = true; + break; + case IRQ_TYPE_LEVEL_LOW: + case IRQ_TYPE_EDGE_FALLING: + active_high = false; + break; + default: + return dev_err_probe(dev, -EINVAL, "Unsupported interrupt type\n"); + } + + rc = regmap_assign_bits(data->regmap, DPS310_CFG_REG, DPS310_INT_HL, + active_high); + if (rc) + return rc; + + data->trig = devm_iio_trigger_alloc(dev, "%s-dev%d", iio->name, + iio_device_id(iio)); + if (!data->trig) + return -ENOMEM; + + data->trig->ops = &dps310_trigger_ops; + iio_trigger_set_drvdata(data->trig, data); + + rc = devm_request_threaded_irq(dev, irq, dps310_irq_handler, + dps310_irq_thread, IRQF_ONESHOT, + iio->name, data); + if (rc) + return rc; + + return devm_iio_trigger_register(dev, data->trig); +} + static void dps310_standby(void *action_data) { struct dps310_data *data = action_data; @@ -1404,6 +1517,7 @@ static const struct regmap_config dps310_regmap_config = { .val_bits = 8, .writeable_reg = dps310_is_writeable_reg, .volatile_reg = dps310_is_volatile_reg, + .precious_reg = dps310_is_precious_reg, .cache_type = REGCACHE_RBTREE, .max_register = 0x62, /* No documentation available on this register */ }; @@ -1470,8 +1584,9 @@ static int dps310_probe(struct i2c_client *client) /* * The device measures continuously in background mode, so a triggered * capture is just a read of the latest results. The setup ops run the - * FIFO drain when no trigger is attached. The trigger is not aligned - * with the measurements, so the timestamp is taken in the handler. + * FIFO drain when no trigger is attached. Only the data-ready trigger + * is aligned with the measurements, so for others the timestamp is + * taken in the handler. */ rc = devm_iio_triggered_buffer_setup(dev, iio, NULL, dps310_trigger_handler, @@ -1484,6 +1599,12 @@ static int dps310_probe(struct i2c_client *client) if (rc) return rc; + if (client->irq > 0) { + rc = dps310_trigger_probe(data); + if (rc) + return rc; + } + rc = devm_iio_device_register(dev, iio); if (rc) return rc; -- 2.43.0 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] iio: pressure: dps310: add a data-ready trigger 2026-11-10 15:42 ` [PATCH 2/2] iio: pressure: dps310: add a data-ready trigger Rupesh Majhi @ 2026-11-10 16:48 ` Andy Shevchenko 2026-11-11 2:15 ` sashiko-bot 1 sibling, 0 replies; 6+ messages in thread From: Andy Shevchenko @ 2026-11-10 16:48 UTC (permalink / raw) To: Rupesh Majhi Cc: Andy Shevchenko, Conor Dooley, David Lechner, Eddie James, Jonathan Cameron, Krzysztof Kozlowski, Nuno Sá, Rob Herring, devicetree, linux-iio, linux-kernel, Paulius Zaleckas On Tue, Nov 10, 2026 at 05:42:54PM +0200, Rupesh Majhi wrote: > With an interrupt wired to SDO, the chip can signal each new pressure > result. Expose it as a trigger, so captures follow the measurements and > scans carry the time the result was ready, not when the handler ran. > > Polarity follows the interrupt type. Status latches while the interrupt > is disabled, so it is cleared before enabling. The trigger is not the > default, so FIFO mode without a trigger is unchanged. ... > +static int dps310_trigger_set_state(struct iio_trigger *trig, bool state) > +{ > + struct dps310_data *data = iio_trigger_get_drvdata(trig); struct regmap *map = data->regmap; > + unsigned int status; > + int rc; > + > + guard(mutex)(&data->lock); > + > + /* Status latched while disabled would fire a stale interrupt */ > + if (state) { > + rc = regmap_read(data->regmap, DPS310_INT_STS, &status); (as per below) > + if (rc) > + return rc; > + } > + > + return regmap_assign_bits(data->regmap, DPS310_CFG_REG, DPS310_INT_PRS, > + state); return regmap_assign_bits(map, DPS310_CFG_REG, DPS310_INT_PRS, state); > +} ... > +static int dps310_trigger_probe(struct dps310_data *data) > +{ > + struct device *dev = &data->client->dev; struct regmap *map = data->regmap; > + struct iio_dev *iio = data->iio; > + int irq = data->client->irq; > + bool active_high; > + int rc; > + > + switch (irq_get_trigger_type(irq)) { > + case IRQ_TYPE_LEVEL_HIGH: > + case IRQ_TYPE_EDGE_RISING: > + active_high = true; > + break; > + case IRQ_TYPE_LEVEL_LOW: > + case IRQ_TYPE_EDGE_FALLING: > + active_high = false; > + break; > + default: > + return dev_err_probe(dev, -EINVAL, "Unsupported interrupt type\n"); > + } > + rc = regmap_assign_bits(data->regmap, DPS310_CFG_REG, DPS310_INT_HL, > + active_high); rc = regmap_assign_bits(map, DPS310_CFG_REG, DPS310_INT_HL, active_high); > + if (rc) > + return rc; > + > + data->trig = devm_iio_trigger_alloc(dev, "%s-dev%d", iio->name, > + iio_device_id(iio)); > + if (!data->trig) > + return -ENOMEM; > + > + data->trig->ops = &dps310_trigger_ops; > + iio_trigger_set_drvdata(data->trig, data); > + > + rc = devm_request_threaded_irq(dev, irq, dps310_irq_handler, > + dps310_irq_thread, IRQF_ONESHOT, > + iio->name, data); > + if (rc) > + return rc; > + > + return devm_iio_trigger_register(dev, data->trig); > +} -- With Best Regards, Andy Shevchenko ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] iio: pressure: dps310: add a data-ready trigger 2026-11-10 15:42 ` [PATCH 2/2] iio: pressure: dps310: add a data-ready trigger Rupesh Majhi 2026-11-10 16:48 ` Andy Shevchenko @ 2026-11-11 2:15 ` sashiko-bot 2026-11-11 20:00 ` Rupesh Majhi 1 sibling, 1 reply; 6+ messages in thread From: sashiko-bot @ 2026-11-11 2:15 UTC (permalink / raw) To: Rupesh Majhi; +Cc: devicetree, robh, conor+dt Thank you for your contribution! Sashiko AI review found 1 potential issue to consider: - [High] iio: pressure: dps310: blocking temp wait in dps310_fill_channels() on IRQ -- commit f0cb91c380b85ec52615026366938a6f2c5145ae Author: Rupesh Majhi <zoone.rupert@gmail.com> iio: pressure: dps310: add a data-ready trigger This commit registers an IIO trigger backed by the DPS310 pressure data-ready interrupt on SDO and uses the interrupt timestamp when capturing scans with the device's own trigger. > diff --git a/drivers/iio/pressure/dps310.c b/drivers/iio/pressure/dps310.c > index 5cee23986f307..76738360e528e 100644 > --- a/drivers/iio/pressure/dps310.c > +++ b/drivers/iio/pressure/dps310.c [ ... ] > @@ -1375,6 +1391,7 @@ static irqreturn_t dps310_trigger_handler(int irq, void *p) > s32 channels[2]; > aligned_s64 timestamp; > } scan = { }; > + s64 timestamp; > int rc; > > mutex_lock(&data->lock); > @@ -1383,7 +1400,12 @@ static irqreturn_t dps310_trigger_handler(int irq, void *p) > if (rc) > goto err; > > - iio_push_to_buffers_with_ts(iio, &scan, sizeof(scan), iio_get_time_ns(iio)); > + if (iio_trigger_using_own(iio)) > + timestamp = data->irq_timestamp; > + else > + timestamp = iio_get_time_ns(iio); > + > + iio_push_to_buffers_with_ts(iio, &scan, sizeof(scan), timestamp); > > err: > iio_trigger_notify_done(iio->trig); > @@ -1391,6 +1413,97 @@ static irqreturn_t dps310_trigger_handler(int irq, void *p) > return IRQ_HANDLED; > } > > +static irqreturn_t dps310_irq_handler(int irq, void *private) > +{ > + struct dps310_data *data = private; > + > + data->irq_timestamp = iio_get_time_ns(data->iio); > + > + return IRQ_WAKE_THREAD; > +} > + > +static irqreturn_t dps310_irq_thread(int irq, void *private) > +{ > + struct dps310_data *data = private; > + unsigned int status; > + > + if (regmap_read(data->regmap, DPS310_INT_STS, &status)) > + return IRQ_NONE; > + > + if (!(status & DPS310_INT_STS_PRS)) > + return IRQ_NONE; > + > + iio_trigger_poll_nested(data->trig); > + > + return IRQ_HANDLED; > +} [Severity: High] When the pressure sampling rate is higher than the temperature rate (for example, any pressure rate above the 1 Hz default temperature rate), does dps310_trigger_handler() block waiting for the next temperature conversion before reading the pressure sample that fired DPS310_INT_PRS? dps310_irq_thread() clears DPS310_INT_STS and calls iio_trigger_poll_nested() -> dps310_trigger_handler() -> dps310_fill_channels(): drivers/iio/pressure/dps310.c:dps310_fill_channels() { /* Compensation needs a temperature, so it is sampled either way */ rc = dps310_read_temp_raw_locked(data); if (rc) return rc; ... if (test_bit(DPS310_SCAN_PRESSURE, scan_mask)) { rc = dps310_read_pres_raw_locked(data); Reading DPS310_TMP_BASE clears DPS310_TMP_RDY, so on the next pressure interrupt dps310_read_temp_raw_locked() sleeps until another temperature measurement finishes. While it sleeps, pressure capture is throttled to the temperature rate, new pressure conversions overwrite DPS310_PRS_B0..B2 so the newer sample is pushed with the earlier data->irq_timestamp, and DPS310_INT_STS_PRS is re-latched without being cleared by dps310_read_pres_raw_locked() (leaving SDO asserted, which causes an immediate spurious interrupt on level-triggered IRQs or stalls edge-triggered IRQs). Should dps310_fill_channels() read pressure first and use dps310_refresh_temp_locked() like dps310_read_pressure_value() does? -- Sashiko AI review · https://sashiko.dev/#/patchset/20261110154254.39092-1-zoone.rupert@gmail.com?part=2 ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] iio: pressure: dps310: add a data-ready trigger 2026-11-11 2:15 ` sashiko-bot @ 2026-11-11 20:00 ` Rupesh Majhi 0 siblings, 0 replies; 6+ messages in thread From: Rupesh Majhi @ 2026-11-11 20:00 UTC (permalink / raw) To: sashiko-reviews Cc: Andy Shevchenko, Conor Dooley, David Lechner, Eddie James, Jonathan Cameron, Krzysztof Kozlowski, Nuno Sá, Rob Herring, devicetree, linux-iio, linux-kernel, Paulius Zaleckas On Wed, 11 Nov 2026 02:15:48 +0000 sashiko-bot@kernel.org wrote: > Should dps310_fill_channels() read pressure first and use > dps310_refresh_temp_locked() like dps310_read_pressure_value() does? Yes. The wait came with the triggered buffer support, so it is older than this patch and holds any trigger faster than temperature to the temperature rate. Fixed on its own: https://lore.kernel.org/linux-iio/20261111195118.36853-1-zoone.rupert@gmail.com/ With the fix, this trigger keeps up at 8 and 32 Hz with temperature at 1 Hz. I'll mention it in v2. Rupesh ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-11-11 20:00 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-11-10 15:42 [PATCH 0/2] iio: pressure: dps310: data-ready trigger Rupesh Majhi 2026-11-10 15:42 ` [PATCH 1/2] dt-bindings: iio: pressure: infineon,dps310: Add interrupts Rupesh Majhi 2026-11-10 15:42 ` [PATCH 2/2] iio: pressure: dps310: add a data-ready trigger Rupesh Majhi 2026-11-10 16:48 ` Andy Shevchenko 2026-11-11 2:15 ` sashiko-bot 2026-11-11 20:00 ` Rupesh Majhi
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox