Commit 6e82ae6b authored by Jean-Baptiste Maneyrol's avatar Jean-Baptiste Maneyrol Committed by Jonathan Cameron

iio: imu: inv_mpu6050: fix no data on MPU6050

Some chips have a fifo overflow bit issue where the bit is always
set. The result is that every data is dropped.

Change fifo overflow management by checking fifo count against
a maximum value.

Add fifo size in chip hardware set of values.

Fixes: f5057e7b ("iio: imu: inv_mpu6050: better fifo overflow handling")
Cc: stable@vger.kernel.org
Signed-off-by: default avatarJean-Baptiste Maneyrol <jmaneyrol@invensense.com>
Signed-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent 431f7667
...@@ -114,54 +114,63 @@ static const struct inv_mpu6050_hw hw_info[] = { ...@@ -114,54 +114,63 @@ static const struct inv_mpu6050_hw hw_info[] = {
.name = "MPU6050", .name = "MPU6050",
.reg = &reg_set_6050, .reg = &reg_set_6050,
.config = &chip_config_6050, .config = &chip_config_6050,
.fifo_size = 1024,
}, },
{ {
.whoami = INV_MPU6500_WHOAMI_VALUE, .whoami = INV_MPU6500_WHOAMI_VALUE,
.name = "MPU6500", .name = "MPU6500",
.reg = &reg_set_6500, .reg = &reg_set_6500,
.config = &chip_config_6050, .config = &chip_config_6050,
.fifo_size = 512,
}, },
{ {
.whoami = INV_MPU6515_WHOAMI_VALUE, .whoami = INV_MPU6515_WHOAMI_VALUE,
.name = "MPU6515", .name = "MPU6515",
.reg = &reg_set_6500, .reg = &reg_set_6500,
.config = &chip_config_6050, .config = &chip_config_6050,
.fifo_size = 512,
}, },
{ {
.whoami = INV_MPU6000_WHOAMI_VALUE, .whoami = INV_MPU6000_WHOAMI_VALUE,
.name = "MPU6000", .name = "MPU6000",
.reg = &reg_set_6050, .reg = &reg_set_6050,
.config = &chip_config_6050, .config = &chip_config_6050,
.fifo_size = 1024,
}, },
{ {
.whoami = INV_MPU9150_WHOAMI_VALUE, .whoami = INV_MPU9150_WHOAMI_VALUE,
.name = "MPU9150", .name = "MPU9150",
.reg = &reg_set_6050, .reg = &reg_set_6050,
.config = &chip_config_6050, .config = &chip_config_6050,
.fifo_size = 1024,
}, },
{ {
.whoami = INV_MPU9250_WHOAMI_VALUE, .whoami = INV_MPU9250_WHOAMI_VALUE,
.name = "MPU9250", .name = "MPU9250",
.reg = &reg_set_6500, .reg = &reg_set_6500,
.config = &chip_config_6050, .config = &chip_config_6050,
.fifo_size = 512,
}, },
{ {
.whoami = INV_MPU9255_WHOAMI_VALUE, .whoami = INV_MPU9255_WHOAMI_VALUE,
.name = "MPU9255", .name = "MPU9255",
.reg = &reg_set_6500, .reg = &reg_set_6500,
.config = &chip_config_6050, .config = &chip_config_6050,
.fifo_size = 512,
}, },
{ {
.whoami = INV_ICM20608_WHOAMI_VALUE, .whoami = INV_ICM20608_WHOAMI_VALUE,
.name = "ICM20608", .name = "ICM20608",
.reg = &reg_set_6500, .reg = &reg_set_6500,
.config = &chip_config_6050, .config = &chip_config_6050,
.fifo_size = 512,
}, },
{ {
.whoami = INV_ICM20602_WHOAMI_VALUE, .whoami = INV_ICM20602_WHOAMI_VALUE,
.name = "ICM20602", .name = "ICM20602",
.reg = &reg_set_icm20602, .reg = &reg_set_icm20602,
.config = &chip_config_6050, .config = &chip_config_6050,
.fifo_size = 1008,
}, },
}; };
......
...@@ -100,12 +100,14 @@ struct inv_mpu6050_chip_config { ...@@ -100,12 +100,14 @@ struct inv_mpu6050_chip_config {
* @name: name of the chip. * @name: name of the chip.
* @reg: register map of the chip. * @reg: register map of the chip.
* @config: configuration of the chip. * @config: configuration of the chip.
* @fifo_size: size of the FIFO in bytes.
*/ */
struct inv_mpu6050_hw { struct inv_mpu6050_hw {
u8 whoami; u8 whoami;
u8 *name; u8 *name;
const struct inv_mpu6050_reg_map *reg; const struct inv_mpu6050_reg_map *reg;
const struct inv_mpu6050_chip_config *config; const struct inv_mpu6050_chip_config *config;
size_t fifo_size;
}; };
/* /*
......
...@@ -180,9 +180,6 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p) ...@@ -180,9 +180,6 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p)
"failed to ack interrupt\n"); "failed to ack interrupt\n");
goto flush_fifo; goto flush_fifo;
} }
/* handle fifo overflow by reseting fifo */
if (int_status & INV_MPU6050_BIT_FIFO_OVERFLOW_INT)
goto flush_fifo;
if (!(int_status & INV_MPU6050_BIT_RAW_DATA_RDY_INT)) { if (!(int_status & INV_MPU6050_BIT_RAW_DATA_RDY_INT)) {
dev_warn(regmap_get_device(st->map), dev_warn(regmap_get_device(st->map),
"spurious interrupt with status 0x%x\n", int_status); "spurious interrupt with status 0x%x\n", int_status);
...@@ -211,6 +208,18 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p) ...@@ -211,6 +208,18 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p)
if (result) if (result)
goto end_session; goto end_session;
fifo_count = get_unaligned_be16(&data[0]); fifo_count = get_unaligned_be16(&data[0]);
/*
* Handle fifo overflow by resetting fifo.
* Reset if there is only 3 data set free remaining to mitigate
* possible delay between reading fifo count and fifo data.
*/
nb = 3 * bytes_per_datum;
if (fifo_count >= st->hw->fifo_size - nb) {
dev_warn(regmap_get_device(st->map), "fifo overflow reset\n");
goto flush_fifo;
}
/* compute and process all complete datum */ /* compute and process all complete datum */
nb = fifo_count / bytes_per_datum; nb = fifo_count / bytes_per_datum;
inv_mpu6050_update_period(st, pf->timestamp, nb); inv_mpu6050_update_period(st, pf->timestamp, nb);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment