2023-12-29 09:26:03

by Petre Rodan

[permalink] [raw]
Subject: [PATCH v3 00/10] changes to mprls0025pa

A number of fixes to the mprls0025pa driver:
- an off-by-one initially caused by a typo in the bindings file
- two error fields are never checked during sensor interaction
- unsafe initialization if the driver is instantiated via sysfs
and the bindings are missing

Quality of life changes:
- a refactor that adds a pressure-triplet property which initializes
pmin-pascal and pmax-pascal just like in the hsc030pa driver.
The user only needs to extract a short string from the chip name
instead of looking up the chip in the datasheet, understand the
nomenclature, extract the measurement range and then convert all units
to pascals.

New feature:
- SPI compatibility for Honeywell MPR sensors that require it.

Both binding and driver are backwards compatible.
Tested in I2C and SPI modes with two different sensors.
The refactor requires property function present in the togreg branch.

Datasheet: https://prod-edam.honeywell.com/content/dam/honeywell-edam/sps/siot/en-us/products/sensors/pressure-sensors/board-mount-pressure-sensors/micropressure-mpr-series/documents/sps-siot-mpr-series-datasheet-32332628-ciid-172626.pdf
Co-developed-by: Andreas Klinger <[email protected]>
Signed-off-by: Andreas Klinger <[email protected]>
Signed-off-by: Petre Rodan <[email protected]>

Petre Rodan (10):
dt-bindings: iio: pressure: honeywell,mprls0025pa.yaml improvements
dt-bindings: iio: pressure: honeywell,mprls0025pa.yaml add
pressure-triplet
dt-bindings: iio: pressure: honeywell,mprls0025pa.yaml add spi bus
iio: pressure: mprls0025pa fix off-by-one enum
iio: pressure: mprls0025pa improve driver error resilience
iio: pressure: mprls0025pa remove defaults
iio: pressure: mprls0025pa whitespace cleanup
iio: pressure: mprls0025pa refactor
iio: pressure: mprls0025pa add triplet property
iio: pressure: mprls0025pa add SPI driver

.../iio/pressure/honeywell,mprls0025pa.yaml | 98 ++++--
MAINTAINERS | 3 +-
drivers/iio/pressure/Kconfig | 14 +-
drivers/iio/pressure/Makefile | 2 +
drivers/iio/pressure/mprls0025pa.c | 313 +++++++++---------
drivers/iio/pressure/mprls0025pa.h | 102 ++++++
drivers/iio/pressure/mprls0025pa_i2c.c | 98 ++++++
drivers/iio/pressure/mprls0025pa_spi.c | 89 +++++
8 files changed, 542 insertions(+), 177 deletions(-)
create mode 100644 drivers/iio/pressure/mprls0025pa.h
create mode 100644 drivers/iio/pressure/mprls0025pa_i2c.c
create mode 100644 drivers/iio/pressure/mprls0025pa_spi.c

--
2.41.0



2023-12-29 09:26:30

by Petre Rodan

[permalink] [raw]
Subject: [PATCH v3 01/10] dt-bindings: iio: pressure: honeywell,mprls0025pa.yaml improvements

Define enum inside the honeywell,transfer-function property block.

Set the correct irq edge in the example block.
Based on the datasheet, in table 13 on page 11:
"End-of-conversion indicator: This pin is set high when a measurement
and calculation have been completed and the data is ready to be
clocked out"

Add description on End-of-conversion interrupt.

Acked-by: Krzysztof Kozlowski <[email protected]>
Co-developed-by: Andreas Klinger <[email protected]>
Signed-off-by: Andreas Klinger <[email protected]>
Signed-off-by: Petre Rodan <[email protected]>
---
v2 -> v3 no changes

.../bindings/iio/pressure/honeywell,mprls0025pa.yaml | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/iio/pressure/honeywell,mprls0025pa.yaml b/Documentation/devicetree/bindings/iio/pressure/honeywell,mprls0025pa.yaml
index d9e903fbfd99..84ced4e5a7da 100644
--- a/Documentation/devicetree/bindings/iio/pressure/honeywell,mprls0025pa.yaml
+++ b/Documentation/devicetree/bindings/iio/pressure/honeywell,mprls0025pa.yaml
@@ -42,6 +42,10 @@ properties:
maxItems: 1

interrupts:
+ description:
+ Optional interrupt for indicating End-of-conversion.
+ If not present, the driver loops for a while until the received status
+ byte indicates correct measurement.
maxItems: 1

reset-gpios:
@@ -65,6 +69,7 @@ properties:
1 - A, 10% to 90% of 2^24 (1677722 .. 15099494)
2 - B, 2.5% to 22.5% of 2^24 (419430 .. 3774874)
3 - C, 20% to 80% of 2^24 (3355443 .. 13421773)
+ enum: [1, 2, 3]
$ref: /schemas/types.yaml#/definitions/uint32

vdd-supply:
@@ -93,7 +98,7 @@ examples:
reg = <0x18>;
reset-gpios = <&gpio3 19 GPIO_ACTIVE_HIGH>;
interrupt-parent = <&gpio3>;
- interrupts = <21 IRQ_TYPE_EDGE_FALLING>;
+ interrupts = <21 IRQ_TYPE_EDGE_RISING>;
honeywell,pmin-pascal = <0>;
honeywell,pmax-pascal = <172369>;
honeywell,transfer-function = <1>;
--
2.41.0


2023-12-29 09:26:44

by Petre Rodan

[permalink] [raw]
Subject: [PATCH v3 05/10] iio: pressure: mprls0025pa improve driver error resilience

Improve driver error resilience by ignoring the measurement if any of
the 3 error flags gets set while interacting with the sensor.
Based on the datasheet, in table 14 on page 14, the status byte
contains:
bit 5 busy flag - 1 if device is busy
bit 2 memory integrity/error flag - 1 if integrity test failed
bit 0 math saturation - 1 if internal math saturation has occurred

Co-developed-by: Andreas Klinger <[email protected]>
Signed-off-by: Andreas Klinger <[email protected]>
Signed-off-by: Petre Rodan <[email protected]>
---
v2 -> v3 no changes

drivers/iio/pressure/mprls0025pa.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/iio/pressure/mprls0025pa.c b/drivers/iio/pressure/mprls0025pa.c
index e3f0de020a40..233cc1dc38ad 100644
--- a/drivers/iio/pressure/mprls0025pa.c
+++ b/drivers/iio/pressure/mprls0025pa.c
@@ -39,6 +39,8 @@
#define MPR_I2C_MEMORY BIT(2) /* integrity test passed */
#define MPR_I2C_MATH BIT(0) /* internal math saturation */

