devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 0/5] iio: mpl3115: add support for DRDY interrupt
@ 2025-10-02 20:02 Antoni Pokusinski
  2025-10-02 20:02 ` [PATCH v4 1/5] dt-bindings: iio: pressure: add binding for mpl3115 Antoni Pokusinski
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Antoni Pokusinski @ 2025-10-02 20:02 UTC (permalink / raw)
  To: jic23, dlechner, nuno.sa, andy, robh, krzk+dt, conor+dt
  Cc: linux-kernel, devicetree, linux-iio, linux, rodrigo.gobbi.7,
	naresh.solanki, michal.simek, grantpeltier93, farouk.bouabid,
	marcelo.schmitt1, Antoni Pokusinski

Hello,
This set of patches adds support for the DRDY interrupt in the MPL3115
pressure sensor. The device has 2 interrupt lines, hence the new
binding. I also added support for the sampling frequency which
determines the time interval between subsequent measurements (in the
continuous measurements mode) so it's obiously tied to the DRDY
interrupt feature.

Kind regards,
Antoni Pokusinski

---
Changes since v3:
* P2: created mpl3115_fill_trig_buffer
* P2: trigger_handler: replaced scoped_guard with mutex_lock
* P2: includes: removed linux/cleanup.h

* P3: new patch: renamed MPL3115_CTRL_* macros to MPL3115_CTRL1_*

* P4: extracted the MPL3115_CTRL_* renames into a separate patch (P3 now)
* P4: trigger_probe: placed devm_request_threaded_irq() call before
                     devm_iio_trigger_register()
* P4: trigger_probe: removed switch(irq_cfg_flags) together with the
                     enum mpl3115_irq_type and added 2 separate
                     variables to handle interrupt setup logic 
* P4: set_trigger_state: factored out the CTRL_REG1 and CTRL_REG4 writes 
                         into a separate function mpl3115_config_interrupt

* P5: samp_freq_table: added spaces before "},"

Changes since v2:
* P4: included linux/bitfield.h

Changes since v1:
* P1: add `vdd-supply` and `vddio-supply`

* P2: new patch: use guards from cleanup.h   

* P3: change macros of control register bits to convention
      MPL3115_CTRLX_NAME
* P3: MPL3115_PT_DATA_EVENT_ALL: use GENMASK
* P3: trigger_probe: do not fail if dev_fwnode() returns NULL
* P3: trigger_probe: use devm_iio_trigger_register()
* P3: trigger_probe: introduced enum mpl3115_irq_type and 
      changed IRQ setup logic accordingly

* P4: MPL3115_CTRL2_ST: use GENMASK
* P4: read_raw: samp_freq: use FIELD_GET
* P4: write_raw: samp_freq: use FIELD_PREP
---

Antoni Pokusinski (5):
  dt-bindings: iio: pressure: add binding for mpl3115
  iio: mpl3115: add separate function for triggered buffer data
    collection
  iio: mpl3115: rename CTRL_REG1 field macros
  iio: mpl3115: add support for DRDY interrupt
  iio: mpl3115: add support for sampling frequency

 .../bindings/iio/pressure/fsl,mpl3115.yaml    |  71 ++++
 .../devicetree/bindings/trivial-devices.yaml  |   2 -
 drivers/iio/pressure/mpl3115.c                | 331 ++++++++++++++++--
 3 files changed, 364 insertions(+), 40 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/iio/pressure/fsl,mpl3115.yaml

-- 
2.25.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v4 1/5] dt-bindings: iio: pressure: add binding for mpl3115
  2025-10-02 20:02 [PATCH v4 0/5] iio: mpl3115: add support for DRDY interrupt Antoni Pokusinski
@ 2025-10-02 20:02 ` Antoni Pokusinski
  2025-10-02 20:02 ` [PATCH v4 2/5] iio: mpl3115: add separate function for triggered buffer data collection Antoni Pokusinski
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Antoni Pokusinski @ 2025-10-02 20:02 UTC (permalink / raw)
  To: jic23, dlechner, nuno.sa, andy, robh, krzk+dt, conor+dt
  Cc: linux-kernel, devicetree, linux-iio, linux, rodrigo.gobbi.7,
	naresh.solanki, michal.simek, grantpeltier93, farouk.bouabid,
	marcelo.schmitt1, Antoni Pokusinski

MPL3115 is an I2C pressure and temperature sensor. It features 2
interrupt lines which can be configured to indicate events such as data
ready or pressure/temperature threshold reached.

Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Antoni Pokusinski <apokusinski01@gmail.com>
---
 .../bindings/iio/pressure/fsl,mpl3115.yaml    | 71 +++++++++++++++++++
 .../devicetree/bindings/trivial-devices.yaml  |  2 -
 2 files changed, 71 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/iio/pressure/fsl,mpl3115.yaml

diff --git a/Documentation/devicetree/bindings/iio/pressure/fsl,mpl3115.yaml b/Documentation/devicetree/bindings/iio/pressure/fsl,mpl3115.yaml
new file mode 100644
index 000000000000..2933c2e10695
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/pressure/fsl,mpl3115.yaml
@@ -0,0 +1,71 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/pressure/fsl,mpl3115.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MPL3115 precision pressure sensor with altimetry
+
+maintainers:
+  - Antoni Pokusinski <apokusinski01@gmail.com>
+
+description: |
+  MPL3115 is a pressure/altitude and temperature sensor with I2C interface.
+  It features two programmable interrupt lines which indicate events such as
+  data ready or pressure/temperature threshold reached.
+  https://www.nxp.com/docs/en/data-sheet/MPL3115A2.pdf
+
+properties:
+  compatible:
+    const: fsl,mpl3115
+
+  reg:
+    maxItems: 1
+
+  vdd-supply: true
+
+  vddio-supply: true
+
+  interrupts:
+    minItems: 1
+    maxItems: 2
+
+  interrupt-names:
+    minItems: 1
+    maxItems: 2
+    items:
+      enum:
+        - INT1
+        - INT2
+
+  drive-open-drain:
+    type: boolean
+    description:
+      set if the specified interrupt pins should be configured as
+      open drain. If not set, defaults to push-pull.
+
+required:
+  - compatible
+  - reg
+  - vdd-supply
+  - vddio-supply
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        pressure@60 {
+            compatible = "fsl,mpl3115";
+            reg = <0x60>;
+            vdd-supply = <&vdd>;
+            vddio-supply = <&vddio>;
+            interrupt-parent = <&gpio1>;
+            interrupts = <4 IRQ_TYPE_EDGE_FALLING>;
+            interrupt-names = "INT2";
+        };
+    };
diff --git a/Documentation/devicetree/bindings/trivial-devices.yaml b/Documentation/devicetree/bindings/trivial-devices.yaml
index f3dd18681aa6..918d4a12d61c 100644
--- a/Documentation/devicetree/bindings/trivial-devices.yaml
+++ b/Documentation/devicetree/bindings/trivial-devices.yaml
@@ -113,8 +113,6 @@ properties:
           - fsl,mma7660
             # MMA8450Q: Xtrinsic Low-power, 3-axis Xtrinsic Accelerometer
           - fsl,mma8450
-            # MPL3115: Absolute Digital Pressure Sensor
-          - fsl,mpl3115
             # MPR121: Proximity Capacitive Touch Sensor Controller
           - fsl,mpr121
             # Honeywell Humidicon HIH-6130 humidity/temperature sensor
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v4 2/5] iio: mpl3115: add separate function for triggered buffer data collection
  2025-10-02 20:02 [PATCH v4 0/5] iio: mpl3115: add support for DRDY interrupt Antoni Pokusinski
  2025-10-02 20:02 ` [PATCH v4 1/5] dt-bindings: iio: pressure: add binding for mpl3115 Antoni Pokusinski
