Add Invensense ICM42607
Subsystems (4)
v2 cover Add Invensense ICM42607
From: Chris Morgan <[email protected]>
Add support for the ICM42607 IMU. This sensor shares the same functionality but a different register layout with the existing ICM42600.
This driver should work with the ICM42607 and ICM42607P over both I2C and SPI, however only the ICM42607P over I2C could be tested.
Changes Since V1:
- Instead of creating a new driver, merged with the existing inv_icm42600 driver. This necessitated adding some code to the existing driver to permit using a different register layout for the same functionality.
- Split changes up a bit more to decrease the size of the individual patches. Note that patch 0004 is still pretty hefty; if I need to split further I may need to create some temporary stub functions.
- Used guard() and PM_RUNTIME_ACQUIRE_AUTOSUSPEND() on the new functions per Jonathan's recommendations.
Chris Morgan (5):
dt-bindings: iio: imu: add icm42607
iio: imu: inv_icm42600: Add support for using alternate registers
iio: imu: inv_icm42600: Add registers for icm42607
iio: imu: inv_icm42600: Add support for icm42607
arm64: dts: rockchip: Add icm42607p IMU for RG-DS
.../bindings/iio/imu/invensense,icm42600.yaml | 4 + .../dts/rockchip/rk3568-anbernic-rg-ds.dts | 20 +- drivers/iio/imu/inv_icm42600/inv_icm42600.h | 333 +++++++- .../iio/imu/inv_icm42600/inv_icm42600_accel.c | 497 ++++++++++- .../imu/inv_icm42600/inv_icm42600_buffer.c | 240 +++++- .../imu/inv_icm42600/inv_icm42600_buffer.h | 5 + .../iio/imu/inv_icm42600/inv_icm42600_core.c | 795 +++++++++++++++--- .../iio/imu/inv_icm42600/inv_icm42600_gyro.c | 379 ++++++++- .../iio/imu/inv_icm42600/inv_icm42600_i2c.c | 53 +- .../iio/imu/inv_icm42600/inv_icm42600_spi.c | 59 +- .../iio/imu/inv_icm42600/inv_icm42600_temp.c | 64 ++ .../iio/imu/inv_icm42600/inv_icm42600_temp.h | 4 + 12 files changed, 2289 insertions(+), 164 deletions(-)
Signature · 1 line
2.43.0
PATCH v2 1/5 dt-bindings: iio: imu: add icm42607
From: Chris Morgan <[email protected]>
Add bindings for ICM-42607 and ICM-42607-P.
--- .../devicetree/bindings/iio/imu/invensense,icm42600.yaml | 4 ++++ 1 file changed, 4 insertions(+)
Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml +4 -0
@@ -30,6 +30,8 @@ properties: - invensense,icm42600 - invensense,icm42602 - invensense,icm42605 + - invensense,icm42607 + - invensense,icm42607p - invensense,icm42622 - invensense,icm42631 - invensense,icm42686
@@ -53,6 +55,8 @@ properties: drive-open-drain: type: boolean + mount-matrix: true + vdd-supply: description: Regulator that provides power to the sensor
Signature · 1 line
2.43.0
Re: [PATCH V2 1/5] dt-bindings: iio: imu: add icm42607
pw-bot: not-applicable
PATCH v2 2/5 iio: imu: inv_icm42600: Add support for using alternate registers
In reply to Chris MorganFrom: Chris Morgan <[email protected]>
Add support to the existing inv_icm42600 to support similar hardware with slightly different register layouts. For example the icm42607 and icm42607p has most of the same functionality and even many of the same registers, but the addresses for indiviual registers differ.
--- drivers/iio/imu/inv_icm42600/inv_icm42600.h | 28 +- .../iio/imu/inv_icm42600/inv_icm42600_accel.c | 15 +- .../iio/imu/inv_icm42600/inv_icm42600_core.c | 257 ++++++++++-------- .../iio/imu/inv_icm42600/inv_icm42600_gyro.c | 13 +- 4 files changed, 188 insertions(+), 125 deletions(-)
drivers/iio/imu/inv_icm42600/inv_icm42600.h +24 -4
@@ -143,6 +143,26 @@ struct inv_icm42600_apex { } wom; }; +typedef int (*inv_icm42600_bus_setup )(struct inv_icm42600_state *); + +struct inv_icm42600_funcs { +int (*setup)(struct inv_icm42600_state *st, +inv_icm42600_bus_setup bus_setup); + +/* timestamp_setup optional, not present on icm42607 */ +int (*timestamp_setup)(struct inv_icm42600_state *st); + +int (*buffer_init)(struct inv_icm42600_state *st); +int (*gyro_init)(struct inv_icm42600_state *st, +struct iio_dev *indio_dev); +int (*accel_init)(struct inv_icm42600_state *st, +struct iio_dev *indio_dev); +int (*suspend)(struct device *dev); +int (*resume)(struct device *dev); +int (*runtime_suspend)(struct device *dev); +int (*runtime_resume)(struct device *dev); +}; +/** * struct inv_icm42600_state - driver state variables * @lock: lock for serializing multiple registers access.
@@ -160,6 +180,7 @@ struct inv_icm42600_apex {* @timestamp: interrupt timestamps. * @apex: APEX (Advanced Pedometer and Event detection) management * @fifo: FIFO management structure. +* @hw_funcs: Device specific hardware functions. * @buffer: data transfer buffer aligned for DMA. */ struct inv_icm42600_state {
@@ -180,6 +201,7 @@ struct inv_icm42600_state { } timestamp;struct inv_icm42600_apex apex;struct inv_icm42600_fifo fifo; +struct inv_icm42600_funcs *hw_funcs;u8 buffer[3 ]__aligned(IIO_DMA_MINALIGN) ; };
@@ -440,8 +462,6 @@ struct inv_icm42600_sensor_state {#define INV_ICM42600_TEMP_STARTUP_TIME_MS 14#define INV_ICM42600_SUSPEND_DELAY_MS 2000 -typedef int (*inv_icm42600_bus_setup )(struct inv_icm42600_state *); -extern const struct regmap_config inv_icm42600_regmap_config;extern const struct regmap_config inv_icm42600_spi_regmap_config;extern const struct dev_pm_ops inv_icm42600_pm_ops;
@@ -472,11 +492,11 @@ int inv_icm42600_debugfs_reg(struct iio_dev *indio_dev, unsigned int reg,int inv_icm42600_core_probe (struct regmap *regmap,int chip,inv_icm42600_bus_setup bus_setup); -struct iio_dev *inv_icm42600_gyro_init (struct inv_icm42600_state *st); +int inv_icm42600_gyro_init (struct inv_icm42600_state *st,struct iio_dev *indio_dev);int inv_icm42600_gyro_parse_fifo (struct iio_dev *indio_dev); -struct iio_dev *inv_icm42600_accel_init (struct inv_icm42600_state *st); +int inv_icm42600_accel_init (struct inv_icm42600_state *st,struct iio_dev *indio_dev);int inv_icm42600_accel_parse_fifo (struct iio_dev *indio_dev);
drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c +7 -8
@@ -1137,22 +1137,21 @@ static const struct iio_info inv_icm42600_accel_info = { .write_event_value = inv_icm42600_accel_write_event_value, }; -struct iio_dev *inv_icm42600_accel_init (struct inv_icm42600_state *st) +int inv_icm42600_accel_init (struct inv_icm42600_state *st,struct iio_dev *indio_dev) {struct device *dev =regmap_get_device (st->map);const char *name;struct inv_icm42600_sensor_state *accel_st;struct inv_sensors_timestamp_chip ts_chip; -struct iio_dev *indio_dev;int ret; name =devm_kasprintf (dev,GFP_KERNEL ,"%s-accel" , st->name);if (!name) -return ERR_PTR (-ENOMEM ); +return -ENOMEM ; indio_dev =devm_iio_device_alloc (dev,sizeof (*accel_st));if (!indio_dev) -return ERR_PTR (-ENOMEM ); +return -ENOMEM ; accel_st =iio_priv (indio_dev);switch (st->chip) {
@@ -1189,18 +1188,18 @@ struct iio_dev *inv_icm42600_accel_init(struct inv_icm42600_state *st) ret =devm_iio_kfifo_buffer_setup (dev, indio_dev, &inv_icm42600_buffer_ops);if (ret) -return ERR_PTR (ret); +return ret; ret =devm_iio_device_register (dev, indio_dev);if (ret) -return ERR_PTR (ret); +return ret;/* accel events are wakeup capable */ ret =devm_device_init_wakeup (&indio_dev->dev);if (ret) -return ERR_PTR (ret); +return ret; -return indio_dev; +return 0 ; }int inv_icm42600_accel_parse_fifo (struct iio_dev *indio_dev)
drivers/iio/imu/inv_icm42600/inv_icm42600_core.c +151 -106
291 lines not on this page · raw message
drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c +6 -7
@@ -725,22 +725,21 @@ static const struct iio_info inv_icm42600_gyro_info = { .hwfifo_flush_to_buffer = inv_icm42600_gyro_hwfifo_flush, }; -struct iio_dev *inv_icm42600_gyro_init (struct inv_icm42600_state *st) +int inv_icm42600_gyro_init (struct inv_icm42600_state *st,struct iio_dev *indio_dev) {struct device *dev =regmap_get_device (st->map);const char *name;struct inv_icm42600_sensor_state *gyro_st;struct inv_sensors_timestamp_chip ts_chip; -struct iio_dev *indio_dev;int ret; name =devm_kasprintf (dev,GFP_KERNEL ,"%s-gyro" , st->name);if (!name) -return ERR_PTR (-ENOMEM ); +return -ENOMEM ; indio_dev =devm_iio_device_alloc (dev,sizeof (*gyro_st));if (!indio_dev) -return ERR_PTR (-ENOMEM ); +return -ENOMEM ; gyro_st =iio_priv (indio_dev);switch (st->chip) {
@@ -775,13 +774,13 @@ struct iio_dev *inv_icm42600_gyro_init(struct inv_icm42600_state *st) ret =devm_iio_kfifo_buffer_setup (dev, indio_dev, &inv_icm42600_buffer_ops);if (ret) -return ERR_PTR (ret); +return ret; ret =devm_iio_device_register (dev, indio_dev);if (ret) -return ERR_PTR (ret); +return ret; -return indio_dev; +return 0 ; }int inv_icm42600_gyro_parse_fifo (struct iio_dev *indio_dev)
Signature · 1 line
2.43.0
Jonathan Cameron
maintainerRe: [PATCH V2 2/5] iio: imu: inv_icm42600: Add support for using alternate registers
Quoted 15 lines · On Thu, 19 Mar 2026 13:29:38 -0500 Chris Morgan <[email protected]> wrote:
From: Chris Morgan <[email protected]>
Add support to the existing
inv_icm42600to support similar hardware with slightly different register layouts. For example the icm42607 and icm42607p has most of the same functionality and even many of the same registers, but the addresses for indiviual registers differ.Signed-off-by Chris Morgan <[email protected]>drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c +0
-0
drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c struct iio_dev *inv_icm42600_gyro_init(struct inv_icm42600_state *st) · line 779
Quoted 7 lines
drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c +1
-1@@ -775,13 +774,13 @@ struct iio_dev *inv_icm42600_gyro_init(struct inv_icm42600_state *st) ret =devm_iio_kfifo_buffer_setup (dev, indio_dev, &inv_icm42600_buffer_ops);if (ret) -return ERR_PTR (ret); +return ret; ret =devm_iio_device_register (dev, indio_dev);
return devm_iio_device_register() now make sense.
PATCH v2 3/5 iio: imu: inv_icm42600: Add registers for icm42607
In reply to Chris MorganFrom: Chris Morgan <[email protected]>
Add the register layout for the icm_42607. Most of the registers are similar to that of the icm42600, though at different addresses.
--- drivers/iio/imu/inv_icm42600/inv_icm42600.h | 284 ++++++++++++++++++++ 1 file changed, 284 insertions(+)
drivers/iio/imu/inv_icm42600/inv_icm42600.h +284 -0
@@ -22,6 +22,8 @@ enum inv_icm42600_chip {INV_CHIP_ICM42600 ,INV_CHIP_ICM42602 ,INV_CHIP_ICM42605 , +INV_CHIP_ICM42607 , +INV_CHIP_ICM42607P ,INV_CHIP_ICM42686 ,INV_CHIP_ICM42622 , INV_CHIP_ICM42688,
@@ -70,6 +72,13 @@ enum inv_icm42686_gyro_fs {INV_ICM42686_GYRO_FS_31_25DPS , INV_ICM42686_GYRO_FS_NB, }; +enum inv_icm42607_gyro_fs { +INV_ICM42607_GYRO_FS_2000DPS , +INV_ICM42607_GYRO_FS_1000DPS , +INV_ICM42607_GYRO_FS_500DPS , +INV_ICM42607_GYRO_FS_250DPS , +INV_ICM42607_GYRO_FS_NB +};/* accelerometer fullscale values */ enum inv_icm42600_accel_fs {
@@ -106,6 +115,21 @@ enum inv_icm42600_odr { INV_ICM42600_ODR_NB, }; +enum inv_icm42607_odr { +INV_ICM42607_ODR_1600HZ =5 , +INV_ICM42607_ODR_800HZ , +INV_ICM42607_ODR_400HZ , +INV_ICM42607_ODR_200HZ , +INV_ICM42607_ODR_100HZ , +INV_ICM42607_ODR_50HZ , +INV_ICM42607_ODR_25HZ , +INV_ICM42607_ODR_12_5HZ , +INV_ICM42607_ODR_6_25HZ_LP , +INV_ICM42607_ODR_3_125HZ_LP , +INV_ICM42607_ODR_1_5625HZ_LP , +INV_ICM42607_ODR_NB +}; +enum inv_icm42600_filter {/* Low-Noise mode sensor data filter (3rd order filter by default) */ INV_ICM42600_FILTER_BW_ODR_DIV_2 ,
@@ -115,6 +139,26 @@ enum inv_icm42600_filter { INV_ICM42600_FILTER_AVG_16X = 6, }; +enum inv_icm42607_filter { +/* Low-Noise mode sensor data filter */ +INV_ICM42607_FILTER_BYPASS , +INV_ICM42607_FILTER_BW_180HZ , +INV_ICM42607_FILTER_BW_121HZ , +INV_ICM42607_FILTER_BW_73HZ , +INV_ICM42607_FILTER_BW_53HZ , +INV_ICM42607_FILTER_BW_34HZ , +INV_ICM42607_FILTER_BW_25HZ , +INV_ICM42607_FILTER_BW_16HZ , + +/* Low-Power mode sensor data filter (averaging) */ +INV_ICM42607_FILTER_AVG_2X =0 , +INV_ICM42607_FILTER_AVG_4X , +INV_ICM42607_FILTER_AVG_8X , +INV_ICM42607_FILTER_AVG_16X , +INV_ICM42607_FILTER_AVG_32X , +INV_ICM42607_FILTER_AVG_64X , +}; +struct inv_icm42600_sensor_conf {int mode;int fs;
@@ -453,6 +497,246 @@ struct inv_icm42600_sensor_state {#define INV_ICM42600_REG_OFFSET_USER7 0x407E#define INV_ICM42600_REG_OFFSET_USER8 0x407F +/* ICM42607 Specific registers. */ + +/* Virtual register addresses: @bank on MSB (4 upper bits), @address on LSB */ + +/* Register Map for User Bank 0 */ +#define INV_ICM42607_REG_DEVICE_CONFIG 0x01 +#define INV_ICM42607_DEVICE_CONFIG_SPI_AP_4WIRE BIT(2) +#define INV_ICM42607_DEVICE_CONFIG_SPI_MODE BIT(0) + +#define INV_ICM42607_REG_SIGNAL_PATH_RESET 0x02 +#define INV_ICM42607_SIGNAL_PATH_RESET_SOFT_RESET BIT(4) +#define INV_ICM42607_SIGNAL_PATH_RESET_FIFO_FLUSH BIT(2) + +#define INV_ICM42607_REG_DRIVE_CONFIG1 0x03 +#define INV_ICM42607_DRIVE_CONFIG1_I3C_DDR_MASK GENMASK(5, 3) +#define INV_ICM42607_DRIVE_CONFIG1_I3C_DDR (_rate) \ +FIELD_PREP(INV_ICM42607_DRIVE_CONFIG1_I3C_DDR_MASK, (_rate)) +#define INV_ICM42607_DRIVE_CONFIG1_I3C_SDR_MASK GENMASK(2, 0) +#define INV_ICM42607_DRIVE_CONFIG1_I3C_SDR (_rate) \ +FIELD_PREP(INV_ICM42607_DRIVE_CONFIG1_I3C_SDR_MASK, (_rate)) + +#define INV_ICM42607_REG_DRIVE_CONFIG2 0x04 +#define INV_ICM42607_DRIVE_CONFIG2_I2C_MASK GENMASK(5, 3) +#define INV_ICM42607_DRIVE_CONFIG2_I2C (_rate) \ +FIELD_PREP(INV_ICM42607_DRIVE_CONFIG2_I2C_MASK, (_rate)) +#define INV_ICM42607_DRIVE_CONFIG2_ALL_MASK GENMASK(2, 0) +#define INV_ICM42607_DRIVE_CONFIG2_ALL (_rate) \ +FIELD_PREP(INV_ICM42607_DRIVE_CONFIG2_ALL_MASK, (_rate)) + +#define INV_ICM42607_REG_DRIVE_CONFIG3 0x05 +#define INV_ICM42607_DRIVE_CONFIG3_SPI_MASK GENMASK(2, 0) +#define INV_ICM42607_DRIVE_CONFIG3_SPI (_rate) \ +FIELD_PREP(INV_ICM42607_DRIVE_CONFIG3_SPI_MASK, (_rate)) + +#define INV_ICM42607_REG_INT_CONFIG 0x06 +#define INV_ICM42607_INT_CONFIG_INT2_LATCHED BIT(5) +#define INV_ICM42607_INT_CONFIG_INT2_PUSH_PULL BIT(4) +#define INV_ICM42607_INT_CONFIG_INT2_ACTIVE_HIGH BIT(3) +#define INV_ICM42607_INT_CONFIG_INT2_ACTIVE_LOW 0x00 +#define INV_ICM42607_INT_CONFIG_INT1_LATCHED BIT(2) +#define INV_ICM42607_INT_CONFIG_INT1_PUSH_PULL BIT(1) +#define INV_ICM42607_INT_CONFIG_INT1_ACTIVE_HIGH BIT(0) +#define INV_ICM42607_INT_CONFIG_INT1_ACTIVE_LOW 0x00 + +/* all sensor data are 16 bits (2 registers wide) in big-endian */ +#define INV_ICM42607_REG_TEMP_DATA1 0x09 +#define INV_ICM42607_REG_TEMP_DATA0 0x0A +#define INV_ICM42607_REG_ACCEL_DATA_X1 0x0B +#define INV_ICM42607_REG_ACCEL_DATA_X0 0x0C +#define INV_ICM42607_REG_ACCEL_DATA_Y1 0x0D +#define INV_ICM42607_REG_ACCEL_DATA_Y0 0x0E +#define INV_ICM42607_REG_ACCEL_DATA_Z1 0x0F +#define INV_ICM42607_REG_ACCEL_DATA_Z0 0x10 +#define INV_ICM42607_REG_GYRO_DATA_X1 0x11 +#define INV_ICM42607_REG_GYRO_DATA_X0 0x12 +#define INV_ICM42607_REG_GYRO_DATA_Y1 0x13 +#define INV_ICM42607_REG_GYRO_DATA_Y0 0x14 +#define INV_ICM42607_REG_GYRO_DATA_Z1 0x15 +#define INV_ICM42607_REG_GYRO_DATA_Z0 0x16 +#define INV_ICM42607_DATA_INVALID -32768 + +#define INV_ICM42607_REG_TMST_FSYNCH 0x17 +#define INV_ICM42607_REG_TMST_FSYNCL 0x18 + +/* APEX Data Registers */ +#define INV_ICM42607_REG_APEX_DATA0 0x31 +#define INV_ICM42607_REG_APEX_DATA1 0x32 +#define INV_ICM42607_REG_APEX_DATA2 0x33 +#define INV_ICM42607_REG_APEX_DATA3 0x34 +#define INV_ICM42607_REG_APEX_DATA4 0x1D +#define INV_ICM42607_REG_APEX_DATA5 0x1E + +#define INV_ICM42607_REG_PWR_MGMT0 0x1F +#define INV_ICM42607_PWR_MGMT0_ACCEL_LP_CLK_SEL BIT(7) +#define INV_ICM42607_PWR_MGMT0_IDLE BIT(4) +#define INV_ICM42607_PWR_MGMT0_GYRO_MODE_MASK GENMASK(3, 2) +#define INV_ICM42607_PWR_MGMT0_GYRO (_mode) \ +FIELD_PREP(INV_ICM42607_PWR_MGMT0_GYRO_MODE_MASK, (_mode)) +#define INV_ICM42607_PWR_MGMT0_ACCEL_MODE_MASK GENMASK(1, 0) +#define INV_ICM42607_PWR_MGMT0_ACCEL (_mode) \ +FIELD_PREP(INV_ICM42607_PWR_MGMT0_ACCEL_MODE_MASK, (_mode)) + +#define INV_ICM42607_REG_GYRO_CONFIG0 0x20 +#define INV_ICM42607_GYRO_CONFIG0_FS_SEL_MASK GENMASK(6, 5) +#define INV_ICM42607_GYRO_CONFIG0_FS_SEL (_fs) \ +FIELD_PREP(INV_ICM42607_GYRO_CONFIG0_FS_SEL_MASK, (_fs)) +#define INV_ICM42607_GYRO_CONFIG0_ODR_MASK GENMASK(3, 0) +#define INV_ICM42607_GYRO_CONFIG0_ODR (_odr) \ +FIELD_PREP(INV_ICM42607_GYRO_CONFIG0_ODR_MASK, (_odr)) + +#define INV_ICM42607_REG_ACCEL_CONFIG0 0x21 +#define INV_ICM42607_ACCEL_CONFIG0_FS_SEL_MASK GENMASK(6, 5) +#define INV_ICM42607_ACCEL_CONFIG0_FS_SEL (_fs) \ +FIELD_PREP(INV_ICM42607_ACCEL_CONFIG0_FS_SEL_MASK, (_fs)) +#define INV_ICM42607_ACCEL_CONFIG0_ODR_MASK GENMASK(3, 0) +#define INV_ICM42607_ACCEL_CONFIG0_ODR (_odr) \ +FIELD_PREP(INV_ICM42607_ACCEL_CONFIG0_ODR_MASK, (_odr)) + +#define INV_ICM42607_REG_TEMP_CONFIG0 0x22 +#define INV_ICM42607_TEMP_CONFIG0_FILTER_MASK GENMASK(6, 4) +#define INV_ICM42607_TEMP_CONFIG0_FILTER (_filter) \ +FIELD_PREP(INV_ICM42607_TEMP_CONFIG0_FILTER_MASK, (_filter)) + +#define INV_ICM42607_REG_GYRO_CONFIG1 0x23 +#define INV_ICM42607_GYRO_CONFIG1_FILTER_MASK GENMASK(2, 0) +#define INV_ICM42607_GYRO_CONFIG1_FILTER (_filter) \ +FIELD_PREP(INV_ICM42607_GYRO_CONFIG1_FILTER_MASK, (_filter)) + +#define INV_ICM42607_REG_ACCEL_CONFIG1 0x24 +#define INV_ICM42607_ACCEL_CONFIG1_AVG_MASK GENMASK(6, 4) +#define INV_ICM42607_ACCEL_CONFIG1_AVG (_avg) \ +FIELD_PREP(INV_ICM42607_ACCEL_CONFIG1_AVG_MASK, (_avg)) +#define INV_ICM42607_ACCEL_CONFIG1_FILTER_MASK GENMASK(2, 0) +#define INV_ICM42607_ACCEL_CONFIG1_FILTER (_filter) \ +FIELD_PREP(INV_ICM42607_ACCEL_CONFIG1_FILTER_MASK, (_filter)) + +#define INV_ICM42607_REG_APEX_CONFIG0 0x25 +#define INV_ICM42607_APEX_CONFIG0_DMP_POWER_SAVE_EN BIT(3) +#define INV_ICM42607_APEX_CONFIG0_DMP_INIT_EN BIT(2) +#define INV_ICM42607_APEX_CONFIG0_DMP_MEM_RESET_EN BIT(0) + +#define INV_ICM42607_REG_APEX_CONFIG1 0x26 +#define INV_ICM42607_APEX_CONFIG1_SMD_ENABLE BIT(6) +#define INV_ICM42607_APEX_CONFIG1_FF_ENABLE BIT(5) +#define INV_ICM42607_APEX_CONFIG1_TILT_ENABLE BIT(4) +#define INV_ICM42607_APEX_CONFIG1_PED_ENABLE BIT(3) +#define INV_ICM42607_APEX_CONFIG1_DMP_ODR_MASK GENMASK(1, 0) +#define INV_ICM42607_APEX_CONFIG1_DMP_ODR (_odr) \ +FIELD_PREP(INV_ICM42607_APEX_CONFIG1_DMP_ODR_MASK, (_odr)) + +#define INV_ICM42607_REG_WOM_CONFIG 0x27 +#define INV_ICM42607_WOM_CONFIG_INT_DUR_MASK GENMASK(4, 3) +#define INV_ICM42607_WOM_CONFIG_INT_DUR (_dur) \ +FIELD_PREP(INV_ICM42607_WOM_CONFIG_INT_DUR_MASK, (_dur)) +#define INV_ICM42607_WOM_CONFIG_INT_MODE BIT(2) +#define INV_ICM42607_WOM_CONFIG_MODE BIT(1) +#define INV_ICM42607_WOM_CONFIG_EN BIT(0) + +#define INV_ICM42607_REG_FIFO_CONFIG1 0x28 +#define INV_ICM42607_FIFO_CONFIG1_MODE BIT(1) +#define INV_ICM42607_FIFO_CONFIG1_BYPASS BIT(0) + +#define INV_ICM42607_REG_FIFO_CONFIG2 0x29 +#define INV_ICM42607_REG_FIFO_CONFIG3 0x2A +#define INV_ICM42607_FIFO_WATERMARK_VAL (_wm) \ + cpu_to_le16((_wm) & GENMASK(11, 0)) +/* FIFO is 2048 bytes, let 12 samples for reading latency */ +#define INV_ICM42607_FIFO_WATERMARK_MAX (2048 - 12 * 16) + +#define INV_ICM42607_REG_INT_SOURCE0 0x2B +#define INV_ICM42607_INT_SOURCE0_ST_INT1_EN BIT(7) +#define INV_ICM42607_INT_SOURCE0_FSYNC_INT1_EN BIT(6) +#define INV_ICM42607_INT_SOURCE0_PLL_RDY_INT1_EN BIT(5) +#define INV_ICM42607_INT_SOURCE0_RESET_DONE_INT1_EN BIT(4) +#define INV_ICM42607_INT_SOURCE0_DRDY_INT1_EN BIT(3) +#define INV_ICM42607_INT_SOURCE0_FIFO_THS_INT1_EN BIT(2) +#define INV_ICM42607_INT_SOURCE0_FIFO_FULL_INT1_EN BIT(1) +#define INV_ICM42607_INT_SOURCE0_AGC_RDY_INT1_EN BIT(0) + +#define INV_ICM42607_REG_INT_SOURCE1 0x2C +#define INV_ICM42607_INT_SOURCE1_I3C_ERROR_INT1_EN BIT(6) +#define INV_ICM42607_INT_SOURCE1_SMD_INT1_EN BIT(3) +#define INV_ICM42607_INT_SOURCE1_WOM_INT1_EN GENMASK(2, 0) + +#define INV_ICM42607_REG_INT_SOURCE3 0x2D +#define INV_ICM42607_INT_SOURCE3_ST_INT2_EN BIT(7) +#define INV_ICM42607_INT_SOURCE3_FSYNC_INT2_EN BIT(6) +#define INV_ICM42607_INT_SOURCE3_PLL_RDY_INT2_EN BIT(5) +#define INV_ICM42607_INT_SOURCE3_RESET_DONE_INT2_EN BIT(4) +#define INV_ICM42607_INT_SOURCE3_DRDY_INT2_EN BIT(3) +#define INV_ICM42607_INT_SOURCE3_FIFO_THS_INT2_EN BIT(2) +#define INV_ICM42607_INT_SOURCE3_FIFO_FULL_INT2_EN BIT(1) +#define INV_ICM42607_INT_SOURCE3_AGC_RDY_INT2_EN BIT(0) + +#define INV_ICM42607_REG_INT_SOURCE4 0x2E +#define INV_ICM42607_INT_SOURCE4_I3C_ERROR_INT2_EN BIT(6) +#define INV_ICM42607_INT_SOURCE4_SMD_INT2_EN BIT(3) +#define INV_ICM42607_INT_SOURCE4_WOM_Z_INT2_EN BIT(2) +#define INV_ICM42607_INT_SOURCE4_WOM_Y_INT2_EN BIT(1) +#define INV_ICM42607_INT_SOURCE4_WOM_X_INT2_EN BIT(0) + +#define INV_ICM42607_REG_FIFO_LOST_PKT0 0x2F +#define INV_ICM42607_REG_FIFO_LOST_PKT1 0x30 + +#define INV_ICM42607_REG_INTF_CONFIG0 0x35 +#define INV_ICM42607_INTF_CONFIG0_FIFO_COUNT_FORMAT BIT(6) +#define INV_ICM42607_INTF_CONFIG0_FIFO_COUNT_ENDIAN BIT(5) +#define INV_ICM42607_INTF_CONFIG0_SENSOR_DATA_ENDIAN BIT(4) +#define INV_ICM42607_INTF_CONFIG0_UI_SIFS_CFG_MASK GENMASK(1, 0) +#define INV_ICM42607_INTF_CONFIG0_UI_SIFS_CFG_SPI_DIS \ +FIELD_PREP(INV_ICM42607_INTF_CONFIG0_UI_SIFS_CFG_MASK, 2) +#define INV_ICM42607_INTF_CONFIG0_UI_SIFS_CFG_I2C_DIS \ +FIELD_PREP(INV_ICM42607_INTF_CONFIG0_UI_SIFS_CFG_MASK, 3) + +#define INV_ICM42607_REG_INTF_CONFIG1 0x36 +#define INV_ICM42607_INTF_CONFIG1_I3C_SDR_EN BIT(3) +#define INV_ICM42607_INTF_CONFIG1_I3C_DDR_EN BIT(2) +#define INV_ICM42607_INTF_CONFIG1_CLKSEL_MASK GENMASK(1, 0) +#define INV_ICM42607_INTF_CONFIG1_CLKSEL_PLL \ +FIELD_PREP(INV_ICM42607_INTF_CONFIG1_CLKSEL_MASK, 1) + +#define INV_ICM42607_REG_INT_STATUS_DRDY 0x39 +#define INV_ICM42607_INT_STATUS_DRDY_DATA_RDY BIT(0) + +#define INV_ICM42607_REG_INT_STATUS 0x3A +#define INV_ICM42607_INT_STATUS_ST BIT(7) +#define INV_ICM42607_INT_STATUS_FSYNC BIT(6) +#define INV_ICM42607_INT_STATUS_PLL_RDY BIT(5) +#define INV_ICM42607_INT_STATUS_RESET_DONE BIT(4) +#define INV_ICM42607_INT_STATUS_FIFO_THS BIT(2) +#define INV_ICM42607_INT_STATUS_FIFO_FULL BIT(1) +#define INV_ICM42607_INT_STATUS_AGC_RDY BIT(0) + +#define INV_ICM42607_REG_INT_STATUS2 0x3B +#define INV_ICM42607_INT_STATUS2_SMD BIT(3) +#define INV_ICM42607_INT_STATUS2_WOM_INT GENMASK(2, 0) + +#define INV_ICM42607_REG_INT_STATUS3 0x3C +#define INV_ICM42607_INT_STATUS3_STEP_DET BIT(5) +#define INV_ICM42607_INT_STATUS3_STEP_CNT_OVF BIT(4) +#define INV_ICM42607_INT_STATUS3_TILT_DET BIT(3) +#define INV_ICM42607_INT_STATUS3_FF_DET BIT(2) + +/* +* FIFO access registers +* FIFO count is 16 bits (2 registers) big-endian +* FIFO data is a continuous read register to read FIFO content +*/ +#define INV_ICM42607_REG_FIFO_COUNTH 0x3D +#define INV_ICM42607_REG_FIFO_COUNTL 0x3E +#define INV_ICM42607_REG_FIFO_DATA 0x3F + +#define INV_ICM42607_REG_ACCEL_WOM_X_THR 0x4b +#define INV_ICM42607_REG_ACCEL_WOM_Y_THR 0x4c +#define INV_ICM42607_REG_ACCEL_WOM_Z_THR 0x4d + +#define INV_ICM42607_REG_WHOAMI 0x75 +#define INV_ICM42607P_WHOAMI 0x60 +#define INV_ICM42607_WHOAMI 0x67 +/* Sleep times required by the driver */ #define INV_ICM42600_POWER_UP_TIME_MS 100#define INV_ICM42600_RESET_TIME_MS 1
Signature · 1 line
2.43.0
Jonathan Cameron
maintainerRe: [PATCH V2 3/5] iio: imu: inv_icm42600: Add registers for icm42607
Quoted 6 lines · On Thu, 19 Mar 2026 13:29:39 -0500 Chris Morgan <[email protected]> wrote:
From: Chris Morgan <[email protected]>
Add the register layout for the
icm_42607. Most of the registers are similar to that of the icm42600, though at different addresses.Signed-off-by Chris Morgan <[email protected]>
Hi Chris,
Just taking a quick look given Jean-Baptiste's concerns about doing this in the existing driver.
Thanks,
Jonathan
Quoted 8 lines
drivers/iio/imu/inv_icm42600/inv_icm42600.h +7
-0+/* ICM42607 Specific registers. */ + +/* Virtual register addresses: @bank on MSB (4 upper bits), @address on LSB */ + +/* Register Map for User Bank 0 */ +#define INV_ICM42607_REG_DEVICE_CONFIG 0x01 +#define INV_ICM42607_DEVICE_CONFIG_SPI_AP_4WIRE BIT(2)
drivers/iio/imu/inv_icm42600/inv_icm42600.h struct inv_icm42600_sensor_state { · line 516
Quoted 10 lines
drivers/iio/imu/inv_icm42600/inv_icm42600.h +10
-0+#define INV_ICM42607_DEVICE_CONFIG_SPI_MODE BIT(0) + +#define INV_ICM42607_REG_SIGNAL_PATH_RESET 0x02 +#define INV_ICM42607_SIGNAL_PATH_RESET_SOFT_RESET BIT(4) +#define INV_ICM42607_SIGNAL_PATH_RESET_FIFO_FLUSH BIT(2) + +#define INV_ICM42607_REG_DRIVE_CONFIG1 0x03 +#define INV_ICM42607_DRIVE_CONFIG1_I3C_DDR_MASK GENMASK(5, 3) +#define INV_ICM42607_DRIVE_CONFIG1_I3C_DDR (_rate) \ +FIELD_PREP(INV_ICM42607_DRIVE_CONFIG1_I3C_DDR_MASK, (_rate))
I'd indent the second line of these two line defines to make it easier to see it's a continuation.
Quoted 3 lines
drivers/iio/imu/inv_icm42600/inv_icm42600.h +3
-0+#define INV_ICM42607_DRIVE_CONFIG1_I3C_SDR_MASK GENMASK(2, 0) +#define INV_ICM42607_DRIVE_CONFIG1_I3C_SDR (_rate) \ +FIELD_PREP(INV_ICM42607_DRIVE_CONFIG1_I3C_SDR_MASK, (_rate))
PATCH v2 4/5 iio: imu: inv_icm42600: Add support for icm42607
In reply to Chris MorganFrom: Chris Morgan <[email protected]>
Add support for the icm42607 and icm42607p over both I2C and SPI. Note that at this time only the icm42607 over i2c has been tested.
This driver was updated based on the existing icm42600 along with the datasheet from Invensense and out-of-tree sources included in the LineageOS kernels [1] and Rockchip kernels [2], both derived from sources provided by Invensense.
[1] https://github.com/LineageOS/android_kernel_nvidia_kernel-nx/tree/lineage-23.0/drivers/iio/imu/inv_icm42607x
[2] https://github.com/rockchip-linux/kernel/tree/develop-6.6/drivers/iio/imu/inv_icm42670
--- drivers/iio/imu/inv_icm42600/inv_icm42600.h | 25 +- .../iio/imu/inv_icm42600/inv_icm42600_accel.c | 482 +++++++++++++++- .../imu/inv_icm42600/inv_icm42600_buffer.c | 240 +++++++- .../imu/inv_icm42600/inv_icm42600_buffer.h | 5 + .../iio/imu/inv_icm42600/inv_icm42600_core.c | 544 +++++++++++++++++- .../iio/imu/inv_icm42600/inv_icm42600_gyro.c | 366 +++++++++++- .../iio/imu/inv_icm42600/inv_icm42600_i2c.c | 53 +- .../iio/imu/inv_icm42600/inv_icm42600_spi.c | 59 +- .../iio/imu/inv_icm42600/inv_icm42600_temp.c | 64 +++ .../iio/imu/inv_icm42600/inv_icm42600_temp.h | 4 + 10 files changed, 1799 insertions(+), 43 deletions(-)
drivers/iio/imu/inv_icm42600/inv_icm42600.h +22 -3
@@ -262,7 +262,7 @@ struct inv_icm42600_sensor_state {const int *scales;size_t scales_len;enum inv_icm42600_sensor_mode power_mode; -enum inv_icm42600_filter filter; +int filter;/* either inv_icm42600_filter or inv_icm42607_filter */ struct inv_sensors_timestamp ts; };
@@ -748,6 +748,7 @@ FIELD_PREP(INV_ICM42607_INTF_CONFIG1_CLKSEL_MASK, 1)extern const struct regmap_config inv_icm42600_regmap_config;extern const struct regmap_config inv_icm42600_spi_regmap_config; +extern const struct regmap_config inv_icm42607_regmap_config;extern const struct dev_pm_ops inv_icm42600_pm_ops; const struct iio_mount_matrix *
@@ -755,20 +756,32 @@ inv_icm42600_get_mount_matrix(const struct iio_dev *indio_dev, const struct iio_chan_spec *chan);u32 inv_icm42600_odr_to_period (enum inv_icm42600_odr odr); +u32 inv_icm42607_odr_to_period (enum inv_icm42607_odr odr);int inv_icm42600_set_accel_conf (struct inv_icm42600_state *st,struct inv_icm42600_sensor_conf *conf,unsigned int *sleep_ms); +int inv_icm42607_set_accel_conf (struct inv_icm42600_state *st, +struct inv_icm42600_sensor_conf *conf, +unsigned int *sleep_ms);int inv_icm42600_set_gyro_conf (struct inv_icm42600_state *st,struct inv_icm42600_sensor_conf *conf,unsigned int *sleep_ms); +int inv_icm42607_set_gyro_conf (struct inv_icm42600_state *st, +struct inv_icm42600_sensor_conf *conf, +unsigned int *sleep_ms);int inv_icm42600_set_temp_conf (struct inv_icm42600_state *st,bool enable,unsigned int *sleep_ms); +int inv_icm42607_set_temp_conf (struct inv_icm42600_state *st,bool enable, +unsigned int *sleep_ms);int inv_icm42600_enable_wom (struct inv_icm42600_state *st); +int inv_icm42607_enable_wom (struct inv_icm42600_state *st); +int inv_icm42600_disable_wom (struct inv_icm42600_state *st); +int inv_icm42607_disable_wom (struct inv_icm42600_state *st);int inv_icm42600_debugfs_reg (struct iio_dev *indio_dev,unsigned int reg,unsigned int writeval,unsigned int *readval);
@@ -776,11 +789,17 @@ int inv_icm42600_debugfs_reg(struct iio_dev *indio_dev, unsigned int reg,int inv_icm42600_core_probe (struct regmap *regmap,int chip,inv_icm42600_bus_setup bus_setup); -int inv_icm42600_gyro_init (struct inv_icm42600_state *st,struct iio_dev *indio_dev); +int inv_icm42600_gyro_init (struct inv_icm42600_state *st, +struct iio_dev *indio_dev); +int inv_icm42607_gyro_init (struct inv_icm42600_state *st, +struct iio_dev *indio_dev);int inv_icm42600_gyro_parse_fifo (struct iio_dev *indio_dev); -int inv_icm42600_accel_init (struct inv_icm42600_state *st,struct iio_dev *indio_dev); +int inv_icm42600_accel_init (struct inv_icm42600_state *st, +struct iio_dev *indio_dev); +int inv_icm42607_accel_init (struct inv_icm42600_state *st, +struct iio_dev *indio_dev);int inv_icm42600_accel_parse_fifo (struct iio_dev *indio_dev);
drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c +473 -9
613 lines not on this page · raw message
drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c +235 -5
324 lines not on this page · raw message
drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h +5 -0
@@ -79,13 +79,18 @@ ssize_t inv_icm42600_fifo_decode_packet(const void *packet, const void **accel, const void **timestamp, unsigned int *odr);extern const struct iio_buffer_setup_ops inv_icm42600_buffer_ops; +extern const struct iio_buffer_setup_ops inv_icm42607_buffer_ops;int inv_icm42600_buffer_init (struct inv_icm42600_state *st); +int inv_icm42607_buffer_init (struct inv_icm42600_state *st);void inv_icm42600_buffer_update_fifo_period (struct inv_icm42600_state *st); +void inv_icm42607_buffer_update_fifo_period (struct inv_icm42600_state *st);int inv_icm42600_buffer_set_fifo_en (struct inv_icm42600_state *st,unsigned int fifo_en); +int inv_icm42607_buffer_set_fifo_en (struct inv_icm42600_state *st, +unsigned int fifo_en);int inv_icm42600_buffer_update_watermark (struct inv_icm42600_state *st);
drivers/iio/imu/inv_icm42600/inv_icm42600_core.c +534 -10
670 lines not on this page · raw message
drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c +361 -5
451 lines not on this page · raw message
drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c +48 -5
77 lines not on this page · raw message
drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c +53 -6
83 lines not on this page · raw message
drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c +64 -0
73 lines not on this page · raw message
drivers/iio/imu/inv_icm42600/inv_icm42600_temp.h +4 -0
@@ -27,4 +27,8 @@ int inv_icm42600_temp_read_raw(struct iio_dev *indio_dev,struct iio_chan_spec const *chan, int *val, int *val2, long mask); +int inv_icm42607_temp_read_raw (struct iio_dev *indio_dev, +struct iio_chan_spec const *chan, +int *val,int *val2,long mask); +#endif
Signature · 1 line
2.43.0
kernel test robot
build botRe: [PATCH V2 4/5] iio: imu: inv_icm42600: Add support for icm42607
kernel test robot noticed the following build warnings:
Hi Chris,
kernel test robot noticed the following build warnings:
[auto build test WARNING on rockchip/for-next]
[also build test WARNING on linus/master v7.0-rc4 next-20260320] [cannot apply to jic23-iio/togreg]
[If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Chris-Morgan/dt-bindings-iio-imu-add-icm42607/20260320-061927 base: https://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git for-next patch link: https://lore.kernel.org/r/20260319182956.146976-5-macroalpha82%40gmail.com patch subject: [PATCH V2 4/5] iio: imu: inv_icm42600: Add support for icm42607 config: i386-buildonly-randconfig-003-20260320 (https://download.01.org/0day-ci/archive/20260321/[email protected]/config) compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260321/[email protected]/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
All warnings (new ones prefixed by >>):
>> drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c:108:18: warning: unused variable 'inv_icm42607_accel_filter_values' [-Wunused-const-variable]
108 | static const int inv_icm42607_accel_filter_values[] = {
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~1 warning generated.
vim +/inv_icm42607_accel_filter_values +108 drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c
95
96 static const char * const inv_icm42600_accel_power_mode_items[] = {
97 "low-noise",
98 "low-power",
99 };
100 static const int inv_icm42600_accel_power_mode_values[] = {
101 INV_ICM42600_SENSOR_MODE_LOW_NOISE,
102 INV_ICM42600_SENSOR_MODE_LOW_POWER,
103 };
104 static const int inv_icm42600_accel_filter_values[] = {
105 INV_ICM42600_FILTER_BW_ODR_DIV_2,
106 INV_ICM42600_FILTER_AVG_16X,
107 };
> 108 static const int inv_icm42607_accel_filter_values[] = { 109 INV_ICM42607_FILTER_BW_25HZ,
110 INV_ICM42607_FILTER_AVG_16X,
111 };
112
Signature · 2 lines
0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
kernel test robot
build botRe: [PATCH V2 4/5] iio: imu: inv_icm42600: Add support for icm42607
In reply to Chris Morgankernel test robot noticed the following build warnings:
Hi Chris,
kernel test robot noticed the following build warnings:
[auto build test WARNING on rockchip/for-next]
[also build test WARNING on linus/master v7.0-rc4 next-20260320] [cannot apply to jic23-iio/togreg]
[If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Chris-Morgan/dt-bindings-iio-imu-add-icm42607/20260320-061927 base: https://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git for-next patch link: https://lore.kernel.org/r/20260319182956.146976-5-macroalpha82%40gmail.com patch subject: [PATCH V2 4/5] iio: imu: inv_icm42600: Add support for icm42607 config: i386-randconfig-r134-20260320 (https://download.01.org/0day-ci/archive/20260321/[email protected]/config) compiler: gcc-13 (Debian 13.3.0-16) 13.3.0 sparse: v0.6.5-rc1 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260321/[email protected]/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
All warnings (new ones prefixed by >>):
drivers/iio/imu/inv_icm42600/inv_icm42600_core.c: In function 'inv_icm42607_hw_suspend':
>> drivers/iio/imu/inv_icm42600/inv_icm42600_core.c:1150:13: warning: variable 'accel_conf' set but not used [-Wunused-but-set-variable]
1150 | int accel_conf;
| ^~~~~~~~~~
--
>> drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c:108:18: warning: 'inv_icm42607_accel_filter_values' defined but not used [-Wunused-const-variable=]
108 | static const int inv_icm42607_accel_filter_values[] = {
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~vim +/accel_conf +1150 drivers/iio/imu/inv_icm42600/inv_icm42600_core.c
1144
1145 static int inv_icm42607_hw_suspend(struct device *dev)
1146 {
1147 struct inv_icm42600_state *st = dev_get_drvdata(dev);
1148 struct device *accel_dev;
1149 bool wakeup;
> 1150 int accel_conf;
1151 int ret = 0;
1152
1153 guard(mutex)(&st->lock);
1154
1155 st->suspended.gyro = st->conf.gyro.mode;
1156 st->suspended.accel = st->conf.accel.mode;
1157 st->suspended.temp = st->conf.temp_en;
1158 if (pm_runtime_suspended(dev))
1159 return 0;
1160
1161 if (st->fifo.on) {
1162 ret = regmap_write(st->map, INV_ICM42607_REG_FIFO_CONFIG1,
1163 INV_ICM42607_FIFO_CONFIG1_BYPASS);
1164 if (ret)
1165 return ret;
1166 }
1167
1168 /* keep chip on and wake-up capable if APEX and wakeup on */
1169 accel_dev = &st->indio_accel->dev;
1170 wakeup = st->apex.on && device_may_wakeup(accel_dev);
1171 if (wakeup) {
1172 /* keep accel on and setup irq for wakeup */
1173 accel_conf = st->conf.accel.mode;
1174 enable_irq_wake(st->irq);
1175 disable_irq(st->irq);
1176 } else {
1177 /* disable APEX features and accel if wakeup disabled */
1178 if (st->apex.wom.enable) {
1179 ret = inv_icm42607_disable_wom(st);
1180 if (ret)
1181 return ret;
1182 }
1183 accel_conf = INV_ICM42600_SENSOR_MODE_OFF;
1184 }
1185
1186 ret = inv_icm42607_set_pwr_mgmt0(st, INV_ICM42600_SENSOR_MODE_OFF,
1187 INV_ICM42600_SENSOR_MODE_OFF, false,
1188 NULL);
1189 if (ret)
1190 return ret;
1191
1192 if (!wakeup)
1193 regulator_disable(st->vddio_supply);
1194
1195 return 0;
1196 }
1197
Signature · 2 lines
0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
Jonathan Cameron
maintainerRe: [PATCH V2 4/5] iio: imu: inv_icm42600: Add support for icm42607
In reply to Chris MorganQuoted 10 lines · On Thu, 19 Mar 2026 13:29:40 -0500 Chris Morgan <[email protected]> wrote:
From: Chris Morgan <[email protected]>
Add support for the icm42607 and icm42607p over both I2C and SPI. Note that at this time only the icm42607 over i2c has been tested.
This driver was updated based on the existing icm42600 along with the datasheet from Invensense and out-of-tree sources included in the LineageOS kernels [1] and Rockchip kernels [2], both derived from sources provided by Invensense.
Quoted 4 lines
[1] https://github.com/LineageOS/android_kernel_nvidia_kernel-nx/tree/lineage-23.0/drivers/iio/imu/inv_icm42607x
[2] https://github.com/rockchip-linux/kernel/tree/develop-6.6/drivers/iio/imu/inv_icm42670Signed-off-by Chris Morgan <[email protected]>
Hi Chris,
Just a quick look to see what was here.
A few comments inline but the big question is clearly whether or not it makes sense to share the driver at all.
Thanks,
Jonathan
Quoted 6 lines
int
inv_icm42600_accel_init(struct inv_icm42600_state *st, struct iio_dev *indio_dev){drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c +0
-0struct device *dev =regmap_get_device (st->map);@@ -1202,6 +1610,62 @@ int inv_icm42600_accel_init(struct inv_icm42600_state *st, struct iio_dev *indioreturn 0 ; }
drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c int inv_icm42600_accel_init(struct inv_icm42600_state *st, struct iio_dev *indio · line 1621
Quoted 10 lines
drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c +8
-0+int inv_icm42607_accel_init (struct inv_icm42600_state *st,struct iio_dev *indio_dev) +{ +/* accel events are wakeup capable */ + ret =devm_device_init_wakeup (&indio_dev->dev); +if (ret) +return ret; + +return 0 ;
return devm_device_init_wakeup();
Quoted 11 lines
drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c +1
-0+}drivers/iio/imu/inv_icm42600/inv_icm42600_core.c +0
-0.gyro = { .mode = INV_ICM42600_SENSOR_MODE_OFF,
drivers/iio/imu/inv_icm42600/inv_icm42600_core.c static const struct inv_icm42600_hw inv_icm42600_hw[INV_CHIP_NB] = { · line 196
Quoted 4 lines
drivers/iio/imu/inv_icm42600/inv_icm42600_core.c +1
-0@@ -157,6 +193,16 @@ static const struct inv_icm42600_hw inv_icm42600_hw[INV_CHIP_NB] = { .name = "icm42605", .conf = &inv_icm42600_default_conf, }, + [INV_CHIP_ICM42607] = {
If this goes ahead, we'd probably want to break up the structure arrays, drop the enum and instead have extern lines for each individual names structure in the header.
The aim is both give more readable handling using the generic functions to get the data from whatever firmware is in use and ensure all control is via 'data' in the chip type specific structures.
We used to do the enum thing a lot but it proved to be a not particularly good idea and we've been slowly ripping it out again in recent years!
Quoted 20 lines
drivers/iio/imu/inv_icm42600/inv_icm42600_core.c +19
-0+ .whoami = INV_ICM42607_WHOAMI, + .name = "icm42607", + .conf = &inv_icm42607_default_conf, + }, + [INV_CHIP_ICM42607P] = { + .whoami = INV_ICM42607P_WHOAMI, + .name = "icm42607p", + .conf = &inv_icm42607_default_conf, + }, +/** +* inv_icm42607_setup() - check and setup chip +* @st: driver internal state +* @bus_setup: callback for setting up bus specific registers +* +* Returns 0 on success, a negative error code otherwise. +*/ +static int inv_icm42607_setup (struct inv_icm42600_state *st, +inv_icm42600_bus_setup bus_setup) +{
drivers/iio/imu/inv_icm42600/inv_icm42600_core.c static const struct inv_icm42600_hw inv_icm42600_hw[INV_CHIP_NB] = {
Quoted 10 lines
drivers/iio/imu/inv_icm42600/inv_icm42600_core.c +10
-0+const struct inv_icm42600_hw *hw = &inv_icm42600_hw[st->chip]; +const struct device *dev =regmap_get_device (st->map); +unsigned int val; +int ret; + + ret =regmap_read (st->map,INV_ICM42607_REG_WHOAMI , &val); +if (ret) +return ret; + +if (val != hw->whoami)
I guess the driver is doing this for other devices. That's a historical thing. For new code (+ slowly fixing up drivers) we always accept the dt binding value even if there is a whoami match failure because that enables fallback compatibles. That is newer devices can be supported by older kernels without requiring code changes.
Instead just print an info message as it might help with debugging.
Quoted 20 lines
drivers/iio/imu/inv_icm42600/inv_icm42600_core.c +4
-0+return dev_err_probe (dev, -ENODEV , +"invalid whoami %#02x expected %#02x (%s)\n" , + val, hw->whoami, hw->name); +drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c +4
-0static int inv_icm42600_gyro_read_sensor (struct inv_icm42600_state *st,struct iio_chan_spec const *chan,s16 *val)@@ -188,6 +265,58 @@ static int inv_icm42600_gyro_read_sensor(struct inv_icm42600_state *st,return ret; } +static int inv_icm42607_gyro_read_sensor (struct inv_icm42600_state *st, +struct iio_chan_spec const *chan, +s16 *val) +{
...
drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c static int inv_icm42600_gyro_read_sensor(struct inv_icm42600_state *st, · line 308
Quoted 7 lines
drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c +7
-0+ conf.mode =INV_ICM42600_SENSOR_MODE_LOW_NOISE ; + ret =inv_icm42607_set_gyro_conf (st, &conf,NULL ); +if (ret) +return ret; + +/* read gyro register data */ + data = (__be16 *)&st->buffer[0 ];
Similar to below, I'd be use the buffer directly in the call and an unaligned get to reduce alignment assumptions.
And sizeof(__be16) given then there won't be a local variable to use.
drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c static int inv_icm42600_gyro_read_sensor(struct inv_icm42600_state *st, · line 315
Quoted 7 lines
drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c +7
-0+ ret =regmap_bulk_read (st->map, reg, data,sizeof (*data)); +if (ret) +return ret; + + *val = (s16 )be16_to_cpup (data); +if (*val ==INV_ICM42607_DATA_INVALID ) + ret = -EINVAL ;
return -EINVAL; return 0;
Quoted 10 lines
drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c +3
-0+ +return ret; +}static int inv_icm42600_gyro_read_scale (struct iio_dev *indio_dev,int *val,int *val2)@@ -276,12 +419,21 @@ static int inv_icm42600_gyro_write_scale(struct iio_dev *indio_dev, conf.fs = idx /2 ;
drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c static int inv_icm42600_gyro_write_scale(struct iio_dev *indio_dev, · line 284
Quoted 10 lines
drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c +3
-5-pm_runtime_get_sync (dev); - -scoped_guard (mutex, &st->lock) - ret = inv_icm42600_set_gyro_conf(st, &conf, NULL); +PM_RUNTIME_ACQUIRE_AUTOSUSPEND (dev, pm); +if (PM_RUNTIME_ACQUIRE_ERR (&pm)) +return -ENXIO ; -pm_runtime_put_autosuspend (dev);
Do this in a precursor patch, not buried in here.
Quoted 23 lines
drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c +13
-0+switch (st->chip) { +case INV_CHIP_ICM42607 : +case INV_CHIP_ICM42607P : +scoped_guard (mutex, &st->lock) + ret = inv_icm42607_set_gyro_conf(st, &conf, NULL); +break ; +default : +scoped_guard (mutex, &st->lock) + ret = inv_icm42600_set_gyro_conf(st, &conf, NULL); +break ; + }return ret; }@@ -783,6 +1089,56 @@ int inv_icm42600_gyro_init(struct inv_icm42600_state *st, struct iio_dev *indio_return 0 ; } +int inv_icm42607_gyro_init (struct inv_icm42600_state *st,struct iio_dev *indio_dev) +{
...
drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c
Quoted 4 lines
drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c +4
-0+ + ret =devm_iio_device_register (dev, indio_dev); +if (ret) +return ret;
return devm_iio_device_register();
Quoted 23 lines
drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c +3
-0+ +return 0 ; +}drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c +0
-6static int inv_icm42600_probe (struct spi_device *spi) {const void *match;@@ -59,12 +88,22 @@ static int inv_icm42600_probe(struct spi_device *spi)return -EINVAL ; chip = (uintptr_t )match; -/* use SPI specific regmap */ - regmap =devm_regmap_init_spi (spi, &inv_icm42600_spi_regmap_config); -if (IS_ERR (regmap)) -return PTR_ERR (regmap); - -return inv_icm42600_core_probe (regmap, chip, inv_icm42600_spi_bus_setup);
drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c static int inv_icm42600_probe(struct spi_device *spi) · line 100
Quoted 10 lines
drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c +10
-0+switch (chip) { +case INV_CHIP_ICM42607 : +case INV_CHIP_ICM42607P : + regmap =devm_regmap_init_spi (spi, &inv_icm42607_regmap_config); +if (IS_ERR (regmap)) +return PTR_ERR (regmap); +return inv_icm42600_core_probe (regmap, chip, + inv_icm42607_spi_bus_setup); +default : +/* use SPI specific regmap */
This comment is a bit odd given the above is also an SPI specific regmap and the naming makes it obvious. Drop the comment.
Quoted 15 lines
drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c +6
-0+ regmap =devm_regmap_init_spi (spi, &inv_icm42600_spi_regmap_config); +if (IS_ERR (regmap)) +return PTR_ERR (regmap); +return inv_icm42600_core_probe (regmap, chip, + inv_icm42600_spi_bus_setup); + } }drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c +0
-0@@ -46,6 +46,34 @@ static int inv_icm42600_temp_read(struct inv_icm42600_state *st, s16 *temp)return ret; }
drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c static int inv_icm42600_temp_read(struct inv_icm42600_state *st, s16 *temp) · line 57
Quoted 10 lines
drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c +9
-0+static int inv_icm42607_temp_read (struct inv_icm42600_state *st,s16 *temp) +{ +struct device *dev =regmap_get_device (st->map); +__be16 *raw; +int ret; + +PM_RUNTIME_ACQUIRE_AUTOSUSPEND (dev, pm); +if (PM_RUNTIME_ACQUIRE_ERR (&pm)) +return -ENXIO ;
No problem with this in general as it makes the code cleaner, but I'd kind of expect to ensure consistent local style by updating other places in a precursor patch.
drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c static int inv_icm42600_temp_read(struct inv_icm42600_state *st, s16 *temp) · line 65
Quoted 8 lines
drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c +8
-0+ +guard (mutex)(&st->lock); + + ret =inv_icm42607_set_temp_conf (st, true,NULL ); +if (ret) +return ret; + + raw = (__be16 *)&st->buffer[0 ];
Whilst existing code does this, I'm not sure why we'd pass cast to __be16 * before passing it to a function taking a void *
drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c static int inv_icm42600_temp_read(struct inv_icm42600_state *st, s16 *temp) · line 70
Quoted 5 lines
drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c +5
-0+ ret =regmap_bulk_read (st->map,INV_ICM42607_REG_TEMP_DATA1 , raw,sizeof (*raw)); +if (ret) +return ret; + + *temp = (s16 )be16_to_cpup (raw);
Also true in existing code, but this is making a strong assumption about continued behaviour of IIO_DMA_MINALIGN and that being at least 2.
I'd be tempted to use an unaligned get just to avoid that assumption.
drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c static int inv_icm42600_temp_read(struct inv_icm42600_state *st, s16 *temp) · line 72
Quoted 2 lines
drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c +2
-0+if (*temp ==INV_ICM42600_DATA_INVALID ) + ret = -EINVAL ;
return -EINVAL; ?
No point in setting it otherwise.
Quoted 3 lines
drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c +3
-0+ +return 0 ; +}
PATCH v2 5/5 arm64: dts: rockchip: Add icm42607p IMU for RG-DS
In reply to Chris MorganFrom: Chris Morgan <[email protected]>
Add the Invensense ICM42607P IMU for the Anbernic RG-DS. Mount-matrix was tested with iio-sensor-proxy and reports correct orientation.
--- .../dts/rockchip/rk3568-anbernic-rg-ds.dts | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-)
arch/arm64/boot/dts/rockchip/rk3568-anbernic-rg-ds.dts +19 -1
@@ -871,7 +871,18 @@ aw87391_pa_r: audio-codec@5b { sound-name-prefix = "Right Amp"; }; - /* invensense,icm42607p at 0x68 */ + icm42607p: imu@68 { + compatible = "invensense,icm42607p"; + reg = <0x68>; + interrupt-names = "INT1"; + interrupt-parent = <&gpio0>; + interrupts = <RK_PD6 IRQ_TYPE_EDGE_FALLING>; + mount-matrix = "-1", "0", "0", + "0", "1", "0", + "0", "0", "-1"; + pinctrl-0 = <&accel_irq>; + pinctrl-names = "default"; + }; }; &i2c3 {
@@ -932,6 +943,13 @@ &i2s1_8ch { }; &pinctrl { + accel { + accel_irq: accel-irq { + rockchip,pins = + <0 RK_PD6 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + gpio-keys { vol_keys_l: vol-keys_l { rockchip,pins =
Signature · 1 line
2.43.0
Jean-Baptiste Maneyrol
maintainerQuoted 46 lines
________________________________________
From: Chris Morgan <[email protected]>
Sent: Thursday, March 19, 2026 19:29
To: [email protected] <[email protected]>
Cc: [email protected] <[email protected]>; [email protected] <[email protected]>; [email protected] <[email protected]>; [email protected] <[email protected]>; Jean-Baptiste Maneyrol <[email protected]>; [email protected] <[email protected]>; [email protected] <[email protected]>; [email protected] <[email protected]>; [email protected] <[email protected]>; [email protected] <[email protected]>; [email protected] <[email protected]>; [email protected] <[email protected]>; Chris Morgan <[email protected]> Subject: [PATCH v2 0/5] Add Invensense ICM42607
From: Chris Morgan <macromorgan@ hotmail. com> Add support for the ICM42607 IMU. This sensor shares the same functionality but a different register layout with the existing ICM42600. This driver should work with the ICM42607 and ICM42607P
ZjQcmQRYFpfptBannerStart
This Message Is From an Untrusted Sender
You have not previously corresponded with this sender.
ZjQcmQRYFpfptBannerEnd
From: Chris Morgan <[email protected]>Add support for the ICM42607 IMU. This sensor shares the same functionality but a different register layout with the existing ICM42600.
This driver should work with the ICM42607 and ICM42607P over both I2C and SPI, however only the ICM42607P over I2C could be tested.
Changes Since V1:
- Instead of creating a new driver, merged with the existinginv_icm42600driver. This necessitated adding some code to the existing driver to permit using a different register layout for the same functionality.
- Split changes up a bit more to decrease the size of the individual patches. Note that patch 0004 is still pretty hefty; if I need to split further I may need to create some temporary stub functions.
- Usedguard()andPM_RUNTIME_ACQUIRE_AUTOSUSPEND()on the new functions per Jonathan's recommendations.Chris Morgan (5):
dt-bindings: iio: imu: add icm42607
iio: imu:inv_icm42600: Add support for using alternate registers
iio: imu:inv_icm42600: Add registers for icm42607
iio: imu:inv_icm42600: Add support for icm42607
arm64: dts: rockchip: Add icm42607p IMU for RG-DS
.../bindings/iio/imu/invensense,icm42600.yaml| 4 +.../dts/rockchip/rk3568-anbernic-rg-ds.dts| 20 +-drivers/iio/imu/inv_icm42600/inv_icm42600.h| 333 +++++++-.../iio/imu/inv_icm42600/inv_icm42600_accel.c| 497 ++++++++++-.../imu/inv_icm42600/inv_icm42600_buffer.c| 240 +++++-.../imu/inv_icm42600/inv_icm42600_buffer.h| 5 +
Quoted 12 lines
.../iio/imu/inv_icm42600/inv_icm42600_core.c | 795 +++++++++++++++--- .../iio/imu/inv_icm42600/inv_icm42600_gyro.c | 379 ++++++++- .../iio/imu/inv_icm42600/inv_icm42600_i2c.c | 53 +- .../iio/imu/inv_icm42600/inv_icm42600_spi.c | 59 +- .../iio/imu/inv_icm42600/inv_icm42600_temp.c | 64 ++ .../iio/imu/inv_icm42600/inv_icm42600_temp.h | 4 + 12 files changed, 2289 insertions(+), 164 deletions(-)Signature · 1 line
2.43.0
Hello Chris,
thanks for the patch, but beware that there is a major difference between this chip and inv_icm42600 chips family that is preventing to have a common driver.
inv_icm42600 chips are using direct register access with bank while icm42607 chip is using indirect register access using IREG specific registers. Some registers cannot be read/write directly and requires programming specific registers. The mechanism is similar to the one in inv_icm45600 driver, you can have a look in this driver.
Using the same driver is not possible I think, since register access is different.
And there are also more differences between the 2 chip families that is making a common driver quite difficult to do.
Thanks,
JB
_______________________________________________
Linux-rockchip mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-rockchip
Quoted 61 lines · Jean-Baptiste Maneyrol
Quoted 46 lines
________________________________________
From: Chris Morgan <[email protected]>
Sent: Thursday, March 19, 2026 19:29
To: [email protected] <[email protected]>
Cc: [email protected] <[email protected]>; [email protected] <[email protected]>; [email protected] <[email protected]>; [email protected] <[email protected]>; Jean-Baptiste Maneyrol <[email protected]>; [email protected] <[email protected]>; [email protected] <[email protected]>; [email protected] <[email protected]>; [email protected] <[email protected]>; [email protected] <[email protected]>; [email protected] <[email protected]>; [email protected] <[email protected]>; Chris Morgan <[email protected]> Subject: [PATCH v2 0/5] Add Invensense ICM42607
From: Chris Morgan <macromorgan@ hotmail. com> Add support for the ICM42607 IMU. This sensor shares the same functionality but a different register layout with the existing ICM42600. This driver should work with the ICM42607 and ICM42607P
ZjQcmQRYFpfptBannerStart
This Message Is From an Untrusted Sender
You have not previously corresponded with this sender.
ZjQcmQRYFpfptBannerEnd
From: Chris Morgan <[email protected]>Add support for the ICM42607 IMU. This sensor shares the same functionality but a different register layout with the existing ICM42600.
This driver should work with the ICM42607 and ICM42607P over both I2C and SPI, however only the ICM42607P over I2C could be tested.
Changes Since V1:
- Instead of creating a new driver, merged with the existinginv_icm42600driver. This necessitated adding some code to the existing driver to permit using a different register layout for the same functionality.
- Split changes up a bit more to decrease the size of the individual patches. Note that patch 0004 is still pretty hefty; if I need to split further I may need to create some temporary stub functions.
- Usedguard()andPM_RUNTIME_ACQUIRE_AUTOSUSPEND()on the new functions per Jonathan's recommendations.Chris Morgan (5):
dt-bindings: iio: imu: add icm42607
iio: imu:inv_icm42600: Add support for using alternate registers
iio: imu:inv_icm42600: Add registers for icm42607
iio: imu:inv_icm42600: Add support for icm42607
arm64: dts: rockchip: Add icm42607p IMU for RG-DS
.../bindings/iio/imu/invensense,icm42600.yaml| 4 +.../dts/rockchip/rk3568-anbernic-rg-ds.dts| 20 +-drivers/iio/imu/inv_icm42600/inv_icm42600.h| 333 +++++++-.../iio/imu/inv_icm42600/inv_icm42600_accel.c| 497 ++++++++++-.../imu/inv_icm42600/inv_icm42600_buffer.c| 240 +++++-.../imu/inv_icm42600/inv_icm42600_buffer.h| 5 +Quoted 12 lines
.../iio/imu/inv_icm42600/inv_icm42600_core.c | 795 +++++++++++++++--- .../iio/imu/inv_icm42600/inv_icm42600_gyro.c | 379 ++++++++- .../iio/imu/inv_icm42600/inv_icm42600_i2c.c | 53 +- .../iio/imu/inv_icm42600/inv_icm42600_spi.c | 59 +- .../iio/imu/inv_icm42600/inv_icm42600_temp.c | 64 ++ .../iio/imu/inv_icm42600/inv_icm42600_temp.h | 4 + 12 files changed, 2289 insertions(+), 164 deletions(-)Signature · 1 line
2.43.0Hello Chris,
Quoted 8 lines
thanks for the patch, but beware that there is a major difference between this chip and
inv_icm42600chips family that is preventing to have a common driver.
inv_icm42600chips are using direct register access with bank while icm42607 chip is using indirect register access using IREG specific registers. Some registers cannot be read/write directly and requires programming specific registers. The mechanism is similar to the one ininv_icm45600driver, you can have a look in this driver.
I didn't see anything in the datasheet for the 42607P in regards to the IREG, but I did see something in the 42607C. That said, near as I can tell from the drivers that I used as a reference from the Rockchip and Lineage trees this driver doesn't access anything from those registers.
Still, I'll defer to you on what you think is best. As long as I can use my accelerometer that's all I care about.
Quoted 8 lines
Using the same driver is not possible I think, since register access is different.
And there are also more differences between the 2 chip families that is making a common driver quite difficult to do.
Thanks,
JB
Chris
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 71 lines · Chris Morgan
Quoted 61 lines · Jean-Baptiste Maneyrol
Quoted 46 lines
________________________________________
From: Chris Morgan <[email protected]>
Sent: Thursday, March 19, 2026 19:29
To: [email protected] <[email protected]>
Cc: [email protected] <[email protected]>; [email protected] <[email protected]>; [email protected] <[email protected]>; [email protected] <[email protected]>; Jean-Baptiste Maneyrol <[email protected]>; [email protected] <[email protected]>; [email protected] <[email protected]>; [email protected] <[email protected]>; [email protected] <[email protected]>; [email protected] <[email protected]>; [email protected] <[email protected]>; [email protected] <[email protected]>; Chris Morgan <[email protected]> Subject: [PATCH v2 0/5] Add Invensense ICM42607
From: Chris Morgan <macromorgan@ hotmail. com> Add support for the ICM42607 IMU. This sensor shares the same functionality but a different register layout with the existing ICM42600. This driver should work with the ICM42607 and ICM42607P
ZjQcmQRYFpfptBannerStart
This Message Is From an Untrusted Sender
You have not previously corresponded with this sender.
ZjQcmQRYFpfptBannerEnd
From: Chris Morgan <[email protected]>Add support for the ICM42607 IMU. This sensor shares the same functionality but a different register layout with the existing ICM42600.
This driver should work with the ICM42607 and ICM42607P over both I2C and SPI, however only the ICM42607P over I2C could be tested.
Changes Since V1:
- Instead of creating a new driver, merged with the existinginv_icm42600driver. This necessitated adding some code to the existing driver to permit using a different register layout for the same functionality.
- Split changes up a bit more to decrease the size of the individual patches. Note that patch 0004 is still pretty hefty; if I need to split further I may need to create some temporary stub functions.
- Usedguard()andPM_RUNTIME_ACQUIRE_AUTOSUSPEND()on the new functions per Jonathan's recommendations.Chris Morgan (5):
dt-bindings: iio: imu: add icm42607
iio: imu:inv_icm42600: Add support for using alternate registers
iio: imu:inv_icm42600: Add registers for icm42607
iio: imu:inv_icm42600: Add support for icm42607
arm64: dts: rockchip: Add icm42607p IMU for RG-DS
.../bindings/iio/imu/invensense,icm42600.yaml| 4 +.../dts/rockchip/rk3568-anbernic-rg-ds.dts| 20 +-drivers/iio/imu/inv_icm42600/inv_icm42600.h| 333 +++++++-.../iio/imu/inv_icm42600/inv_icm42600_accel.c| 497 ++++++++++-.../imu/inv_icm42600/inv_icm42600_buffer.c| 240 +++++-.../imu/inv_icm42600/inv_icm42600_buffer.h| 5 +Quoted 12 lines
.../iio/imu/inv_icm42600/inv_icm42600_core.c | 795 +++++++++++++++--- .../iio/imu/inv_icm42600/inv_icm42600_gyro.c | 379 ++++++++- .../iio/imu/inv_icm42600/inv_icm42600_i2c.c | 53 +- .../iio/imu/inv_icm42600/inv_icm42600_spi.c | 59 +- .../iio/imu/inv_icm42600/inv_icm42600_temp.c | 64 ++ .../iio/imu/inv_icm42600/inv_icm42600_temp.h | 4 + 12 files changed, 2289 insertions(+), 164 deletions(-)Signature · 1 line
2.43.0Hello Chris,
Quoted 8 lines
thanks for the patch, but beware that there is a major difference between this chip and
inv_icm42600chips family that is preventing to have a common driver.
inv_icm42600chips are using direct register access with bank while icm42607 chip is using indirect register access using IREG specific registers. Some registers cannot be read/write directly and requires programming specific registers. The mechanism is similar to the one ininv_icm45600driver, you can have a look in this driver.
Quoted 7 lines
I didn't see anything in the datasheet for the 42607P in regards to the IREG, but I did see something in the 42607C. That said, near as I can tell from the drivers that I used as a reference from the Rockchip and Lineage trees this driver doesn't access anything from those registers.
Still, I'll defer to you on what you think is best. As long as I can use my accelerometer that's all I care about.
So closer looking at the 42607-C datasheet, it looks like they have MREG banks, is that what you're talking about?
If so I can either remove this and create a new driver (as I did with V1), or I can just keep the 42607P in this driver since it does appear to use only direct register access.
Let me know what you think so I can rewrite and resubmit it. I'll try to better break it up this time too by seeing if I can make temp, gyro, and accel functions all with different commits.
Thank you,
Chris
Quoted 11 lines
Quoted 9 lines
Using the same driver is not possible I think, since register access is different.
And there are also more differences between the 2 chip families that is making a common driver quite difficult to do.
Thanks,
JBChris
Quoted 6 lines · Chris Morgan
Add support for the ICM42607 IMU. This sensor shares the same functionality but a different register layout with the existing ICM42600.
This driver should work with the ICM42607 and ICM42607P over both I2C and SPI, however only the ICM42607P over I2C could be tested.
Please, make sure each patch is ~750 ±150 LoC, so it's reviewable. Last patch is unreviewable 2k+ LoC!
Signature · 2 lines
With Best Regards, Andy Shevchenko