summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Nyekjaer <sean@geanix.com>2021-05-06 09:09:40 +0200
committerJonathan Cameron <Jonathan.Cameron@huawei.com>2021-05-17 13:54:24 +0100
commitaf959b7b96b87aee13ed5b0041fc14ca2e72cc84 (patch)
treea2a0796981e601b09c81ebcd6f27dc650118ba21
parent79e3a5bdd9efbdf4e1069793d7735b432d641e7c (diff)
downloadlinux-af959b7b96b87aee13ed5b0041fc14ca2e72cc84.tar.bz2
iio: accel: fxls8962af: fix errata bug E3 - I2C burst reads
When flushing the hw fifo there is a bug in the I2C that prevents burst reads of more than one sample pair. Signed-off-by: Sean Nyekjaer <sean@geanix.com> Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
-rw-r--r--drivers/iio/accel/fxls8962af-core.c33
1 files changed, 30 insertions, 3 deletions
diff --git a/drivers/iio/accel/fxls8962af-core.c b/drivers/iio/accel/fxls8962af-core.c
index 3ea8488ed4c2..9fe5a18a605c 100644
--- a/drivers/iio/accel/fxls8962af-core.c
+++ b/drivers/iio/accel/fxls8962af-core.c
@@ -14,6 +14,7 @@
#include <linux/bits.h>
#include <linux/bitfield.h>
+#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/of_irq.h>
#include <linux/pm_runtime.h>
@@ -623,16 +624,42 @@ static const struct iio_buffer_setup_ops fxls8962af_buffer_ops = {
.postdisable = fxls8962af_buffer_postdisable,
};
+static int fxls8962af_i2c_raw_read_errata3(struct fxls8962af_data *data,
+ u16 *buffer, int samples,
+ int sample_length)
+{
+ int i, ret;
+
+ for (i = 0; i < samples; i++) {
+ ret = regmap_raw_read(data->regmap, FXLS8962AF_BUF_X_LSB,
+ &buffer[i * 3], sample_length);
+ if (ret)
+ return ret;
+ }
+
+ return ret;
+}
+
static int fxls8962af_fifo_transfer(struct fxls8962af_data *data,
u16 *buffer, int samples)
{
struct device *dev = regmap_get_device(data->regmap);
int sample_length = 3 * sizeof(*buffer);
- int ret;
int total_length = samples * sample_length;
+ int ret;
+
+ if (i2c_verify_client(dev))
+ /*
+ * Due to errata bug:
+ * E3: FIFO burst read operation error using I2C interface
+ * We have to avoid burst reads on I2C..
+ */
+ ret = fxls8962af_i2c_raw_read_errata3(data, buffer, samples,
+ sample_length);
+ else
+ ret = regmap_raw_read(data->regmap, FXLS8962AF_BUF_X_LSB, buffer,
+ total_length);
- ret = regmap_raw_read(data->regmap, FXLS8962AF_BUF_X_LSB, buffer,
- total_length);
if (ret)
dev_err(dev, "Error transferring data from fifo: %d\n", ret);