[PATCH v4 3/5] iio: imu: inv_icm42607: Add support for ICM-42370-P

From: Kanak Shilledar

Date: Thu Sep 17 2026 - 09:54:30 EST


Add support for the Invensense ICM-42370-P MEMS MotionTracking 3-axis
accelerometer with built-in temperature sensor. This device is almost
identical to the existing Invensense ICM-42607-P IMU, but lacks
gyroscope. The device supports I2C, SPI and I3C, implement only I2C
support. Provide basic support for raw sensor reads via sysfs. There is
also a built-in temperature sensor but it can not be turned off similar
to the ICM-42607. Return with `dev_err_probe()` when WHO_AM_I read
fails.

Datasheet: https://www.invensense.tdk.com/en-us/products/3-axis/icm-42370-p
Datasheet: https://www.lcsc.com/product-detail/C5129967.html
Signed-off-by: Kanak Shilledar <kanak.shilledar@xxxxxxxx>
---
drivers/iio/imu/inv_icm42607/inv_icm42607.h | 3 ++
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c | 35 ++++++++++++++++++++----
drivers/iio/imu/inv_icm42607/inv_icm42607_i2c.c | 6 ++++
3 files changed, 38 insertions(+), 6 deletions(-)

diff --git a/drivers/iio/imu/inv_icm42607/inv_icm42607.h b/drivers/iio/imu/inv_icm42607/inv_icm42607.h
index 4d51b0da1aa16..ca5f59eb436c0 100644
--- a/drivers/iio/imu/inv_icm42607/inv_icm42607.h
+++ b/drivers/iio/imu/inv_icm42607/inv_icm42607.h
@@ -130,6 +130,7 @@ struct inv_icm42607_hw {
const char *name;
const struct inv_icm42607_conf *conf;
u8 whoami;
+ bool has_gyro;
};

/**
@@ -366,6 +367,7 @@ struct inv_icm42607_sensor_state {
#define INV_ICM42607_REG_FIFO_DATA 0x3F

#define INV_ICM42607_REG_WHOAMI 0x75
+#define INV_ICM42370P_WHOAMI 0x0D
#define INV_ICM42607P_WHOAMI 0x60
#define INV_ICM42607_WHOAMI 0x67

@@ -392,6 +394,7 @@ typedef int (*inv_icm42607_bus_setup)(struct inv_icm42607_state *);
extern const struct regmap_config inv_icm42607_regmap_config;
extern const struct inv_icm42607_hw inv_icm42607_hw_data;
extern const struct inv_icm42607_hw inv_icm42607p_hw_data;
+extern const struct inv_icm42607_hw inv_icm42370p_hw_data;
extern const struct dev_pm_ops inv_icm42607_pm_ops;

const struct iio_mount_matrix *
diff --git a/drivers/iio/imu/inv_icm42607/inv_icm42607_core.c b/drivers/iio/imu/inv_icm42607/inv_icm42607_core.c
index 190e998f7b8ef..114e7afcda391 100644
--- a/drivers/iio/imu/inv_icm42607/inv_icm42607_core.c
+++ b/drivers/iio/imu/inv_icm42607/inv_icm42607_core.c
@@ -92,10 +92,27 @@ static const struct inv_icm42607_conf inv_icm42607_default_conf = {
},
};

+static const struct inv_icm42607_conf inv_icm42370_default_conf = {
+ .accel = {
+ .mode = INV_ICM42607_SENSOR_MODE_OFF,
+ .fs = INV_ICM42607_ACCEL_FS_4G,
+ .odr = INV_ICM42607_ODR_100HZ,
+ .filter = INV_ICM42607_FILTER_BW_25HZ,
+ },
+};
+
+const struct inv_icm42607_hw inv_icm42370p_hw_data = {
+ .whoami = INV_ICM42370P_WHOAMI,
+ .name = "icm42370p",
+ .conf = &inv_icm42370_default_conf,
+};
+EXPORT_SYMBOL_NS_GPL(inv_icm42370p_hw_data, "IIO_ICM42607");
+
const struct inv_icm42607_hw inv_icm42607_hw_data = {
.whoami = INV_ICM42607_WHOAMI,
.name = "icm42607",
.conf = &inv_icm42607_default_conf,
+ .has_gyro = true,
};
EXPORT_SYMBOL_NS_GPL(inv_icm42607_hw_data, "IIO_ICM42607");

@@ -103,6 +120,7 @@ const struct inv_icm42607_hw inv_icm42607p_hw_data = {
.whoami = INV_ICM42607P_WHOAMI,
.name = "icm42607p",
.conf = &inv_icm42607_default_conf,
+ .has_gyro = true,
};
EXPORT_SYMBOL_NS_GPL(inv_icm42607p_hw_data, "IIO_ICM42607");

@@ -468,7 +486,7 @@ static int inv_icm42607_setup(struct inv_icm42607_state *st,

ret = regmap_read(st->map, INV_ICM42607_REG_WHOAMI, &val);
if (ret)
- return ret;
+ return dev_err_probe(dev, ret, "WHOAMI read failed\n");

/* Warn, but don't fail. */
if (val != st->hw->whoami)
@@ -630,15 +648,20 @@ int inv_icm42607_core_probe(struct regmap *regmap,
pm_runtime_set_autosuspend_delay(dev, INV_ICM42607_SUSPEND_DELAY_MS);
pm_runtime_use_autosuspend(dev);

- /* Initialize IIO device for Accel */
+ /*
+ * Invensense, ICM42607 and ICM42607P both have accelerometer
+ * and gyroscope functionality. Whereas, Invensense, ICM42370
+ * has only accelerometer.
+ */
st->indio_accel = inv_icm42607_accel_init(st);
if (IS_ERR(st->indio_accel))
return PTR_ERR(st->indio_accel);

- /* Initialize IIO device for Gyro */
- st->indio_gyro = inv_icm42607_gyro_init(st);
- if (IS_ERR(st->indio_gyro))
- return PTR_ERR(st->indio_gyro);
+ if (st->hw->has_gyro) {
+ st->indio_gyro = inv_icm42607_gyro_init(st);
+ if (IS_ERR(st->indio_gyro))
+ return PTR_ERR(st->indio_gyro);
+ }

return 0;
}
diff --git a/drivers/iio/imu/inv_icm42607/inv_icm42607_i2c.c b/drivers/iio/imu/inv_icm42607/inv_icm42607_i2c.c
index e903106af84a8..cfafba2e3e68e 100644
--- a/drivers/iio/imu/inv_icm42607/inv_icm42607_i2c.c
+++ b/drivers/iio/imu/inv_icm42607/inv_icm42607_i2c.c
@@ -63,6 +63,9 @@ static const struct i2c_device_id inv_icm42607_id[] = {
}, {
.name = "icm42607p",
.driver_data = (kernel_ulong_t)&inv_icm42607p_hw_data,
+ }, {
+ .name = "icm42370p",
+ .driver_data = (kernel_ulong_t)&inv_icm42370p_hw_data,
},
{ }
};
@@ -75,6 +78,9 @@ static const struct of_device_id inv_icm42607_of_matches[] = {
}, {
.compatible = "invensense,icm42607p",
.data = &inv_icm42607p_hw_data,
+ }, {
+ .compatible = "invensense,icm42370p",
+ .data = &inv_icm42370p_hw_data,
},
{ }
};

--
2.43.0