+#define MPR_I2C_ERR_FLAG (MPR_I2C_BUSY | MPR_I2C_MEMORY | MPR_I2C_MATH)
+
/*
* support _RAW sysfs interface:
*
@@ -213,7 +215,7 @@ static int mpr_read_pressure(struct mpr_data *data, s32 *press)
status);
return status;
}
- if (!(status & MPR_I2C_BUSY))
+ if (!(status & MPR_I2C_ERR_FLAG))
break;
}
if (i == nloops) {
@@ -233,7 +235,7 @@ static int mpr_read_pressure(struct mpr_data *data, s32 *press)
return -EIO;
}

- if (buf[0] & MPR_I2C_BUSY) {
+ if (buf[0] & MPR_I2C_ERR_FLAG) {
/*
* it should never be the case that status still indicates
* business
--
2.41.0


2023-12-29 09:26:45

by Petre Rodan

[permalink] [raw]
Subject: [PATCH v3 06/10] iio: pressure: mprls0025pa remove defaults

This driver supports 32*3 combinations of fixed ranges and transfer
functions, plus custom ranges.

So statistically a user has more than 99% chance that the provided
default configuration will generate invalid pressure readings if the
bindings are not initialized and the driver is instantiated via sysfs.

The current patch removes this loophole making sure the driver loads
only if the firmware properties are present.

Co-developed-by: Andreas Klinger <[email protected]>
Signed-off-by: Andreas Klinger <[email protected]>
Signed-off-by: Petre Rodan <[email protected]>
---
v2 -> v3 drop the use of dev_fwnode() entirely

drivers/iio/pressure/mprls0025pa.c | 48 +++++++++++++-----------------
1 file changed, 20 insertions(+), 28 deletions(-)

diff --git a/drivers/iio/pressure/mprls0025pa.c b/drivers/iio/pressure/mprls0025pa.c
index 233cc1dc38ad..e0a2a60c6245 100644
--- a/drivers/iio/pressure/mprls0025pa.c
+++ b/drivers/iio/pressure/mprls0025pa.c
@@ -353,34 +353,26 @@ static int mpr_probe(struct i2c_client *client)
return dev_err_probe(dev, ret,
"can't get and enable vdd supply\n");

- if (dev_fwnode(dev)) {
- ret = device_property_read_u32(dev, "honeywell,pmin-pascal",
- &data->pmin);
- if (ret)
- return dev_err_probe(dev, ret,
- "honeywell,pmin-pascal could not be read\n");
- ret = device_property_read_u32(dev, "honeywell,pmax-pascal",
- &data->pmax);
- if (ret)
- return dev_err_probe(dev, ret,
- "honeywell,pmax-pascal could not be read\n");
- ret = device_property_read_u32(dev,
- "honeywell,transfer-function", &func);
- if (ret)
- return dev_err_probe(dev, ret,
- "honeywell,transfer-function could not be read\n");
- data->function = func - 1;
- if (data->function > MPR_FUNCTION_C)
- return dev_err_probe(dev, -EINVAL,
- "honeywell,transfer-function %d invalid\n",
- data->function);
- } else {
- /* when loaded as i2c device we need to use default values */
- dev_notice(dev, "firmware node not found; using defaults\n");
- data->pmin = 0;
- data->pmax = 172369; /* 25 psi */
- data->function = MPR_FUNCTION_A;
- }
+ ret = device_property_read_u32(dev, "honeywell,pmin-pascal",
+ &data->pmin);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "honeywell,pmin-pascal could not be read\n");
+ ret = device_property_read_u32(dev, "honeywell,pmax-pascal",
+ &data->pmax);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "honeywell,pmax-pascal could not be read\n");
+ ret = device_property_read_u32(dev,
+ "honeywell,transfer-function", &func);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "honeywell,transfer-function could not be read\n");
+ data->function = func - 1;
+ if (data->function > MPR_FUNCTION_C)
+ return dev_err_probe(dev, -EINVAL,
+ "honeywell,transfer-function %d invalid\n",
+ data->function);

data->outmin = mpr_func_spec[data->function].output_min;
data->outmax = mpr_func_spec[data->function].output_max;
--
2.41.0


2023-12-29 09:26:48

by Petre Rodan

[permalink] [raw]
Subject: [PATCH v3 07/10] iio: pressure: mprls0025pa whitespace cleanup

Fix indentation and whitespace in code that will not get refactored.

Make URL inside comment copy-paste friendly.

Co-developed-by: Andreas Klinger <[email protected]>
Signed-off-by: Andreas Klinger <[email protected]>
Signed-off-by: Petre Rodan <[email protected]>
---
v2 -> v3 even more whitespace

drivers/iio/pressure/mprls0025pa.c | 35 +++++++++++++++---------------
1 file changed, 17 insertions(+), 18 deletions(-)

diff --git a/drivers/iio/pressure/mprls0025pa.c b/drivers/iio/pressure/mprls0025pa.c
index e0a2a60c6245..fef3ca69c4f0 100644
--- a/drivers/iio/pressure/mprls0025pa.c
+++ b/drivers/iio/pressure/mprls0025pa.c
@@ -5,10 +5,7 @@
* Copyright (c) Andreas Klinger <[email protected]>
*
* Data sheet:
- * https://prod-edam.honeywell.com/content/dam/honeywell-edam/sps/siot/en-us/
- * products/sensors/pressure-sensors/board-mount-pressure-sensors/
- * micropressure-mpr-series/documents/
- * sps-siot-mpr-series-datasheet-32332628-ciid-172626.pdf
+ * https://prod-edam.honeywell.com/content/dam/honeywell-edam/sps/siot/en-us/products/sensors/pressure-sensors/board-mount-pressure-sensors/micropressure-mpr-series/documents/sps-siot-mpr-series-datasheet-32332628-ciid-172626.pdf
*
* 7-bit I2C default slave address: 0x18
*/
@@ -84,9 +81,9 @@ struct mpr_func_spec {
};

static const struct mpr_func_spec mpr_func_spec[] = {
- [MPR_FUNCTION_A] = {.output_min = 1677722, .output_max = 15099494},
- [MPR_FUNCTION_B] = {.output_min = 419430, .output_max = 3774874},
- [MPR_FUNCTION_C] = {.output_min = 3355443, .output_max = 13421773},
+ [MPR_FUNCTION_A] = { .output_min = 1677722, .output_max = 15099494 },
+ [MPR_FUNCTION_B] = { .output_min = 419430, .output_max = 3774874 },
+ [MPR_FUNCTION_C] = { .output_min = 3355443, .output_max = 13421773 },
};

struct mpr_chan {
@@ -273,7 +270,7 @@ static irqreturn_t mpr_trigger_handler(int irq, void *p)
goto err;

iio_push_to_buffers_with_timestamp(indio_dev, &data->chan,
- iio_get_time_ns(indio_dev));
+ iio_get_time_ns(indio_dev));

err:
mutex_unlock(&data->lock);
@@ -351,7 +348,7 @@ static int mpr_probe(struct i2c_client *client)
ret = devm_regulator_get_enable(dev, "vdd");
if (ret)
return dev_err_probe(dev, ret,
- "can't get and enable vdd supply\n");
+ "can't get and enable vdd supply\n");

ret = device_property_read_u32(dev, "honeywell,pmin-pascal",
&data->pmin);
@@ -379,42 +376,44 @@ static int mpr_probe(struct i2c_client *client)

/* use 64 bit calculation for preserving a reasonable precision */
scale = div_s64(((s64)(data->pmax - data->pmin)) * NANO,
- data->outmax - data->outmin);
+ data->outmax - data->outmin);
data->scale = div_s64_rem(scale, NANO, &data->scale2);
/*
* multiply with NANO before dividing by scale and later divide by NANO
* again.
*/
offset = ((-1LL) * (s64)data->outmin) * NANO -
- div_s64(div_s64((s64)data->pmin * NANO, scale), NANO);
+ div_s64(div_s64((s64)data->pmin * NANO, scale), NANO);
data->offset = div_s64_rem(offset, NANO, &data->offset2);

