diff options
author | Sean Nyekjaer <sean@geanix.com> | 2021-05-06 09:09:40 +0200 |
---|---|---|
committer | Jonathan Cameron <Jonathan.Cameron@huawei.com> | 2021-05-17 13:54:24 +0100 |
commit | af959b7b96b87aee13ed5b0041fc14ca2e72cc84 (patch) | |
tree | a2a0796981e601b09c81ebcd6f27dc650118ba21 /drivers/iio/accel | |
parent | 79e3a5bdd9efbdf4e1069793d7735b432d641e7c (diff) |
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>
Diffstat (limited to 'drivers/iio/accel')
-rw-r--r-- | drivers/iio/accel/fxls8962af-core.c | 33 |
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); |