[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20251218-mprls_cleanup-v1-9-b36a170f1a5c@subdimension.ro>
Date: Thu, 18 Dec 2025 13:05:51 +0200
From: Petre Rodan <petre.rodan@...dimension.ro>
To: Jonathan Cameron <jic23@...nel.org>,
David Lechner <dlechner@...libre.com>,
Nuno Sá <nuno.sa@...log.com>,
Andy Shevchenko <andy@...nel.org>, Andreas Klinger <ak@...klinger.de>
Cc: linux-iio@...r.kernel.org, linux-kernel@...r.kernel.org,
Jonathan Cameron <Jonathan.Cameron@...wei.com>
Subject: [PATCH 09/14] iio: pressure: mprls0025pa: mitigate SPI CS delay
violation
Based on the sensor datasheet in chapter 7.6 SPI timing, Table 20,
during the SPI transfer there is a minimum time interval between the
CS being asserted and the first clock edge (tHDSS).
This minimum interval of 2.5us is being violated if two consecutive SPI
transfers are queued up, at least on my SPI controller (omap2_mcspi) [1]
As you can see in the first package that only contains a NOP the interval
is 0.75us (half a 800kHz clock cycle).
This patch mitigates the problem by implementing a different measurement
technique that does not involve checking for the EOC indicator before
reading the conversion, thus making sure SPI transfers are not queued up.
see Option 2 in Table 19 SPI output measurement command.
Note that Honeywell's example code also follows this technique for both i2c
and SPI.
This change only affects users that do not define the EOC interrupt in the
device tree.
Remove defines that are no longer used.
[1] https://pasteboard.co/66WN38MRI1wc.png
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?download=false
Signed-off-by: Petre Rodan <petre.rodan@...dimension.ro>
---
drivers/iio/pressure/mprls0025pa.c | 33 ++++-----------------------------
1 file changed, 4 insertions(+), 29 deletions(-)
diff --git a/drivers/iio/pressure/mprls0025pa.c b/drivers/iio/pressure/mprls0025pa.c
index 973d205da3e9..a1d7ec358036 100644
--- a/drivers/iio/pressure/mprls0025pa.c
+++ b/drivers/iio/pressure/mprls0025pa.c
@@ -12,12 +12,14 @@
#include <linux/array_size.h>
#include <linux/bitfield.h>
#include <linux/bits.h>
+#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/math64.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/property.h>
#include <linux/string.h>
+#include <linux/time.h>
#include <linux/units.h>
#include <linux/gpio/consumer.h>
@@ -35,10 +37,6 @@
/* 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)
#define MPR_CMD_NOP 0xf0
#define MPR_CMD_SYNC 0xaa
@@ -204,8 +202,7 @@ static void mpr_reset(struct mpr_data *data)
static int mpr_read_pressure(struct mpr_data *data, s32 *press)
{
struct device *dev = data->dev;
- int ret, i;
- int nloops = 10;
+ int ret;
reinit_completion(&data->completion);
@@ -222,29 +219,7 @@ static int mpr_read_pressure(struct mpr_data *data, s32 *press)
return -ETIMEDOUT;
}
} else {
- /* wait until status indicates data is ready */
- for (i = 0; i < nloops; i++) {
- /*
- * datasheet only says to wait at least 5 ms for the
- * data but leave the maximum response time open
- * --> let's try it nloops (10) times which seems to be
- * quite long
- */
- usleep_range(5000, 10000);
- ret = data->ops->read(data, MPR_CMD_NOP, 1);
- if (ret < 0) {
- dev_err(dev,
- "error while reading, status: %d\n",
- ret);
- return ret;
- }
- if (!(data->rx_buf[0] & MPR_ST_ERR_FLAG))
- break;
- }
- if (i == nloops) {
- dev_err(dev, "timeout while reading\n");
- return -ETIMEDOUT;
- }
+ fsleep(5 * USEC_PER_MSEC);
}
memset(data->rx_buf, 0, sizeof(data->rx_buf));
--
2.51.2
Powered by blists - more mailing lists