if (data->irq > 0) {
ret = devm_request_irq(dev, data->irq, mpr_eoc_handler,
- IRQF_TRIGGER_RISING, client->name, data);
+ IRQF_TRIGGER_RISING,
+ client->name,
+ data);
if (ret)
return dev_err_probe(dev, ret,
- "request irq %d failed\n", data->irq);
+ "request irq %d failed\n", data->irq);
}

data->gpiod_reset = devm_gpiod_get_optional(dev, "reset",
- GPIOD_OUT_HIGH);
+ GPIOD_OUT_HIGH);
if (IS_ERR(data->gpiod_reset))
return dev_err_probe(dev, PTR_ERR(data->gpiod_reset),
- "request reset-gpio failed\n");
+ "request reset-gpio failed\n");

mpr_reset(data);

ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
- mpr_trigger_handler, NULL);
+ mpr_trigger_handler, NULL);
if (ret)
return dev_err_probe(dev, ret,
- "iio triggered buffer setup failed\n");
+ "iio triggered buffer setup failed\n");

ret = devm_iio_device_register(dev, indio_dev);
if (ret)
return dev_err_probe(dev, ret,
- "unable to register iio device\n");
+ "unable to register iio device\n");

return 0;
}
--
2.41.0


2023-12-29 09:26:53

by Petre Rodan

[permalink] [raw]
Subject: [PATCH v3 08/10] iio: pressure: mprls0025pa refactor

Refactor driver by splitting the code into core and i2c.

Seemingly redundant read/write function parameters are required for
compatibility with the SPI driver.

Co-developed-by: Andreas Klinger <[email protected]>
Signed-off-by: Andreas Klinger <[email protected]>
Signed-off-by: Petre Rodan <[email protected]>
---
v2 -> v3 move '#include <linux/iio/iio.h>' to mprls0025pa.h
fix checkpatch.pl warnings related to mprls0025pa.h

MAINTAINERS | 3 +-
drivers/iio/pressure/Kconfig | 6 +
drivers/iio/pressure/Makefile | 1 +
drivers/iio/pressure/mprls0025pa.c | 185 +++++++------------------
drivers/iio/pressure/mprls0025pa.h | 102 ++++++++++++++
drivers/iio/pressure/mprls0025pa_i2c.c | 98 +++++++++++++
6 files changed, 262 insertions(+), 133 deletions(-)
create mode 100644 drivers/iio/pressure/mprls0025pa.h
create mode 100644 drivers/iio/pressure/mprls0025pa_i2c.c

diff --git a/MAINTAINERS b/MAINTAINERS
index a31b1b20c6f6..77ee0b4d9f73 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9686,10 +9686,11 @@ F: drivers/iio/pressure/hsc030pa*

HONEYWELL MPRLS0025PA PRESSURE SENSOR SERIES IIO DRIVER
M: Andreas Klinger <[email protected]>
+M: Petre Rodan <[email protected]>
L: [email protected]
S: Maintained
F: Documentation/devicetree/bindings/iio/pressure/honeywell,mprls0025pa.yaml
-F: drivers/iio/pressure/mprls0025pa.c
+F: drivers/iio/pressure/mprls0025pa*

HOST AP DRIVER
L: [email protected]
diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig
index 79adfd059c3a..f03007cfec85 100644
--- a/drivers/iio/pressure/Kconfig
+++ b/drivers/iio/pressure/Kconfig
@@ -182,6 +182,7 @@ config MPL3115
config MPRLS0025PA
tristate "Honeywell MPRLS0025PA (MicroPressure sensors series)"
depends on I2C
+ select MPRLS0025PA_I2C if I2C
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
help
@@ -192,6 +193,11 @@ config MPRLS0025PA
To compile this driver as a module, choose M here: the module will be
called mprls0025pa.

+config MPRLS0025PA_I2C
+ tristate
+ depends on MPRLS0025PA
+ depends on I2C
+
config MS5611
tristate "Measurement Specialties MS5611 pressure sensor driver"
select IIO_BUFFER
diff --git a/drivers/iio/pressure/Makefile b/drivers/iio/pressure/Makefile
index b0f8b94662f2..7754135e190c 100644
--- a/drivers/iio/pressure/Makefile
+++ b/drivers/iio/pressure/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_MPL115_I2C) += mpl115_i2c.o
obj-$(CONFIG_MPL115_SPI) += mpl115_spi.o
obj-$(CONFIG_MPL3115) += mpl3115.o
obj-$(CONFIG_MPRLS0025PA) += mprls0025pa.o
+obj-$(CONFIG_MPRLS0025PA_I2C) += mprls0025pa_i2c.o
obj-$(CONFIG_MS5611) += ms5611_core.o
obj-$(CONFIG_MS5611_I2C) += ms5611_i2c.o
obj-$(CONFIG_MS5611_SPI) += ms5611_spi.o
diff --git a/drivers/iio/pressure/mprls0025pa.c b/drivers/iio/pressure/mprls0025pa.c
index fef3ca69c4f0..ce20cf362fac 100644
--- a/drivers/iio/pressure/mprls0025pa.c
+++ b/drivers/iio/pressure/mprls0025pa.c
@@ -7,12 +7,11 @@
* Data sheet:
* https://prod-edam.honeywell.com/content/dam/honeywell-edam/sps/siot/en-us/products/sensors/pressure-sensors/board-mount-pressure-sensors/micropressure-mpr-series/documents/sps-siot-mpr-series-datasheet-32332628-ciid-172626.pdf
*
- * 7-bit I2C default slave address: 0x18
*/

-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/i2c.h>
+#include <linux/array_size.h>
+#include <linux/bitfield.h>
+#include <linux/bits.h>
#include <linux/math64.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
@@ -22,7 +21,6 @@
#include <linux/gpio/consumer.h>

#include <linux/iio/buffer.h>
-#include <linux/iio/iio.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>

@@ -30,13 +28,15 @@

#include <asm/unaligned.h>

-/* bits in i2c status byte */
-#define MPR_I2C_POWER BIT(6) /* device is powered */
-#define MPR_I2C_BUSY BIT(5) /* device is busy */
-#define MPR_I2C_MEMORY BIT(2) /* integrity test passed */
-#define MPR_I2C_MATH BIT(0) /* internal math saturation */
+#include "mprls0025pa.h"

-#define MPR_I2C_ERR_FLAG (MPR_I2C_BUSY | MPR_I2C_MEMORY | MPR_I2C_MATH)
+/* bits in status byte */
+#define MPR_ST_POWER BIT(6) /* device is powered */
+#define MPR_ST_BUSY BIT(5) /* device is busy */
+#define MPR_ST_MEMORY BIT(2) /* integrity test passed */
+#define MPR_ST_MATH BIT(0) /* internal math saturation */
+
+#define MPR_ST_ERR_FLAG (MPR_ST_BUSY | MPR_ST_MEMORY | MPR_ST_MATH)

