Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -114,54 +114,63 @@ static const struct inv_mpu6050_hw hw_info[] = {
		.name = "MPU6050",
		.reg = &reg_set_6050,
		.config = &chip_config_6050,
		.fifo_size = 1024,
	},
	{
		.whoami = INV_MPU6500_WHOAMI_VALUE,
		.name = "MPU6500",
		.reg = &reg_set_6500,
		.config = &chip_config_6050,
		.fifo_size = 512,
	},
	{
		.whoami = INV_MPU6515_WHOAMI_VALUE,
		.name = "MPU6515",
		.reg = &reg_set_6500,
		.config = &chip_config_6050,
		.fifo_size = 512,
	},
	{
		.whoami = INV_MPU6000_WHOAMI_VALUE,
		.name = "MPU6000",
		.reg = &reg_set_6050,
		.config = &chip_config_6050,
		.fifo_size = 1024,
	},
	{
		.whoami = INV_MPU9150_WHOAMI_VALUE,
		.name = "MPU9150",
		.reg = &reg_set_6050,
		.config = &chip_config_6050,
		.fifo_size = 1024,
	},
	{
		.whoami = INV_MPU9250_WHOAMI_VALUE,
		.name = "MPU9250",
		.reg = &reg_set_6500,
		.config = &chip_config_6050,
		.fifo_size = 512,
	},
	{
		.whoami = INV_MPU9255_WHOAMI_VALUE,
		.name = "MPU9255",
		.reg = &reg_set_6500,
		.config = &chip_config_6050,
		.fifo_size = 512,
	},
	{
		.whoami = INV_ICM20608_WHOAMI_VALUE,
		.name = "ICM20608",
		.reg = &reg_set_6500,
		.config = &chip_config_6050,
		.fifo_size = 512,
	},
	{
		.whoami = INV_ICM20602_WHOAMI_VALUE,
		.name = "ICM20602",
		.reg = &reg_set_icm20602,
		.config = &chip_config_6050,
		.fifo_size = 1008,
	},
};

+2 −0
Original line number Diff line number Diff line
@@ -100,12 +100,14 @@ struct inv_mpu6050_chip_config {
 *  @name:      name of the chip.
 *  @reg:   register map of the chip.
 *  @config:    configuration of the chip.
 *  @fifo_size:	size of the FIFO in bytes.
 */
struct inv_mpu6050_hw {
	u8 whoami;
	u8 *name;
	const struct inv_mpu6050_reg_map *reg;
	const struct inv_mpu6050_chip_config *config;
	size_t fifo_size;
};

/*
+12 −3
Original line number Diff line number Diff line
@@ -180,9 +180,6 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p)
			"failed to ack interrupt\n");
		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)) {
		dev_warn(regmap_get_device(st->map),
			"spurious interrupt with status 0x%x\n", int_status);
@@ -211,6 +208,18 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p)
	if (result)
		goto end_session;
	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 */
	nb = fifo_count / bytes_per_datum;
	inv_mpu6050_update_period(st, pf->timestamp, nb);