Commit 0b70c084 authored by Jean-Baptiste Maneyrol's avatar Jean-Baptiste Maneyrol Committed by Jonathan Cameron

iio: imu: inv_mpu6050: add WoM (Wake-on-Motion) sensor

WoM is a threshold test on accel value comparing actual sample with
previous one. It maps best to roc rising event.

Add support of a new WOM sensor and functions for handling the associated
roc_rising event. The event value is in SI units. Ensure WOM is stopped and
restarted at suspend-resume, handle usage with buffer data ready interrupt,
and handle change in sampling rate impacting already set roc value.
Signed-off-by: default avatarJean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
Link: https://lore.kernel.org/r/20240311160557.437337-2-inv.git-commit@tdk.comSigned-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent e264b086
This diff is collapsed.
...@@ -88,11 +88,12 @@ enum inv_devices { ...@@ -88,11 +88,12 @@ enum inv_devices {
INV_NUM_PARTS INV_NUM_PARTS
}; };
/* chip sensors mask: accelerometer, gyroscope, temperature, magnetometer */ /* chip sensors mask: accelerometer, gyroscope, temperature, magnetometer, WoM */
#define INV_MPU6050_SENSOR_ACCL BIT(0) #define INV_MPU6050_SENSOR_ACCL BIT(0)
#define INV_MPU6050_SENSOR_GYRO BIT(1) #define INV_MPU6050_SENSOR_GYRO BIT(1)
#define INV_MPU6050_SENSOR_TEMP BIT(2) #define INV_MPU6050_SENSOR_TEMP BIT(2)
#define INV_MPU6050_SENSOR_MAGN BIT(3) #define INV_MPU6050_SENSOR_MAGN BIT(3)
#define INV_MPU6050_SENSOR_WOM BIT(4)
/** /**
* struct inv_mpu6050_chip_config - Cached chip configuration data. * struct inv_mpu6050_chip_config - Cached chip configuration data.
...@@ -104,11 +105,13 @@ enum inv_devices { ...@@ -104,11 +105,13 @@ enum inv_devices {
* @gyro_en: gyro engine enabled * @gyro_en: gyro engine enabled
* @temp_en: temperature sensor enabled * @temp_en: temperature sensor enabled
* @magn_en: magn engine (i2c master) enabled * @magn_en: magn engine (i2c master) enabled
* @wom_en: Wake-on-Motion enabled
* @accl_fifo_enable: enable accel data output * @accl_fifo_enable: enable accel data output
* @gyro_fifo_enable: enable gyro data output * @gyro_fifo_enable: enable gyro data output
* @temp_fifo_enable: enable temp data output * @temp_fifo_enable: enable temp data output
* @magn_fifo_enable: enable magn data output * @magn_fifo_enable: enable magn data output
* @divider: chip sample rate divider (sample rate divider - 1) * @divider: chip sample rate divider (sample rate divider - 1)
* @roc_threshold: save ROC threshold (WoM) set value
*/ */
struct inv_mpu6050_chip_config { struct inv_mpu6050_chip_config {
unsigned int clk:3; unsigned int clk:3;
...@@ -119,12 +122,14 @@ struct inv_mpu6050_chip_config { ...@@ -119,12 +122,14 @@ struct inv_mpu6050_chip_config {
unsigned int gyro_en:1; unsigned int gyro_en:1;
unsigned int temp_en:1; unsigned int temp_en:1;
unsigned int magn_en:1; unsigned int magn_en:1;
unsigned int wom_en:1;
unsigned int accl_fifo_enable:1; unsigned int accl_fifo_enable:1;
unsigned int gyro_fifo_enable:1; unsigned int gyro_fifo_enable:1;
unsigned int temp_fifo_enable:1; unsigned int temp_fifo_enable:1;
unsigned int magn_fifo_enable:1; unsigned int magn_fifo_enable:1;
u8 divider; u8 divider;
u8 user_ctrl; u8 user_ctrl;
u64 roc_threshold;
}; };
/* /*
...@@ -256,12 +261,16 @@ struct inv_mpu6050_state { ...@@ -256,12 +261,16 @@ struct inv_mpu6050_state {
#define INV_MPU6050_REG_INT_ENABLE 0x38 #define INV_MPU6050_REG_INT_ENABLE 0x38
#define INV_MPU6050_BIT_DATA_RDY_EN 0x01 #define INV_MPU6050_BIT_DATA_RDY_EN 0x01
#define INV_MPU6050_BIT_DMP_INT_EN 0x02 #define INV_MPU6050_BIT_DMP_INT_EN 0x02
#define INV_MPU6500_BIT_WOM_INT_EN BIT(6)
#define INV_ICM20608_BIT_WOM_INT_EN GENMASK(7, 5)
#define INV_MPU6050_REG_RAW_ACCEL 0x3B #define INV_MPU6050_REG_RAW_ACCEL 0x3B
#define INV_MPU6050_REG_TEMPERATURE 0x41 #define INV_MPU6050_REG_TEMPERATURE 0x41
#define INV_MPU6050_REG_RAW_GYRO 0x43 #define INV_MPU6050_REG_RAW_GYRO 0x43
#define INV_MPU6050_REG_INT_STATUS 0x3A #define INV_MPU6050_REG_INT_STATUS 0x3A
#define INV_MPU6500_BIT_WOM_INT BIT(6)
#define INV_ICM20608_BIT_WOM_INT GENMASK(7, 5)
#define INV_MPU6050_BIT_FIFO_OVERFLOW_INT 0x10 #define INV_MPU6050_BIT_FIFO_OVERFLOW_INT 0x10
#define INV_MPU6050_BIT_RAW_DATA_RDY_INT 0x01 #define INV_MPU6050_BIT_RAW_DATA_RDY_INT 0x01
...@@ -301,6 +310,11 @@ struct inv_mpu6050_state { ...@@ -301,6 +310,11 @@ struct inv_mpu6050_state {
#define INV_MPU6050_BIT_PWR_ACCL_STBY 0x38 #define INV_MPU6050_BIT_PWR_ACCL_STBY 0x38
#define INV_MPU6050_BIT_PWR_GYRO_STBY 0x07 #define INV_MPU6050_BIT_PWR_GYRO_STBY 0x07
/* ICM20609 registers */
#define INV_ICM20609_REG_ACCEL_WOM_X_THR 0x20
#define INV_ICM20609_REG_ACCEL_WOM_Y_THR 0x21
#define INV_ICM20609_REG_ACCEL_WOM_Z_THR 0x22
/* ICM20602 register */ /* ICM20602 register */
#define INV_ICM20602_REG_I2C_IF 0x70 #define INV_ICM20602_REG_I2C_IF 0x70
#define INV_ICM20602_BIT_I2C_IF_DIS 0x40 #define INV_ICM20602_BIT_I2C_IF_DIS 0x40
...@@ -320,6 +334,10 @@ struct inv_mpu6050_state { ...@@ -320,6 +334,10 @@ struct inv_mpu6050_state {
/* mpu6500 registers */ /* mpu6500 registers */
#define INV_MPU6500_REG_ACCEL_CONFIG_2 0x1D #define INV_MPU6500_REG_ACCEL_CONFIG_2 0x1D
#define INV_ICM20689_BITS_FIFO_SIZE_MAX 0xC0 #define INV_ICM20689_BITS_FIFO_SIZE_MAX 0xC0
#define INV_MPU6500_REG_WOM_THRESHOLD 0x1F
#define INV_MPU6500_REG_ACCEL_INTEL_CTRL 0x69
#define INV_MPU6500_BIT_ACCEL_INTEL_EN BIT(7)
#define INV_MPU6500_BIT_ACCEL_INTEL_MODE BIT(6)
#define INV_MPU6500_REG_ACCEL_OFFSET 0x77 #define INV_MPU6500_REG_ACCEL_OFFSET 0x77
/* delay time in milliseconds */ /* delay time in milliseconds */
......
...@@ -33,10 +33,8 @@ static int inv_reset_fifo(struct iio_dev *indio_dev) ...@@ -33,10 +33,8 @@ static int inv_reset_fifo(struct iio_dev *indio_dev)
reset_fifo_fail: reset_fifo_fail:
dev_err(regmap_get_device(st->map), "reset fifo failed %d\n", result); dev_err(regmap_get_device(st->map), "reset fifo failed %d\n", result);
result = regmap_write(st->map, st->reg->int_enable, return regmap_update_bits(st->map, st->reg->int_enable,
INV_MPU6050_BIT_DATA_RDY_EN); INV_MPU6050_BIT_DATA_RDY_EN, INV_MPU6050_BIT_DATA_RDY_EN);
return result;
} }
/* /*
......
...@@ -135,11 +135,13 @@ int inv_mpu6050_prepare_fifo(struct inv_mpu6050_state *st, bool enable) ...@@ -135,11 +135,13 @@ int inv_mpu6050_prepare_fifo(struct inv_mpu6050_state *st, bool enable)
ret = regmap_write(st->map, st->reg->user_ctrl, d); ret = regmap_write(st->map, st->reg->user_ctrl, d);
if (ret) if (ret)
return ret; return ret;
/* enable interrupt */ /* enable data interrupt */
ret = regmap_write(st->map, st->reg->int_enable, ret = regmap_update_bits(st->map, st->reg->int_enable,
INV_MPU6050_BIT_DATA_RDY_EN); INV_MPU6050_BIT_DATA_RDY_EN, INV_MPU6050_BIT_DATA_RDY_EN);
} else { } else {
ret = regmap_write(st->map, st->reg->int_enable, 0); /* disable data interrupt */
ret = regmap_update_bits(st->map, st->reg->int_enable,
INV_MPU6050_BIT_DATA_RDY_EN, 0);
if (ret) if (ret)
return ret; return ret;
ret = regmap_write(st->map, st->reg->fifo_en, 0); ret = regmap_write(st->map, st->reg->fifo_en, 0);
...@@ -172,9 +174,9 @@ static int inv_mpu6050_set_enable(struct iio_dev *indio_dev, bool enable) ...@@ -172,9 +174,9 @@ static int inv_mpu6050_set_enable(struct iio_dev *indio_dev, bool enable)
return result; return result;
/* /*
* In case autosuspend didn't trigger, turn off first not * In case autosuspend didn't trigger, turn off first not
* required sensors. * required sensors excepted WoM
*/ */
result = inv_mpu6050_switch_engine(st, false, ~scan); result = inv_mpu6050_switch_engine(st, false, ~scan & ~INV_MPU6050_SENSOR_WOM);
if (result) if (result)
goto error_power_off; goto error_power_off;
result = inv_mpu6050_switch_engine(st, true, scan); result = inv_mpu6050_switch_engine(st, true, scan);
......
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