/*
* support _RAW sysfs interface:
@@ -69,12 +69,6 @@
* transfer function B: 2.5% to 22.5% of 2^24
* transfer function C: 20% to 80% of 2^24
*/
-enum mpr_func_id {
- MPR_FUNCTION_A,
- MPR_FUNCTION_B,
- MPR_FUNCTION_C,
-};
-
struct mpr_func_spec {
u32 output_min;
u32 output_max;
@@ -86,45 +80,6 @@ static const struct mpr_func_spec mpr_func_spec[] = {
[MPR_FUNCTION_C] = { .output_min = 3355443, .output_max = 13421773 },
};

-struct mpr_chan {
- s32 pres; /* pressure value */
- s64 ts; /* timestamp */
-};
-
-struct mpr_data {
- struct i2c_client *client;
- struct mutex lock; /*
- * access to device during read
- */
- u32 pmin; /* minimal pressure in pascal */
- u32 pmax; /* maximal pressure in pascal */
- enum mpr_func_id function; /* transfer function */
- u32 outmin; /*
- * minimal numerical range raw
- * value from sensor
- */
- u32 outmax; /*
- * maximal numerical range raw
- * value from sensor
- */
- int scale; /* int part of scale */
- int scale2; /* nano part of scale */
- int offset; /* int part of offset */
- int offset2; /* nano part of offset */
- struct gpio_desc *gpiod_reset; /* reset */
- int irq; /*
- * end of conversion irq;
- * used to distinguish between
- * irq mode and reading in a
- * loop until data is ready
- */
- struct completion completion; /* handshake from irq to read */
- struct mpr_chan chan; /*
- * channel values for buffered
- * mode
- */
-};
-
static const struct iio_chan_spec mpr_channels[] = {
{
.type = IIO_PRESSURE,
@@ -152,11 +107,11 @@ static void mpr_reset(struct mpr_data *data)
}

/**
- * mpr_read_pressure() - Read pressure value from sensor via I2C
+ * mpr_read_pressure() - Read pressure value from sensor
* @data: Pointer to private data struct.
* @press: Output value read from sensor.
*
- * Reading from the sensor by sending and receiving I2C telegrams.
+ * Reading from the sensor by sending and receiving telegrams.
*
* If there is an end of conversion (EOC) interrupt registered the function
* waits for a maximum of one second for the interrupt.
@@ -169,25 +124,17 @@ static void mpr_reset(struct mpr_data *data)
*/
static int mpr_read_pressure(struct mpr_data *data, s32 *press)
{
- struct device *dev = &data->client->dev;
+ struct device *dev = data->dev;
int ret, i;
- u8 wdata[] = {0xAA, 0x00, 0x00};
- s32 status;
int nloops = 10;
- u8 buf[4];

reinit_completion(&data->completion);

- ret = i2c_master_send(data->client, wdata, sizeof(wdata));
+ ret = data->ops->write(data, MPR_CMD_SYNC, MPR_PKT_SYNC_LEN);
if (ret < 0) {
dev_err(dev, "error while writing ret: %d\n", ret);
return ret;
}
- if (ret != sizeof(wdata)) {
- dev_err(dev, "received size doesn't fit - ret: %d / %u\n", ret,
- (u32)sizeof(wdata));
- return -EIO;
- }

if (data->irq > 0) {
ret = wait_for_completion_timeout(&data->completion, HZ);
@@ -205,14 +152,14 @@ static int mpr_read_pressure(struct mpr_data *data, s32 *press)
* quite long
*/
usleep_range(5000, 10000);
- status = i2c_smbus_read_byte(data->client);
- if (status < 0) {
+ ret = data->ops->read(data, MPR_CMD_NOP, 1);
+ if (ret < 0) {
dev_err(dev,
"error while reading, status: %d\n",
- status);
- return status;
+ ret);
+ return ret;
}
- if (!(status & MPR_I2C_ERR_FLAG))
+ if (!(data->buffer[0] & MPR_ST_ERR_FLAG))
break;
}
if (i == nloops) {
@@ -221,29 +168,19 @@ static int mpr_read_pressure(struct mpr_data *data, s32 *press)
}
}

- ret = i2c_master_recv(data->client, buf, sizeof(buf));
- if (ret < 0) {
- dev_err(dev, "error in i2c_master_recv ret: %d\n", ret);
+ ret = data->ops->read(data, MPR_CMD_NOP, MPR_PKT_NOP_LEN);
+ if (ret < 0)
return ret;
- }
- if (ret != sizeof(buf)) {
- dev_err(dev, "received size doesn't fit - ret: %d / %u\n", ret,
- (u32)sizeof(buf));
- return -EIO;
- }

- if (buf[0] & MPR_I2C_ERR_FLAG) {
- /*
- * it should never be the case that status still indicates
- * business
- */
- dev_err(dev, "data still not ready: %08x\n", buf[0]);
+ if (data->buffer[0] & MPR_ST_ERR_FLAG) {
+ dev_err(data->dev,
+ "unexpected status byte %02x\n", data->buffer[0]);
return -ETIMEDOUT;
}

- *press = get_unaligned_be24(&buf[1]);
+ *press = get_unaligned_be24(&data->buffer[1]);

- dev_dbg(dev, "received: %*ph cnt: %d\n", ret, buf, *press);
+ dev_dbg(dev, "received: %*ph cnt: %d\n", ret, data->buffer, *press);

return 0;
}
@@ -315,26 +252,22 @@ static const struct iio_info mpr_info = {
.read_raw = &mpr_read_raw,
};

-static int mpr_probe(struct i2c_client *client)
+int mpr_common_probe(struct device *dev, const struct mpr_ops *ops, int irq)
{
int ret;
struct mpr_data *data;
struct iio_dev *indio_dev;
- struct device *dev = &client->dev;
s64 scale, offset;
u32 func;

- if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_BYTE))
- return dev_err_probe(dev, -EOPNOTSUPP,
- "I2C functionality not supported\n");
-
indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
if (!indio_dev)
- return dev_err_probe(dev, -ENOMEM, "couldn't get iio_dev\n");
+ return -ENOMEM;

data = iio_priv(indio_dev);
- data->client = client;
- data->irq = client->irq;
+ data->dev = dev;
+ data->ops = ops;
+ data->irq = irq;

mutex_init(&data->lock);
init_completion(&data->completion);
@@ -350,16 +283,10 @@ static int mpr_probe(struct i2c_client *client)
return dev_err_probe(dev, ret,
"can't get and enable vdd supply\n");

- ret = device_property_read_u32(dev, "honeywell,pmin-pascal",
- &data->pmin);
+ ret = data->ops->init(data->dev);
if (ret)
- return dev_err_probe(dev, ret,
- "honeywell,pmin-pascal could not be read\n");
- ret = device_property_read_u32(dev, "honeywell,pmax-pascal",
- &data->pmax);
- if (ret)
- return dev_err_probe(dev, ret,
- "honeywell,pmax-pascal could not be read\n");
+ return ret;
+
ret = device_property_read_u32(dev,
"honeywell,transfer-function", &func);
if (ret)
@@ -371,6 +298,21 @@ static int mpr_probe(struct i2c_client *client)
"honeywell,transfer-function %d invalid\n",
data->function);

+ ret = device_property_read_u32(dev, "honeywell,pmin-pascal",
+ &data->pmin);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "honeywell,pmin-pascal could not be read\n");
+ ret = device_property_read_u32(dev, "honeywell,pmax-pascal",
+ &data->pmax);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "honeywell,pmax-pascal could not be read\n");
+
+ if (data->pmin >= data->pmax)
+ return dev_err_probe(dev, -EINVAL,
+ "pressure limits are invalid\n");
+
data->outmin = mpr_func_spec[data->function].output_min;
data->outmax = mpr_func_spec[data->function].output_max;

