From: Remi Buisson <remi.buisson@tdk.com>
Add SPI 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 | 5 +-
drivers/iio/imu/inv_icm45600/inv_icm45600_spi.c | 106 ++++++++++++++++++++++++
3 files changed, 131 insertions(+), 1 deletion(-)
diff --git a/drivers/iio/imu/inv_icm45600/Kconfig b/drivers/iio/imu/inv_icm45600/Kconfig
index 5b044a954e952ffa8e44507eea42872e1f3161bc..01399d136a7ea3aa92a3a18ea455c95c0a6578b3 100644
--- a/drivers/iio/imu/inv_icm45600/Kconfig
+++ b/drivers/iio/imu/inv_icm45600/Kconfig
@@ -26,3 +26,24 @@ config INV_ICM45600_I2C
This driver can be built as a module. The module will be called
inv-icm45600-i2c.
+
+config INV_ICM45600_SPI
+ tristate "InvenSense ICM-456xx SPI driver"
+ depends on SPI_MASTER
+ select INV_ICM45600
+ select REGMAP_SPI
+ help
+ This driver supports the InvenSense ICM-456xx motion tracking
+ devices over SPI.
+ 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-spi.
diff --git a/drivers/iio/imu/inv_icm45600/Makefile b/drivers/iio/imu/inv_icm45600/Makefile
index 371585e29e92e78a30c7d40c1389548fa22a999a..244cc8aa1f79e3367ac6925504cfd9d5b918a0e6 100644
--- a/drivers/iio/imu/inv_icm45600/Makefile
+++ b/drivers/iio/imu/inv_icm45600/Makefile
@@ -7,4 +7,7 @@ inv-icm45600-y += inv_icm45600_accel.o
inv-icm45600-y += inv_icm45600_gyro.o
obj-$(CONFIG_INV_ICM45600_I2C) += inv-icm45600-i2c.o
-inv-icm45600-i2c-y += inv_icm45600_i2c.o
\ No newline at end of file
+inv-icm45600-i2c-y += inv_icm45600_i2c.o
+
+obj-$(CONFIG_INV_ICM45600_SPI) += inv-icm45600-spi.o
+inv-icm45600-spi-y += inv_icm45600_spi.o
diff --git a/drivers/iio/imu/inv_icm45600/inv_icm45600_spi.c b/drivers/iio/imu/inv_icm45600/inv_icm45600_spi.c
new file mode 100644
index 0000000000000000000000000000000000000000..2fd4ecce24bd60aa2112e1bcae3f7196504df637
--- /dev/null
+++ b/drivers/iio/imu/inv_icm45600/inv_icm45600_spi.c
@@ -0,0 +1,106 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/* Copyright (C) 2025 InvenSense, Inc. */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/regmap.h>
+#include <linux/spi/spi.h>
+
+#include "inv_icm45600.h"
+
+static const struct regmap_config inv_icm45600_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+};
+
+static int inv_icm45600_spi_bus_setup(struct inv_icm45600_state *st)
+{
+ /* Set slew rates for SPI. */
+ return regmap_update_bits(st->map, INV_ICM45600_REG_DRIVE_CONFIG0,
+ INV_ICM45600_DRIVE_CONFIG0_SPI_MASK,
+ FIELD_PREP(INV_ICM45600_DRIVE_CONFIG0_SPI_MASK,
+ INV_ICM45600_SPI_SLEW_RATE_5NS));
+}
+
+static int inv_icm45600_probe(struct spi_device *spi)
+{
+ const struct inv_icm45600_chip_info *chip_info;
+ struct regmap *regmap;
+
+ chip_info = spi_get_device_match_data(spi);
+ if (!chip_info)
+ return -ENODEV;
+
+ /* Use SPI specific regmap. */
+ regmap = devm_regmap_init_spi(spi, &inv_icm45600_regmap_config);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+
+ return inv_icm45600_core_probe(regmap, chip_info, true,
+ inv_icm45600_spi_bus_setup);
+}
+
+/*
+ * The device id table is used to identify which device is
+ * supported by this driver.
+ */
+static const struct spi_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(spi, 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 spi_driver inv_icm45600_driver = {
+ .driver = {
+ .name = "inv-icm45600-spi",
+ .of_match_table = inv_icm45600_of_matches,
+ .pm = pm_ptr(&inv_icm45600_pm_ops),
+ },
+ .id_table = inv_icm45600_id,
+ .probe = inv_icm45600_probe,
+};
+module_spi_driver(inv_icm45600_driver);
+
+MODULE_AUTHOR("InvenSense, Inc.");
+MODULE_DESCRIPTION("InvenSense ICM-456xx SPI 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/20250710-170143 base: f8f559752d573a051a984adda8d2d1464f92f954 patch link: https://lore.kernel.org/r/20250710-add_newport_driver-v2-6-bf76d8142ef2%40tdk.com patch subject: [PATCH v2 6/8] iio: imu: inv_icm45600: add SPI driver for inv_icm45600 driver config: mips-randconfig-r072-20250711 (https://download.01.org/0day-ci/archive/20250711/202507111201.r62j5rb6-lkp@intel.com/config) compiler: clang version 21.0.0git (https://github.com/llvm/llvm-project 01c97b4953e87ae455bd4c41e3de3f0f0f29c61c) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250711/202507111201.r62j5rb6-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/202507111201.r62j5rb6-lkp@intel.com/ All warnings (new ones prefixed by >>): >> drivers/iio/imu/inv_icm45600/inv_icm45600_accel.c:107:7: warning: variable 'sleep' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized] 107 | if (*scan_mask & (BIT(INV_ICM45600_ACCEL_SCAN_X) | | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 108 | BIT(INV_ICM45600_ACCEL_SCAN_Y) | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 109 | BIT(INV_ICM45600_ACCEL_SCAN_Z))) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/iio/imu/inv_icm45600/inv_icm45600_accel.c:123:6: note: uninitialized use occurs here 123 | if (sleep) | ^~~~~ drivers/iio/imu/inv_icm45600/inv_icm45600_accel.c:107:3: note: remove the 'if' if its condition is always true 107 | if (*scan_mask & (BIT(INV_ICM45600_ACCEL_SCAN_X) | | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 108 | BIT(INV_ICM45600_ACCEL_SCAN_Y) | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 109 | BIT(INV_ICM45600_ACCEL_SCAN_Z))) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/iio/imu/inv_icm45600/inv_icm45600_accel.c:100:20: note: initialize the variable 'sleep' to silence this warning 100 | unsigned int sleep; | ^ | = 0 1 warning generated. -- >> drivers/iio/imu/inv_icm45600/inv_icm45600_gyro.c:107:7: warning: variable 'sleep' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized] 107 | if (*scan_mask & (BIT(INV_ICM45600_GYRO_SCAN_X) | | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 108 | BIT(INV_ICM45600_GYRO_SCAN_Y) | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 109 | BIT(INV_ICM45600_GYRO_SCAN_Z))) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/iio/imu/inv_icm45600/inv_icm45600_gyro.c:121:6: note: uninitialized use occurs here 121 | if (sleep) | ^~~~~ drivers/iio/imu/inv_icm45600/inv_icm45600_gyro.c:107:3: note: remove the 'if' if its condition is always true 107 | if (*scan_mask & (BIT(INV_ICM45600_GYRO_SCAN_X) | | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 108 | BIT(INV_ICM45600_GYRO_SCAN_Y) | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 109 | BIT(INV_ICM45600_GYRO_SCAN_Z))) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/iio/imu/inv_icm45600/inv_icm45600_gyro.c:100:20: note: initialize the variable 'sleep' to silence this warning 100 | unsigned int sleep; | ^ | = 0 1 warning generated. vim +107 drivers/iio/imu/inv_icm45600/inv_icm45600_accel.c 1fb5c2bf7348d06 Remi Buisson 2025-07-10 91 1fb5c2bf7348d06 Remi Buisson 2025-07-10 92 /* enable accelerometer sensor and FIFO write */ 1fb5c2bf7348d06 Remi Buisson 2025-07-10 93 static int inv_icm45600_accel_update_scan_mode(struct iio_dev *indio_dev, 1fb5c2bf7348d06 Remi Buisson 2025-07-10 94 const unsigned long *scan_mask) 1fb5c2bf7348d06 Remi Buisson 2025-07-10 95 { 1fb5c2bf7348d06 Remi Buisson 2025-07-10 96 struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev); 1fb5c2bf7348d06 Remi Buisson 2025-07-10 97 struct inv_icm45600_sensor_state *accel_st = iio_priv(indio_dev); 1fb5c2bf7348d06 Remi Buisson 2025-07-10 98 struct inv_icm45600_sensor_conf conf = INV_ICM45600_SENSOR_CONF_INIT; 1fb5c2bf7348d06 Remi Buisson 2025-07-10 99 unsigned int fifo_en = 0; 1fb5c2bf7348d06 Remi Buisson 2025-07-10 100 unsigned int sleep; 1fb5c2bf7348d06 Remi Buisson 2025-07-10 101 int ret; 1fb5c2bf7348d06 Remi Buisson 2025-07-10 102 1fb5c2bf7348d06 Remi Buisson 2025-07-10 103 scoped_guard(mutex, &st->lock) { 1fb5c2bf7348d06 Remi Buisson 2025-07-10 104 if (*scan_mask & BIT(INV_ICM45600_ACCEL_SCAN_TEMP)) 1fb5c2bf7348d06 Remi Buisson 2025-07-10 105 fifo_en |= INV_ICM45600_SENSOR_TEMP; 1fb5c2bf7348d06 Remi Buisson 2025-07-10 106 1fb5c2bf7348d06 Remi Buisson 2025-07-10 @107 if (*scan_mask & (BIT(INV_ICM45600_ACCEL_SCAN_X) | 1fb5c2bf7348d06 Remi Buisson 2025-07-10 108 BIT(INV_ICM45600_ACCEL_SCAN_Y) | 1fb5c2bf7348d06 Remi Buisson 2025-07-10 109 BIT(INV_ICM45600_ACCEL_SCAN_Z))) { 1fb5c2bf7348d06 Remi Buisson 2025-07-10 110 /* enable accel sensor */ 1fb5c2bf7348d06 Remi Buisson 2025-07-10 111 conf.mode = accel_st->power_mode; 1fb5c2bf7348d06 Remi Buisson 2025-07-10 112 ret = inv_icm45600_set_accel_conf(st, &conf, &sleep); 1fb5c2bf7348d06 Remi Buisson 2025-07-10 113 if (ret) 1fb5c2bf7348d06 Remi Buisson 2025-07-10 114 return ret; 1fb5c2bf7348d06 Remi Buisson 2025-07-10 115 fifo_en |= INV_ICM45600_SENSOR_ACCEL; 1fb5c2bf7348d06 Remi Buisson 2025-07-10 116 } 1fb5c2bf7348d06 Remi Buisson 2025-07-10 117 1fb5c2bf7348d06 Remi Buisson 2025-07-10 118 /* Update data FIFO write. */ 1fb5c2bf7348d06 Remi Buisson 2025-07-10 119 ret = inv_icm45600_buffer_set_fifo_en(st, fifo_en | st->fifo.en); 1fb5c2bf7348d06 Remi Buisson 2025-07-10 120 } 1fb5c2bf7348d06 Remi Buisson 2025-07-10 121 1fb5c2bf7348d06 Remi Buisson 2025-07-10 122 /* Sleep required time. */ 1fb5c2bf7348d06 Remi Buisson 2025-07-10 123 if (sleep) 1fb5c2bf7348d06 Remi Buisson 2025-07-10 124 msleep(sleep); 1fb5c2bf7348d06 Remi Buisson 2025-07-10 125 1fb5c2bf7348d06 Remi Buisson 2025-07-10 126 return ret; 1fb5c2bf7348d06 Remi Buisson 2025-07-10 127 } 1fb5c2bf7348d06 Remi Buisson 2025-07-10 128 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
On Fri, Jul 11, 2025 at 12:55:25PM +0800, kernel test robot wrote: > Hi Remi, > > drivers/iio/imu/inv_icm45600/inv_icm45600_accel.c:100:20: note: initialize the variable 'sleep' to silence this warning > 100 | unsigned int sleep; > | ^ > | = 0 For the record, this is usually bad advice by the compiler. You need to either check for errors, or do something else. > drivers/iio/imu/inv_icm45600/inv_icm45600_gyro.c:100:20: note: initialize the variable 'sleep' to silence this warning > 100 | unsigned int sleep; > | ^ > | = 0 Ditto. -- With Best Regards, Andy Shevchenko
© 2016 - 2025 Red Hat, Inc.