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

Commit 22904bdf authored by Randolph Maaßen's avatar Randolph Maaßen Committed by Jonathan Cameron
Browse files

iio: imu: mpu6050: Add support for the ICM 20602 IMU



The Invensense ICM-20602 is a 6-axis MotionTracking device that
combines a 3-axis gyroscope and an 3-axis accelerometer. It is very
similar to the ICM-20608 imu which is already supported by the mpu6050
driver. The main difference is that the ICM-20602 has the i2c bus
disable bit in a separate register.

Signed-off-by: default avatarRandolph Maaßen <gaireg@gaireg.de>
Signed-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent d9f5c4e2
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -13,8 +13,8 @@ config INV_MPU6050_I2C
	select INV_MPU6050_IIO
	select REGMAP_I2C
	help
	  This driver supports the Invensense MPU6050/6500/9150 and ICM20608
	  motion tracking devices over I2C.
	  This driver supports the Invensense MPU6050/6500/9150 and
	  ICM20608/20602 motion tracking devices over I2C.
	  This driver can be built as a module. The module will be called
	  inv-mpu6050-i2c.

@@ -24,7 +24,7 @@ config INV_MPU6050_SPI
	select INV_MPU6050_IIO
	select REGMAP_SPI
	help
	  This driver supports the Invensense MPU6050/6500/9150 and ICM20608
	  motion tracking devices over SPI.
	  This driver supports the Invensense MPU6050/6500/9150 and
	  ICM20608/20602 motion tracking devices over SPI.
	  This driver can be built as a module. The module will be called
	  inv-mpu6050-spi.
+31 −0
Original line number Diff line number Diff line
@@ -38,6 +38,29 @@ static const int gyro_scale_6050[] = {133090, 266181, 532362, 1064724};
 */
static const int accel_scale[] = {598, 1196, 2392, 4785};

static const struct inv_mpu6050_reg_map reg_set_icm20602 = {
	.sample_rate_div	= INV_MPU6050_REG_SAMPLE_RATE_DIV,
	.lpf                    = INV_MPU6050_REG_CONFIG,
	.accel_lpf              = INV_MPU6500_REG_ACCEL_CONFIG_2,
	.user_ctrl              = INV_MPU6050_REG_USER_CTRL,
	.fifo_en                = INV_MPU6050_REG_FIFO_EN,
	.gyro_config            = INV_MPU6050_REG_GYRO_CONFIG,
	.accl_config            = INV_MPU6050_REG_ACCEL_CONFIG,
	.fifo_count_h           = INV_MPU6050_REG_FIFO_COUNT_H,
	.fifo_r_w               = INV_MPU6050_REG_FIFO_R_W,
	.raw_gyro               = INV_MPU6050_REG_RAW_GYRO,
	.raw_accl               = INV_MPU6050_REG_RAW_ACCEL,
	.temperature            = INV_MPU6050_REG_TEMPERATURE,
	.int_enable             = INV_MPU6050_REG_INT_ENABLE,
	.int_status             = INV_MPU6050_REG_INT_STATUS,
	.pwr_mgmt_1             = INV_MPU6050_REG_PWR_MGMT_1,
	.pwr_mgmt_2             = INV_MPU6050_REG_PWR_MGMT_2,
	.int_pin_cfg            = INV_MPU6050_REG_INT_PIN_CFG,
	.accl_offset            = INV_MPU6500_REG_ACCEL_OFFSET,
	.gyro_offset            = INV_MPU6050_REG_GYRO_OFFSET,
	.i2c_if                 = INV_ICM20602_REG_I2C_IF,
};