@@ -389,7 +331,7 @@ static int mpr_probe(struct i2c_client *client)
if (data->irq > 0) {
ret = devm_request_irq(dev, data->irq, mpr_eoc_handler,
IRQF_TRIGGER_RISING,
- client->name,
+ dev_name(dev),
data);
if (ret)
return dev_err_probe(dev, ret,
@@ -417,29 +359,8 @@ static int mpr_probe(struct i2c_client *client)

return 0;
}
-
-static const struct of_device_id mpr_matches[] = {
- { .compatible = "honeywell,mprls0025pa" },
- { }
-};
-MODULE_DEVICE_TABLE(of, mpr_matches);
-
-static const struct i2c_device_id mpr_id[] = {
- { "mprls0025pa" },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, mpr_id);
-
-static struct i2c_driver mpr_driver = {
- .probe = mpr_probe,
- .id_table = mpr_id,
- .driver = {
- .name = "mprls0025pa",
- .of_match_table = mpr_matches,
- },
-};
-module_i2c_driver(mpr_driver);
+EXPORT_SYMBOL_NS(mpr_common_probe, IIO_HONEYWELL_MPRLS0025PA);

MODULE_AUTHOR("Andreas Klinger <[email protected]>");
-MODULE_DESCRIPTION("Honeywell MPRLS0025PA I2C driver");
+MODULE_DESCRIPTION("Honeywell MPR pressure sensor core driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/iio/pressure/mprls0025pa.h b/drivers/iio/pressure/mprls0025pa.h
new file mode 100644
index 000000000000..9d5c30afa9d6
--- /dev/null
+++ b/drivers/iio/pressure/mprls0025pa.h
@@ -0,0 +1,102 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * MPRLS0025PA - Honeywell MicroPressure pressure sensor series driver
+ *
+ * Copyright (c) Andreas Klinger <[email protected]>
+ *
+ * Data sheet:
+ * https://prod-edam.honeywell.com/content/dam/honeywell-edam/sps/siot/en-us/products/sensors/pressure-sensors/board-mount-pressure-sensors/micropressure-mpr-series/documents/sps-siot-mpr-series-datasheet-32332628-ciid-172626.pdf
+ */
+
+#ifndef _MPRLS0025PA_H
+#define _MPRLS0025PA_H
+
+#include <linux/completion.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/mutex.h>
+#include <linux/stddef.h>
+#include <linux/types.h>
+
+#include <linux/iio/iio.h>
+
+#define MPR_MEASUREMENT_RD_SIZE 4
+#define MPR_CMD_NOP 0xf0
+#define MPR_CMD_SYNC 0xaa
+#define MPR_PKT_NOP_LEN MPR_MEASUREMENT_RD_SIZE
+#define MPR_PKT_SYNC_LEN 3
+
+struct device;
+
+struct iio_chan_spec;
+struct iio_dev;
+
+struct mpr_data;
+struct mpr_ops;
+
+/**
+ * struct mpr_chan
+ * @pres: pressure value
+ * @ts: timestamp
+ */
+struct mpr_chan {
+ s32 pres;
+ s64 ts;
+};
+
+enum mpr_func_id {
+ MPR_FUNCTION_A,
+ MPR_FUNCTION_B,
+ MPR_FUNCTION_C,
+};
+
+/**
+ * struct mpr_data
+ * @dev: current device structure
+ * @ops: functions that implement the sensor reads/writes, bus init
+ * @lock: access to device during read
+ * @pmin: minimal pressure in pascal
+ * @pmax: maximal pressure in pascal
+ * @function: transfer function
+ * @outmin: minimum raw pressure in counts (based on transfer function)
+ * @outmax: maximum raw pressure in counts (based on transfer function)
+ * @scale: pressure scale
+ * @scale2: pressure scale, decimal number
+ * @offset: pressure offset
+ * @offset2: pressure offset, decimal number
+ * @gpiod_reset: reset
+ * @irq: end of conversion irq. used to distinguish between irq mode and
+ * reading in a loop until data is ready
+ * @completion: handshake from irq to read
+ * @chan: channel values for buffered mode
+ * @buffer: raw conversion data
+ */
+struct mpr_data {
+ struct device *dev;
+ const struct mpr_ops *ops;
+ struct mutex lock;
+ u32 pmin;
+ u32 pmax;
+ enum mpr_func_id function;
+ u32 outmin;
+ u32 outmax;
+ int scale;
+ int scale2;
+ int offset;
+ int offset2;
+ struct gpio_desc *gpiod_reset;
+ int irq;
+ struct completion completion;
+ struct mpr_chan chan;
+ u8 buffer[MPR_MEASUREMENT_RD_SIZE] __aligned(IIO_DMA_MINALIGN);
+};
+
+struct mpr_ops {
+ int (*init)(struct device *dev);
+ int (*read)(struct mpr_data *data, const u8 cmd, const u8 cnt);
+ int (*write)(struct mpr_data *data, const u8 cmd, const u8 cnt);
+};
+
+int mpr_common_probe(struct device *dev, const struct mpr_ops *ops, int irq);
+
+#endif
diff --git a/drivers/iio/pressure/mprls0025pa_i2c.c b/drivers/iio/pressure/mprls0025pa_i2c.c
new file mode 100644
index 000000000000..7e9d1617c9f3
--- /dev/null
+++ b/drivers/iio/pressure/mprls0025pa_i2c.c
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * MPRLS0025PA - Honeywell MicroPressure pressure sensor series driver
+ *
+ * Copyright (c) Andreas Klinger <[email protected]>
+ *
+ * Data sheet:
+ * https://prod-edam.honeywell.com/content/dam/honeywell-edam/sps/siot/en-us/products/sensors/pressure-sensors/board-mount-pressure-sensors/micropressure-mpr-series/documents/sps-siot-mpr-series-datasheet-32332628-ciid-172626.pdf
+ */
+
+#include <linux/errno.h>
+#include <linux/i2c.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+
+#include "mprls0025pa.h"
+
+static int mpr_i2c_init(struct device *unused)
+{
+ return 0;
+}
+
+static int mpr_i2c_read(struct mpr_data *data, const u8 unused, const u8 cnt)
+{
+ int ret;
+ struct i2c_client *client = to_i2c_client(data->dev);
+
+ if (cnt > MPR_MEASUREMENT_RD_SIZE)
+ return -EOVERFLOW;
+
+ memset(data->buffer, 0, MPR_MEASUREMENT_RD_SIZE);
+ ret = i2c_master_recv(client, data->buffer, cnt);
+ if (ret < 0)
+ return ret;
+ else if (ret != cnt)
+ return -EIO;
+
+ return 0;
+}
+
+static int mpr_i2c_write(struct mpr_data *data, const u8 cmd, const u8 unused)
+{
+ int ret;
+ struct i2c_client *client = to_i2c_client(data->dev);
+ u8 wdata[MPR_PKT_SYNC_LEN];
+
+ memset(wdata, 0, sizeof(wdata));
+ wdata[0] = cmd;
+
+ ret = i2c_master_send(client, wdata, MPR_PKT_SYNC_LEN);
+ if (ret < 0)
+ return ret;
+ else if (ret != MPR_PKT_SYNC_LEN)
+ return -EIO;
+
+ return 0;
+}
+
+static const struct mpr_ops mpr_i2c_ops = {
+ .init = mpr_i2c_init,
+ .read = mpr_i2c_read,
+ .write = mpr_i2c_write,
+};
+
+static int mpr_i2c_probe(struct i2c_client *client)
+{
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_BYTE))
+ return -EOPNOTSUPP;
+
+ return mpr_common_probe(&client->dev, &mpr_i2c_ops, client->irq);
+}
+
+static const struct of_device_id mpr_i2c_match[] = {
+ { .compatible = "honeywell,mprls0025pa" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, mpr_i2c_match);
+
+static const struct i2c_device_id mpr_i2c_id[] = {
+ { "mprls0025pa" },
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, mpr_i2c_id);
+
+static struct i2c_driver mpr_i2c_driver = {
+ .probe = mpr_i2c_probe,
+ .id_table = mpr_i2c_id,
+ .driver = {
+ .name = "mprls0025pa",
+ .of_match_table = mpr_i2c_match,
+ },
+};
+module_i2c_driver(mpr_i2c_driver);
+
+MODULE_AUTHOR("Andreas Klinger <[email protected]>");
+MODULE_DESCRIPTION("Honeywell MPR pressure sensor i2c driver");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS(IIO_HONEYWELL_MPRLS0025PA);
--
2.41.0


2023-12-29 09:27:41

by Petre Rodan

[permalink] [raw]
Subject: [PATCH v3 10/10] iio: pressure: mprls0025pa add SPI driver

Add SPI component of the driver.

Tested with mprls0015pa0000sa in spi mode on BeagleBone Black on
slightly patched 6.7.0-rc6 mainline.

Tested with mprls0025pa in i2c mode on BeagleBone Black with togreg
branch on
git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git
(tag: iio-for-6.8a)

Tested-by: Andreas Klinger <[email protected]>
Signed-off-by: Petre Rodan <[email protected]>
---
v2 -> v3 removed iio.h include line

drivers/iio/pressure/Kconfig | 8 ++-
drivers/iio/pressure/Makefile | 1 +
drivers/iio/pressure/mprls0025pa_spi.c | 89 ++++++++++++++++++++++++++
3 files changed, 97 insertions(+), 1 deletion(-)
create mode 100644 drivers/iio/pressure/mprls0025pa_spi.c

diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig
index f03007cfec85..5da7931dc537 100644
--- a/drivers/iio/pressure/Kconfig
+++ b/drivers/iio/pressure/Kconfig
@@ -181,8 +181,9 @@ config MPL3115

config MPRLS0025PA
tristate "Honeywell MPRLS0025PA (MicroPressure sensors series)"
- depends on I2C
+ depends on (I2C || SPI_MASTER)
select MPRLS0025PA_I2C if I2C
+ select MPRLS0025PA_SPI if SPI_MASTER
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
help
@@ -198,6 +199,11 @@ config MPRLS0025PA_I2C
depends on MPRLS0025PA
depends on I2C

+config MPRLS0025PA_SPI
+ tristate
+ depends on MPRLS0025PA
+ depends on SPI_MASTER
+
config MS5611
tristate "Measurement Specialties MS5611 pressure sensor driver"
select IIO_BUFFER
diff --git a/drivers/iio/pressure/Makefile b/drivers/iio/pressure/Makefile
index 7754135e190c..a93709e35760 100644
--- a/drivers/iio/pressure/Makefile
+++ b/drivers/iio/pressure/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_MPL115_SPI) += mpl115_spi.o
obj-$(CONFIG_MPL3115) += mpl3115.o
obj-$(CONFIG_MPRLS0025PA) += mprls0025pa.o
obj-$(CONFIG_MPRLS0025PA_I2C) += mprls0025pa_i2c.o
+obj-$(CONFIG_MPRLS0025PA_SPI) += mprls0025pa_spi.o
obj-$(CONFIG_MS5611) += ms5611_core.o
obj-$(CONFIG_MS5611_I2C) += ms5611_i2c.o
obj-$(CONFIG_MS5611_SPI) += ms5611_spi.o
diff --git a/drivers/iio/pressure/mprls0025pa_spi.c b/drivers/iio/pressure/mprls0025pa_spi.c
new file mode 100644
index 000000000000..32f6c2e60380
--- /dev/null
+++ b/drivers/iio/pressure/mprls0025pa_spi.c
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * MPRLS0025PA - Honeywell MicroPressure MPR series SPI sensor driver
+ *
+ * Copyright (c) 2024 Petre Rodan <[email protected]>
+ *
+ * Data sheet:
+ * https://prod-edam.honeywell.com/content/dam/honeywell-edam/sps/siot/en-us/products/sensors/pressure-sensors/board-mount-pressure-sensors/micropressure-mpr-series/documents/sps-siot-mpr-series-datasheet-32332628-ciid-172626.pdf
+ */
+
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/spi/spi.h>
+#include <linux/stddef.h>
+
+#include "mprls0025pa.h"
+
+struct mpr_spi_buf {
+ u8 tx[MPR_MEASUREMENT_RD_SIZE] __aligned(IIO_DMA_MINALIGN);
+};
+
+static int mpr_spi_init(struct device *dev)
+{
+ struct spi_device *spi = to_spi_device(dev);
+ struct mpr_spi_buf *buf;
+
+ buf = devm_kzalloc(dev, sizeof(*buf), GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ spi_set_drvdata(spi, buf);
+
+ return 0;
+}
+
+static int mpr_spi_xfer(struct mpr_data *data, const u8 cmd, const u8 pkt_len)
+{
+ struct spi_device *spi = to_spi_device(data->dev);
+ struct mpr_spi_buf *buf = spi_get_drvdata(spi);
+ struct spi_transfer xfer;
+
+ if (pkt_len > MPR_MEASUREMENT_RD_SIZE)
+ return -EOVERFLOW;
+
+ buf->tx[0] = cmd;
+ xfer.tx_buf = buf->tx;
+ xfer.rx_buf = data->buffer;
+ xfer.len = pkt_len;
+
+ return spi_sync_transfer(spi, &xfer, 1);
+}
+
+static const struct mpr_ops mpr_spi_ops = {
+ .init = mpr_spi_init,
+ .read = mpr_spi_xfer,
+ .write = mpr_spi_xfer,
+};
+
+static int mpr_spi_probe(struct spi_device *spi)
+{
+ return mpr_common_probe(&spi->dev, &mpr_spi_ops, spi->irq);
+}
+
+static const struct of_device_id mpr_spi_match[] = {
+ { .compatible = "honeywell,mprls0025pa" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, mpr_spi_match);
+
+static const struct spi_device_id mpr_spi_id[] = {
+ { "mprls0025pa" },
+ {}
+};
+MODULE_DEVICE_TABLE(spi, mpr_spi_id);
+
+static struct spi_driver mpr_spi_driver = {
+ .driver = {
+ .name = "mprls0025pa",
+ .of_match_table = mpr_spi_match,
+ },
+ .probe = mpr_spi_probe,
+ .id_table = mpr_spi_id,
+};
+module_spi_driver(mpr_spi_driver);
+
+MODULE_AUTHOR("Petre Rodan <[email protected]>");
+MODULE_DESCRIPTION("Honeywell MPR pressure sensor spi driver");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS(IIO_HONEYWELL_MPRLS0025PA);
--
2.41.0


2023-12-29 09:28:42

by Petre Rodan

[permalink] [raw]
Subject: [PATCH v3 09/10] iio: pressure: mprls0025pa add triplet property

Add honeywell,pressure-triplet property that automatically initializes
pmin-pascal, pmax-pascal so that the user is not required to look-up
the chip in the datasheet and convert various units to pascals himself.

Co-developed-by: Andreas Klinger <[email protected]>
Signed-off-by: Andreas Klinger <[email protected]>
Signed-off-by: Petre Rodan <[email protected]>
---
v2 -> v3 no changes

drivers/iio/pressure/mprls0025pa.c | 105 ++++++++++++++++++++++++++---
1 file changed, 97 insertions(+), 8 deletions(-)

diff --git a/drivers/iio/pressure/mprls0025pa.c b/drivers/iio/pressure/mprls0025pa.c
index ce20cf362fac..33a15d4c642c 100644
--- a/drivers/iio/pressure/mprls0025pa.c
+++ b/drivers/iio/pressure/mprls0025pa.c
@@ -80,6 +80,78 @@ static const struct mpr_func_spec mpr_func_spec[] = {
[MPR_FUNCTION_C] = { .output_min = 3355443, .output_max = 13421773 },
};

+enum mpr_variants {
+ MPR0001BA = 0x00, MPR01_6BA = 0x01, MPR02_5BA = 0x02, MPR0060MG = 0x03,
+ MPR0100MG = 0x04, MPR0160MG = 0x05, MPR0250MG = 0x06, MPR0400MG = 0x07,
+ MPR0600MG = 0x08, MPR0001BG = 0x09, MPR01_6BG = 0x0a, MPR02_5BG = 0x0b,
+ MPR0100KA = 0x0c, MPR0160KA = 0x0d, MPR0250KA = 0x0e, MPR0006KG = 0x0f,
+ MPR0010KG = 0x10, MPR0016KG = 0x11, MPR0025KG = 0x12, MPR0040KG = 0x13,
+ MPR0060KG = 0x14, MPR0100KG = 0x15, MPR0160KG = 0x16, MPR0250KG = 0x17,
+ MPR0015PA = 0x18, MPR0025PA = 0x19, MPR0030PA = 0x1a, MPR0001PG = 0x1b,
+ MPR0005PG = 0x1c, MPR0015PG = 0x1d, MPR0030PG = 0x1e, MPR0300YG = 0x1f,
+ MPR_VARIANTS_MAX
+};
+
+static const char * const mpr_triplet_variants[MPR_VARIANTS_MAX] = {
+ [MPR0001BA] = "0001BA", [MPR01_6BA] = "01.6BA", [MPR02_5BA] = "02.5BA",
+ [MPR0060MG] = "0060MG", [MPR0100MG] = "0100MG", [MPR0160MG] = "0160MG",
+ [MPR0250MG] = "0250MG", [MPR0400MG] = "0400MG", [MPR0600MG] = "0600MG",
+ [MPR0001BG] = "0001BG", [MPR01_6BG] = "01.6BG", [MPR02_5BG] = "02.5BG",
+ [MPR0100KA] = "0100KA", [MPR0160KA] = "0160KA", [MPR0250KA] = "0250KA",
+ [MPR0006KG] = "0006KG", [MPR0010KG] = "0010KG", [MPR0016KG] = "0016KG",
+ [MPR0025KG] = "0025KG", [MPR0040KG] = "0040KG", [MPR0060KG] = "0060KG",
+ [MPR0100KG] = "0100KG", [MPR0160KG] = "0160KG", [MPR0250KG] = "0250KG",
+ [MPR0015PA] = "0015PA", [MPR0025PA] = "0025PA", [MPR0030PA] = "0030PA",
+ [MPR0001PG] = "0001PG", [MPR0005PG] = "0005PG", [MPR0015PG] = "0015PG",
+ [MPR0030PG] = "0030PG", [MPR0300YG] = "0300YG"
+};
+
+/**
+ * struct mpr_range_config - list of pressure ranges based on nomenclature
+ * @pmin: lowest pressure that can be measured
+ * @pmax: highest pressure that can be measured
+ */
+struct mpr_range_config {
+ const s32 pmin;
+ const s32 pmax;
+};
+
+/* All min max limits have been converted to pascals */
+static const struct mpr_range_config mpr_range_config[MPR_VARIANTS_MAX] = {
+ [MPR0001BA] = { .pmin = 0, .pmax = 100000 },
+ [MPR01_6BA] = { .pmin = 0, .pmax = 160000 },
+ [MPR02_5BA] = { .pmin = 0, .pmax = 250000 },
+ [MPR0060MG] = { .pmin = 0, .pmax = 6000 },
+ [MPR0100MG] = { .pmin = 0, .pmax = 10000 },
+ [MPR0160MG] = { .pmin = 0, .pmax = 16000 },
+ [MPR0250MG] = { .pmin = 0, .pmax = 25000 },
+ [MPR0400MG] = { .pmin = 0, .pmax = 40000 },
+ [MPR0600MG] = { .pmin = 0, .pmax = 60000 },
+ [MPR0001BG] = { .pmin = 0, .pmax = 100000 },
+ [MPR01_6BG] = { .pmin = 0, .pmax = 160000 },
+ [MPR02_5BG] = { .pmin = 0, .pmax = 250000 },
+ [MPR0100KA] = { .pmin = 0, .pmax = 100000 },
+ [MPR0160KA] = { .pmin = 0, .pmax = 160000 },
+ [MPR0250KA] = { .pmin = 0, .pmax = 250000 },
+ [MPR0006KG] = { .pmin = 0, .pmax = 6000 },
+ [MPR0010KG] = { .pmin = 0, .pmax = 10000 },
+ [MPR0016KG] = { .pmin = 0, .pmax = 16000 },
+ [MPR0025KG] = { .pmin = 0, .pmax = 25000 },
+ [MPR0040KG] = { .pmin = 0, .pmax = 40000 },
+ [MPR0060KG] = { .pmin = 0, .pmax = 60000 },
+ [MPR0100KG] = { .pmin = 0, .pmax = 100000 },
+ [MPR0160KG] = { .pmin = 0, .pmax = 160000 },
+ [MPR0250KG] = { .pmin = 0, .pmax = 250000 },
+ [MPR0015PA] = { .pmin = 0, .pmax = 103421 },
+ [MPR0025PA] = { .pmin = 0, .pmax = 172369 },
+ [MPR0030PA] = { .pmin = 0, .pmax = 206843 },
+ [MPR0001PG] = { .pmin = 0, .pmax = 6895 },
+ [MPR0005PG] = { .pmin = 0, .pmax = 34474 },
+ [MPR0015PG] = { .pmin = 0, .pmax = 103421 },
+ [MPR0030PG] = { .pmin = 0, .pmax = 206843 },
+ [MPR0300YG] = { .pmin = 0, .pmax = 39997 }
+};
+
static const struct iio_chan_spec mpr_channels[] = {
{
.type = IIO_PRESSURE,
@@ -257,6 +329,7 @@ int mpr_common_probe(struct device *dev, const struct mpr_ops *ops, int irq)
int ret;
struct mpr_data *data;
struct iio_dev *indio_dev;
+ const char *triplet;
s64 scale, offset;
u32 func;

@@ -298,16 +371,32 @@ int mpr_common_probe(struct device *dev, const struct mpr_ops *ops, int irq)
"honeywell,transfer-function %d invalid\n",
data->function);

- ret = device_property_read_u32(dev, "honeywell,pmin-pascal",
- &data->pmin);
- if (ret)
- return dev_err_probe(dev, ret,
+ ret = device_property_read_string(dev, "honeywell,pressure-triplet",
+ &triplet);
+ if (ret) {
+ ret = device_property_read_u32(dev, "honeywell,pmin-pascal",
+ &data->pmin);
+ if (ret)
+ return dev_err_probe(dev, ret,
"honeywell,pmin-pascal could not be read\n");
- ret = device_property_read_u32(dev, "honeywell,pmax-pascal",
- &data->pmax);
- if (ret)
- return dev_err_probe(dev, ret,
+
+ ret = device_property_read_u32(dev, "honeywell,pmax-pascal",
+ &data->pmax);
+ if (ret)
+ return dev_err_probe(dev, ret,
"honeywell,pmax-pascal could not be read\n");
+ } else {
+ ret = device_property_match_property_string(dev,
+ "honeywell,pressure-triplet",
+ mpr_triplet_variants,
+ MPR_VARIANTS_MAX);
+ if (ret < 0)
+ return dev_err_probe(dev, -EINVAL,
+ "honeywell,pressure-triplet is invalid\n");
+
+ data->pmin = mpr_range_config[ret].pmin;
+ data->pmax = mpr_range_config[ret].pmax;
+ }

if (data->pmin >= data->pmax)
return dev_err_probe(dev, -EINVAL,
--
2.41.0


2024-01-06 15:25:15

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH v3 07/10] iio: pressure: mprls0025pa whitespace cleanup

On Fri, Dec 29, 2023 at 11:24:35AM +0200, Petre Rodan wrote:
> Fix indentation and whitespace in code that will not get refactored.
>
> Make URL inside comment copy-paste friendly.

...

> ret = devm_request_irq(dev, data->irq, mpr_eoc_handler,
> - IRQF_TRIGGER_RISING, client->name, data);
> + IRQF_TRIGGER_RISING,
> + client->name,
> + data);

The last two are perfectly located on a single line and be even coupled
semantically together.

No need to resend the patch just because of this, Jonathan can amend, I think,
when applying.

--
With Best Regards,
Andy Shevchenko



2024-01-06 15:57:53

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH v3 10/10] iio: pressure: mprls0025pa add SPI driver

On Fri, Dec 29, 2023 at 11:24:38AM +0200, Petre Rodan wrote:
> Add SPI component of the driver.

> Tested with mprls0015pa0000sa in spi mode on BeagleBone Black on
> slightly patched 6.7.0-rc6 mainline.

> Tested with mprls0025pa in i2c mode on BeagleBone Black with togreg
> branch on
> git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git
> (tag: iio-for-6.8a)

I believe these paragraphs can be moved to the patch submission comments from
the commit message...

> Tested-by: Andreas Klinger <[email protected]>
> Signed-off-by: Petre Rodan <[email protected]>
> ---
> v2 -> v3 removed iio.h include line

...somewhere here.

...

> +#include <linux/mod_devicetable.h>
> +#include <linux/module.h>
> +#include <linux/spi/spi.h>
> +#include <linux/stddef.h>

Basically here we need additionally these ones:

device.h
errno.h
types.h

(I haven't checked i2c counterpart for the similarities).

--
With Best Regards,
Andy Shevchenko



2024-01-06 16:06:04

by Petre Rodan

[permalink] [raw]
Subject: Re: [PATCH v3 10/10] iio: pressure: mprls0025pa add SPI driver


hello Andy,

On Sat, Jan 06, 2024 at 05:30:21PM +0200, Andy Shevchenko wrote:
> On Fri, Dec 29, 2023 at 11:24:38AM +0200, Petre Rodan wrote:
> > Add SPI component of the driver.
>
> > Tested with mprls0015pa0000sa in spi mode on BeagleBone Black on
> > slightly patched 6.7.0-rc6 mainline.
>
> > Tested with mprls0025pa in i2c mode on BeagleBone Black with togreg
> > branch on
> > git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git
> > (tag: iio-for-6.8a)
>
> I believe these paragraphs can be moved to the patch submission comments from
> the commit message...
>
> > Tested-by: Andreas Klinger <[email protected]>
> > Signed-off-by: Petre Rodan <[email protected]>
> > ---
> > v2 -> v3 removed iio.h include line
>
> ...somewhere here.
>
> ...
>
> > +#include <linux/mod_devicetable.h>
> > +#include <linux/module.h>
> > +#include <linux/spi/spi.h>
> > +#include <linux/stddef.h>
>
> Basically here we need additionally these ones:
>
> device.h
> errno.h
> types.h

ok, I'll add errno.h. the other two are in the shared .h file.

cheers,
peter

> (I haven't checked i2c counterpart for the similarities).
>
> --
> With Best Regards,
> Andy Shevchenko
>
>

--
petre rodan


Attachments:
(No filename) (1.23 kB)
signature.asc (849.00 B)
Download all attachments

2024-01-06 16:08:12

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH v3 10/10] iio: pressure: mprls0025pa add SPI driver

On Sat, Jan 06, 2024 at 06:02:52PM +0200, Petre Rodan wrote:
> On Sat, Jan 06, 2024 at 05:30:21PM +0200, Andy Shevchenko wrote:
> > On Fri, Dec 29, 2023 at 11:24:38AM +0200, Petre Rodan wrote:
> > > Add SPI component of the driver.

> > > +#include <linux/mod_devicetable.h>
> > > +#include <linux/module.h>
> > > +#include <linux/spi/spi.h>
> > > +#include <linux/stddef.h>
> >
> > Basically here we need additionally these ones:
> >
> > device.h
> > errno.h
> > types.h
>
> ok, I'll add errno.h. the other two are in the shared .h file.

Yes, but it's better to follow IWYI principle. Generally speaking
there is no guarantee that above will be _always_ the case.

Anyway, I leave this to Jonathan.

--
With Best Regards,
Andy Shevchenko



2024-01-07 16:32:31

by Jonathan Cameron

[permalink] [raw]
Subject: Re: [PATCH v3 10/10] iio: pressure: mprls0025pa add SPI driver

On Sat, 6 Jan 2024 18:07:55 +0200
Andy Shevchenko <[email protected]> wrote:

> On Sat, Jan 06, 2024 at 06:02:52PM +0200, Petre Rodan wrote:
> > On Sat, Jan 06, 2024 at 05:30:21PM +0200, Andy Shevchenko wrote:
> > > On Fri, Dec 29, 2023 at 11:24:38AM +0200, Petre Rodan wrote:
> > > > Add SPI component of the driver.
>
> > > > +#include <linux/mod_devicetable.h>
> > > > +#include <linux/module.h>
> > > > +#include <linux/spi/spi.h>
> > > > +#include <linux/stddef.h>
> > >
> > > Basically here we need additionally these ones:
> > >
> > > device.h
> > > errno.h
> > > types.h
> >
> > ok, I'll add errno.h. the other two are in the shared .h file.
>
> Yes, but it's better to follow IWYI principle. Generally speaking
> there is no guarantee that above will be _always_ the case.
>
> Anyway, I leave this to Jonathan.
>
When it's a local include to the driver like this I don't mind
as much if the includes aren't there in the c file, but do generally
'slightly prefer' them to be so. As such I've added them here and
in the i2c file (I also renamed that patch as 'refactor' isn't
exactly descriptive in the patch title!) I suspect none of us
feel that strongly about this so rather than slowing things down
I took a fairly random decision that let me apply the series today.

Anyhow, along with dropping the text on what this was tested on in
the final patch - series applied to the togreg branch of iio.git.

However, I'll be rebasing that tree on rc1 once available hence
for now this will only be pushed out as testing for 0-day to get
a head start on poking it.

Thanks,

Jonathan