@ 2025-10-02 20:02 ` Antoni Pokusinski
  2025-10-02 20:02 ` [PATCH v4 3/5] iio: mpl3115: rename CTRL_REG1 field macros Antoni Pokusinski
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Antoni Pokusinski @ 2025-10-02 20:02 UTC (permalink / raw)
  To: jic23, dlechner, nuno.sa, andy, robh, krzk+dt, conor+dt
  Cc: linux-kernel, devicetree, linux-iio, linux, rodrigo.gobbi.7,
	naresh.solanki, michal.simek, grantpeltier93, farouk.bouabid,
	marcelo.schmitt1, Antoni Pokusinski

Factor out the code responsible for collecting data for the triggered
buffer from the trigger handler into a separate function.

Signed-off-by: Antoni Pokusinski <apokusinski01@gmail.com>
---
 drivers/iio/pressure/mpl3115.c | 54 +++++++++++++++++++---------------
 1 file changed, 30 insertions(+), 24 deletions(-)

diff --git a/drivers/iio/pressure/mpl3115.c b/drivers/iio/pressure/mpl3115.c
index 579da60ef441..1da78081ca7e 100644
--- a/drivers/iio/pressure/mpl3115.c
+++ b/drivers/iio/pressure/mpl3115.c
@@ -148,47 +148,53 @@ static int mpl3115_read_raw(struct iio_dev *indio_dev,
 	return -EINVAL;
 }
 
-static irqreturn_t mpl3115_trigger_handler(int irq, void *p)
+static int mpl3115_fill_trig_buffer(struct iio_dev *indio_dev, u8 *buffer)
 {
-	struct iio_poll_func *pf = p;
-	struct iio_dev *indio_dev = pf->indio_dev;
 	struct mpl3115_data *data = iio_priv(indio_dev);
-	/*
-	 * 32-bit channel + 16-bit channel + padding + ts
-	 * Note that it is possible for only one of the first 2
-	 * channels to be enabled. If that happens, the first element
-	 * of the buffer may be either 16 or 32-bits.  As such we cannot
-	 * use a simple structure definition to express this data layout.
-	 */
-	u8 buffer[16] __aligned(8) = { };
 	int ret, pos = 0;
 
-	mutex_lock(&data->lock);
 	ret = mpl3115_request(data);
-	if (ret < 0) {
-		mutex_unlock(&data->lock);
-		goto done;
-	}
+	if (ret < 0)
+		return ret;
 
 	if (test_bit(0, indio_dev->active_scan_mask)) {
 		ret = i2c_smbus_read_i2c_block_data(data->client,
 			MPL3115_OUT_PRESS, 3, &buffer[pos]);
-		if (ret < 0) {
-			mutex_unlock(&data->lock);
-			goto done;
-		}
+		if (ret < 0)
+			return ret;
 		pos += 4;
 	}
 
 	if (test_bit(1, indio_dev->active_scan_mask)) {
 		ret = i2c_smbus_read_i2c_block_data(data->client,
 			MPL3115_OUT_TEMP, 2, &buffer[pos]);
-		if (ret < 0) {
-			mutex_unlock(&data->lock);
-			goto done;
-		}
+		if (ret < 0)
+			return ret;
 	}
+
+	return 0;
+}
+
+static irqreturn_t mpl3115_trigger_handler(int irq, void *p)
+{
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->indio_dev;
+	struct mpl3115_data *data = iio_priv(indio_dev);
+	/*
+	 * 32-bit channel + 16-bit channel + padding + ts
+	 * Note that it is possible for only one of the first 2
+	 * channels to be enabled. If that happens, the first element
+	 * of the buffer may be either 16 or 32-bits.  As such we cannot
+	 * use a simple structure definition to express this data layout.
+	 */
+	u8 buffer[16] __aligned(8) = { };
+	int ret;
+
+	mutex_lock(&data->lock);
+	ret = mpl3115_fill_trig_buffer(indio_dev, buffer);
 	mutex_unlock(&data->lock);
+	if (ret)
+		goto done;
 
 	iio_push_to_buffers_with_ts(indio_dev, buffer, sizeof(buffer),
 				    iio_get_time_ns(indio_dev));
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v4 3/5] iio: mpl3115: rename CTRL_REG1 field macros
  2025-10-02 20:02 [PATCH v4 0/5] iio: mpl3115: add support for DRDY interrupt Antoni Pokusinski
  2025-10-02 20:02 ` [PATCH v4 1/5] dt-bindings: iio: pressure: add binding for mpl3115 Antoni Pokusinski
  2025-10-02 20:02 ` [PATCH v4 2/5] iio: mpl3115: add separate function for triggered buffer data collection Antoni Pokusinski
@ 2025-10-02 20:02 ` Antoni Pokusinski
  2025-10-02 20:02 ` [PATCH v4 4/5] iio: mpl3115: add support for DRDY interrupt Antoni Pokusinski
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Antoni Pokusinski @ 2025-10-02 20:02 UTC (permalink / raw)
  To: jic23, dlechner, nuno.sa, andy, robh, krzk+dt, conor+dt
  Cc: linux-kernel, devicetree, linux-iio, linux, rodrigo.gobbi.7,
	naresh.solanki, michal.simek, grantpeltier93, farouk.bouabid,
	marcelo.schmitt1, Antoni Pokusinski

Rename the bitfield macros of CTRL_REG1, so that their names clearly
indicate their relation to CTRL_REG1.

This is a preparation for introducing the support for the DRDY interrupt
which requires the usage of other control registers.

Signed-off-by: Antoni Pokusinski <apokusinski01@gmail.com>
---
 drivers/iio/pressure/mpl3115.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/iio/pressure/mpl3115.c b/drivers/iio/pressure/mpl3115.c
index 1da78081ca7e..61830edd959b 100644
--- a/drivers/iio/pressure/mpl3115.c
+++ b/drivers/iio/pressure/mpl3115.c
@@ -30,10 +30,10 @@
 #define MPL3115_STATUS_PRESS_RDY BIT(2)
 #define MPL3115_STATUS_TEMP_RDY BIT(1)
 
-#define MPL3115_CTRL_RESET BIT(2) /* software reset */
-#define MPL3115_CTRL_OST BIT(1) /* initiate measurement */
-#define MPL3115_CTRL_ACTIVE BIT(0) /* continuous measurement */
-#define MPL3115_CTRL_OS_258MS (BIT(5) | BIT(4)) /* 64x oversampling */
+#define MPL3115_CTRL1_RESET BIT(2) /* software reset */
+#define MPL3115_CTRL1_OST BIT(1) /* initiate measurement */
+#define MPL3115_CTRL1_ACTIVE BIT(0) /* continuous measurement */
+#define MPL3115_CTRL1_OS_258MS GENMASK(5, 4) /* 64x oversampling */
 
 struct mpl3115_data {
 	struct i2c_client *client;
@@ -47,7 +47,7 @@ static int mpl3115_request(struct mpl3115_data *data)
 
 	/* trigger measurement */
 	ret = i2c_smbus_write_byte_data(data->client, MPL3115_CTRL_REG1,
-		data->ctrl_reg1 | MPL3115_CTRL_OST);
+		data->ctrl_reg1 | MPL3115_CTRL1_OST);
 	if (ret < 0)
 		return ret;
 
@@ -56,7 +56,7 @@ static int mpl3115_request(struct mpl3115_data *data)
 		if (ret < 0)
 			return ret;
 		/* wait for data ready, i.e. OST cleared */
-		if (!(ret & MPL3115_CTRL_OST))
+		if (!(ret & MPL3115_CTRL1_OST))
 			break;
 		msleep(20);
 	}
@@ -268,10 +268,10 @@ static int mpl3115_probe(struct i2c_client *client)
 
 	/* software reset, I2C transfer is aborted (fails) */
 	i2c_smbus_write_byte_data(client, MPL3115_CTRL_REG1,
-		MPL3115_CTRL_RESET);
+		MPL3115_CTRL1_RESET);
 	msleep(50);
 
-	data->ctrl_reg1 = MPL3115_CTRL_OS_258MS;
+	data->ctrl_reg1 = MPL3115_CTRL1_OS_258MS;
 	ret = i2c_smbus_write_byte_data(client, MPL3115_CTRL_REG1,
 		data->ctrl_reg1);
 	if (ret < 0)
@@ -295,7 +295,7 @@ static int mpl3115_probe(struct i2c_client *client)
 static int mpl3115_standby(struct mpl3115_data *data)
 {
 	return i2c_smbus_write_byte_data(data->client, MPL3115_CTRL_REG1,
-		data->ctrl_reg1 & ~MPL3115_CTRL_ACTIVE);
+		data->ctrl_reg1 & ~MPL3115_CTRL1_ACTIVE);
 }
 
 static void mpl3115_remove(struct i2c_client *client)
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v4 4/5] iio: mpl3115: add support for DRDY interrupt
  2025-10-02 20:02 [PATCH v4 0/5] iio: mpl3115: add support for DRDY interrupt Antoni Pokusinski
                   ` (2 preceding siblings ...)
  2025-10-02 20:02 ` [PATCH v4 3/5] iio: mpl3115: rename CTRL_REG1 field macros Antoni Pokusinski
@ 2025-10-02 20:02 ` Antoni Pokusinski
  2025-10-02 20:02 ` [PATCH v4 5/5] iio: mpl3115: add support for sampling frequency Antoni Pokusinski
  2025-10-03 16:48 ` [PATCH v4 0/5] iio: mpl3115: add support for DRDY interrupt Jonathan Cameron
  5 siblings, 0 replies; 7+ messages in thread
From: Antoni Pokusinski @ 2025-10-02 20:02 UTC (permalink / raw)
  To: jic23, dlechner, nuno.sa, andy, robh, krzk+dt, conor+dt
  Cc: linux-kernel, devicetree, linux-iio, linux, rodrigo.gobbi.7,
	naresh.solanki, michal.simek, grantpeltier93, farouk.bouabid,
	marcelo.schmitt1, Antoni Pokusinski

MPL3115 sensor features a "data ready" interrupt which indicates the
presence of new measurements.

Signed-off-by: Antoni Pokusinski <apokusinski01@gmail.com>
---
 drivers/iio/pressure/mpl3115.c | 183 +++++++++++++++++++++++++++++++--
 1 file changed, 175 insertions(+), 8 deletions(-)

diff --git a/drivers/iio/pressure/mpl3115.c b/drivers/iio/pressure/mpl3115.c
index 61830edd959b..e1b2c9f2bb43 100644
--- a/drivers/iio/pressure/mpl3115.c
+++ b/drivers/iio/pressure/mpl3115.c
@@ -7,40 +7,66 @@
  * (7-bit I2C slave address 0x60)
  *
  * TODO: FIFO buffer, altimeter mode, oversampling, continuous mode,
- * interrupts, user offset correction, raw mode
+ * user offset correction, raw mode
  */
 
-#include <linux/module.h>
+#include <linux/cleanup.h>
+#include <linux/delay.h>
 #include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/property.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/buffer.h>
 #include <linux/iio/triggered_buffer.h>
-#include <linux/delay.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/trigger.h>
 
 #define MPL3115_STATUS 0x00
 #define MPL3115_OUT_PRESS 0x01 /* MSB first, 20 bit */
 #define MPL3115_OUT_TEMP 0x04 /* MSB first, 12 bit */
 #define MPL3115_WHO_AM_I 0x0c
+#define MPL3115_INT_SOURCE 0x12
+#define MPL3115_PT_DATA_CFG 0x13
 #define MPL3115_CTRL_REG1 0x26
+#define MPL3115_CTRL_REG3 0x28
+#define MPL3115_CTRL_REG4 0x29
+#define MPL3115_CTRL_REG5 0x2a
 
 #define MPL3115_DEVICE_ID 0xc4
 
 #define MPL3115_STATUS_PRESS_RDY BIT(2)
 #define MPL3115_STATUS_TEMP_RDY BIT(1)
 
+#define MPL3115_INT_SRC_DRDY BIT(7)
+
+#define MPL3115_PT_DATA_EVENT_ALL GENMASK(2, 0)
+
 #define MPL3115_CTRL1_RESET BIT(2) /* software reset */
 #define MPL3115_CTRL1_OST BIT(1) /* initiate measurement */
 #define MPL3115_CTRL1_ACTIVE BIT(0) /* continuous measurement */
 #define MPL3115_CTRL1_OS_258MS GENMASK(5, 4) /* 64x oversampling */
 
+#define MPL3115_CTRL3_IPOL1 BIT(5)
+#define MPL3115_CTRL3_IPOL2 BIT(1)
+
+#define MPL3115_CTRL4_INT_EN_DRDY BIT(7)
+
+#define MPL3115_CTRL5_INT_CFG_DRDY BIT(7)
+
 struct mpl3115_data {
 	struct i2c_client *client;
+	struct iio_trigger *drdy_trig;
 	struct mutex lock;
 	u8 ctrl_reg1;
 };
 
+enum mpl3115_irq_pin {
+	MPL3115_IRQ_INT1,
+	MPL3115_IRQ_INT2,
+};
+
 static int mpl3115_request(struct mpl3115_data *data)
 {
 	int ret, tries = 15;
@@ -153,9 +179,11 @@ static int mpl3115_fill_trig_buffer(struct iio_dev *indio_dev, u8 *buffer)
 	struct mpl3115_data *data = iio_priv(indio_dev);
 	int ret, pos = 0;
 
-	ret = mpl3115_request(data);
-	if (ret < 0)
-		return ret;
+	if (!(data->ctrl_reg1 & MPL3115_CTRL1_ACTIVE)) {
+		ret = mpl3115_request(data);
+		if (ret < 0)
+			return ret;
+	}
 
 	if (test_bit(0, indio_dev->active_scan_mask)) {
 		ret = i2c_smbus_read_i2c_block_data(data->client,
@@ -234,10 +262,145 @@ static const struct iio_chan_spec mpl3115_channels[] = {
 	IIO_CHAN_SOFT_TIMESTAMP(2),
 };
 
+static irqreturn_t mpl3115_interrupt_handler(int irq, void *private)
+{
+	struct iio_dev *indio_dev = private;
+	struct mpl3115_data *data = iio_priv(indio_dev);
+	int ret;
+
+	ret = i2c_smbus_read_byte_data(data->client, MPL3115_INT_SOURCE);
+	if (ret < 0)
+		return IRQ_HANDLED;
+
+	if (!(ret & MPL3115_INT_SRC_DRDY))
+		return IRQ_NONE;
+
+	iio_trigger_poll_nested(data->drdy_trig);
+
+	return IRQ_HANDLED;
+}
+
+static int mpl3115_config_interrupt(struct mpl3115_data *data,
+				    u8 ctrl_reg1, u8 ctrl_reg4)
+{
+	int ret;
+
+	ret = i2c_smbus_write_byte_data(data->client, MPL3115_CTRL_REG1,
+					ctrl_reg1);
+	if (ret < 0)
+		return ret;
+
+	ret = i2c_smbus_write_byte_data(data->client, MPL3115_CTRL_REG4,
+					ctrl_reg4);
+	if (ret < 0)
+		goto reg1_cleanup;
+
+	data->ctrl_reg1 = ctrl_reg1;
+
+	return 0;
+
+reg1_cleanup:
+	i2c_smbus_write_byte_data(data->client, MPL3115_CTRL_REG1,
+				  data->ctrl_reg1);
+	return ret;
+}
+
+static int mpl3115_set_trigger_state(struct iio_trigger *trig, bool state)
+{
+	struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
+	struct mpl3115_data *data = iio_priv(indio_dev);
+	u8 ctrl_reg1 = data->ctrl_reg1;
+	u8 ctrl_reg4 = state ? MPL3115_CTRL4_INT_EN_DRDY : 0;
+
+	if (state)
+		ctrl_reg1 |= MPL3115_CTRL1_ACTIVE;
+	else
+		ctrl_reg1 &= ~MPL3115_CTRL1_ACTIVE;
+
+	guard(mutex)(&data->lock);
+
+	return mpl3115_config_interrupt(data, ctrl_reg1, ctrl_reg4);
+}
+
+static const struct iio_trigger_ops mpl3115_trigger_ops = {
+	.set_trigger_state = mpl3115_set_trigger_state,
+};
+
 static const struct iio_info mpl3115_info = {
 	.read_raw = &mpl3115_read_raw,
 };
 
+static int mpl3115_trigger_probe(struct mpl3115_data *data,
+				 struct iio_dev *indio_dev)
+{
+	struct fwnode_handle *fwnode = dev_fwnode(&data->client->dev);
+	int ret, irq, irq_type, irq_pin = MPL3115_IRQ_INT1;
+
+	irq = fwnode_irq_get_byname(fwnode, "INT1");
+	if (irq < 0) {
+		irq = fwnode_irq_get_byname(fwnode, "INT2");
+		if (irq < 0)
+			return 0;
+
+		irq_pin = MPL3115_IRQ_INT2;
+	}
+
+	irq_type = irq_get_trigger_type(irq);
+	if (irq_type != IRQF_TRIGGER_RISING && irq_type != IRQF_TRIGGER_FALLING)
+		return -EINVAL;
+
+	ret = i2c_smbus_write_byte_data(data->client, MPL3115_PT_DATA_CFG,
+					MPL3115_PT_DATA_EVENT_ALL);
+	if (ret < 0)
+		return ret;
+
+	if (irq_pin == MPL3115_IRQ_INT1) {
+		ret = i2c_smbus_write_byte_data(data->client,
+						MPL3115_CTRL_REG5,
+						MPL3115_CTRL5_INT_CFG_DRDY);
+		if (ret)
+			return ret;
+
+		if (irq_type == IRQF_TRIGGER_RISING) {
+			ret = i2c_smbus_write_byte_data(data->client,
+							MPL3115_CTRL_REG3,
+							MPL3115_CTRL3_IPOL1);
+			if (ret)
+				return ret;
+		}
+	} else if (irq_type == IRQF_TRIGGER_RISING) {
+		ret = i2c_smbus_write_byte_data(data->client, MPL3115_CTRL_REG3,
+						MPL3115_CTRL3_IPOL2);
+		if (ret)
+			return ret;
+	}
+
+	data->drdy_trig = devm_iio_trigger_alloc(&data->client->dev,
+						 "%s-dev%d",
+						 indio_dev->name,
+						 iio_device_id(indio_dev));
+	if (!data->drdy_trig)
+		return -ENOMEM;
+
+	data->drdy_trig->ops = &mpl3115_trigger_ops;
+	iio_trigger_set_drvdata(data->drdy_trig, indio_dev);
+
+	ret = devm_request_threaded_irq(&data->client->dev, irq, NULL,
+					mpl3115_interrupt_handler,
+					IRQF_ONESHOT,
+					"mpl3115_irq", indio_dev);
+	if (ret)
+		return ret;
+
+	ret = devm_iio_trigger_register(&data->client->dev, data->drdy_trig);
+	if (ret)
+		return ret;
+
+	indio_dev->trig = iio_trigger_get(data->drdy_trig);
+
+	return 0;
+}
+
 static int mpl3115_probe(struct i2c_client *client)
 {
 	const struct i2c_device_id *id = i2c_client_get_device_id(client);
@@ -277,6 +440,10 @@ static int mpl3115_probe(struct i2c_client *client)
 	if (ret < 0)
 		return ret;
 
+	ret = mpl3115_trigger_probe(data, indio_dev);
+	if (ret)
+		return ret;
+
 	ret = iio_triggered_buffer_setup(indio_dev, NULL,
 		mpl3115_trigger_handler, NULL);
 	if (ret < 0)
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v4 5/5] iio: mpl3115: add support for sampling frequency
  2025-10-02 20:02 [PATCH v4 0/5] iio: mpl3115: add support for DRDY interrupt Antoni Pokusinski
                   ` (3 preceding siblings ...)
  2025-10-02 20:02 ` [PATCH v4 4/5] iio: mpl3115: add support for DRDY interrupt Antoni Pokusinski
@ 2025-10-02 20:02 ` Antoni Pokusinski
  2025-10-03 16:48 ` [PATCH v4 0/5] iio: mpl3115: add support for DRDY interrupt Jonathan Cameron
  5 siblings, 0 replies; 7+ messages in thread
From: Antoni Pokusinski @ 2025-10-02 20:02 UTC (permalink / raw)
  To: jic23, dlechner, nuno.sa, andy, robh, krzk+dt, conor+dt
  Cc: linux-kernel, devicetree, linux-iio, linux, rodrigo.gobbi.7,
	naresh.solanki, michal.simek, grantpeltier93, farouk.bouabid,
	marcelo.schmitt1, Antoni Pokusinski

When the device is in ACTIVE mode the temperature and pressure measurements
are collected with a frequency determined by the ST[3:0] bits of CTRL_REG2
register.

Reviewed-by: Nuno Sá <nuno.sa@analog.com>
Signed-off-by: Antoni Pokusinski <apokusinski01@gmail.com>
---
 drivers/iio/pressure/mpl3115.c | 82 ++++++++++++++++++++++++++++++++++
 1 file changed, 82 insertions(+)

diff --git a/drivers/iio/pressure/mpl3115.c b/drivers/iio/pressure/mpl3115.c
index e1b2c9f2bb43..c212dfdf59ff 100644
--- a/drivers/iio/pressure/mpl3115.c
+++ b/drivers/iio/pressure/mpl3115.c
@@ -10,6 +10,7 @@
  * user offset correction, raw mode
  */
 
+#include <linux/bitfield.h>
 #include <linux/cleanup.h>
 #include <linux/delay.h>
 #include <linux/i2c.h>
@@ -30,6 +31,7 @@
 #define MPL3115_INT_SOURCE 0x12
 #define MPL3115_PT_DATA_CFG 0x13
 #define MPL3115_CTRL_REG1 0x26
+#define MPL3115_CTRL_REG2 0x27
 #define MPL3115_CTRL_REG3 0x28
 #define MPL3115_CTRL_REG4 0x29
 #define MPL3115_CTRL_REG5 0x2a
@@ -48,6 +50,8 @@
 #define MPL3115_CTRL1_ACTIVE BIT(0) /* continuous measurement */
 #define MPL3115_CTRL1_OS_258MS GENMASK(5, 4) /* 64x oversampling */
 
+#define MPL3115_CTRL2_ST GENMASK(3, 0)
+
 #define MPL3115_CTRL3_IPOL1 BIT(5)
 #define MPL3115_CTRL3_IPOL2 BIT(1)
 
@@ -55,6 +59,25 @@
 
 #define MPL3115_CTRL5_INT_CFG_DRDY BIT(7)
 
+static const unsigned int mpl3115_samp_freq_table[][2] = {
+	{ 1,      0 },
+	{ 0, 500000 },
+	{ 0, 250000 },
+	{ 0, 125000 },
+	{ 0,  62500 },
+	{ 0,  31250 },
+	{ 0,  15625 },
+	{ 0,   7812 },
+	{ 0,   3906 },
+	{ 0,   1953 },
+	{ 0,    976 },
+	{ 0,    488 },
+	{ 0,    244 },
+	{ 0,    122 },
+	{ 0,     61 },
+	{ 0,     30 },
+};
+
 struct mpl3115_data {
 	struct i2c_client *client;
 	struct iio_trigger *drdy_trig;
@@ -170,10 +193,61 @@ static int mpl3115_read_raw(struct iio_dev *indio_dev,
 		default:
 			return -EINVAL;
 		}
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		ret = i2c_smbus_read_byte_data(data->client, MPL3115_CTRL_REG2);
+		if (ret < 0)
+			return ret;
+
+		ret = FIELD_GET(MPL3115_CTRL2_ST, ret);
+
+		*val = mpl3115_samp_freq_table[ret][0];
+		*val2 = mpl3115_samp_freq_table[ret][1];
+		return IIO_VAL_INT_PLUS_MICRO;
 	}
 	return -EINVAL;
 }
 
+static int mpl3115_read_avail(struct iio_dev *indio_dev,
+			      struct iio_chan_spec const *chan,
+			      const int **vals, int *type, int *length,
+			      long mask)
+{
+	if (mask != IIO_CHAN_INFO_SAMP_FREQ)
+		return -EINVAL;
+
+	*type = IIO_VAL_INT_PLUS_MICRO;
+	*length = ARRAY_SIZE(mpl3115_samp_freq_table) * 2;
+	*vals = (int *)mpl3115_samp_freq_table;
+	return IIO_AVAIL_LIST;
+}
+
+static int mpl3115_write_raw(struct iio_dev *indio_dev,
+			     const struct iio_chan_spec *chan,
+			     int val, int val2, long mask)
+{
+	struct mpl3115_data *data = iio_priv(indio_dev);
+	int i, ret;
+
+	if (mask != IIO_CHAN_INFO_SAMP_FREQ)
+		return -EINVAL;
+
+	for (i = 0; i < ARRAY_SIZE(mpl3115_samp_freq_table); i++)
+		if (val == mpl3115_samp_freq_table[i][0] &&
+		    val2 == mpl3115_samp_freq_table[i][1])
+			break;
+
+	if (i == ARRAY_SIZE(mpl3115_samp_freq_table))
+		return -EINVAL;
+
+	if (!iio_device_claim_direct(indio_dev))
+		return -EBUSY;
+
+	ret = i2c_smbus_write_byte_data(data->client, MPL3115_CTRL_REG2,
+					FIELD_PREP(MPL3115_CTRL2_ST, i));
+	iio_device_release_direct(indio_dev);
+	return ret;
+}
+
 static int mpl3115_fill_trig_buffer(struct iio_dev *indio_dev, u8 *buffer)
 {
 	struct mpl3115_data *data = iio_priv(indio_dev);
@@ -237,6 +311,9 @@ static const struct iio_chan_spec mpl3115_channels[] = {
 		.type = IIO_PRESSURE,
 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
 		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
+		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
+		.info_mask_shared_by_all_available =
+			BIT(IIO_CHAN_INFO_SAMP_FREQ),
 		.scan_index = 0,
 		.scan_type = {
 			.sign = 'u',
@@ -250,6 +327,9 @@ static const struct iio_chan_spec mpl3115_channels[] = {
 		.type = IIO_TEMP,
 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
 		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
+		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
+		.info_mask_shared_by_all_available =
+			BIT(IIO_CHAN_INFO_SAMP_FREQ),
 		.scan_index = 1,
 		.scan_type = {
 			.sign = 's',
@@ -328,6 +408,8 @@ static const struct iio_trigger_ops mpl3115_trigger_ops = {
 
 static const struct iio_info mpl3115_info = {
 	.read_raw = &mpl3115_read_raw,
+	.read_avail = &mpl3115_read_avail,
+	.write_raw = &mpl3115_write_raw,
 };
 
 static int mpl3115_trigger_probe(struct mpl3115_data *data,
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v4 0/5] iio: mpl3115: add support for DRDY interrupt
  2025-10-02 20:02 [PATCH v4 0/5] iio: mpl3115: add support for DRDY interrupt Antoni Pokusinski
                   ` (4 preceding siblings ...)
  2025-10-02 20:02 ` [PATCH v4 5/5] iio: mpl3115: add support for sampling frequency Antoni Pokusinski
@ 2025-10-03 16:48 ` Jonathan Cameron
  5 siblings, 0 replies; 7+ messages in thread
From: Jonathan Cameron @ 2025-10-03 16:48 UTC (permalink / raw)
  To: Antoni Pokusinski
  Cc: dlechner, nuno.sa, andy, robh, krzk+dt, conor+dt, linux-kernel,
	devicetree, linux-iio, linux, rodrigo.gobbi.7, naresh.solanki,
	michal.simek, grantpeltier93, farouk.bouabid, marcelo.schmitt1

On Thu,  2 Oct 2025 22:02:01 +0200
Antoni Pokusinski <apokusinski01@gmail.com> wrote:

> Hello,
> This set of patches adds support for the DRDY interrupt in the MPL3115
> pressure sensor. The device has 2 interrupt lines, hence the new
> binding. I also added support for the sampling frequency which
> determines the time interval between subsequent measurements (in the
> continuous measurements mode) so it's obiously tied to the DRDY
> interrupt feature.

Hi Antoni,

LGTM. Applied to the testing branch of iio.git. I'll rebase that on rc1 once
available and then push it out as the togreg branch which linux-next
picks up.

thanks,

Jonathan

> 
> Kind regards,
> Antoni Pokusinski
> 
> ---
> Changes since v3:
> * P2: created mpl3115_fill_trig_buffer
> * P2: trigger_handler: replaced scoped_guard with mutex_lock
> * P2: includes: removed linux/cleanup.h
> 
> * P3: new patch: renamed MPL3115_CTRL_* macros to MPL3115_CTRL1_*
> 
> * P4: extracted the MPL3115_CTRL_* renames into a separate patch (P3 now)
> * P4: trigger_probe: placed devm_request_threaded_irq() call before
>                      devm_iio_trigger_register()
> * P4: trigger_probe: removed switch(irq_cfg_flags) together with the
>                      enum mpl3115_irq_type and added 2 separate
>                      variables to handle interrupt setup logic 
> * P4: set_trigger_state: factored out the CTRL_REG1 and CTRL_REG4 writes 
>                          into a separate function mpl3115_config_interrupt
> 
> * P5: samp_freq_table: added spaces before "},"
> 
> Changes since v2:
> * P4: included linux/bitfield.h
> 
> Changes since v1:
> * P1: add `vdd-supply` and `vddio-supply`
> 
> * P2: new patch: use guards from cleanup.h   
> 
> * P3: change macros of control register bits to convention
>       MPL3115_CTRLX_NAME
> * P3: MPL3115_PT_DATA_EVENT_ALL: use GENMASK
> * P3: trigger_probe: do not fail if dev_fwnode() returns NULL
> * P3: trigger_probe: use devm_iio_trigger_register()
> * P3: trigger_probe: introduced enum mpl3115_irq_type and 
>       changed IRQ setup logic accordingly
> 
> * P4: MPL3115_CTRL2_ST: use GENMASK
> * P4: read_raw: samp_freq: use FIELD_GET
> * P4: write_raw: samp_freq: use FIELD_PREP
> ---
> 
> Antoni Pokusinski (5):
>   dt-bindings: iio: pressure: add binding for mpl3115
>   iio: mpl3115: add separate function for triggered buffer data
>     collection
>   iio: mpl3115: rename CTRL_REG1 field macros
>   iio: mpl3115: add support for DRDY interrupt
>   iio: mpl3115: add support for sampling frequency
> 
>  .../bindings/iio/pressure/fsl,mpl3115.yaml    |  71 ++++
>  .../devicetree/bindings/trivial-devices.yaml  |   2 -
>  drivers/iio/pressure/mpl3115.c                | 331 ++++++++++++++++--
>  3 files changed, 364 insertions(+), 40 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/iio/pressure/fsl,mpl3115.yaml
> 


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2025-10-03 16:48 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-02 20:02 [PATCH v4 0/5] iio: mpl3115: add support for DRDY interrupt Antoni Pokusinski
2025-10-02 20:02 ` [PATCH v4 1/5] dt-bindings: iio: pressure: add binding for mpl3115 Antoni Pokusinski
2025-10-02 20:02 ` [PATCH v4 2/5] iio: mpl3115: add separate function for triggered buffer data collection Antoni Pokusinski
2025-10-02 20:02 ` [PATCH v4 3/5] iio: mpl3115: rename CTRL_REG1 field macros Antoni Pokusinski
2025-10-02 20:02 ` [PATCH v4 4/5] iio: mpl3115: add support for DRDY interrupt Antoni Pokusinski
2025-10-02 20:02 ` [PATCH v4 5/5] iio: mpl3115: add support for sampling frequency Antoni Pokusinski
2025-10-03 16:48 ` [PATCH v4 0/5] iio: mpl3115: add support for DRDY interrupt Jonathan Cameron

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).