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: Randolph Maaßen <gaireg@gaireg.de> Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
This commit is contained in:
		
							parent
							
								
									d9f5c4e237
								
							
						
					
					
						commit
						22904bdff9
					
				| @ -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. | ||||
|  | ||||
| @ -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 = ®_set_6500, | ||||
| 		.config = &chip_config_6050, | ||||
| 	}, | ||||
| 	{ | ||||
| 		.whoami = INV_ICM20602_WHOAMI_VALUE, | ||||
| 		.name = "ICM20602", | ||||
| 		.reg = ®_set_icm20602, | ||||
| 		.config = &chip_config_6050, | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| int inv_mpu6050_switch_engine(struct inv_mpu6050_state *st, bool en, u32 mask) | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -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 { | ||||
|  | ||||
| @ -31,9 +31,14 @@ static int inv_mpu_i2c_disable(struct iio_dev *indio_dev) | ||||
| 	if (ret) | ||||
| 		return ret; | ||||
| 
 | ||||
| 	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 (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}, | ||||
| 	{} | ||||
| }; | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user