static const struct inv_mpu6050_reg_map reg_set_6500 = {
	.sample_rate_div	= INV_MPU6050_REG_SAMPLE_RATE_DIV,
	.lpf                    = INV_MPU6050_REG_CONFIG,
@@ -58,6 +81,7 @@ static const struct inv_mpu6050_reg_map reg_set_6500 = {
	.int_pin_cfg		= INV_MPU6050_REG_INT_PIN_CFG,
	.accl_offset		= INV_MPU6500_REG_ACCEL_OFFSET,
	.gyro_offset		= INV_MPU6050_REG_GYRO_OFFSET,
	.i2c_if                 = 0,
};

static const struct inv_mpu6050_reg_map reg_set_6050 = {
@@ -78,6 +102,7 @@ static const struct inv_mpu6050_reg_map reg_set_6050 = {
	.int_pin_cfg		= INV_MPU6050_REG_INT_PIN_CFG,
	.accl_offset		= INV_MPU6050_REG_ACCEL_OFFSET,
	.gyro_offset		= INV_MPU6050_REG_GYRO_OFFSET,
	.i2c_if                 = 0,
};

static const struct inv_mpu6050_chip_config chip_config_6050 = {
@@ -140,6 +165,12 @@ static const struct inv_mpu6050_hw hw_info[] = {
		.reg = &reg_set_6500,
		.config = &chip_config_6050,
	},
	{
		.whoami = INV_ICM20602_WHOAMI_VALUE,
		.name = "ICM20602",
		.reg = &reg_set_icm20602,
		.config = &chip_config_6050,
	},
};

int inv_mpu6050_switch_engine(struct inv_mpu6050_state *st, bool en, u32 mask)
+6 −0
Original line number Diff line number Diff line
@@ -127,6 +127,7 @@ static int inv_mpu_probe(struct i2c_client *client,
	st = iio_priv(dev_get_drvdata(&client->dev));
	switch (st->chip_type) {
	case INV_ICM20608:
	case INV_ICM20602:
		/* no i2c auxiliary bus on the chip */
		break;
	default:
@@ -179,6 +180,7 @@ static const struct i2c_device_id inv_mpu_id[] = {
	{"mpu9250", INV_MPU9250},
	{"mpu9255", INV_MPU9255},
	{"icm20608", INV_ICM20608},
	{"icm20602", INV_ICM20602},
	{}
};

@@ -213,6 +215,10 @@ static const struct of_device_id inv_of_match[] = {
		.compatible = "invensense,icm20608",
		.data = (void *)INV_ICM20608
	},
	{
		.compatible = "invensense,icm20602",
		.data = (void *)INV_ICM20602
	},
	{ }
};
MODULE_DEVICE_TABLE(of, inv_of_match);
+8 −0
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@
 *  @int_pin_cfg;	Controls interrupt pin configuration.
 *  @accl_offset:	Controls the accelerometer calibration offset.
 *  @gyro_offset:	Controls the gyroscope calibration offset.
 *  @i2c_if:		Controls the i2c interface
 */
struct inv_mpu6050_reg_map {
	u8 sample_rate_div;
@@ -65,6 +66,7 @@ struct inv_mpu6050_reg_map {
	u8 int_pin_cfg;
	u8 accl_offset;
	u8 gyro_offset;
	u8 i2c_if;
};

/*device enum */
@@ -77,6 +79,7 @@ enum inv_devices {
	INV_MPU9250,
	INV_MPU9255,
	INV_ICM20608,
	INV_ICM20602,
	INV_NUM_PARTS
};

@@ -195,6 +198,10 @@ struct inv_mpu6050_state {
#define INV_MPU6050_BIT_PWR_ACCL_STBY       0x38
#define INV_MPU6050_BIT_PWR_GYRO_STBY       0x07

/* ICM20602 register */
#define INV_ICM20602_REG_I2C_IF             0x70
#define INV_ICM20602_BIT_I2C_IF_DIS         0x40

#define INV_MPU6050_REG_FIFO_COUNT_H        0x72
#define INV_MPU6050_REG_FIFO_R_W            0x74

@@ -261,6 +268,7 @@ struct inv_mpu6050_state {
#define INV_MPU9255_WHOAMI_VALUE		0x73
#define INV_MPU6515_WHOAMI_VALUE		0x74
#define INV_ICM20608_WHOAMI_VALUE		0xAF
#define INV_ICM20602_WHOAMI_VALUE		0x12

/* scan element definition */
enum inv_mpu6050_scan {
+9 −3
Original line number Diff line number Diff line
@@ -31,9 +31,14 @@ static int inv_mpu_i2c_disable(struct iio_dev *indio_dev)
	if (ret)
		return ret;

	if (st->reg->i2c_if) {
		ret = regmap_write(st->map, st->reg->i2c_if,
				   INV_ICM20602_BIT_I2C_IF_DIS);
	} else {
		st->chip_config.user_ctrl |= INV_MPU6050_BIT_I2C_IF_DIS;
		ret = regmap_write(st->map, st->reg->user_ctrl,
				   st->chip_config.user_ctrl);
	}
	if (ret) {
		inv_mpu6050_set_power_itg(st, false);
		return ret;
@@ -81,6 +86,7 @@ static const struct spi_device_id inv_mpu_id[] = {
	{"mpu9250", INV_MPU9250},
	{"mpu9255", INV_MPU9255},
	{"icm20608", INV_ICM20608},
	{"icm20602", INV_ICM20602},
	{}
};