[PATCH v2 5/8] iio: imu: inv_icm45600: add I2C driver for inv_icm45600 driver

Remi Buisson via B4 Relay posted 8 patches 2 months, 4 weeks ago
There is a newer version of this series
[PATCH v2 5/8] iio: imu: inv_icm45600: add I2C driver for inv_icm45600 driver
Posted by Remi Buisson via B4 Relay 2 months, 4 weeks ago
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 ced5e1d9f2c10400cfa4878146672d41f815c22a..371585e29e92e78a30c7d40c1389548fa22a999a 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_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
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
Re: [PATCH v2 5/8] iio: imu: inv_icm45600: add I2C driver for inv_icm45600 driver
Posted by Dan Carpenter 2 months, 3 weeks ago
Hi Remi,

kernel test robot noticed the following build warnings:

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-5-bf76d8142ef2%40tdk.com
patch subject: [PATCH v2 5/8] iio: imu: inv_icm45600: add I2C driver for inv_icm45600 driver
config: s390-randconfig-r073-20250712 (https://download.01.org/0day-ci/archive/20250713/202507130115.7g0XWB2E-lkp@intel.com/config)
compiler: clang version 21.0.0git (https://github.com/llvm/llvm-project 01c97b4953e87ae455bd4c41e3de3f0f0f29c61c)

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>
| Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
| Closes: https://lore.kernel.org/r/202507130115.7g0XWB2E-lkp@intel.com/

smatch warnings:
drivers/iio/imu/inv_icm45600/inv_icm45600_gyro.c:121 inv_icm45600_gyro_update_scan_mode() error: uninitialized symbol 'sleep'.
drivers/iio/imu/inv_icm45600/inv_icm45600_accel.c:123 inv_icm45600_accel_update_scan_mode() error: uninitialized symbol 'sleep'.

vim +/sleep +121 drivers/iio/imu/inv_icm45600/inv_icm45600_gyro.c

1fb5c2bf7348d0 Remi Buisson 2025-07-10   93  static int inv_icm45600_gyro_update_scan_mode(struct iio_dev *indio_dev,
1fb5c2bf7348d0 Remi Buisson 2025-07-10   94  					      const unsigned long *scan_mask)
1fb5c2bf7348d0 Remi Buisson 2025-07-10   95  {
1fb5c2bf7348d0 Remi Buisson 2025-07-10   96  	struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev);
1fb5c2bf7348d0 Remi Buisson 2025-07-10   97  	struct inv_icm45600_sensor_state *gyro_st = iio_priv(indio_dev);
1fb5c2bf7348d0 Remi Buisson 2025-07-10   98  	struct inv_icm45600_sensor_conf conf = INV_ICM45600_SENSOR_CONF_INIT;
1fb5c2bf7348d0 Remi Buisson 2025-07-10   99  	unsigned int fifo_en = 0;
1fb5c2bf7348d0 Remi Buisson 2025-07-10  100  	unsigned int sleep;
1fb5c2bf7348d0 Remi Buisson 2025-07-10  101  	int ret;
1fb5c2bf7348d0 Remi Buisson 2025-07-10  102  
1fb5c2bf7348d0 Remi Buisson 2025-07-10  103  	scoped_guard(mutex, &st->lock) {
1fb5c2bf7348d0 Remi Buisson 2025-07-10  104  		if (*scan_mask & BIT(INV_ICM45600_GYRO_SCAN_TEMP))
1fb5c2bf7348d0 Remi Buisson 2025-07-10  105  			fifo_en |= INV_ICM45600_SENSOR_TEMP;
1fb5c2bf7348d0 Remi Buisson 2025-07-10  106  
1fb5c2bf7348d0 Remi Buisson 2025-07-10  107  		if (*scan_mask & (BIT(INV_ICM45600_GYRO_SCAN_X) |
1fb5c2bf7348d0 Remi Buisson 2025-07-10  108  				 BIT(INV_ICM45600_GYRO_SCAN_Y) |
1fb5c2bf7348d0 Remi Buisson 2025-07-10  109  				 BIT(INV_ICM45600_GYRO_SCAN_Z))) {
1fb5c2bf7348d0 Remi Buisson 2025-07-10  110  			/* enable gyro sensor */
1fb5c2bf7348d0 Remi Buisson 2025-07-10  111  			conf.mode = gyro_st->power_mode;
1fb5c2bf7348d0 Remi Buisson 2025-07-10  112  			ret = inv_icm45600_set_gyro_conf(st, &conf, &sleep);

sleep isn't necessarily set if nothing changed.

1fb5c2bf7348d0 Remi Buisson 2025-07-10  113  			if (ret)
1fb5c2bf7348d0 Remi Buisson 2025-07-10  114  				return ret;
1fb5c2bf7348d0 Remi Buisson 2025-07-10  115  			fifo_en |= INV_ICM45600_SENSOR_GYRO;
1fb5c2bf7348d0 Remi Buisson 2025-07-10  116  		}
1fb5c2bf7348d0 Remi Buisson 2025-07-10  117  		/* update data FIFO write */
1fb5c2bf7348d0 Remi Buisson 2025-07-10  118  		ret = inv_icm45600_buffer_set_fifo_en(st, fifo_en | st->fifo.en);
1fb5c2bf7348d0 Remi Buisson 2025-07-10  119  	}
1fb5c2bf7348d0 Remi Buisson 2025-07-10  120  	/* sleep required time */
1fb5c2bf7348d0 Remi Buisson 2025-07-10 @121  	if (sleep)
1fb5c2bf7348d0 Remi Buisson 2025-07-10  122  		msleep(sleep);
1fb5c2bf7348d0 Remi Buisson 2025-07-10  123  
1fb5c2bf7348d0 Remi Buisson 2025-07-10  124  	return ret;
1fb5c2bf7348d0 Remi Buisson 2025-07-10  125  }

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Re: [PATCH v2 5/8] iio: imu: inv_icm45600: add I2C driver for inv_icm45600 driver
Posted by Andy Shevchenko 2 months, 3 weeks ago
On Mon, Jul 14, 2025 at 11:21:17PM +0300, Dan Carpenter wrote:
> Hi Remi,
> 
> kernel test robot noticed the following build warnings:

It looks like a false positive, but the code is fragile.

> 1fb5c2bf7348d0 Remi Buisson 2025-07-10   99  	unsigned int fifo_en = 0;
> 1fb5c2bf7348d0 Remi Buisson 2025-07-10  100  	unsigned int sleep;
> 1fb5c2bf7348d0 Remi Buisson 2025-07-10  101  	int ret;
> 1fb5c2bf7348d0 Remi Buisson 2025-07-10  102  
> 1fb5c2bf7348d0 Remi Buisson 2025-07-10  103  	scoped_guard(mutex, &st->lock) {
> 1fb5c2bf7348d0 Remi Buisson 2025-07-10  104  		if (*scan_mask & BIT(INV_ICM45600_GYRO_SCAN_TEMP))
> 1fb5c2bf7348d0 Remi Buisson 2025-07-10  105  			fifo_en |= INV_ICM45600_SENSOR_TEMP;
> 1fb5c2bf7348d0 Remi Buisson 2025-07-10  106  
> 1fb5c2bf7348d0 Remi Buisson 2025-07-10  107  		if (*scan_mask & (BIT(INV_ICM45600_GYRO_SCAN_X) |
> 1fb5c2bf7348d0 Remi Buisson 2025-07-10  108  				 BIT(INV_ICM45600_GYRO_SCAN_Y) |
> 1fb5c2bf7348d0 Remi Buisson 2025-07-10  109  				 BIT(INV_ICM45600_GYRO_SCAN_Z))) {
> 1fb5c2bf7348d0 Remi Buisson 2025-07-10  110  			/* enable gyro sensor */
> 1fb5c2bf7348d0 Remi Buisson 2025-07-10  111  			conf.mode = gyro_st->power_mode;
> 1fb5c2bf7348d0 Remi Buisson 2025-07-10  112  			ret = inv_icm45600_set_gyro_conf(st, &conf, &sleep);
> 
> sleep isn't necessarily set if nothing changed.
> 
> 1fb5c2bf7348d0 Remi Buisson 2025-07-10  113  			if (ret)
> 1fb5c2bf7348d0 Remi Buisson 2025-07-10  114  				return ret;
> 1fb5c2bf7348d0 Remi Buisson 2025-07-10  115  			fifo_en |= INV_ICM45600_SENSOR_GYRO;
> 1fb5c2bf7348d0 Remi Buisson 2025-07-10  116  		}
> 1fb5c2bf7348d0 Remi Buisson 2025-07-10  117  		/* update data FIFO write */
> 1fb5c2bf7348d0 Remi Buisson 2025-07-10  118  		ret = inv_icm45600_buffer_set_fifo_en(st, fifo_en | st->fifo.en);
> 1fb5c2bf7348d0 Remi Buisson 2025-07-10  119  	}
> 1fb5c2bf7348d0 Remi Buisson 2025-07-10  120  	/* sleep required time */
> 1fb5c2bf7348d0 Remi Buisson 2025-07-10 @121  	if (sleep)
> 1fb5c2bf7348d0 Remi Buisson 2025-07-10  122  		msleep(sleep);
> 1fb5c2bf7348d0 Remi Buisson 2025-07-10  123  
> 1fb5c2bf7348d0 Remi Buisson 2025-07-10  124  	return ret;

-- 
With Best Regards,
Andy Shevchenko
Re: [PATCH v2 5/8] iio: imu: inv_icm45600: add I2C driver for inv_icm45600 driver
Posted by kernel test robot 2 months, 4 weeks ago
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-5-bf76d8142ef2%40tdk.com
patch subject: [PATCH v2 5/8] iio: imu: inv_icm45600: add I2C driver for inv_icm45600 driver
config: m68k-allmodconfig (https://download.01.org/0day-ci/archive/20250711/202507111539.F4FrQltx-lkp@intel.com/config)
compiler: m68k-linux-gcc (GCC) 15.1.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250711/202507111539.F4FrQltx-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/202507111539.F4FrQltx-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> drivers/iio/imu/inv_icm45600/inv_icm45600_core.c:894:12: warning: 'inv_icm45600_runtime_resume' defined but not used [-Wunused-function]
     894 | static int inv_icm45600_runtime_resume(struct device *dev)
         |            ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/iio/imu/inv_icm45600/inv_icm45600_core.c:875:12: warning: 'inv_icm45600_runtime_suspend' defined but not used [-Wunused-function]
     875 | static int inv_icm45600_runtime_suspend(struct device *dev)
         |            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/iio/imu/inv_icm45600/inv_icm45600_core.c:832:12: warning: 'inv_icm45600_resume' defined but not used [-Wunused-function]
     832 | static int inv_icm45600_resume(struct device *dev)
         |            ^~~~~~~~~~~~~~~~~~~
>> drivers/iio/imu/inv_icm45600/inv_icm45600_core.c:790:12: warning: 'inv_icm45600_suspend' defined but not used [-Wunused-function]
     790 | static int inv_icm45600_suspend(struct device *dev)
         |            ^~~~~~~~~~~~~~~~~~~~


vim +/inv_icm45600_runtime_resume +894 drivers/iio/imu/inv_icm45600/inv_icm45600_core.c

01fd98fed267cd Remi Buisson 2025-07-10  785  
01fd98fed267cd Remi Buisson 2025-07-10  786  /*
01fd98fed267cd Remi Buisson 2025-07-10  787   * Suspend saves sensors state and turns everything off.
01fd98fed267cd Remi Buisson 2025-07-10  788   * Check first if runtime suspend has not already done the job.
01fd98fed267cd Remi Buisson 2025-07-10  789   */
01fd98fed267cd Remi Buisson 2025-07-10 @790  static int inv_icm45600_suspend(struct device *dev)
01fd98fed267cd Remi Buisson 2025-07-10  791  {
01fd98fed267cd Remi Buisson 2025-07-10  792  	struct inv_icm45600_state *st = dev_get_drvdata(dev);
01fd98fed267cd Remi Buisson 2025-07-10  793  	int ret;
01fd98fed267cd Remi Buisson 2025-07-10  794  
01fd98fed267cd Remi Buisson 2025-07-10  795  	guard(mutex)(&st->lock);
01fd98fed267cd Remi Buisson 2025-07-10  796  
01fd98fed267cd Remi Buisson 2025-07-10  797  	st->suspended.gyro = st->conf.gyro.mode;
01fd98fed267cd Remi Buisson 2025-07-10  798  	st->suspended.accel = st->conf.accel.mode;
01fd98fed267cd Remi Buisson 2025-07-10  799  	if (pm_runtime_suspended(dev))
01fd98fed267cd Remi Buisson 2025-07-10  800  		return 0;
01fd98fed267cd Remi Buisson 2025-07-10  801  
eaedaea6990c59 Remi Buisson 2025-07-10  802  	/* Disable FIFO data streaming. */
eaedaea6990c59 Remi Buisson 2025-07-10  803  	if (st->fifo.on) {
eaedaea6990c59 Remi Buisson 2025-07-10  804  		unsigned int val;
eaedaea6990c59 Remi Buisson 2025-07-10  805  
eaedaea6990c59 Remi Buisson 2025-07-10  806  		ret = regmap_clear_bits(st->map, INV_ICM45600_REG_FIFO_CONFIG3,
eaedaea6990c59 Remi Buisson 2025-07-10  807  					INV_ICM45600_FIFO_CONFIG3_IF_EN);
eaedaea6990c59 Remi Buisson 2025-07-10  808  		if (ret)
eaedaea6990c59 Remi Buisson 2025-07-10  809  			return ret;
eaedaea6990c59 Remi Buisson 2025-07-10  810  		val = FIELD_PREP(INV_ICM45600_FIFO_CONFIG0_MODE_MASK,
eaedaea6990c59 Remi Buisson 2025-07-10  811  			INV_ICM45600_FIFO_CONFIG0_MODE_BYPASS);
eaedaea6990c59 Remi Buisson 2025-07-10  812  		ret = regmap_update_bits(st->map, INV_ICM45600_REG_FIFO_CONFIG0,
eaedaea6990c59 Remi Buisson 2025-07-10  813  					 INV_ICM45600_FIFO_CONFIG0_MODE_MASK, val);
eaedaea6990c59 Remi Buisson 2025-07-10  814  		if (ret)
eaedaea6990c59 Remi Buisson 2025-07-10  815  			return ret;
eaedaea6990c59 Remi Buisson 2025-07-10  816  	}
eaedaea6990c59 Remi Buisson 2025-07-10  817  
01fd98fed267cd Remi Buisson 2025-07-10  818  	ret = inv_icm45600_set_pwr_mgmt0(st, INV_ICM45600_SENSOR_MODE_OFF,
01fd98fed267cd Remi Buisson 2025-07-10  819  					 INV_ICM45600_SENSOR_MODE_OFF, NULL);
01fd98fed267cd Remi Buisson 2025-07-10  820  	if (ret)
01fd98fed267cd Remi Buisson 2025-07-10  821  		return ret;
01fd98fed267cd Remi Buisson 2025-07-10  822  
01fd98fed267cd Remi Buisson 2025-07-10  823  	regulator_disable(st->vddio_supply);
01fd98fed267cd Remi Buisson 2025-07-10  824  
01fd98fed267cd Remi Buisson 2025-07-10  825  	return 0;
01fd98fed267cd Remi Buisson 2025-07-10  826  }
01fd98fed267cd Remi Buisson 2025-07-10  827  
01fd98fed267cd Remi Buisson 2025-07-10  828  /*
01fd98fed267cd Remi Buisson 2025-07-10  829   * System resume gets the system back on and restores the sensors state.
01fd98fed267cd Remi Buisson 2025-07-10  830   * Manually put runtime power management in system active state.
01fd98fed267cd Remi Buisson 2025-07-10  831   */
01fd98fed267cd Remi Buisson 2025-07-10 @832  static int inv_icm45600_resume(struct device *dev)
01fd98fed267cd Remi Buisson 2025-07-10  833  {
01fd98fed267cd Remi Buisson 2025-07-10  834  	struct inv_icm45600_state *st = dev_get_drvdata(dev);
eaedaea6990c59 Remi Buisson 2025-07-10  835  	struct inv_icm45600_sensor_state *gyro_st = iio_priv(st->indio_gyro);
eaedaea6990c59 Remi Buisson 2025-07-10  836  	struct inv_icm45600_sensor_state *accel_st = iio_priv(st->indio_accel);
01fd98fed267cd Remi Buisson 2025-07-10  837  	int ret;
01fd98fed267cd Remi Buisson 2025-07-10  838  
01fd98fed267cd Remi Buisson 2025-07-10  839  	guard(mutex)(&st->lock);
01fd98fed267cd Remi Buisson 2025-07-10  840  
01fd98fed267cd Remi Buisson 2025-07-10  841  	ret = inv_icm45600_enable_regulator_vddio(st);
01fd98fed267cd Remi Buisson 2025-07-10  842  	if (ret)
01fd98fed267cd Remi Buisson 2025-07-10  843  		return ret;
01fd98fed267cd Remi Buisson 2025-07-10  844  
01fd98fed267cd Remi Buisson 2025-07-10  845  	pm_runtime_disable(dev);
01fd98fed267cd Remi Buisson 2025-07-10  846  	pm_runtime_set_active(dev);
01fd98fed267cd Remi Buisson 2025-07-10  847  	pm_runtime_enable(dev);
01fd98fed267cd Remi Buisson 2025-07-10  848  
01fd98fed267cd Remi Buisson 2025-07-10  849  	/* Restore sensors state. */
eaedaea6990c59 Remi Buisson 2025-07-10  850  	ret = inv_icm45600_set_pwr_mgmt0(st, st->suspended.gyro,
01fd98fed267cd Remi Buisson 2025-07-10  851  					 st->suspended.accel, NULL);
eaedaea6990c59 Remi Buisson 2025-07-10  852  	if (ret)
eaedaea6990c59 Remi Buisson 2025-07-10  853  		return ret;
01fd98fed267cd Remi Buisson 2025-07-10  854  
eaedaea6990c59 Remi Buisson 2025-07-10  855  	/* Restore FIFO data streaming. */
eaedaea6990c59 Remi Buisson 2025-07-10  856  	if (st->fifo.on) {
eaedaea6990c59 Remi Buisson 2025-07-10  857  		unsigned int val;
eaedaea6990c59 Remi Buisson 2025-07-10  858  
eaedaea6990c59 Remi Buisson 2025-07-10  859  		inv_sensors_timestamp_reset(&gyro_st->ts);
eaedaea6990c59 Remi Buisson 2025-07-10  860  		inv_sensors_timestamp_reset(&accel_st->ts);
eaedaea6990c59 Remi Buisson 2025-07-10  861  		val = FIELD_PREP(INV_ICM45600_FIFO_CONFIG0_MODE_MASK,
eaedaea6990c59 Remi Buisson 2025-07-10  862  			INV_ICM45600_FIFO_CONFIG0_MODE_STREAM);
eaedaea6990c59 Remi Buisson 2025-07-10  863  		ret = regmap_update_bits(st->map, INV_ICM45600_REG_FIFO_CONFIG0,
eaedaea6990c59 Remi Buisson 2025-07-10  864  					 INV_ICM45600_FIFO_CONFIG0_MODE_MASK, val);
eaedaea6990c59 Remi Buisson 2025-07-10  865  		if (ret)
eaedaea6990c59 Remi Buisson 2025-07-10  866  			return ret;
eaedaea6990c59 Remi Buisson 2025-07-10  867  		ret = regmap_set_bits(st->map, INV_ICM45600_REG_FIFO_CONFIG3,
eaedaea6990c59 Remi Buisson 2025-07-10  868  				      INV_ICM45600_FIFO_CONFIG3_IF_EN);
eaedaea6990c59 Remi Buisson 2025-07-10  869  	}
eaedaea6990c59 Remi Buisson 2025-07-10  870  
eaedaea6990c59 Remi Buisson 2025-07-10  871  	return ret;
01fd98fed267cd Remi Buisson 2025-07-10  872  }
01fd98fed267cd Remi Buisson 2025-07-10  873  
01fd98fed267cd Remi Buisson 2025-07-10  874  /* Runtime suspend will turn off sensors that are enabled by iio devices. */
01fd98fed267cd Remi Buisson 2025-07-10 @875  static int inv_icm45600_runtime_suspend(struct device *dev)
01fd98fed267cd Remi Buisson 2025-07-10  876  {
01fd98fed267cd Remi Buisson 2025-07-10  877  	struct inv_icm45600_state *st = dev_get_drvdata(dev);
01fd98fed267cd Remi Buisson 2025-07-10  878  	int ret;
01fd98fed267cd Remi Buisson 2025-07-10  879  
01fd98fed267cd Remi Buisson 2025-07-10  880  	guard(mutex)(&st->lock);
01fd98fed267cd Remi Buisson 2025-07-10  881  
01fd98fed267cd Remi Buisson 2025-07-10  882  	/* disable all sensors */
01fd98fed267cd Remi Buisson 2025-07-10  883  	ret = inv_icm45600_set_pwr_mgmt0(st, INV_ICM45600_SENSOR_MODE_OFF,
01fd98fed267cd Remi Buisson 2025-07-10  884  					 INV_ICM45600_SENSOR_MODE_OFF, NULL);
01fd98fed267cd Remi Buisson 2025-07-10  885  	if (ret)
01fd98fed267cd Remi Buisson 2025-07-10  886  		return ret;
01fd98fed267cd Remi Buisson 2025-07-10  887  
01fd98fed267cd Remi Buisson 2025-07-10  888  	regulator_disable(st->vddio_supply);
01fd98fed267cd Remi Buisson 2025-07-10  889  
01fd98fed267cd Remi Buisson 2025-07-10  890  	return 0;
01fd98fed267cd Remi Buisson 2025-07-10  891  }
01fd98fed267cd Remi Buisson 2025-07-10  892  
01fd98fed267cd Remi Buisson 2025-07-10  893  /* Sensors are enabled by iio devices, no need to turn them back on here. */
01fd98fed267cd Remi Buisson 2025-07-10 @894  static int inv_icm45600_runtime_resume(struct device *dev)
01fd98fed267cd Remi Buisson 2025-07-10  895  {
01fd98fed267cd Remi Buisson 2025-07-10  896  	struct inv_icm45600_state *st = dev_get_drvdata(dev);
01fd98fed267cd Remi Buisson 2025-07-10  897  
01fd98fed267cd Remi Buisson 2025-07-10  898  	guard(mutex)(&st->lock);
01fd98fed267cd Remi Buisson 2025-07-10  899  
01fd98fed267cd Remi Buisson 2025-07-10  900  	return inv_icm45600_enable_regulator_vddio(st);
01fd98fed267cd Remi Buisson 2025-07-10  901  }
01fd98fed267cd Remi Buisson 2025-07-10  902  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki