* [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