From: Remi Buisson <remi.buisson@tdk.com>
Add I2C driver for InvenSense ICM-456000 devices.
Signed-off-by: Remi Buisson <remi.buisson@tdk.com>
---
drivers/iio/imu/inv_icm45600/Kconfig | 21 ++++++
drivers/iio/imu/inv_icm45600/Makefile | 3 +
drivers/iio/imu/inv_icm45600/inv_icm45600_i2c.c | 98 +++++++++++++++++++++++++
3 files changed, 122 insertions(+)
diff --git a/drivers/iio/imu/inv_icm45600/Kconfig b/drivers/iio/imu/inv_icm45600/Kconfig
index ea0a8d20cba26549b74105fa6fdbca1ddb222633..5b044a954e952ffa8e44507eea42872e1f3161bc 100644
--- a/drivers/iio/imu/inv_icm45600/Kconfig
+++ b/drivers/iio/imu/inv_icm45600/Kconfig
@@ -5,3 +5,24 @@ config INV_ICM45600
select IIO_BUFFER
select IIO_KFIFO_BUF
select IIO_INV_SENSORS_TIMESTAMP
+
+config INV_ICM45600_I2C
+ tristate "InvenSense ICM-456xx I2C driver"
+ depends on I2C
+ select INV_ICM45600
+ select REGMAP_I2C
+ help
+ This driver supports the InvenSense ICM-456xx motion tracking
+ devices over I2C.
+ Supported devices:
+ - ICM-45605
+ - ICM-45606
+ - ICM-45608
+ - ICM-45634
+ - ICM-45686
+ - ICM-45687
+ - ICM-45688-P
+ - ICM-45689
+
+ This driver can be built as a module. The module will be called
+ inv-icm45600-i2c.
diff --git a/drivers/iio/imu/inv_icm45600/Makefile b/drivers/iio/imu/inv_icm45600/Makefile
index e34553d2b74dc46bb0f533d2bd0875655f91c781..c43e5d6ad3a2ddbd666d77630015c440e740d969 100644
--- a/drivers/iio/imu/inv_icm45600/Makefile
+++ b/drivers/iio/imu/inv_icm45600/Makefile
@@ -5,3 +5,6 @@ inv-icm45600-y += inv_icm45600_core.o
inv-icm45600-y += inv_icm45600_buffer.o
inv-icm45600-y += inv_icm45600_gyro.o
inv-icm45600-y += inv_icm45600_accel.o
+
+obj-$(CONFIG_INV_ICM45600_I2C) += inv-icm45600-i2c.o
+inv-icm45600-i2c-y += inv_icm45600_i2c.o
diff --git a/drivers/iio/imu/inv_icm45600/inv_icm45600_i2c.c b/drivers/iio/imu/inv_icm45600/inv_icm45600_i2c.c
new file mode 100644
index 0000000000000000000000000000000000000000..5ebc18121a11f8ad576efb4d4cf80091c13af31d
--- /dev/null
+++ b/drivers/iio/imu/inv_icm45600/inv_icm45600_i2c.c
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/* Copyright (C) 2025 InvenSense, Inc. */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/regmap.h>
+
+#include "inv_icm45600.h"
+
+static const struct regmap_config inv_icm45600_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+};
+
+static int inv_icm45600_probe(struct i2c_client *client)
+{
+ const struct inv_icm45600_chip_info *chip_info;
+ struct regmap *regmap;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
+ return -ENODEV;
+
+ chip_info = device_get_match_data(&client->dev);
+ if (!chip_info)
+ return -ENODEV;
+
+ regmap = devm_regmap_init_i2c(client, &inv_icm45600_regmap_config);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+
+ return inv_icm45600_core_probe(regmap, chip_info, true, NULL);
+}
+
+/*
+ * The device id table is used to identify which device is
+ * supported by this driver.
+ */
+static const struct i2c_device_id inv_icm45600_id[] = {
+ { "icm45605", (kernel_ulong_t)&inv_icm45605_chip_info },
+ { "icm45606", (kernel_ulong_t)&inv_icm45606_chip_info },
+ { "icm45608", (kernel_ulong_t)&inv_icm45608_chip_info },
+ { "icm45634", (kernel_ulong_t)&inv_icm45634_chip_info },
+ { "icm45686", (kernel_ulong_t)&inv_icm45686_chip_info },
+ { "icm45687", (kernel_ulong_t)&inv_icm45687_chip_info },
+ { "icm45688p", (kernel_ulong_t)&inv_icm45688p_chip_info },
+ { "icm45689", (kernel_ulong_t)&inv_icm45689_chip_info },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, inv_icm45600_id);
+
+static const struct of_device_id inv_icm45600_of_matches[] = {
+ {
+ .compatible = "invensense,icm45605",
+ .data = &inv_icm45605_chip_info,
+ }, {
+ .compatible = "invensense,icm45606",
+ .data = &inv_icm45606_chip_info,
+ }, {
+ .compatible = "invensense,icm45608",
+ .data = &inv_icm45608_chip_info,
+ }, {
+ .compatible = "invensense,icm45634",
+ .data = &inv_icm45634_chip_info,
+ }, {
+ .compatible = "invensense,icm45686",
+ .data = &inv_icm45686_chip_info,
+ }, {
+ .compatible = "invensense,icm45687",
+ .data = &inv_icm45687_chip_info,
+ }, {
+ .compatible = "invensense,icm45688p",
+ .data = &inv_icm45688p_chip_info,
+ }, {
+ .compatible = "invensense,icm45689",
+ .data = &inv_icm45689_chip_info,
+ },
+ { }
+};
+MODULE_DEVICE_TABLE(of, inv_icm45600_of_matches);
+
+static struct i2c_driver inv_icm45600_driver = {
+ .driver = {
+ .name = "inv-icm45600-i2c",
+ .of_match_table = inv_icm45600_of_matches,
+ .pm = pm_ptr(&inv_icm45600_pm_ops),
+ },
+ .id_table = inv_icm45600_id,
+ .probe = inv_icm45600_probe,
+};
+module_i2c_driver(inv_icm45600_driver);
+
+MODULE_AUTHOR("InvenSense, Inc.");
+MODULE_DESCRIPTION("InvenSense ICM-456xx I2C driver");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("IIO_ICM45600");
--
2.34.1
Hi Remi, kernel test robot noticed the following build warnings: [auto build test WARNING on f8f559752d573a051a984adda8d2d1464f92f954] url: https://github.com/intel-lab-lkp/linux/commits/Remi-Buisson-via-B4-Relay/dt-bindings-iio-imu-Add-inv_icm45600/20250814-170722 base: f8f559752d573a051a984adda8d2d1464f92f954 patch link: https://lore.kernel.org/r/20250814-add_newport_driver-v4-6-4464b6600972%40tdk.com patch subject: [PATCH v4 6/9] iio: imu: inv_icm45600: add I2C driver for inv_icm45600 driver config: s390-allmodconfig (https://download.01.org/0day-ci/archive/20250815/202508151941.BweGaEVT-lkp@intel.com/config) compiler: clang version 18.1.8 (https://github.com/llvm/llvm-project 3b5b5c1ec4a3095ab096dd780e84d7ab81f3d7ff) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250815/202508151941.BweGaEVT-lkp@intel.com/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 <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202508151941.BweGaEVT-lkp@intel.com/ All warnings (new ones prefixed by >>): >> drivers/iio/imu/inv_icm45600/inv_icm45600_core.c:908:12: warning: result of comparison of constant 32768 with expression of type 's16' (aka 'short') is always false [-Wtautological-constant-out-of-range-compare] 908 | if (*temp == INV_ICM45600_DATA_INVALID) | ~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/iio/imu/inv_icm45600/inv_icm45600_core.c:785:12: warning: unused function 'inv_icm45600_suspend' [-Wunused-function] 785 | static int inv_icm45600_suspend(struct device *dev) | ^~~~~~~~~~~~~~~~~~~~ drivers/iio/imu/inv_icm45600/inv_icm45600_core.c:820:12: warning: unused function 'inv_icm45600_resume' [-Wunused-function] 820 | static int inv_icm45600_resume(struct device *dev) | ^~~~~~~~~~~~~~~~~~~ drivers/iio/imu/inv_icm45600/inv_icm45600_core.c:860:12: warning: unused function 'inv_icm45600_runtime_suspend' [-Wunused-function] 860 | static int inv_icm45600_runtime_suspend(struct device *dev) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/iio/imu/inv_icm45600/inv_icm45600_core.c:879:12: warning: unused function 'inv_icm45600_runtime_resume' [-Wunused-function] 879 | static int inv_icm45600_runtime_resume(struct device *dev) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ 5 warnings generated. vim +908 drivers/iio/imu/inv_icm45600/inv_icm45600_core.c 8891b99381240f Remi Buisson 2025-08-14 887 2570c7e48ace35 Remi Buisson 2025-08-14 888 static int _inv_icm45600_temp_read(struct inv_icm45600_state *st, s16 *temp) 2570c7e48ace35 Remi Buisson 2025-08-14 889 { 2570c7e48ace35 Remi Buisson 2025-08-14 890 struct inv_icm45600_sensor_conf conf = INV_ICM45600_SENSOR_CONF_KEEP_VALUES; 2570c7e48ace35 Remi Buisson 2025-08-14 891 int ret; 2570c7e48ace35 Remi Buisson 2025-08-14 892 2570c7e48ace35 Remi Buisson 2025-08-14 893 /* Make sure a sensor is on. */ 2570c7e48ace35 Remi Buisson 2025-08-14 894 if (st->conf.gyro.mode == INV_ICM45600_SENSOR_MODE_OFF && 2570c7e48ace35 Remi Buisson 2025-08-14 895 st->conf.accel.mode == INV_ICM45600_SENSOR_MODE_OFF) { 2570c7e48ace35 Remi Buisson 2025-08-14 896 conf.mode = INV_ICM45600_SENSOR_MODE_LOW_POWER; 2570c7e48ace35 Remi Buisson 2025-08-14 897 ret = inv_icm45600_set_accel_conf(st, &conf, NULL); 2570c7e48ace35 Remi Buisson 2025-08-14 898 if (ret) 2570c7e48ace35 Remi Buisson 2025-08-14 899 return ret; 2570c7e48ace35 Remi Buisson 2025-08-14 900 } 2570c7e48ace35 Remi Buisson 2025-08-14 901 2570c7e48ace35 Remi Buisson 2025-08-14 902 ret = regmap_bulk_read(st->map, INV_ICM45600_REG_TEMP_DATA, 2570c7e48ace35 Remi Buisson 2025-08-14 903 &st->buffer.u16, sizeof(st->buffer.u16)); 2570c7e48ace35 Remi Buisson 2025-08-14 904 if (ret) 2570c7e48ace35 Remi Buisson 2025-08-14 905 return ret; 2570c7e48ace35 Remi Buisson 2025-08-14 906 2570c7e48ace35 Remi Buisson 2025-08-14 907 *temp = (s16)le16_to_cpup(&st->buffer.u16); 2570c7e48ace35 Remi Buisson 2025-08-14 @908 if (*temp == INV_ICM45600_DATA_INVALID) 2570c7e48ace35 Remi Buisson 2025-08-14 909 return -EINVAL; 2570c7e48ace35 Remi Buisson 2025-08-14 910 2570c7e48ace35 Remi Buisson 2025-08-14 911 return 0; 2570c7e48ace35 Remi Buisson 2025-08-14 912 } 2570c7e48ace35 Remi Buisson 2025-08-14 913 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
On Fri, 15 Aug 2025 19:31:38 +0800 kernel test robot <lkp@intel.com> wrote: > Hi Remi, > > kernel test robot noticed the following build warnings: > > [auto build test WARNING on f8f559752d573a051a984adda8d2d1464f92f954] > > url: https://github.com/intel-lab-lkp/linux/commits/Remi-Buisson-via-B4-Relay/dt-bindings-iio-imu-Add-inv_icm45600/20250814-170722 > base: f8f559752d573a051a984adda8d2d1464f92f954 > patch link: https://lore.kernel.org/r/20250814-add_newport_driver-v4-6-4464b6600972%40tdk.com > patch subject: [PATCH v4 6/9] iio: imu: inv_icm45600: add I2C driver for inv_icm45600 driver > config: s390-allmodconfig (https://download.01.org/0day-ci/archive/20250815/202508151941.BweGaEVT-lkp@intel.com/config) > compiler: clang version 18.1.8 (https://github.com/llvm/llvm-project 3b5b5c1ec4a3095ab096dd780e84d7ab81f3d7ff) > reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250815/202508151941.BweGaEVT-lkp@intel.com/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 <lkp@intel.com> > | Closes: https://lore.kernel.org/oe-kbuild-all/202508151941.BweGaEVT-lkp@intel.com/ > > All warnings (new ones prefixed by >>): > > >> drivers/iio/imu/inv_icm45600/inv_icm45600_core.c:908:12: warning: result of comparison of constant 32768 with expression of type 's16' (aka 'short') is always false [-Wtautological-constant-out-of-range-compare] > 908 | if (*temp == INV_ICM45600_DATA_INVALID) > | ~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~ That one will need fixing up. > drivers/iio/imu/inv_icm45600/inv_icm45600_core.c:785:12: warning: unused function 'inv_icm45600_suspend' [-Wunused-function] > 785 | static int inv_icm45600_suspend(struct device *dev) > | ^~~~~~~~~~~~~~~~~~~~ These too me a minute. You have the deprecated functions for actually filling in +EXPORT_NS_GPL_DEV_PM_OPS(inv_icm45600_pm_ops, IIO_ICM45600) = { + SET_SYSTEM_SLEEP_PM_OPS(inv_icm45600_suspend, inv_icm45600_resume) + SET_RUNTIME_PM_OPS(inv_icm45600_runtime_suspend, + inv_icm45600_runtime_resume, NULL) +}; + should be +EXPORT_NS_GPL_DEV_PM_OPS(inv_icm45600_pm_ops, IIO_ICM45600) = { + SYSTEM_SLEEP_PM_OPS(inv_icm45600_suspend, inv_icm45600_resume) + RUNTIME_PM_OPS(inv_icm45600_runtime_suspend, + inv_icm45600_runtime_resume, NULL) +}; + Or use _DEFINE_DEV_PM_OPS() to set all this. > drivers/iio/imu/inv_icm45600/inv_icm45600_core.c:820:12: warning: unused function 'inv_icm45600_resume' [-Wunused-function] > 820 | static int inv_icm45600_resume(struct device *dev) > | ^~~~~~~~~~~~~~~~~~~ > drivers/iio/imu/inv_icm45600/inv_icm45600_core.c:860:12: warning: unused function 'inv_icm45600_runtime_suspend' [-Wunused-function] > 860 | static int inv_icm45600_runtime_suspend(struct device *dev) > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ > drivers/iio/imu/inv_icm45600/inv_icm45600_core.c:879:12: warning: unused function 'inv_icm45600_runtime_resume' [-Wunused-function] > 879 | static int inv_icm45600_runtime_resume(struct device *dev) > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ > 5 warnings generated. > > > vim +908 drivers/iio/imu/inv_icm45600/inv_icm45600_core.c > > 8891b99381240f Remi Buisson 2025-08-14 887 > 2570c7e48ace35 Remi Buisson 2025-08-14 888 static int _inv_icm45600_temp_read(struct inv_icm45600_state *st, s16 *temp) > 2570c7e48ace35 Remi Buisson 2025-08-14 889 { > 2570c7e48ace35 Remi Buisson 2025-08-14 890 struct inv_icm45600_sensor_conf conf = INV_ICM45600_SENSOR_CONF_KEEP_VALUES; > 2570c7e48ace35 Remi Buisson 2025-08-14 891 int ret; > 2570c7e48ace35 Remi Buisson 2025-08-14 892 > 2570c7e48ace35 Remi Buisson 2025-08-14 893 /* Make sure a sensor is on. */ > 2570c7e48ace35 Remi Buisson 2025-08-14 894 if (st->conf.gyro.mode == INV_ICM45600_SENSOR_MODE_OFF && > 2570c7e48ace35 Remi Buisson 2025-08-14 895 st->conf.accel.mode == INV_ICM45600_SENSOR_MODE_OFF) { > 2570c7e48ace35 Remi Buisson 2025-08-14 896 conf.mode = INV_ICM45600_SENSOR_MODE_LOW_POWER; > 2570c7e48ace35 Remi Buisson 2025-08-14 897 ret = inv_icm45600_set_accel_conf(st, &conf, NULL); > 2570c7e48ace35 Remi Buisson 2025-08-14 898 if (ret) > 2570c7e48ace35 Remi Buisson 2025-08-14 899 return ret; > 2570c7e48ace35 Remi Buisson 2025-08-14 900 } > 2570c7e48ace35 Remi Buisson 2025-08-14 901 > 2570c7e48ace35 Remi Buisson 2025-08-14 902 ret = regmap_bulk_read(st->map, INV_ICM45600_REG_TEMP_DATA, > 2570c7e48ace35 Remi Buisson 2025-08-14 903 &st->buffer.u16, sizeof(st->buffer.u16)); > 2570c7e48ace35 Remi Buisson 2025-08-14 904 if (ret) > 2570c7e48ace35 Remi Buisson 2025-08-14 905 return ret; > 2570c7e48ace35 Remi Buisson 2025-08-14 906 > 2570c7e48ace35 Remi Buisson 2025-08-14 907 *temp = (s16)le16_to_cpup(&st->buffer.u16); > 2570c7e48ace35 Remi Buisson 2025-08-14 @908 if (*temp == INV_ICM45600_DATA_INVALID) > 2570c7e48ace35 Remi Buisson 2025-08-14 909 return -EINVAL; > 2570c7e48ace35 Remi Buisson 2025-08-14 910 > 2570c7e48ace35 Remi Buisson 2025-08-14 911 return 0; > 2570c7e48ace35 Remi Buisson 2025-08-14 912 } > 2570c7e48ace35 Remi Buisson 2025-08-14 913 >
© 2016 - 2025 Red Hat, Inc.