Add Invensense ICM42607
Subsystems (3)
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.
Chris Morgan (3):
dt-bindings: iio: imu: icm42607: Add devicetree binding
iio: imu: inv_icm42607: add new inv_icm42607 driver
arm64: dts: rockchip: Add icm42607p IMU for RG-DS
.../bindings/iio/imu/invensense,icm42607.yaml | 92 ++ .../dts/rockchip/rk3568-anbernic-rg-ds.dts | 20 +- drivers/iio/imu/Kconfig | 1 + drivers/iio/imu/Makefile | 1 + drivers/iio/imu/inv_icm42607/Kconfig | 30 + drivers/iio/imu/inv_icm42607/Makefile | 14 + drivers/iio/imu/inv_icm42607/inv_icm42607.h | 472 ++++++++ .../iio/imu/inv_icm42607/inv_icm42607_accel.c | 1025 +++++++++++++++++ .../imu/inv_icm42607/inv_icm42607_buffer.c | 566 +++++++++ .../imu/inv_icm42607/inv_icm42607_buffer.h | 100 ++ .../iio/imu/inv_icm42607/inv_icm42607_core.c | 811 +++++++++++++ .../iio/imu/inv_icm42607/inv_icm42607_gyro.c | 578 ++++++++++ .../iio/imu/inv_icm42607/inv_icm42607_i2c.c | 93 ++ .../iio/imu/inv_icm42607/inv_icm42607_spi.c | 100 ++ .../iio/imu/inv_icm42607/inv_icm42607_temp.c | 82 ++ .../iio/imu/inv_icm42607/inv_icm42607_temp.h | 30 + 16 files changed, 4014 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/iio/imu/invensense,icm42607.yaml create mode 100644 drivers/iio/imu/inv_icm42607/Kconfig create mode 100644 drivers/iio/imu/inv_icm42607/Makefile create mode 100644 drivers/iio/imu/inv_icm42607/inv_icm42607.h create mode 100644 drivers/iio/imu/inv_icm42607/inv_icm42607_accel.c create mode 100644 drivers/iio/imu/inv_icm42607/inv_icm42607_buffer.c create mode 100644 drivers/iio/imu/inv_icm42607/inv_icm42607_buffer.h create mode 100644 drivers/iio/imu/inv_icm42607/inv_icm42607_core.c create mode 100644 drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c create mode 100644 drivers/iio/imu/inv_icm42607/inv_icm42607_i2c.c create mode 100644 drivers/iio/imu/inv_icm42607/inv_icm42607_spi.c create mode 100644 drivers/iio/imu/inv_icm42607/inv_icm42607_temp.c create mode 100644 drivers/iio/imu/inv_icm42607/inv_icm42607_temp.h
Signature · 1 line
2.43.0
PATCH 1/3 dt-bindings: iio: imu: icm42607: Add devicetree binding
From: Chris Morgan <[email protected]>
Add devicetree binding for the Invensense ICM42607 and Invensense ICM42607P inertial measurement unit. This unit is a combined accelerometer, gyroscope, and thermometer available via I2C or SPI.
This device is functionally very similar to the icm42600 series with a very different register layout.
--- .../bindings/iio/imu/invensense,icm42607.yaml | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/imu/invensense,icm42607.yaml
Documentation/devicetree/bindings/iio/imu/invensense,icm42607.yaml new file +92 -0
@@ -0,0 +1,92 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/imu/invensense,icm42607.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: InvenSense ICM-42607 Inertial Measurement Unit + +description: | + 6-axis MotionTracking device that combines a 3-axis gyroscope and a 3-axis + accelerometer. + +properties: + compatible: + enum: + - invensense,icm42607 + - invensense,icm42607p + reg: + maxItems: 1 + + interrupts: + minItems: 1 + maxItems: 2 + + interrupt-names: + minItems: 1 + maxItems: 2 + items: + enum: + - INT1 + - INT2 + + drive-open-drain: + type: boolean + + mount-matrix: true + + spi-cpha: true + spi-cpol: true + + vdd-supply: + description: Regulator that provides power to the sensor + + vddio-supply: + description: Regulator that provides power to the bus + +required: + - compatible + - reg + - interrupts + +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# + +unevaluatedProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/irq.h> + i2c { + #address-cells = <1>; + #size-cells = <0>; + + icm42607p@68 { + compatible = "invensense,icm42607p"; + reg = <0x68>; + interrupt-parent = <&gpio2>; + interrupts = <7 IRQ_TYPE_EDGE_FALLING>; + interrupt-names = "INT1"; + vdd-supply = <&vdd>; + vddio-supply = <&vddio>; + }; + }; + - | + #include <dt-bindings/interrupt-controller/irq.h> + spi { + #address-cells = <1>; + #size-cells = <0>; + + icm42607p@0 { + compatible = "invensense,icm42607p"; + reg = <0>; + spi-max-frequency = <24000000>; + spi-cpha; + spi-cpol; + interrupt-parent = <&gpio1>; + interrupts = <2 IRQ_TYPE_EDGE_FALLING>; + interrupt-names = "INT1"; + vdd-supply = <&vdd>; + vddio-supply = <&vddio>; + }; + };
Signature · 1 line
2.43.0
Rob Herring (Arm)
maintainerRe: [PATCH 1/3] dt-bindings: iio: imu: icm42607: Add devicetree binding
Quoted 6 lines · Chris Morgan
From: Chris Morgan <[email protected]>
Add devicetree binding for the Invensense ICM42607 and Invensense ICM42607P inertial measurement unit. This unit is a combined accelerometer, gyroscope, and thermometer available via I2C or SPI.
Quoted 9 lines
This device is functionally very similar to the icm42600 series with a very different register layout.
Signed-off-by Chris Morgan <[email protected]>--- .../bindings/iio/imu/invensense,icm42607.yaml | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/imu/invensense,icm42607.yaml
My bot found errors running 'make dt_binding_check' on your patch:
yamllint warnings/errors:
dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/iio/imu/invensense,icm42607.yaml: 'maintainers' is a required property
hint: Metaschema for devicetree binding documentation
from schema $id: http://devicetree.org/meta-schemas/base.yaml
doc reference errors (make refcheckdocs):
See https://patchwork.kernel.org/project/devicetree/patch/[email protected]
The base for the series is generally the latest rc1. A different dependency should be noted in *this* patch.
If you already ran 'make dt_binding_check' and didn't see the above error(s), then make sure 'yamllint' is installed and dt-schema is up to date:
pip3 install dtschema --upgrade
Please check and re-submit after running the above command yourself. Note that DT_SCHEMA_FILES can be set to your schema file to speed up checking your schema. However, it must be unset to test all examples with your schema.
PATCH 2/3 iio: imu: inv_icm42607: add new inv_icm42607 driver
In reply to Chris MorganFrom: Chris Morgan <[email protected]>
Add a new driver for the Invensense ICM42607 IMU. This device is extremely similar to the existing ICM42600 but with a very different register layout.
This driver was built 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. The driver is structured identically to the in-tree ICM42600 driver.
It should work for the ICM42607 and ICM42607P on both the I2C and SPI busses, however only the ICM42607P over I2C has been tested as it is the only hardware I have available.
[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/Kconfig | 1 + drivers/iio/imu/Makefile | 1 + drivers/iio/imu/inv_icm42607/Kconfig | 30 + drivers/iio/imu/inv_icm42607/Makefile | 14 + drivers/iio/imu/inv_icm42607/inv_icm42607.h | 472 ++++++++ .../iio/imu/inv_icm42607/inv_icm42607_accel.c | 1025 +++++++++++++++++ .../imu/inv_icm42607/inv_icm42607_buffer.c | 566 +++++++++ .../imu/inv_icm42607/inv_icm42607_buffer.h | 100 ++ .../iio/imu/inv_icm42607/inv_icm42607_core.c | 811 +++++++++++++ .../iio/imu/inv_icm42607/inv_icm42607_gyro.c | 578 ++++++++++ .../iio/imu/inv_icm42607/inv_icm42607_i2c.c | 93 ++ .../iio/imu/inv_icm42607/inv_icm42607_spi.c | 100 ++ .../iio/imu/inv_icm42607/inv_icm42607_temp.c | 82 ++ .../iio/imu/inv_icm42607/inv_icm42607_temp.h | 30 + 14 files changed, 3903 insertions(+) create mode 100644 drivers/iio/imu/inv_icm42607/Kconfig create mode 100644 drivers/iio/imu/inv_icm42607/Makefile create mode 100644 drivers/iio/imu/inv_icm42607/inv_icm42607.h create mode 100644 drivers/iio/imu/inv_icm42607/inv_icm42607_accel.c create mode 100644 drivers/iio/imu/inv_icm42607/inv_icm42607_buffer.c create mode 100644 drivers/iio/imu/inv_icm42607/inv_icm42607_buffer.h create mode 100644 drivers/iio/imu/inv_icm42607/inv_icm42607_core.c create mode 100644 drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c create mode 100644 drivers/iio/imu/inv_icm42607/inv_icm42607_i2c.c create mode 100644 drivers/iio/imu/inv_icm42607/inv_icm42607_spi.c create mode 100644 drivers/iio/imu/inv_icm42607/inv_icm42607_temp.c create mode 100644 drivers/iio/imu/inv_icm42607/inv_icm42607_temp.h
drivers/iio/imu/Kconfig +1 -0
@@ -109,6 +109,7 @@ config KMX61 be called kmx61. source "drivers/iio/imu/inv_icm42600/Kconfig" +source "drivers/iio/imu/inv_icm42607/Kconfig" source "drivers/iio/imu/inv_icm45600/Kconfig" source "drivers/iio/imu/inv_mpu6050/Kconfig"
drivers/iio/imu/Makefile +1 -0
@@ -25,6 +25,7 @@ obj-$(CONFIG_FXOS8700_I2C) += fxos8700_i2c.o obj-$(CONFIG_FXOS8700_SPI) += fxos8700_spi.o obj-y += inv_icm42600/ +obj-y += inv_icm42607/ obj-y += inv_icm45600/ obj-y += inv_mpu6050/
drivers/iio/imu/inv_icm42607/Kconfig new file +30 -0
@@ -0,0 +1,30 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +config INV_ICM42607 + tristate + select IIO_BUFFER + select IIO_INV_SENSORS_TIMESTAMP + +config INV_ICM42607_I2C + tristate "InvenSense ICM-42607X I2C driver" + depends on I2C + select INV_ICM42607 + select REGMAP_I2C + help + This driver supports the InvenSense ICM-42607 motion tracking + device over I2C. + + This driver can be built as a module. The module will be called + inv-icm42607-i2c. + +config INV_ICM42607_SPI + tristate "InvenSense ICM-42607X SPI driver" + depends on SPI_MASTER + select INV_ICM42607 + select REGMAP_SPI + help + This driver supports the InvenSense ICM-42607 motion tracking + device over SPI. + + This driver can be built as a module. The module will be called + inv-icm42607-spi.
drivers/iio/imu/inv_icm42607/Makefile new file +14 -0
@@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +obj-$(CONFIG_INV_ICM42607) += inv-icm42607.o +inv-icm42607-y += inv_icm42607_core.o +inv-icm42607-y += inv_icm42607_gyro.o +inv-icm42607-y += inv_icm42607_accel.o +inv-icm42607-y += inv_icm42607_buffer.o +inv-icm42607-y += inv_icm42607_temp.o + +obj-$(CONFIG_INV_ICM42607_I2C) += inv-icm42607-i2c.o +inv-icm42607-i2c-y += inv_icm42607_i2c.o + +obj-$(CONFIG_INV_ICM42607_SPI) += inv-icm42607-spi.o +inv-icm42607-spi-y += inv_icm42607_spi.o
drivers/iio/imu/inv_icm42607/inv_icm42607.h new file +472 -0
472 lines not on this page · raw message
drivers/iio/imu/inv_icm42607/inv_icm42607_accel.c new file +1025 -0
1,025 lines not on this page · raw message
drivers/iio/imu/inv_icm42607/inv_icm42607_buffer.c new file +566 -0
566 lines not on this page · raw message
drivers/iio/imu/inv_icm42607/inv_icm42607_buffer.h new file +100 -0
100 lines not on this page · raw message
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c new file +811 -0
779 lines not on this page · raw message
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +578 -0
578 lines not on this page · raw message
drivers/iio/imu/inv_icm42607/inv_icm42607_i2c.c new file +93 -0
93 lines not on this page · raw message
drivers/iio/imu/inv_icm42607/inv_icm42607_spi.c new file +100 -0
100 lines not on this page · raw message
drivers/iio/imu/inv_icm42607/inv_icm42607_temp.c new file +82 -0
82 lines not on this page · raw message
drivers/iio/imu/inv_icm42607/inv_icm42607_temp.h new file +30 -0
Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
Signature · 1 line
2.43.0
Part of the diff is not shown here. View the raw message.
kernel test robot
build botRe: [PATCH 2/3] iio: imu: inv_icm42607: add new inv_icm42607 driver
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-rc1 next-20260224] [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-icm42607-Add-devicetree-binding/20260225-003610 base: https://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git for-next patch link: https://lore.kernel.org/r/20260224163109.370930-3-macroalpha82%40gmail.com patch subject: [PATCH 2/3] iio: imu: inv_icm42607: add new inv_icm42607 driver config: sh-allyesconfig (https://download.01.org/0day-ci/archive/20260225/[email protected]/config) compiler: sh4-linux-gcc (GCC) 15.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260225/[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_icm42607/inv_icm42607_core.c: In function 'inv_icm42607_suspend':
>> drivers/iio/imu/inv_icm42607/inv_icm42607_core.c:670:13: warning: variable 'accel_conf' set but not used [-Wunused-but-set-variable]
670 | int accel_conf;
| ^~~~~~~~~~
--
>> drivers/iio/imu/inv_icm42607/inv_icm42607_accel.c:200:36: warning: 'inv_icm42607_motion_events' defined but not used [-Wunused-const-variable=]
200 | static const struct iio_event_spec inv_icm42607_motion_events[] = {
| ^~~~~~~~~~~~~~~~~~~~~~~~~~vim +/accel_conf +670 drivers/iio/imu/inv_icm42607/inv_icm42607_core.c
660
661 /*
662 * Suspend saves sensors state and turns everything off.
663 * Check first if runtime suspend has not already done the job.
664 */
665 static int inv_icm42607_suspend(struct device *dev)
666 {
667 struct inv_icm42607_state *st = dev_get_drvdata(dev);
668 struct device *accel_dev;
669 bool wakeup;
> 670 int accel_conf;
671 int ret = 0;
672
673 guard(mutex)(&st->lock);
674
675 st->suspended.gyro = st->conf.gyro.mode;
676 st->suspended.accel = st->conf.accel.mode;
677 st->suspended.temp = st->conf.temp_en;
678 if (pm_runtime_suspended(dev))
679 return 0;
680
681 if (st->fifo.on) {
682 ret = regmap_write(st->map, INV_ICM42607_REG_FIFO_CONFIG1,
683 INV_ICM42607_FIFO_CONFIG1_BYPASS);
684 if (ret)
685 return ret;
686 }
687
688 /* keep chip on and wake-up capable if APEX and wakeup on */
689 accel_dev = &st->indio_accel->dev;
690 wakeup = st->apex.on && device_may_wakeup(accel_dev);
691 if (wakeup) {
692 /* keep accel on and setup irq for wakeup */
693 accel_conf = st->conf.accel.mode;
694 enable_irq_wake(st->irq);
695 disable_irq(st->irq);
696 } else {
697 /* disable APEX features and accel if wakeup disabled */
698 if (st->apex.wom.enable) {
699 ret = inv_icm42607_disable_wom(st);
700 if (ret)
701 return ret;
702 }
703 accel_conf = INV_ICM42607_SENSOR_MODE_OFF;
704 }
705
706 ret = inv_icm42607_set_pwr_mgmt0(st, INV_ICM42607_SENSOR_MODE_OFF,
707 INV_ICM42607_SENSOR_MODE_OFF, false,
708 NULL);
709 if (ret)
710 return ret;
711
712 if (!wakeup)
713 regulator_disable(st->vddio_supply);
714
715 return 0;
716 }
717
Signature · 2 lines
0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
kernel test robot
build botRe: [PATCH 2/3] iio: imu: inv_icm42607: add new inv_icm42607 driver
In reply to Chris Morgankernel 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-rc1 next-20260224] [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-icm42607-Add-devicetree-binding/20260225-003610 base: https://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git for-next patch link: https://lore.kernel.org/r/20260224163109.370930-3-macroalpha82%40gmail.com patch subject: [PATCH 2/3] iio: imu: inv_icm42607: add new inv_icm42607 driver config: hexagon-allmodconfig (https://download.01.org/0day-ci/archive/20260225/[email protected]/config) compiler: clang version 17.0.6 (https://github.com/llvm/llvm-project 6009708b4367171ccdbf4b5905cb6a803753fe18) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260225/[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_icm42607/inv_icm42607_accel.c:200:36: warning: unused variable 'inv_icm42607_motion_events' [-Wunused-const-variable]
200 | static const struct iio_event_spec inv_icm42607_motion_events[] = {
| ^~~~~~~~~~~~~~~~~~~~~~~~~~1 warning generated.
vim +/inv_icm42607_motion_events +200 drivers/iio/imu/inv_icm42607/inv_icm42607_accel.c
199
> 200 static const struct iio_event_spec inv_icm42607_motion_events[] = { 201 {
202 .type = IIO_EV_TYPE_THRESH,
203 .dir = IIO_EV_DIR_EITHER,
204 .mask_separate = BIT(IIO_EV_INFO_ENABLE) | BIT(IIO_EV_INFO_VALUE),
205 },
206 };
207
Signature · 2 lines
0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
kernel test robot
build botRe: [PATCH 2/3] iio: imu: inv_icm42607: add new inv_icm42607 driver
In reply to Chris Morgankernel test robot noticed the following build errors:
Hi Chris,
kernel test robot noticed the following build errors:
[auto build test ERROR on rockchip/for-next]
[also build test ERROR on linus/master v7.0-rc1 next-20260224] [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-icm42607-Add-devicetree-binding/20260225-003610 base: https://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git for-next patch link: https://lore.kernel.org/r/20260224163109.370930-3-macroalpha82%40gmail.com patch subject: [PATCH 2/3] iio: imu: inv_icm42607: add new inv_icm42607 driver config: parisc-allyesconfig (https://download.01.org/0day-ci/archive/20260225/[email protected]/config) compiler: hppa-linux-gcc (GCC) 15.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260225/[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 errors (new ones prefixed by >>):
>> hppa-linux-ld: drivers/iio/imu/inv_icm42607/inv_icm42607_spi.o:(.data+0x50): undefined reference to `inv_icm42607_pm_ops'
Signature · 2 lines
0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
Jonathan Cameron
maintainerRe: [PATCH 2/3] iio: imu: inv_icm42607: add new inv_icm42607 driver
In reply to Chris MorganQuoted 12 lines · On Tue, 24 Feb 2026 10:31:04 -0600 Chris Morgan <[email protected]> wrote:
From: Chris Morgan <[email protected]>
Add a new driver for the Invensense ICM42607 IMU. This device is extremely similar to the existing ICM42600 but with a very different register layout.
This driver was built 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. The driver is structured identically to the in-tree ICM42600 driver.
Quoted 8 lines
It should work for the ICM42607 and ICM42607P on both the I2C and SPI busses, however only the ICM42607P over I2C has been tested as it is the only hardware I have available.
[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_icm42670Signed-off-by Chris Morgan <[email protected]>
Hi Chris,
I decided to take a quick look to hopefully be able to point out some minor things that make sense to fix for your split up version.
Jonathan
Quoted 12 lines
drivers/iio/imu/inv_icm42607/inv_icm42607.h new file +5
-0@@ -0,0 +1,472 @@ + +/* ODR values */ +enum inv_icm42607_odr { +INV_ICM42607_ODR_1600HZ =5 , +INV_ICM42607_ODR_800HZ ,
drivers/iio/imu/inv_icm42607/inv_icm42607.h line 76
Quoted 10 lines
drivers/iio/imu/inv_icm42607/inv_icm42607.h new file +10
-0+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,
This is another type of terminating entry, so no comma.
(see below for more on this and make sure to fix all the cases of the same thing)
Quoted 11 lines
drivers/iio/imu/inv_icm42607/inv_icm42607.h new file +1
-0+};drivers/iio/imu/inv_icm42607/inv_icm42607_buffer.c new file +2
-0@@ -0,0 +1,566 @@ + +static size_t inv_icm42607_get_packet_size (unsigned int fifo_en)
drivers/iio/imu/inv_icm42607/inv_icm42607_buffer.c line 154
Quoted 10 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_buffer.c new file +10
-0+{ +size_t packet_size; + +if ((fifo_en &INV_ICM42607_SENSOR_GYRO ) && + (fifo_en &INV_ICM42607_SENSOR_ACCEL )) + packet_size =INV_ICM42607_FIFO_2SENSORS_PACKET_SIZE ; +else + packet_size =INV_ICM42607_FIFO_1SENSOR_PACKET_SIZE ; + +return packet_size;
Not a lot of point in the local variable. I'd get rid of it and just do
return INV_ICM42607_FIFO_2SENSORS_PACKET_SIZE;
Quoted 35 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_buffer.c new file +2
-0+} +drivers/iio/imu/inv_icm42607/inv_icm42607_buffer.h new file +0
-0drivers/iio/imu/inv_icm42607/inv_icm42607_core.c new file +20
-0@@ -0,0 +1,811 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* +* Copyright (C) 2026 InvenSense, Inc. +*/ + +#include <linux/kernel.h> +#include <linux/device.h> +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/delay.h> +#include <linux/mutex.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/regulator/consumer.h> +#include <linux/pm_runtime.h> +#include <linux/property.h> +#include <linux/regmap.h> +#include <linux/iio/iio.h> + +#include "inv_icm42607.h"
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c line 30
Quoted 10 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c new file +10
-0+#include "inv_icm42607_buffer.h" + +static const struct regmap_range_cfg inv_icm42607_regmap_ranges[] = { + { + .name ="user bank" , + .range_min =0x0000 , + .range_max =0x00FF , + .selector_reg =0 ,/* not used */ + .selector_mask =0 ,/* not used */ + .selector_shift =0 ,/* not used */
The defaults of these are otherwise 0. So what's the point in setting them explicitly here? I don't mind if it provides useful educational value.
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c line 96
Quoted 12 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c new file +11
-0+ .window_start = 0, + .window_len = 0x0100, + }, +}; + +u32 inv_icm42607_odr_to_period (enum inv_icm42607_odr odr) +{ +static u32 odr_periods[INV_ICM42607_ODR_NB ] = { +/* Reserved values */ +0 ,0 ,0 ,0 ,0 , + /* 1600Hz */
As below I'd add comments to line with the value they are referring to.
Quoted 24 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c new file +24
-0+625000 , +/* 800Hz */ +1250000 , +/* 400Hz */ +2500000 , +/* 200Hz */ +5000000 , +/* 100 Hz */ +10000000 , +/* 50Hz */ +20000000 , +/* 25Hz */ +40000000 , +/* 12.5Hz */ +80000000 , +/* 6.25Hz */ +160000000 , +/* 3.125Hz */ +320000000 , +/* 1.5625Hz */ + 640000000, + }; + +return odr_periods[odr];
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c
Quoted 10 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c new file +9
-0+} +static irqreturn_t inv_icm42607_irq_handler (int irq,void *_data) +{ +struct inv_icm42607_state *st = _data; +struct device *dev =regmap_get_device (st->map); +unsigned int status; +int ret; + +mutex_lock (&st->lock);
guard() and direct returns should make this easier to read.
Quoted 32 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c new file +32
-0+ +if (st->apex.on) { +unsigned int status2, status3; + +/* read INT_STATUS2 and INT_STATUS3 in 1 operation */ + ret =regmap_bulk_read (st->map,INV_ICM42607_REG_INT_STATUS2 , st->buffer,2 ); +if (ret) + goto out_unlock; + status2 = st->buffer[0 ]; + status3 = st->buffer[1 ]; +inv_icm42607_accel_handle_events (st->indio_accel, status2, status3, + st->timestamp.accel); + } + + ret =regmap_read (st->map,INV_ICM42607_REG_INT_STATUS , &status); +if (ret) + goto out_unlock; + +if (status &INV_ICM42607_INT_STATUS_FIFO_FULL ) +dev_warn (dev,"FIFO full data lost!\n" ); + +if (status &INV_ICM42607_INT_STATUS_FIFO_THS ) { + ret =inv_icm42607_buffer_fifo_read (st,0 ); +if (ret) { +dev_err (dev,"FIFO read error %d\n" , ret); + goto out_unlock; + } + ret =inv_icm42607_buffer_fifo_parse (st); +if (ret) +dev_err (dev,"FIFO parsing error %d\n" , ret); + } +
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c
Quoted 10 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c new file +9
-0+out_unlock: +mutex_unlock (&st->lock); +return IRQ_HANDLED ; +} + +static int inv_icm42607_runtime_suspend (struct device *dev) +{ +struct inv_icm42607_state *st =dev_get_drvdata (dev); +int ret =0 ;
always set, so don't initialise here.
Quoted 27 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c new file +13
-0+ +guard (mutex)(&st->lock); + + ret =inv_icm42607_set_pwr_mgmt0 (st,INV_ICM42607_SENSOR_MODE_OFF , +INV_ICM42607_SENSOR_MODE_OFF , false, +NULL ); +if (ret) +return ret; + +regulator_disable (st->vddio_supply); + +return 0 ; +}drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +7
-0@@ -0,0 +1,578 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* +* Copyright (C) 2026 InvenSense, Inc. +*/ + +#include <linux/kernel.h> +#include <linux/device.h>
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c line 17
Quoted 10 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +10
-0+#include <linux/mutex.h> +#include <linux/pm_runtime.h> +#include <linux/regmap.h> +#include <linux/delay.h> +#include <linux/math64.h> + +#include <linux/iio/buffer.h> +#include <linux/iio/common/inv_sensors_timestamp.h> +#include <linux/iio/iio.h> +#include <linux/iio/kfifo_buf.h>
Some of these seem unlikely. Make sure they are all used in this file. I haven't checked, so may be fine.
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c line 55
Quoted 4 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +4
-0+ +static const struct iio_chan_spec_ext_info inv_icm42607_gyro_ext_infos[] = { +IIO_MOUNT_MATRIX (IIO_SHARED_BY_ALL , inv_icm42607_get_mount_matrix), + {},
{ }Quoted 6 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +5
-0+}; +/* +* IIO buffer data: size must be a power of 2 and timestamp aligned +* 16 bytes: 6 bytes angular velocity, 2 bytes temperature, 8 bytes timestamp +*/
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c line 89
Quoted 10 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +9
-0+struct inv_icm42607_gyro_buffer { +struct inv_icm42607_fifo_sensor_data gyro; +s16 temp; +aligned_s64 timestamp; +}; +static const unsigned long inv_icm42607_gyro_scan_masks[] = { +/* 3-axis gyro + temperature */ +INV_ICM42607_SCAN_MASK_GYRO_3AXIS |INV_ICM42607_SCAN_MASK_TEMP , +0 ,
It's a terminating entry so drop the comma (more below) - note that I review backwards so sometimes review comments may feel odd if you read them forwards.
Quoted 27 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +27
-0+}; + +/* enable gyroscope sensor and FIFO write */ +static int inv_icm42607_gyro_update_scan_mode (struct iio_dev *indio_dev, +const unsigned long *scan_mask) +{ +struct inv_icm42607_state *st =iio_device_get_drvdata (indio_dev); +struct inv_icm42607_sensor_conf conf =INV_ICM42607_SENSOR_CONF_INIT ; +unsigned int fifo_en =0 ; +unsigned int sleep_gyro =0 ; +unsigned int sleep_temp =0 ; +unsigned int sleep; +int ret; + +mutex_lock (&st->lock); + +if (*scan_mask &INV_ICM42607_SCAN_MASK_TEMP ) { +/* enable temp sensor */ + ret =inv_icm42607_set_temp_conf (st, true, &sleep_temp); +if (ret) + goto out_unlock; + fifo_en |=INV_ICM42607_SENSOR_TEMP ; + } + +if (*scan_mask &INV_ICM42607_SCAN_MASK_GYRO_3AXIS ) { +/* enable gyro sensor */ + conf.mode =INV_ICM42607_SENSOR_MODE_LOW_NOISE ;
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c line 126
Quoted 10 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +10
-0+ ret =inv_icm42607_set_gyro_conf (st, &conf, &sleep_gyro); +if (ret) + goto out_unlock; + fifo_en |=INV_ICM42607_SENSOR_GYRO ; + } + +/* update data FIFO write */ + ret =inv_icm42607_buffer_set_fifo_en (st, fifo_en | st->fifo.en); +if (ret) + goto out_unlock;
Why. It's right there. Drop this gotot.
Quoted 24 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +22
-0+ +out_unlock: +mutex_unlock (&st->lock); +/* sleep maximum required time */ + sleep =max (sleep_gyro, sleep_temp); +if (sleep) +msleep (sleep); +return ret; +} + + +static int inv_icm42607_gyro_write_scale (struct iio_dev *indio_dev, +int val,int val2) +{ +struct inv_icm42607_state *st =iio_device_get_drvdata (indio_dev); +struct inv_icm42607_sensor_state *gyro_st =iio_priv (indio_dev); +struct device *dev =regmap_get_device (st->map); +unsigned int idx; +struct inv_icm42607_sensor_conf conf =INV_ICM42607_SENSOR_CONF_INIT ; +int ret; + +for (idx =0 ; idx < gyro_st->scales_len; idx +=2 ) {
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c line 238
Quoted 10 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +10
-0+if (val == gyro_st->scales[idx] && + val2 == gyro_st->scales[idx +1 ]) +break ; + } +if (idx >= gyro_st->scales_len) +return -EINVAL ; + + conf.fs = idx /2 ; + +pm_runtime_get_sync (dev);
Firstly can always fail so these all need checks.
Secondly this would be neater with the scoped based runtime pm stuff I mention below
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c
Quoted 2 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +2
-0+ +scoped_guard (mutex, &st->lock)
After the other change use
guard(mutex)(&st->lock); return inv_icm...
Applies in at least a few other places.
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c line 251
Quoted 11 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +11
-0+ ret =inv_icm42607_set_gyro_conf (st, &conf,NULL ); + +pm_runtime_put_autosuspend (dev); + +return ret; +} + +/* IIO format int + micro */ +static const int inv_icm42607_gyro_odr[] = { +/* 12.5Hz */ +12 ,500000 ,
12, 500000, /* 12.5Hz */
etc if you do want to add the comments. Too much scrolling otherwise!
Quoted 21 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +20
-0+/* 25Hz */ +25 ,0 , +/* 50Hz */ +50 ,0 , +/* 100Hz */ +100 ,0 , +/* 200Hz */ +200 ,0 , +/* 400Hz */ +400 ,0 , +/* 800Hz */ +800 ,0 , +/* 1600Hz */ + 1600, 0, +}; + +static int inv_icm42607_gyro_write_odr (struct iio_dev *indio_dev, +int val,int val2) +{ +struct inv_icm42607_state *st =iio_device_get_drvdata (indio_dev);
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c line 313
Quoted 10 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +10
-0+struct inv_icm42607_sensor_state *gyro_st =iio_priv (indio_dev); +struct inv_sensors_timestamp *ts = &gyro_st->ts; +struct device *dev =regmap_get_device (st->map); +unsigned int idx; +struct inv_icm42607_sensor_conf conf =INV_ICM42607_SENSOR_CONF_INIT ; +int ret; + +for (idx =0 ; idx <ARRAY_SIZE (inv_icm42607_gyro_odr); idx +=2 ) { +if (val == inv_icm42607_gyro_odr[idx] && + val2 == inv_icm42607_gyro_odr[idx +1 ])
Align as
if (val ==... val2 == ...
Quoted 14 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +14
-0+break ; + } +if (idx >=ARRAY_SIZE (inv_icm42607_gyro_odr)) +return -EINVAL ; + + conf.odr = inv_icm42607_gyro_odr_conv[idx /2 ]; + +pm_runtime_get_sync (dev); +mutex_lock (&st->lock); + + ret =inv_sensors_timestamp_update_odr (ts,inv_icm42607_odr_to_period (conf.odr), +iio_buffer_enabled (indio_dev)); +if (ret) + goto out_unlock;
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c line 337
Quoted 10 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +10
-0+ + ret =inv_icm42607_set_gyro_conf (st, &conf,NULL ); +if (ret) + goto out_unlock; +inv_icm42607_buffer_update_fifo_period (st); +inv_icm42607_buffer_update_watermark (st); + +out_unlock: +mutex_unlock (&st->lock); +pm_runtime_put_autosuspend (dev);
As below. Look at whether you can use guard() and the runtime PM acquire to simplify the code flow in this function.
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c line 493
Quoted 10 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +9
-0+ +return ret; +} +struct iio_dev *inv_icm42607_gyro_init (struct inv_icm42607_state *st) +{ +struct device *dev =regmap_get_device (st->map); +const char *name; +struct inv_icm42607_sensor_state *gyro_st; +struct inv_sensors_timestamp_chip ts_chip;
If no other order makes sense, reverse xmas tree is usually fine for kernel code. What we don't like is lack of an obvious reason for the order.
Quoted 50 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +50
-0+struct iio_dev *indio_dev; +int ret; + + name =devm_kasprintf (dev,GFP_KERNEL ,"%s-gyro" , st->name); +if (!name) +return ERR_PTR (-ENOMEM ); + + indio_dev =devm_iio_device_alloc (dev,sizeof (*gyro_st)); +if (!indio_dev) +return ERR_PTR (-ENOMEM ); + gyro_st =iio_priv (indio_dev); + + gyro_st->scales = inv_icm42607_gyro_scale; + gyro_st->scales_len =ARRAY_SIZE (inv_icm42607_gyro_scale); + +/* +* clock period is 32kHz (31250ns) +* jitter is +/- 2% (20 per mille) +*/ + ts_chip.clock_period =31250 ; + ts_chip.jitter =20 ; + ts_chip.init_period =inv_icm42607_odr_to_period (st->conf.accel.odr); +inv_sensors_timestamp_init (&gyro_st->ts, &ts_chip); + +iio_device_set_drvdata (indio_dev, st); + indio_dev->name = name; + indio_dev->info = &inv_icm42607_gyro_info; + indio_dev->modes =INDIO_DIRECT_MODE |INDIO_BUFFER_SOFTWARE ; + indio_dev->channels = inv_icm42607_gyro_channels; + indio_dev->num_channels =ARRAY_SIZE (inv_icm42607_gyro_channels); + indio_dev->available_scan_masks = inv_icm42607_gyro_scan_masks; + indio_dev->setup_ops = &inv_icm42607_buffer_ops; + + ret =devm_iio_kfifo_buffer_setup (dev, indio_dev, + &inv_icm42607_buffer_ops); +if (ret) +return ERR_PTR (ret); + + ret =devm_iio_device_register (dev, indio_dev); +if (ret) +return ERR_PTR (ret); + +return indio_dev; +} + +int inv_icm42607_gyro_parse_fifo (struct iio_dev *indio_dev) +{ +struct inv_icm42607_state *st =iio_device_get_drvdata (indio_dev); +struct inv_icm42607_sensor_state *gyro_st =iio_priv (indio_dev); +struct inv_sensors_timestamp *ts = &gyro_st->ts;
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c line 553
Quoted 10 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +10
-0+ssize_t i, size; +unsigned int no; +const void *accel, *gyro, *timestamp; +const s8 *temp; +unsigned int odr; +s64 ts_val; +struct inv_icm42607_gyro_buffer buffer = { }; + +/* parse all fifo packets */ +for (i =0 , no =0 ; i < st->fifo.count; i += size, ++no) {
for (ssize_t i = 0, unsigned int no = 0; i < ...
Plus reduce the scope of some of the variables above to inside this loop by declaring them here.
Quoted 11 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +11
-0+ size =inv_icm42607_fifo_decode_packet (&st->fifo.data[i], + &accel, &gyro, &temp, ×tamp, &odr); +/* quit if error or FIFO is empty */ +if (size <=0 ) +return size; + +/* skip packet if no gyro data or data is invalid */ +if (gyro ==NULL || !inv_icm42607_fifo_is_data_valid (gyro)) +continue ; + +/* update odr */
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c line 574
Quoted 10 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +10
-0+if (odr &INV_ICM42607_SENSOR_GYRO ) { +inv_sensors_timestamp_apply_odr (ts, st->fifo.period, + st->fifo.nb.total, no); + } + +memcpy (&buffer.gyro, gyro,sizeof (buffer.gyro)); +/* convert 8 bits FIFO temperature in high resolution format */ + buffer.temp = temp ? (*temp *64 ) :0 ; + ts_val =inv_sensors_timestamp_pop (ts); +iio_push_to_buffers_with_timestamp (indio_dev, &buffer, ts_val);
Please use iio_push_to_buffers_with_ts() in new code.
Quoted 11 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +4
-0+ } + +return 0 ; +}drivers/iio/imu/inv_icm42607/inv_icm42607_spi.c new file +0
-0
drivers/iio/imu/inv_icm42607/inv_icm42607_spi.c line 6
Quoted 6 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_spi.c new file +6
-0@@ -0,0 +1,100 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* +* Copyright (C) 2026 InvenSense, Inc. +*/ + +#include <linux/kernel.h>
Look at what is actually used. It is rare a modern driver should be including the catch all headers kernel.h and device.h. There are much more specific headers that are normally an improvement.
drivers/iio/imu/inv_icm42607/inv_icm42607_spi.c line 12
Quoted 6 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_spi.c new file +6
-0+#include <linux/device.h> +#include <linux/module.h> +#include <linux/mod_devicetable.h> +#include <linux/spi/spi.h> +#include <linux/regmap.h> +#include <linux/property.h>
Not seeing this used. Check for other headers and make sure they are only included where things they define are included.
drivers/iio/imu/inv_icm42607/inv_icm42607_spi.c line 23
Quoted 11 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_spi.c new file +11
-0+ +#include "inv_icm42607.h" + +static int inv_icm42607_spi_bus_setup (struct inv_icm42607_state *st) +{ +unsigned int mask, val; +int ret; + + ret =regmap_update_bits (st->map,INV_ICM42607_REG_DEVICE_CONFIG , +INV_ICM42607_DEVICE_CONFIG_SPI_AP_4WIRE , +INV_ICM42607_DEVICE_CONFIG_SPI_AP_4WIRE );
regmap_set_bits() avoids duplicating that field mask.
drivers/iio/imu/inv_icm42607/inv_icm42607_spi.c line 29
Quoted 6 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_spi.c new file +6
-0+if (ret) +return ret; + + ret =regmap_update_bits (st->map,INV_ICM42607_REG_INTF_CONFIG1 , +INV_ICM42607_INTF_CONFIG1_I3C_DDR_EN | +INV_ICM42607_INTF_CONFIG1_I3C_SDR_EN ,0 );
regmap_clear_bits() lets you drop the 0.
drivers/iio/imu/inv_icm42607/inv_icm42607_spi.c line 34
Quoted 5 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_spi.c new file +5
-0+if (ret) +return ret; + + mask =INV_ICM42607_DRIVE_CONFIG3_SPI_MASK ; + val =INV_ICM42607_DRIVE_CONFIG3_SPI (INV_ICM42607_SLEW_RATE_INF_2NS );
Even though it will be a long line, I'd put at least the mask inline and probably even val, just to keep things consistent with other calls around this. As long as it is under 100 chars and helps readability it is fine to go a little wild.
Quoted 7 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_spi.c new file +7
-0+ ret =regmap_update_bits (st->map,INV_ICM42607_REG_DRIVE_CONFIG3 , + mask, val); +if (ret) +return ret; + + return regmap_update_bits(st->map, INV_ICM42607_REG_INTF_CONFIG0, + INV_ICM42607_INTF_CONFIG0_UI_SIFS_CFG_MASK,
drivers/iio/imu/inv_icm42607/inv_icm42607_spi.c line 51
Quoted 10 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_spi.c new file +10
-0+ INV_ICM42607_INTF_CONFIG0_UI_SIFS_CFG_I2C_DIS); +} + +static int inv_icm42607_probe (struct spi_device *spi) +{ +const void *match; +enum inv_icm42607_chip chip; +struct regmap *regmap; + + match =device_get_match_data (&spi->dev);
spi_get_device_match_data() - which will only work if you stop using an enum below.
Quoted 8 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_spi.c new file +8
-0+if (!match) +return -EINVAL ; + chip = (uintptr_t )match; + + regmap =devm_regmap_init_spi (spi, &inv_icm42607_regmap_config); +if (IS_ERR (regmap)) + return dev_err_probe(&spi->dev, PTR_ERR(regmap), + "Failed to register spi regmap %ld\n",
drivers/iio/imu/inv_icm42607/inv_icm42607_spi.c line 69
Quoted 10 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_spi.c new file +10
-0+ PTR_ERR(regmap)); + +return inv_icm42607_core_probe (regmap, chip, + inv_icm42607_spi_bus_setup); +} + +static const struct of_device_id inv_icm42607_of_matches[] = { + { + .compatible ="invensense,icm42607" , + .data = (void *)INV_CHIP_ICM42607 ,
Use a pointer to the structure, not an enum value.
We used to do this enum thing a lot. Experience showed it is harder to read and encourages people to use the enum to makes stuff 'code' that should have been 'data'. + it breaks spi_get_device_match_data() which relies on NULL meaning no match.
drivers/iio/imu/inv_icm42607/inv_icm42607_spi.c line 82
Quoted 13 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_spi.c new file +13
-0+ }, + { + .compatible = "invensense,icm42607p", + .data = (void *)INV_CHIP_ICM42607P, + }, + { } +}; +MODULE_DEVICE_TABLE (of, inv_icm42607_of_matches); + +static const struct spi_device_id inv_icm42607_spi_id_table[] = { + {"icm42607" ,INV_CHIP_ICM42607 }, + {"icm42607p" ,INV_CHIP_ICM42607P }, + { },
No trailing comma for these terminating entries.
Quoted 21 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_spi.c new file +2
-0+}; +MODULE_DEVICE_TABLE (spi, inv_icm42607_spi_id_table);drivers/iio/imu/inv_icm42607/inv_icm42607_temp.c new file +12
-0@@ -0,0 +1,82 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* +* Copyright (C) 2026 InvenSense, Inc. +*/ + +#include <linux/kernel.h> +#include <linux/device.h> +#include <linux/mutex.h> +#include <linux/pm_runtime.h> +#include <linux/regmap.h> +#include <linux/iio/iio.h> +
drivers/iio/imu/inv_icm42607/inv_icm42607_temp.c line 22
Quoted 10 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_temp.c new file +10
-0+#include "inv_icm42607.h" +#include "inv_icm42607_temp.h" + +static int inv_icm42607_temp_read (struct inv_icm42607_state *st,s16 *temp) +{ +struct device *dev =regmap_get_device (st->map); +__be16 *raw; +int ret; + +pm_runtime_get_sync (dev);
Can fail. Note we have some cleanup.h magic now to help with this. Look at PM_RUNTIME_ACQUIRE_AUTOSUSPEND() / PM_RUNTIME_ACQUIRE_ERR()
drivers/iio/imu/inv_icm42607/inv_icm42607_temp.c line 23
Quoted 1 line
drivers/iio/imu/inv_icm42607/inv_icm42607_temp.c new file +1
-0+mutex_lock (&st->lock);
With the acquire stuff in use for runtime PM, this can be handled via guard(mutex)(&st->lock);
drivers/iio/imu/inv_icm42607/inv_icm42607_temp.c line 27
Quoted 4 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_temp.c new file +4
-0+ + ret =inv_icm42607_set_temp_conf (st, true,NULL ); +if (ret) + goto exit;
And after we have cleanup.h handling for all the cleanup, this can be simply return ret;
drivers/iio/imu/inv_icm42607/inv_icm42607_temp.c line 29
Quoted 2 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_temp.c new file +2
-0+ + raw = (__be16 *)&st->buffer[0 ];
I'm not sure why we need the pointer...
drivers/iio/imu/inv_icm42607/inv_icm42607_temp.c line 34
Quoted 5 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_temp.c new file +5
-0+ ret =regmap_bulk_read (st->map,INV_ICM42607_REG_TEMP_DATA1 , raw,sizeof (*raw)); +if (ret) + goto exit; + + *temp = (s16 )be16_to_cpup (raw);
I'd just use the unaligned_get_be16() path here so the code here isn't making alignment assumptions that are in a structure defined elsewhere. Or, use a union so we can have the right type of buffer.
Quoted 5 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_temp.c new file +5
-0+if (*temp ==INV_ICM42607_DATA_INVALID ) + ret = -EINVAL ; + +exit: +mutex_unlock (&st->lock);
drivers/iio/imu/inv_icm42607/inv_icm42607_temp.c line 49
Quoted 10 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_temp.c new file +10
-0+pm_runtime_put_autosuspend (dev); + +return ret; +} + +int inv_icm42607_temp_read_raw (struct iio_dev *indio_dev, +struct iio_chan_spec const *chan, +int *val,int *val2,long mask) +{ +struct inv_icm42607_state *st =iio_device_get_drvdata (indio_dev);
I'd expect to get to this via a pointer stashed in the structure we get from iio_priv() rather than drvdata.
drivers/iio/imu/inv_icm42607/inv_icm42607_temp.c line 53
Quoted 4 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_temp.c new file +4
-0+s16 temp; +int ret; + +if (chan->type !=IIO_TEMP )
Given the function name, this feels like an overly paranoid check. If it's needed, add a comment on why.
drivers/iio/imu/inv_icm42607/inv_icm42607_temp.h line 3
Quoted 12 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_temp.c new file +2
-0+return -EINVAL ; +drivers/iio/imu/inv_icm42607/inv_icm42607_temp.h new file +3
-0@@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* +* Copyright (C) 2026 InvenSense, Inc.
Hi Chris,
Are you working for InvenSense to upstream this driver? Or is your thought that this is based closely on existing code so should reflect that?
If it's the latter then add comments to describe that and provide the cross references in the driver.
Quoted 1 line
drivers/iio/imu/inv_icm42607/inv_icm42607_temp.h new file +1
-0+*/
PATCH 3/3 arm64: dts: rockchip: Add icm42607p IMU for RG-DS
In reply to Chris MorganFrom: 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
@@ -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
Andy Shevchenko
NAKQuoted 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.
Thanks for your contribution, but...
NAK.
It's unreviewable bulk out of 4kLoC! I even won't bother looking at any other messages in this (too mini) series.
TL;DR: reviewable code is limited at ~750 (or less) ± 150 LoC per patch.
Signature · 2 lines
With Best Regards, Andy Shevchenko
Quoted 9 lines · Andy Shevchenko
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.
Quoted 8 lines
Thanks for your contribution, but...
NAK.
It's unreviewable bulk out of 4kLoC! I even won't bother looking at any other messages in this (too mini) series.
TL;DR: reviewable code is limited at ~750 (or less) ± 150 LoC per patch.
Please disregard this series then, I will do my best to split it apart into smaller pieces and resubmit.
Thank you.
Quoted 6 lines
Signature · 3 lines
-- With Best Regards, Andy Shevchenko
Quoted 14 lines · Chris Morgan
Quoted 13 lines · Andy Shevchenko
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.
Thanks for your contribution, but...
NAK.
Quoted 7 lines
Quoted 4 lines
It's unreviewable bulk out of 4kLoC! I even won't bother looking at any other messages in this (too mini) series.
TL;DR: reviewable code is limited at ~750 (or less) ± 150 LoC per patch.
Please disregard this series then, I will do my best to split it apart into smaller pieces and resubmit.
Please do!
Also keep in mind that from the beginning the driver should work, so the split mustn't be by-file, it should be by-feature / documentation.
Signature · 2 lines
With Best Regards, Andy Shevchenko