Skip to contentSkip to conversation

Add Invensense ICM42607

PATCH Superseded Chris Morgan 7 participants 16 messages Mar 19 – Mar 24 1 message not in the archive

Subsystems (4)

v2 of 21 Superseded Latest is v21 →

lore
Share & tools
lore
#0 lore raw

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
#1 lore raw

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
index 119e28a833fd..b69c6bbb6f6b 100644
@@ -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
#3 lore raw

PATCH v2 2/5 iio: imu: inv_icm42600: Add support for using alternate registers

In reply to Chris Morgan

From: 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
index c8b48a5c5ed0..b89078cb5ba0 100644
@@ -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
index 0ab6eddf0543..cbb27c4e6b82 100644
@@ -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
index 11339ddf1da3..32aa2e52df2e 100644
@@ -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
maintainer
#4 lore raw

Re: [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_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_gyro.c +0 -0
index 11339ddf1da3..32aa2e52df2e 100644

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.

#5 lore raw

PATCH v2 3/5 iio: imu: inv_icm42600: Add registers for icm42607

In reply to Chris Morgan

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.

---
 drivers/iio/imu/inv_icm42600/inv_icm42600.h | 284 ++++++++++++++++++++
 1 file changed, 284 insertions(+)
drivers/iio/imu/inv_icm42600/inv_icm42600.h +284 -0
index b89078cb5ba0..ab3616c5ee1a 100644
@@ -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
maintainer
#6 lore raw

Re: [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.

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))
#7 lore raw

PATCH v2 4/5 iio: imu: inv_icm42600: Add support for icm42607

In reply to Chris Morgan

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.

[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
index ab3616c5ee1a..9f25632f1915 100644
@@ -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
index ffca4da1e249..900ee12fdb9d 100644
@@ -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
index 3941186512fb..b5b9e4fe3d0e 100644
@@ -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
#8 lore raw

Re: [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
#9 lore raw

Re: [PATCH V2 4/5] iio: imu: inv_icm42600: Add support for icm42607

In reply to Chris Morgan
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-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
maintainer
#10 lore raw

Re: [PATCH V2 4/5] iio: imu: inv_icm42600: Add support for icm42607

In reply to Chris Morgan
Quoted 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_icm42670

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 -0
 	struct device *dev = regmap_get_device(st->map);
@@ -1202,6 +1610,62 @@ int inv_icm42600_accel_init(struct inv_icm42600_state *st, struct iio_dev *indio
 	return 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
index 29c8c1871e06..949dbf9c2cd3 100644
 
 	.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 -0
index 32aa2e52df2e..eb590eb4f397 100644
 
 static 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 -6
index 13e2e7d38638..6bfd5598b262 100644
 
 static 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
index 727b03d541a5..fdda555dbd16 100644
@@ -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;
+}
#11 lore raw

PATCH v2 5/5 arm64: dts: rockchip: Add icm42607p IMU for RG-DS

In reply to Chris Morgan

From: 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
index 8d906ab02c5f..dca270abc475 100644
@@ -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
#12 lore raw
In reply to Chris Morgan
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 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 +

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

#13 lore raw
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 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 +

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,

Quoted 8 lines

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.

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]

#15 lore raw
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 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 +

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,

Quoted 8 lines

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.

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,
JB

Chris

#16 lore raw
In reply to Chris Morgan
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