Add Invensense ICM42607
Subsystems (4)
v13 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.
Changes Since V1:
- Instead of creating a new driver, merged with the existing inv_icm42600 driver. This necessitated adding some code to the existing driver to permit using a different register layout for the same functionality.
- Split changes up a bit more to decrease the size of the individual patches. Note that patch 0004 is still pretty hefty; if I need to split further I may need to create some temporary stub functions.
- Used guard() and PM_RUNTIME_ACQUIRE_AUTOSUSPEND() on the new functions per Jonathan's recommendations.
Changes Since V2:
- Went back to using a new driver on advice from Invensense engineer.
- Further split changes up into smaller chunks of functionality. Note still that the largest patch is approximately 900 lines, and that while the driver compiles cleanly at each commit it is not able to drive the hardware until the commit that adds the Interrupt (as it also adds the Makefile).
- Change the error to a warning when the devicetree binding does not match the hardware ID.
- Dropped the ack on the devicetree bindings, as I am creating a new file (for a new driver) instead of modifying the existing one.
Changes Since V3:
- Numerous small fixes (too many to list here). Thank you to everyone who provided feedback.
- Split power management additions into an additional commit to break things up further.
- Consolidated devicetree documentation in existing invensense,icm42600.yaml file.
- Removed most of the FIELD_PREP from header file to c files to make code easier to read.
- Changed scale values to 2D arrays for Gyro and Accelerometer.
- Removed IIO_CHAN_INFO_CALIBBIAS attribute.
Changes Since V4:
- Additional numerous small fixes, thank you again for all the feedback.
- Dropped power control API and instead run device in low noise mode.
- Split devicetree bindings into two distinct changes.
- Reordered adding of enums and structs to main header file so that they are only brought in when needed.
- Stopped using enum for driver data and instead am using pointer to device specific driver data.
Changes Since V5:
- Corrected use of "dev_warn_probe" to just "dev_warn".
- Fixed some return scenarios which would unconditionally return 0 when an error was present.
- Corrected use of max() to min() for bounds checking. max() was incorrect.
- Fixed using "st->conf.accel.odr" in the gyroscope function. It should have been "st->conf.gyro.odr" which it now is.
- Additional small fixes suggested by "sashiko.dev".
- Added a regmap cache. I used the datasheet to try and determine which registers might change without explicit writes.
Changes Since V6:
- Corrected additional errors identified by sashiko.dev, mostly fixing potential deadlocks, missing calls for pm runtime, and potential overflow issues.
Changes Since V7:
- Dropped Wake on Movement patches, since some of the functionality was only available for a device on which I cannot test.
- Dropped support for SPI 3-Wire mode, since it complicated the bus setup (and I lack the hardware to test such features anyway).
- Fixed a few additional bugs identified by sashiko.dev bot.
Changes Since V8:
- Added back IRQ dropped accidentally when dropping wake on movement patches.
- Dropped "Reviewed-By" tag on patch 2 because of substantial changes made to devicetree binding documentation.
- Additional small fixes as suggested.
Changes Since V9:
- Removed interrupts (and buffers) from the driver. I previously was unable to detect deadlocks because it turns out my IRQ was not even wired correctly in my device.
- Updated devicetree binding commits to make interrupts optional for users of the icm42607 driver.
Changes Since V10:
- Explicitly specified enum values in header file.
- Removed additional dead code for buffer handling.
- Cleaned up headers.
- Added additional locks as requested by sashiko.dev bot.
Changes Since V11:
- Since driver has shrunk in size considerably, moved i2c bits into first code commit. This ensures that the very first commit with code can now be compiled. The commit after that adds SPI support as it was in the previous versions.
- Used pahole to optimize inv_icm42607_state. Reordering elements reduced size in memory from 384 bytes to 256 bytes.
- Added a map of all readable registers and all writeable registers according to the datasheet.
- Added back some missing headers pointed out by the maintainers.
- Added FIELD_PREP in a few more places to make the code more obvious on what it's doing.
- Added a comment to the power management code to note that temperature sensor being enabled doesn't matter as the clocks are off by default when the gyro and accel channels are off.
- Removed iio_device_claim_direct() calls since it was no longer needed.
- Fixed shared_by_all attributes for temperature sensor.
- Additional miscellanous fixes as requested.
Changes Since V12:
- Removed aligned buffer from inv_icm42607_state struct as we do not currently have the need for it.
- Corrected the order of the odr values in the accel and gyro files as the values were out of order (the place in the array corresponds to the register value).
- Stopped setting the clock value depending upon the temp config. The datasheet advised to keep using the default value.
- Corrected logic when changing between states. We only need to pause when a sensor changes from off to an on state or when the gyro changes from an on state to off.
- Added missing includes for several files.
Chris Morgan (9):
dt-bindings: iio: imu: icm42600: Add mount-matrix to icm42600
dt-bindings: iio: imu: icm42600: Add icm42607
iio: imu: inv_icm42607: Add inv_icm42607 Core Driver
iio: imu: inv_icm42607: Add SPI For icm42607
iio: imu: inv_icm42607: Add PM support for icm42607
iio: imu: inv_icm42607: Add Temp Support in icm42607
iio: imu: inv_icm42607: Add Accelerometer for icm42607
iio: imu: inv_icm42607: Add Gyroscope to icm42607
arm64: dts: rockchip: Add icm42607p IMU for RG-DS
.../bindings/iio/imu/invensense,icm42600.yaml | 20 +- .../dts/rockchip/rk3568-anbernic-rg-ds.dts | 8 +- drivers/iio/imu/Kconfig | 1 + drivers/iio/imu/Makefile | 1 + drivers/iio/imu/inv_icm42607/Kconfig | 30 + drivers/iio/imu/inv_icm42607/Makefile | 13 + drivers/iio/imu/inv_icm42607/inv_icm42607.h | 410 +++++++++++++ .../iio/imu/inv_icm42607/inv_icm42607_accel.c | 373 ++++++++++++ .../iio/imu/inv_icm42607/inv_icm42607_core.c | 546 ++++++++++++++++++ .../iio/imu/inv_icm42607/inv_icm42607_gyro.c | 369 ++++++++++++ .../iio/imu/inv_icm42607/inv_icm42607_i2c.c | 98 ++++ .../iio/imu/inv_icm42607/inv_icm42607_spi.c | 108 ++++ .../iio/imu/inv_icm42607/inv_icm42607_temp.c | 81 +++ .../iio/imu/inv_icm42607/inv_icm42607_temp.h | 37 ++ 14 files changed, 2093 insertions(+), 2 deletions(-) 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_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 v13 1/9 dt-bindings: iio: imu: icm42600: Add mount-matrix to icm42600
From: Chris Morgan <[email protected]>
Add mount-matrix attribute to schema. This attribute has been supported since the first revision of this driver, but was not documented.
--- .../devicetree/bindings/iio/imu/invensense,icm42600.yaml | 2 ++ 1 file changed, 2 insertions(+)
Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml +2 -0
@@ -53,6 +53,8 @@ properties: drive-open-drain: type: boolean + mount-matrix: true + vdd-supply: description: Regulator that provides power to the sensor
Signature · 1 line
2.43.0
PATCH v13 2/9 dt-bindings: iio: imu: icm42600: Add icm42607
In reply to Chris MorganFrom: Chris Morgan <[email protected]>
Add the ICM42607 and ICM42607P inertial measurement unit.
This device is functionally very similar to the icm42600 series with a very different register layout. The driver does not require an interrupt for these specific chip revisions.
--- .../bindings/iio/imu/invensense,icm42600.yaml | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-)
Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml +17 -1
@@ -30,6 +30,8 @@ properties: - invensense,icm42600 - invensense,icm42602 - invensense,icm42605 + - invensense,icm42607 + - invensense,icm42607p - invensense,icm42622 - invensense,icm42631 - invensense,icm42686
@@ -67,10 +69,24 @@ properties: required: - compatible - reg - - interrupts allOf: - $ref: /schemas/spi/spi-peripheral-props.yaml# + - if: + properties: + compatible: + contains: + enum: + - invensense,icm42600 + - invensense,icm42602 + - invensense,icm42605 + - invensense,icm42622 + - invensense,icm42631 + - invensense,icm42686 + - invensense,icm42688 + then: + required: + - interrupts unevaluatedProperties: false
Signature · 1 line
2.43.0
Jonathan Cameron
maintainerRe: [PATCH V13 2/9] dt-bindings: iio: imu: icm42600: Add icm42607
Quoted 7 lines · On Mon, 15 Jun 2026 12:25:45 -0500 Chris Morgan <[email protected]> wrote:
From: Chris Morgan <[email protected]>
Add the ICM42607 and ICM42607P inertial measurement unit.
This device is functionally very similar to the icm42600 series with a very different register layout. The driver does not require an interrupt for these specific chip revisions.
This talks about how they are different from other parts already supported, but I think we need something on how they are different from each other.
I'm kind of assuming one is a subset of the other? If that is the case the ideal might be the more complex part falling back to the simpler one.
Thanks,
Jonathan
Quoted 46 lines
Signed-off-by Chris Morgan <[email protected]>Reviewed-by Krzysztof Kozlowski <[email protected]>--- .../bindings/iio/imu/invensense,icm42600.yaml | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-)Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml +17
-1@@ -30,6 +30,8 @@ properties: - invensense,icm42600 - invensense,icm42602 - invensense,icm42605 + - invensense,icm42607 + - invensense,icm42607p - invensense,icm42622 - invensense,icm42631 - invensense,icm42686@@ -67,10 +69,24 @@ properties: required: - compatible - reg - - interrupts allOf: - $ref: /schemas/spi/spi-peripheral-props.yaml# + - if: + properties: + compatible: + contains: + enum: + - invensense,icm42600 + - invensense,icm42602 + - invensense,icm42605 + - invensense,icm42622 + - invensense,icm42631 + - invensense,icm42686 + - invensense,icm42688 + then: + required: + - interrupts unevaluatedProperties: false
Jean-Baptiste Maneyrol
maintainerRe: [PATCH V13 2/9] dt-bindings: iio: imu: icm42600: Add icm42607
Hello Chris and Jonathan,
concerning dt bindings, my initial understanding was that we had a file per driver. But here, Chris is doing a new driver for icm42607 while adding new bindings here.
Does it means we don't have 1 binding file per driver, and there is no need to create a new binding file for inv_icm42607 driver?
Despite the naming, icm42607 chips are a complete new design very different than all other icm42600 chips. It using similar IPs for things like the FIFO, but all other parts are different. Especially, it doesn't use banks for registers access but indirect access delegated to the chip internals for accessing certain registers.
Thanks,
JB
Quoted 51 lines
From: Chris Morgan <[email protected]>
Add the ICM42607 and ICM42607P inertial measurement unit.
This device is functionally very similar to the icm42600 series with a very different register layout. The driver does not require an interrupt for these specific chip revisions.
Signed-off-by Chris Morgan <[email protected]>Reviewed-by Krzysztof Kozlowski <[email protected]>---
.../bindings/iio/imu/invensense,icm42600.yaml| 18 +++++++++++++++++-1 file changed, 17 insertions(+), 1 deletion(-)Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml +2
-0@@ -30,6 +30,8 @@ properties: - invensense,icm42600 - invensense,icm42602 - invensense,icm42605 + - invensense,icm42607 + - invensense,icm42607p - invensense,icm42622 - invensense,icm42631 - invensense,icm42686@@ -67,10 +69,24 @@ properties:required:
- compatible
- reg
- - interruptsallOf:
- $ref: /schemas/spi/spi-peripheral-props.yaml#Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml +15
-0+ - if: + properties: + compatible: + contains: + enum: + - invensense,icm42600 + - invensense,icm42602 + - invensense,icm42605 + - invensense,icm42622 + - invensense,icm42631 + - invensense,icm42686 + - invensense,icm42688 + then: + required: + - interrupts
Quoted 4 lines
unevaluatedProperties: false
Signature · 1 line
2.43.0
_______________________________________________
Linux-rockchip mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-rockchip
Jonathan Cameron
maintainerRe: [PATCH V13 2/9] dt-bindings: iio: imu: icm42600: Add icm42607
Quoted 8 lines · On Mon, 22 Jun 2026 09:23:28 +0000 Jean-Baptiste Maneyrol…
Hello Chris and Jonathan,
concerning dt bindings, my initial understanding was that we had a file per driver. But here, Chris is doing a new driver for icm42607 while adding new bindings here.
Does it means we don't have 1 binding file per driver, and there is no need to create a new binding file for
inv_icm42607driver?
Yes. We often combine bindings when there is a lot of duplication and only a few device specific rules are needed to describe the new parts.
Jonathan
Quoted 65 lines
Despite the naming, icm42607 chips are a complete new design very different than all other icm42600 chips. It using similar IPs for things like the FIFO, but all other parts are different. Especially, it doesn't use banks for registers access but indirect access delegated to the chip internals for accessing certain registers.
Thanks,
JBQuoted 55 lines
From: Chris Morgan <[email protected]>
Add the ICM42607 and ICM42607P inertial measurement unit.
This device is functionally very similar to the icm42600 series with a very different register layout. The driver does not require an interrupt for these specific chip revisions.
Signed-off-by Chris Morgan <[email protected]>Reviewed-by Krzysztof Kozlowski <[email protected]>---
.../bindings/iio/imu/invensense,icm42600.yaml| 18 +++++++++++++++++-1 file changed, 17 insertions(+), 1 deletion(-)Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml +2
-0@@ -30,6 +30,8 @@ properties: - invensense,icm42600 - invensense,icm42602 - invensense,icm42605 + - invensense,icm42607 + - invensense,icm42607p - invensense,icm42622 - invensense,icm42631 - invensense,icm42686@@ -67,10 +69,24 @@ properties:required:
- compatible
- reg
- - interruptsallOf:
- $ref: /schemas/spi/spi-peripheral-props.yaml#Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml +15
-0+ - if: + properties: + compatible: + contains: + enum: + - invensense,icm42600 + - invensense,icm42602 + - invensense,icm42605 + - invensense,icm42622 + - invensense,icm42631 + - invensense,icm42686 + - invensense,icm42688 + then: + required: + - interruptsunevaluatedProperties: false
Signature · 1 line
2.43.
Re: [PATCH V13 2/9] dt-bindings: iio: imu: icm42600: Add icm42607
In reply to Jean-Baptiste ManeyrolQuoted 6 lines · Jean-Baptiste Maneyrol
Hello Chris and Jonathan,
concerning dt bindings, my initial understanding was that we had a file per driver. But here, Chris is doing a new driver for icm42607 while adding new bindings here.
Quoted 8 lines
Does it means we don't have 1 binding file per driver, and there is no need to create a new binding file for
inv_icm42607driver?Despite the naming, icm42607 chips are a complete new design very different than all other icm42600 chips. It using similar IPs for things like the FIFO, but all other parts are different. Especially, it doesn't use banks for registers access but indirect access delegated to the chip internals for accessing certain registers.
For what it's worth I'm not using any of those registers in the driver currently; from what I see in the datasheets I was able to find on the web the 42607p doesn't do the indirect register access (again unless I'm misreading). To be fair I don't have any other icm42607 chips to test against. The 42607c does appear to do such register access.
Thank you,
Chris
Quoted 59 lines
Thanks,
JBQuoted 55 lines
From: Chris Morgan <[email protected]>
Add the ICM42607 and ICM42607P inertial measurement unit.
This device is functionally very similar to the icm42600 series with a very different register layout. The driver does not require an interrupt for these specific chip revisions.
Signed-off-by Chris Morgan <[email protected]>Reviewed-by Krzysztof Kozlowski <[email protected]>---
.../bindings/iio/imu/invensense,icm42600.yaml| 18 +++++++++++++++++-1 file changed, 17 insertions(+), 1 deletion(-)Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml +2
-0@@ -30,6 +30,8 @@ properties: - invensense,icm42600 - invensense,icm42602 - invensense,icm42605 + - invensense,icm42607 + - invensense,icm42607p - invensense,icm42622 - invensense,icm42631 - invensense,icm42686@@ -67,10 +69,24 @@ properties:required:
- compatible
- reg
- - interruptsallOf:
- $ref: /schemas/spi/spi-peripheral-props.yaml#Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml +15
-0+ - if: + properties: + compatible: + contains: + enum: + - invensense,icm42600 + - invensense,icm42602 + - invensense,icm42605 + - invensense,icm42622 + - invensense,icm42631 + - invensense,icm42686 + - invensense,icm42688 + then: + required: + - interruptsunevaluatedProperties: false
Signature · 1 line
2.43.0
Jean-Baptiste Maneyrol
maintainerRe: [PATCH V13 2/9] dt-bindings: iio: imu: icm42600: Add icm42607
Quoted 31 lines
From: Chris Morgan <[email protected]>
Sent: Tuesday, June 23, 2026 02:06
To: Jean-Baptiste Maneyrol
Cc: Jonathan Cameron; Chris Morgan; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Krzysztof Kozlowski
Subject: Re: [PATCH V13 2/9] dt-bindings: iio: imu: icm42600: Add icm42607On Mon, Jun 22, 2026 at 09: 23: 28AM +0000, Jean-Baptiste Maneyrol wrote: > Hello Chris and Jonathan, > > concerning dt bindings, my initial understanding was that we had a file per > driver. But here, Chris is doing a new driver for ZjQcmQRYFpfptBannerStart
This Message Is From an External Sender
This message came from outside your organization.ZjQcmQRYFpfptBannerEnd
Quoted 6 lines · Jean-Baptiste Maneyrol
Hello Chris and Jonathan,
concerning dt bindings, my initial understanding was that we had a file per driver. But here, Chris is doing a new driver for icm42607 while adding new bindings here.
Quoted 8 lines
Does it means we don't have 1 binding file per driver, and there is no need to create a new binding file for
inv_icm42607driver?Despite the naming, icm42607 chips are a complete new design very different than all other icm42600 chips. It using similar IPs for things like the FIFO, but all other parts are different. Especially, it doesn't use banks for registers access but indirect access delegated to the chip internals for accessing certain registers.
Quoted 8 lines
For what it's worth I'm not using any of those registers in the driver currently; from what I see in the datasheets I was able to find on the web the 42607p doesn't do the indirect register access (again unless I'm misreading). To be fair I don't have any other icm42607 chips to test against. The 42607c does appear to do such register access.
Thank you,
Chris
Hello Chris,
here is a link to download ICM-42670-P datasheet, this chip is completely similar to ICM-42607-P:
https://www.invensense.tdk.com/en-us/download-resource/ds-000451-icm-42670-p-datasheet
Indirect register access is required when you want to use the FIFO for configuring which data is stored inside or when you want to update gyro/accel hardware offsets (calibbias iio attribute usually). Also required for a lot of more complex internal chip configuration.
I didn't had a chance to look at your driver currently. I hope to be able to have a look soon.
I can you give the figures for the required maximum sleep time for accel and gyro startups and stops. Usually, they are not provided in datasheet (only mean values).
Thanks for your work,
JB
Quoted 56 lines
Quoted 56 lines
Thanks,
JBQuoted 51 lines
From: Chris Morgan <[email protected]>
Add the ICM42607 and ICM42607P inertial measurement unit.
This device is functionally very similar to the icm42600 series with a very different register layout. The driver does not require an interrupt for these specific chip revisions.
Signed-off-by Chris Morgan <[email protected]>Reviewed-by Krzysztof Kozlowski <[email protected]>---
.../bindings/iio/imu/invensense,icm42600.yaml| 18 +++++++++++++++++-1 file changed, 17 insertions(+), 1 deletion(-)Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml +2
-0@@ -30,6 +30,8 @@ properties: - invensense,icm42600 - invensense,icm42602 - invensense,icm42605 + - invensense,icm42607 + - invensense,icm42607p - invensense,icm42622 - invensense,icm42631 - invensense,icm42686@@ -67,10 +69,24 @@ properties:required:
- compatible
- reg
- - interruptsallOf:
- $ref: /schemas/spi/spi-peripheral-props.yaml#Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml +15
-0+ - if: + properties: + compatible: + contains: + enum: + - invensense,icm42600 + - invensense,icm42602 + - invensense,icm42605 + - invensense,icm42622 + - invensense,icm42631 + - invensense,icm42686 + - invensense,icm42688 + then: + required: + - interrupts
Quoted 6 lines
Quoted 4 lines
Quoted 4 lines
unevaluatedProperties: false
--
2.43.0
________________________________________
From: Chris Morgan <[email protected]>
Sent: Tuesday, June 23, 2026 02:06
To: Jean-Baptiste Maneyrol
Cc: Jonathan Cameron; Chris Morgan; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Krzysztof Kozlowski
Subject: Re: [PATCH V13 2/9] dt-bindings: iio: imu: icm42600: Add icm42607
On Mon, Jun 22, 2026 at 09: 23: 28AM +0000, Jean-Baptiste Maneyrol wrote: > Hello Chris and Jonathan, > > concerning dt bindings, my initial understanding was that we had a file per > driver. But here, Chris is doing a new driver for ZjQcmQRYFpfptBannerStart
This Message Is From an External Sender
This message came from outside your organization.
ZjQcmQRYFpfptBannerEnd
Quoted 6 lines · Jean-Baptiste Maneyrol
Hello Chris and Jonathan,
concerning dt bindings, my initial understanding was that we had a file per driver. But here, Chris is doing a new driver for icm42607 while adding new bindings here.
Quoted 8 lines
Does it means we don't have 1 binding file per driver, and there is no need to create a new binding file for
inv_icm42607driver?Despite the naming, icm42607 chips are a complete new design very different than all other icm42600 chips. It using similar IPs for things like the FIFO, but all other parts are different. Especially, it doesn't use banks for registers access but indirect access delegated to the chip internals for accessing certain registers.
For what it's worth I'm not using any of those registers in the driver currently; from what I see in the datasheets I was able to find on the web the 42607p doesn't do the indirect register access (again unless I'm misreading). To be fair I don't have any other icm42607 chips to test against. The 42607c does appear to do such register access.
Thank you,
Chris
Quoted 55 lines
Thanks,
JBQuoted 51 lines
From: Chris Morgan <[email protected]>
Add the ICM42607 and ICM42607P inertial measurement unit.
This device is functionally very similar to the icm42600 series with a very different register layout. The driver does not require an interrupt for these specific chip revisions.
Signed-off-by Chris Morgan <[email protected]>Reviewed-by Krzysztof Kozlowski <[email protected]>---
.../bindings/iio/imu/invensense,icm42600.yaml| 18 +++++++++++++++++-1 file changed, 17 insertions(+), 1 deletion(-)Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml +2
-0@@ -30,6 +30,8 @@ properties: - invensense,icm42600 - invensense,icm42602 - invensense,icm42605 + - invensense,icm42607 + - invensense,icm42607p - invensense,icm42622 - invensense,icm42631 - invensense,icm42686@@ -67,10 +69,24 @@ properties:required:
- compatible
- reg
- - interruptsallOf:
- $ref: /schemas/spi/spi-peripheral-props.yaml#Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml +15
-0+ - if: + properties: + compatible: + contains: + enum: + - invensense,icm42600 + - invensense,icm42602 + - invensense,icm42605 + - invensense,icm42622 + - invensense,icm42631 + - invensense,icm42686 + - invensense,icm42688 + then: + required: + - interrupts
Quoted 4 lines
Quoted 4 lines
unevaluatedProperties: false
--
2.43.0
_______________________________________________
Linux-rockchip mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-rockchip
Re: [PATCH V13 2/9] dt-bindings: iio: imu: icm42600: Add icm42607
Quoted 54 lines · Jean-Baptiste Maneyrol
Quoted 31 lines
From: Chris Morgan <[email protected]>
Sent: Tuesday, June 23, 2026 02:06
To: Jean-Baptiste Maneyrol
Cc: Jonathan Cameron; Chris Morgan; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Krzysztof Kozlowski
Subject: Re: [PATCH V13 2/9] dt-bindings: iio: imu: icm42600: Add icm42607On Mon, Jun 22, 2026 at 09: 23: 28AM +0000, Jean-Baptiste Maneyrol wrote: > Hello Chris and Jonathan, > > concerning dt bindings, my initial understanding was that we had a file per > driver. But here, Chris is doing a new driver for ZjQcmQRYFpfptBannerStart
This Message Is From an External Sender
This message came from outside your organization.ZjQcmQRYFpfptBannerEnd
Quoted 6 lines · Jean-Baptiste Maneyrol
Hello Chris and Jonathan,
concerning dt bindings, my initial understanding was that we had a file per driver. But here, Chris is doing a new driver for icm42607 while adding new bindings here.
Quoted 8 lines
Does it means we don't have 1 binding file per driver, and there is no need to create a new binding file for
inv_icm42607driver?Despite the naming, icm42607 chips are a complete new design very different than all other icm42600 chips. It using similar IPs for things like the FIFO, but all other parts are different. Especially, it doesn't use banks for registers access but indirect access delegated to the chip internals for accessing certain registers.
Quoted 8 lines
For what it's worth I'm not using any of those registers in the driver currently; from what I see in the datasheets I was able to find on the web the 42607p doesn't do the indirect register access (again unless I'm misreading). To be fair I don't have any other icm42607 chips to test against. The 42607c does appear to do such register access.
Thank you,
ChrisHello Chris,
here is a link to download ICM-42670-P datasheet, this chip is completely similar to ICM-42607-P:
https://www.invensense.tdk.com/en-us/download-resource/ds-000451-icm-42670-p-datasheetIndirect register access is required when you want to use the FIFO for configuring which data is stored inside or when you want to update gyro/accel hardware offsets (calibbias iio attribute usually). Also required for a lot of more complex internal chip configuration.
I didn't had a chance to look at your driver currently. I hope to be able to have a look soon.
Quoted 6 lines
I can you give the figures for the required maximum sleep time for accel and gyro startups and stops. Usually, they are not provided in datasheet (only mean values).
Thanks for your work,
JB
I guess I had an older or inaccurate datasheet because mine didn't list any of the additional user banks for the 42607p, only for the 42607c.
As of right now I'm not using any of those additional registers, my main goal all along has just been to get the accelerometer working honestly, and so far using things like monitor-sensor this driver seems to be outputting what I expect. I'm not using any of the fifo buffers, wom, or apex stuff currently either as it turns out my implementation doesn't even have an interrupt as best I can tell, I couldn't get any output on the designated IRQ line suggesting it probably wasn't used.
I'm currently using the mean values from the datasheet for the startup times (10ms for the accelerometer, 30ms for the gyroscope). I had a misreading in earlier versions for the temp sensor of 77ms, but looking at the datasheet again it appears it should be 77us. Since the temp sensor needs one of the gyro or accel enabled to be read I'm just not messing with the startup time at all and relying on the longer startup times of the accel or gyro. In the latest version (not pushed yet as I'm still refactoring stuff) I am tracking the timestamp of the gyro start to ensure it has been on at least 45ms before it is shut off, as the datasheet also says minimum run time is 45ms.
If you see anything else let me know, I'm happy to get any help I can.
Thank you,
Chris
Quoted 164 lines
Quoted 57 lines
Quoted 57 lines
Thanks,
JBQuoted 51 lines
From: Chris Morgan <[email protected]>
Add the ICM42607 and ICM42607P inertial measurement unit.
This device is functionally very similar to the icm42600 series with a very different register layout. The driver does not require an interrupt for these specific chip revisions.
Signed-off-by Chris Morgan <[email protected]>Reviewed-by Krzysztof Kozlowski <[email protected]>---
.../bindings/iio/imu/invensense,icm42600.yaml| 18 +++++++++++++++++-1 file changed, 17 insertions(+), 1 deletion(-)Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml +2
-0@@ -30,6 +30,8 @@ properties: - invensense,icm42600 - invensense,icm42602 - invensense,icm42605 + - invensense,icm42607 + - invensense,icm42607p - invensense,icm42622 - invensense,icm42631 - invensense,icm42686@@ -67,10 +69,24 @@ properties:required:
- compatible
- reg
- - interruptsallOf:
- $ref: /schemas/spi/spi-peripheral-props.yaml#Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml +15
-0+ - if: + properties: + compatible: + contains: + enum: + - invensense,icm42600 + - invensense,icm42602 + - invensense,icm42605 + - invensense,icm42622 + - invensense,icm42631 + - invensense,icm42686 + - invensense,icm42688 + then: + required: + - interruptsQuoted 6 lines
Quoted 4 lines
Quoted 4 lines
unevaluatedProperties: false
--
2.43.0________________________________________
From: Chris Morgan <[email protected]>
Sent: Tuesday, June 23, 2026 02:06
To: Jean-Baptiste Maneyrol
Cc: Jonathan Cameron; Chris Morgan; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Krzysztof Kozlowski
Subject: Re: [PATCH V13 2/9] dt-bindings: iio: imu: icm42600: Add icm42607On Mon, Jun 22, 2026 at 09: 23: 28AM +0000, Jean-Baptiste Maneyrol wrote: > Hello Chris and Jonathan, > > concerning dt bindings, my initial understanding was that we had a file per > driver. But here, Chris is doing a new driver for ZjQcmQRYFpfptBannerStart
This Message Is From an External Sender
This message came from outside your organization.ZjQcmQRYFpfptBannerEnd
Quoted 6 lines · Jean-Baptiste Maneyrol
Hello Chris and Jonathan,
concerning dt bindings, my initial understanding was that we had a file per driver. But here, Chris is doing a new driver for icm42607 while adding new bindings here.
Quoted 8 lines
Does it means we don't have 1 binding file per driver, and there is no need to create a new binding file for
inv_icm42607driver?Despite the naming, icm42607 chips are a complete new design very different than all other icm42600 chips. It using similar IPs for things like the FIFO, but all other parts are different. Especially, it doesn't use banks for registers access but indirect access delegated to the chip internals for accessing certain registers.
For what it's worth I'm not using any of those registers in the driver currently; from what I see in the datasheets I was able to find on the web the 42607p doesn't do the indirect register access (again unless I'm misreading). To be fair I don't have any other icm42607 chips to test against. The 42607c does appear to do such register access.
Thank you,
ChrisQuoted 59 lines
Thanks,
JBQuoted 55 lines
From: Chris Morgan <[email protected]>
Add the ICM42607 and ICM42607P inertial measurement unit.
This device is functionally very similar to the icm42600 series with a very different register layout. The driver does not require an interrupt for these specific chip revisions.
Signed-off-by Chris Morgan <[email protected]>Reviewed-by Krzysztof Kozlowski <[email protected]>---
.../bindings/iio/imu/invensense,icm42600.yaml| 18 +++++++++++++++++-1 file changed, 17 insertions(+), 1 deletion(-)Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml +2
-0@@ -30,6 +30,8 @@ properties: - invensense,icm42600 - invensense,icm42602 - invensense,icm42605 + - invensense,icm42607 + - invensense,icm42607p - invensense,icm42622 - invensense,icm42631 - invensense,icm42686@@ -67,10 +69,24 @@ properties:required:
- compatible
- reg
- - interruptsallOf:
- $ref: /schemas/spi/spi-peripheral-props.yaml#Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml +15
-0+ - if: + properties: + compatible: + contains: + enum: + - invensense,icm42600 + - invensense,icm42602 + - invensense,icm42605 + - invensense,icm42622 + - invensense,icm42631 + - invensense,icm42686 + - invensense,icm42688 + then: + required: + - interruptsunevaluatedProperties: false
--
2.43.0
PATCH v13 3/9 iio: imu: inv_icm42607: Add inv_icm42607 Core Driver
In reply to Chris MorganFrom: Chris Morgan <[email protected]>
Add the core component of a new inv_icm42607 driver. This includes a few setup functions and the full register definition in the header file, as well as the bits necessary to compile and probe the device when used on an i2c bus.
--- drivers/iio/imu/Kconfig | 1 + drivers/iio/imu/Makefile | 1 + drivers/iio/imu/inv_icm42607/Kconfig | 18 + drivers/iio/imu/inv_icm42607/Makefile | 7 + drivers/iio/imu/inv_icm42607/inv_icm42607.h | 347 ++++++++++++++++++ .../iio/imu/inv_icm42607/inv_icm42607_core.c | 280 ++++++++++++++ .../iio/imu/inv_icm42607/inv_icm42607_i2c.c | 97 +++++ 7 files changed, 751 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_core.c create mode 100644 drivers/iio/imu/inv_icm42607/inv_icm42607_i2c.c
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 +18 -0
@@ -0,0 +1,18 @@ +# 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-42607 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.
drivers/iio/imu/inv_icm42607/Makefile new file +7 -0
@@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +obj-$(CONFIG_INV_ICM42607) += inv-icm42607.o +inv-icm42607-y += inv_icm42607_core.o + +obj-$(CONFIG_INV_ICM42607_I2C) += inv-icm42607-i2c.o +inv-icm42607-i2c-y += inv_icm42607_i2c.o
drivers/iio/imu/inv_icm42607/inv_icm42607.h new file +347 -0
347 lines not on this page · raw message
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c new file +280 -0
280 lines not on this page · raw message
drivers/iio/imu/inv_icm42607/inv_icm42607_i2c.c new file +97 -0
97 lines not on this page · raw message
Signature · 1 line
2.43.0
Re: [PATCH V13 3/9] iio: imu: inv_icm42607: Add inv_icm42607 Core Driver
Quoted 4 lines · Chris Morgan
Add the core component of a new
inv_icm42607driver. This includes a few setup functions and the full register definition in the header file, as well as the bits necessary to compile and probe the device when used on an i2c bus.
...
drivers/iio/imu/inv_icm42607/inv_icm42607.h line 15
Quoted 10 lines
drivers/iio/imu/inv_icm42607/inv_icm42607.h new file +10
-0+#ifndef INV_ICM42607_H_ +#define INV_ICM42607_H_ + +#include <linux/bits.h> +#include <linux/iio/iio.h> +#include <linux/mutex.h> +#include <linux/regmap.h> +#include <linux/regulator/consumer.h> +#include <linux/time.h> +#include <linux/types.h>
+ asm/byteorder.h // cpu_to_le16()
...
drivers/iio/imu/inv_icm42607/inv_icm42607_i2c.c line 14
Quoted 9 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_i2c.c new file +9
-0+#include <linux/bitfield.h> +#include <linux/dev_printk.h> +#include <linux/err.h> +#include <linux/i2c.h> +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/regmap.h> + +
Single blank line is enough.
Quoted 1 line
+#include "
inv_icm42607.h"
Signature · 2 lines
With Best Regards, Andy Shevchenko
PATCH v13 4/9 iio: imu: inv_icm42607: Add SPI For icm42607
In reply to Chris MorganFrom: Chris Morgan <[email protected]>
Add SPI driver support for InvenSense ICM-42607 devices.
--- drivers/iio/imu/inv_icm42607/Kconfig | 12 ++ drivers/iio/imu/inv_icm42607/Makefile | 3 + .../iio/imu/inv_icm42607/inv_icm42607_spi.c | 107 ++++++++++++++++++ 3 files changed, 122 insertions(+) create mode 100644 drivers/iio/imu/inv_icm42607/inv_icm42607_spi.c
drivers/iio/imu/inv_icm42607/Kconfig +12 -0
@@ -16,3 +16,15 @@ config INV_ICM42607_I2C This driver can be built as a module. The module will be called inv-icm42607-i2c. + +config INV_ICM42607_SPI + tristate "InvenSense ICM-42607 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 +3 -0
@@ -5,3 +5,6 @@ inv-icm42607-y += inv_icm42607_core.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_spi.c new file +107 -0
107 lines not on this page · raw message
Signature · 1 line
2.43.0
PATCH v13 5/9 iio: imu: inv_icm42607: Add PM support for icm42607
In reply to Chris MorganFrom: Chris Morgan <[email protected]>
Add power management support for the ICM42607 device driver.
--- drivers/iio/imu/inv_icm42607/inv_icm42607.h | 18 +++ .../iio/imu/inv_icm42607/inv_icm42607_core.c | 139 ++++++++++++++++++ .../iio/imu/inv_icm42607/inv_icm42607_i2c.c | 1 + .../iio/imu/inv_icm42607/inv_icm42607_spi.c | 1 + 4 files changed, 159 insertions(+)
drivers/iio/imu/inv_icm42607/inv_icm42607.h +18 -0
@@ -9,6 +9,7 @@#include <linux/bits.h> #include <linux/iio/iio.h> #include <linux/mutex.h> +#include <linux/pm.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> #include <linux/time.h>
@@ -105,12 +106,20 @@ struct inv_icm42607_hw {u8 whoami; }; +struct inv_icm42607_suspended { +enum inv_icm42607_sensor_mode gyro; +enum inv_icm42607_sensor_mode accel; +bool temp; +}; +/** * struct inv_icm42607_state - driver state variables * @hw: Hardware specific data. * @lock: lock for serializing multiple registers access. * @map: regmap pointer. * @vddio_supply: I/O voltage regulator for the chip. +* @vddio_en: I/O voltage status for runtime PM. +* @suspended: suspended sensors configuration. * @conf: chip sensors configurations. * @orientation: sensor chip orientation relative to main hardware. */
@@ -119,6 +128,8 @@ struct inv_icm42607_state {struct mutex lock;struct regmap *map;struct regulator *vddio_supply; +bool vddio_en; +struct inv_icm42607_suspended suspended;struct inv_icm42607_conf conf;struct iio_mount_matrix orientation; };
@@ -334,11 +345,18 @@ struct inv_icm42607_state {#define INV_ICM42607_GYRO_STOP_TIME_MS 45#define INV_ICM42607_TEMP_STARTUP_TIME_MS 77 +/* +* Suspend delay assumed from other icm42600 series device, not +* documented in datasheet. +*/ +#define INV_ICM42607_SUSPEND_DELAY_MS (2 * USEC_PER_MSEC) +typedef int (*inv_icm42607_bus_setup )(struct inv_icm42607_state *);extern const struct regmap_config inv_icm42607_regmap_config;extern const struct inv_icm42607_hw inv_icm42607_hw_data;extern const struct inv_icm42607_hw inv_icm42607p_hw_data; +extern const struct dev_pm_ops inv_icm42607_pm_ops; int inv_icm42607_core_probe(struct regmap *regmap, const struct inv_icm42607_hw *hw,
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +139 -0
192 lines not on this page · raw message
drivers/iio/imu/inv_icm42607/inv_icm42607_i2c.c +1 -0
@@ -85,6 +85,7 @@ static struct i2c_driver inv_icm42607_driver = { .driver = { .name = "inv-icm42607-i2c", .of_match_table = inv_icm42607_of_matches, + .pm = pm_ptr(&inv_icm42607_pm_ops), }, .id_table = inv_icm42607_id, .probe = inv_icm42607_probe,
drivers/iio/imu/inv_icm42607/inv_icm42607_spi.c +1 -0
@@ -95,6 +95,7 @@ static struct spi_driver inv_icm42607_driver = { .driver = { .name = "inv-icm42607-spi", .of_match_table = inv_icm42607_of_matches, + .pm = pm_ptr(&inv_icm42607_pm_ops), }, .id_table = inv_icm42607_spi_id_table, .probe = inv_icm42607_probe,
Signature · 1 line
2.43.0
[email protected]
AI reviewRe: [PATCH V13 5/9] iio: imu: inv_icm42607: Add PM support for icm42607
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider: - [High] Missing synchronous suspend during driver unbind leaves hardware sensors powered on and leaking…
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] Missing synchronous suspend during driver unbind leaves hardware sensors powered on and leaking power.
- [Medium] Unconditional 45ms sleep during gyro power-off injects unnecessary delay on every suspend transition.
- [Low] Incorrect constant used for defining the autosuspend delay.
--
commit c053e5ed4a86d71f412c402ec80e9602b6677c2a
Author: Chris Morgan <[email protected]>
iio: imu: inv_icm42607: Add PM support for icm42607
Add power management support for the ICM42607 device driver.
Quoted 3 lines
drivers/iio/imu/inv_icm42607/inv_icm42607.h +0
-0
[ ... ]
drivers/iio/imu/inv_icm42607/inv_icm42607.h struct inv_icm42607_state { · line 352
Quoted 9 lines
drivers/iio/imu/inv_icm42607/inv_icm42607.h +5
-0@@ -334,11 +345,18 @@ struct inv_icm42607_state {#define INV_ICM42607_GYRO_STOP_TIME_MS 45#define INV_ICM42607_TEMP_STARTUP_TIME_MS 77 +/* +* Suspend delay assumed from other icm42600 series device, not +* documented in datasheet. +*/ +#define INV_ICM42607_SUSPEND_DELAY_MS (2 * USEC_PER_MSEC)
[Severity: Low]
Is this using the correct conversion macro? While (2 * USEC_PER_MSEC) evaluates to 2000, USEC_PER_MSEC means microseconds per millisecond. Using it to convert seconds to milliseconds is semantically confusing. Should this be 2 * MSEC_PER_SEC or just the literal 2000?
Quoted 7 lines
drivers/iio/imu/inv_icm42607/inv_icm42607.h +1
-0+typedef int (*inv_icm42607_bus_setup )(struct inv_icm42607_state *);extern const struct regmap_config inv_icm42607_regmap_config;drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +0
-0
[ ... ]
Quoted 16 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +12
-0@@ -103,6 +105,63 @@ const struct inv_icm42607_hw inv_icm42607p_hw_data = { };EXPORT_SYMBOL_NS_GPL (inv_icm42607p_hw_data,"IIO_ICM42607" ); +static int inv_icm42607_set_pwr_mgmt0 (struct inv_icm42607_state *st, +enum inv_icm42607_sensor_mode gyro, +enum inv_icm42607_sensor_mode accel, +bool temp,unsigned int *sleep_ms) +{ +enum inv_icm42607_sensor_mode oldaccel = st->conf.accel.mode; +enum inv_icm42607_sensor_mode oldgyro = st->conf.gyro.mode; +bool oldtemp = st->conf.temp_en; +unsigned int sleepval_ms; +unsigned int val; +int ret; +
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c const struct inv_icm42607_hw inv_icm42607p_hw_data = { · line 129
Quoted 10 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +10
-0+if (gyro == oldgyro && accel == oldaccel && temp == oldtemp) +return 0 ; + +/* +* Datasheet on page 14.26 says we need to ensure the gyro sensor is on +* for a minimum of 45ms. So if we transition from an on state to an +* off state wait 45ms to ensure a sufficient pause before power off. +*/ +if (!gyro && oldgyro) +fsleep (INV_ICM42607_GYRO_STOP_TIME_MS *USEC_PER_MSEC );
[Severity: Medium]
Does this inject a 45ms delay into every runtime suspend transition?
The code unconditionally sleeps for 45ms when turning off the gyro. If the datasheet requires the gyro to remain ON for a minimum of 45ms after power-on, wouldn't it be better to track the power-on timestamp instead of delaying every power-off sequence, even if the gyro has been active for hours?
Quoted 3 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +3
-0+ + val =FIELD_PREP (INV_ICM42607_PWR_MGMT0_GYRO_MODE_MASK , gyro); + val |=FIELD_PREP (INV_ICM42607_PWR_MGMT0_ACCEL_MODE_MASK , accel);
[ ... ]
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c int inv_icm42607_core_probe(struct regmap *regmap, · line 353
Quoted 13 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +7
-0@@ -271,10 +342,78 @@ int inv_icm42607_core_probe(struct regmap *regmap,if (ret)return ret; + ret =devm_pm_runtime_set_active_enabled (dev); +if (ret) +return ret; + +pm_runtime_set_autosuspend_delay (dev,INV_ICM42607_SUSPEND_DELAY_MS ); +pm_runtime_use_autosuspend (dev); +return 0 ; }
[Severity: High]
Does this code leak power on unbind?
Since autosuspend is used, the device doesn't suspend synchronously when pm_runtime_put_sync() is called by the driver core on removal. Instead, an async autosuspend is queued.
When the devres cleanup action invokes pm_runtime_disable(), the pending autosuspend work is cancelled, meaning inv_icm42607_runtime_suspend() is never executed.
If the sensors remain fully powered on in the PWR_MGMT0 register, and the vddio regulator is shared with other devices, will this cause a permanent power leak? Would adding a driver remove callback that calls pm_runtime_dont_use_autosuspend() or pm_runtime_put_sync_suspend() ensure the device powers down synchronously?
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=5
Jonathan Cameron
maintainerRe: [PATCH V13 5/9] iio: imu: inv_icm42607: Add PM support for icm42607
In reply to Chris MorganQuoted 5 lines · On Mon, 15 Jun 2026 12:25:48 -0500 Chris Morgan <[email protected]> wrote:
From: Chris Morgan <[email protected]>
Add power management support for the ICM42607 device driver.
Signed-off-by Chris Morgan <[email protected]>
A few things from taking a look at the sashiko report:
https://sashiko.dev/#/patchset/20260615172554.160910-1-macroalpha82%40gmail.com
Quoted 13 lines
--- drivers/iio/imu/inv_icm42607/inv_icm42607.h | 18 +++ .../iio/imu/inv_icm42607/inv_icm42607_core.c | 139 ++++++++++++++++++ .../iio/imu/inv_icm42607/inv_icm42607_i2c.c | 1 + .../iio/imu/inv_icm42607/inv_icm42607_spi.c | 1 + 4 files changed, 159 insertions(+)drivers/iio/imu/inv_icm42607/inv_icm42607.h +0
-0
drivers/iio/imu/inv_icm42607/inv_icm42607.h struct inv_icm42607_state { · line 352
Quoted 8 lines
drivers/iio/imu/inv_icm42607/inv_icm42607.h +5
-0@@ -334,11 +345,18 @@ struct inv_icm42607_state {#define INV_ICM42607_GYRO_STOP_TIME_MS 45#define INV_ICM42607_TEMP_STARTUP_TIME_MS 77 +/* +* Suspend delay assumed from other icm42600 series device, not +* documented in datasheet. +*/ +#define INV_ICM42607_SUSPEND_DELAY_MS (2 * USEC_PER_MSEC)
Sashiko had a valid comment on this. MSEC_PER_SEC seems more appropriate given this is 2 seconds in milli seconds.
Quoted 43 lines
drivers/iio/imu/inv_icm42607/inv_icm42607.h +2
-0+typedef int (*inv_icm42607_bus_setup )(struct inv_icm42607_state *);extern const struct regmap_config inv_icm42607_regmap_config;extern const struct inv_icm42607_hw inv_icm42607_hw_data;extern const struct inv_icm42607_hw inv_icm42607p_hw_data; +extern const struct dev_pm_ops inv_icm42607_pm_ops; int inv_icm42607_core_probe(struct regmap *regmap, const struct inv_icm42607_hw *hw,drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +11
-0@@ -4,6 +4,7 @@*/ #include <linux/bitfield.h> +#include <linux/cleanup.h> #include <linux/delay.h> #include <linux/dev_printk.h> #include <linux/device/devres.h> @@ -11,6 +12,7 @@#include <linux/iio/iio.h> #include <linux/module.h> #include <linux/mutex.h> +#include <linux/pm_runtime.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> #include <linux/time.h> @@ -103,6 +105,63 @@ const struct inv_icm42607_hw inv_icm42607p_hw_data = { };EXPORT_SYMBOL_NS_GPL (inv_icm42607p_hw_data,"IIO_ICM42607" ); +static int inv_icm42607_set_pwr_mgmt0 (struct inv_icm42607_state *st, +enum inv_icm42607_sensor_mode gyro, +enum inv_icm42607_sensor_mode accel, +bool temp,unsigned int *sleep_ms) +{ +enum inv_icm42607_sensor_mode oldaccel = st->conf.accel.mode; +enum inv_icm42607_sensor_mode oldgyro = st->conf.gyro.mode; +bool oldtemp = st->conf.temp_en; +unsigned int sleepval_ms;
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c const struct inv_icm42607_hw inv_icm42607p_hw_data = { · line 126
Quoted 10 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +10
-0+unsigned int val; +int ret; + +if (gyro == oldgyro && accel == oldaccel && temp == oldtemp) +return 0 ; + +/* +* Datasheet on page 14.26 says we need to ensure the gyro sensor is on +* for a minimum of 45ms. So if we transition from an on state to an +* off state wait 45ms to ensure a sufficient pause before power off.
Sashiko commented on this.. I think what we could do with adding to the comment is what the path is that didn't pass through this function which would ensure we have been on for 30 of this msecs already.
Quoted 50 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +39
-0+*/ +if (!gyro && oldgyro) +fsleep (INV_ICM42607_GYRO_STOP_TIME_MS *USEC_PER_MSEC ); + + val =FIELD_PREP (INV_ICM42607_PWR_MGMT0_GYRO_MODE_MASK , gyro); + val |=FIELD_PREP (INV_ICM42607_PWR_MGMT0_ACCEL_MODE_MASK , accel); + ret =regmap_write (st->map,INV_ICM42607_REG_PWR_MGMT0 , val); +if (ret) +return ret; + + st->conf.gyro.mode = gyro; + st->conf.accel.mode = accel; + st->conf.temp_en = temp; + +/* +* If a state change occurs from off to on, sleep for the startup +* time of the sensor, unless a sleep_ms is specified. Since more +* than one sensor can be transitioned from off to on, select the +* maximum time from each of the sensors changing from off to on. +*/ + sleepval_ms =0 ; +if (temp && !oldtemp) + sleepval_ms =max (sleepval_ms,INV_ICM42607_TEMP_STARTUP_TIME_MS ); + +if (accel && !oldaccel) + sleepval_ms =max (sleepval_ms,INV_ICM42607_ACCEL_STARTUP_TIME_MS ); + +if (gyro && !oldgyro) + sleepval_ms =max (sleepval_ms,INV_ICM42607_GYRO_STARTUP_TIME_MS ); + +if (sleep_ms) + *sleep_ms = sleepval_ms; +else if (sleepval_ms) +fsleep (sleepval_ms *USEC_PER_MSEC ); + +return 0 ; +} int inv_icm42607_core_probe(struct regmap *regmap,@@ -236,6 +305,8 @@ int inv_icm42607_core_probe(struct regmap *regmap,if (!st)return -ENOMEM ; +dev_set_drvdata (dev, st); + ret =devm_mutex_init (dev, &st->lock);if (ret)return ret;
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c int inv_icm42607_core_probe(struct regmap *regmap, · line 350
Quoted 9 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +6
-0@@ -271,10 +342,78 @@ int inv_icm42607_core_probe(struct regmap *regmap,if (ret)return ret; + ret =devm_pm_runtime_set_active_enabled (dev); +if (ret) +return ret; + +pm_runtime_set_autosuspend_delay (dev,INV_ICM42607_SUSPEND_DELAY_MS ); +pm_runtime_use_autosuspend (dev);
Sashiko does put out some stuff here. Please take a look and work out or test if it is right (I think not but haven't checked that carefully!) From a quick look I think that the auto disabling of autosuspend does a rpm_idle() that should result in it suspending...
Quoted 4 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +1
-0+return 0 ; }EXPORT_SYMBOL_NS_GPL (inv_icm42607_core_probe,"IIO_ICM42607" );
Re: [PATCH V13 5/9] iio: imu: inv_icm42607: Add PM support for icm42607
Quoted 85 lines · Jonathan Cameron
Quoted 5 lines · On Mon, 15 Jun 2026 12:25:48 -0500 Chris Morgan <[email protected]> wrote:
From: Chris Morgan <[email protected]>
Add power management support for the ICM42607 device driver.
Signed-off-by Chris Morgan <[email protected]>A few things from taking a look at the sashiko report:
https://sashiko.dev/#/patchset/20260615172554.160910-1-macroalpha82%40gmail.comQuoted 13 lines
--- drivers/iio/imu/inv_icm42607/inv_icm42607.h | 18 +++ .../iio/imu/inv_icm42607/inv_icm42607_core.c | 139 ++++++++++++++++++ .../iio/imu/inv_icm42607/inv_icm42607_i2c.c | 1 + .../iio/imu/inv_icm42607/inv_icm42607_spi.c | 1 + 4 files changed, 159 insertions(+)drivers/iio/imu/inv_icm42607/inv_icm42607.h +0
-0drivers/iio/imu/inv_icm42607/inv_icm42607.h struct inv_icm42607_state { · line 352
Quoted 8 lines
drivers/iio/imu/inv_icm42607/inv_icm42607.h +5
-0@@ -334,11 +345,18 @@ struct inv_icm42607_state {#define INV_ICM42607_GYRO_STOP_TIME_MS 45#define INV_ICM42607_TEMP_STARTUP_TIME_MS 77 +/* +* Suspend delay assumed from other icm42600 series device, not +* documented in datasheet. +*/ +#define INV_ICM42607_SUSPEND_DELAY_MS (2 * USEC_PER_MSEC)Sashiko had a valid comment on this.
MSEC_PER_SECseems more appropriate given this is 2 seconds in milli seconds.Quoted 49 lines
drivers/iio/imu/inv_icm42607/inv_icm42607.h +2
-0+typedef int (*inv_icm42607_bus_setup )(struct inv_icm42607_state *);extern const struct regmap_config inv_icm42607_regmap_config;extern const struct inv_icm42607_hw inv_icm42607_hw_data;extern const struct inv_icm42607_hw inv_icm42607p_hw_data; +extern const struct dev_pm_ops inv_icm42607_pm_ops; int inv_icm42607_core_probe(struct regmap *regmap, const struct inv_icm42607_hw *hw,drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +17
-0@@ -4,6 +4,7 @@*/ #include <linux/bitfield.h> +#include <linux/cleanup.h> #include <linux/delay.h> #include <linux/dev_printk.h> #include <linux/device/devres.h> @@ -11,6 +12,7 @@#include <linux/iio/iio.h> #include <linux/module.h> #include <linux/mutex.h> +#include <linux/pm_runtime.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> #include <linux/time.h> @@ -103,6 +105,63 @@ const struct inv_icm42607_hw inv_icm42607p_hw_data = { };EXPORT_SYMBOL_NS_GPL (inv_icm42607p_hw_data,"IIO_ICM42607" ); +static int inv_icm42607_set_pwr_mgmt0 (struct inv_icm42607_state *st, +enum inv_icm42607_sensor_mode gyro, +enum inv_icm42607_sensor_mode accel, +bool temp,unsigned int *sleep_ms) +{ +enum inv_icm42607_sensor_mode oldaccel = st->conf.accel.mode; +enum inv_icm42607_sensor_mode oldgyro = st->conf.gyro.mode; +bool oldtemp = st->conf.temp_en; +unsigned int sleepval_ms; +unsigned int val; +int ret; + +if (gyro == oldgyro && accel == oldaccel && temp == oldtemp) +return 0 ; +
Quoted 8 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c const struct inv_icm42607_hw inv_icm42607p_hw_data = { · line 126
Quoted 4 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +4
-0+/* +* Datasheet on page 14.26 says we need to ensure the gyro sensor is on +* for a minimum of 45ms. So if we transition from an on state to an +* off state wait 45ms to ensure a sufficient pause before power off. Sashiko commented on this.. I think what we could do with adding to the comment is what the path is that didn't pass through this function which would ensure we have been on for 30 of this msecs already.
I'm going to track whatever time the gyro started, and then if less than 45ms has elapsed just pause the remaining amount of time.
Quoted 54 lines
Quoted 54 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +39
-0+*/ +if (!gyro && oldgyro) +fsleep (INV_ICM42607_GYRO_STOP_TIME_MS *USEC_PER_MSEC ); + + val =FIELD_PREP (INV_ICM42607_PWR_MGMT0_GYRO_MODE_MASK , gyro); + val |=FIELD_PREP (INV_ICM42607_PWR_MGMT0_ACCEL_MODE_MASK , accel); + ret =regmap_write (st->map,INV_ICM42607_REG_PWR_MGMT0 , val); +if (ret) +return ret; + + st->conf.gyro.mode = gyro; + st->conf.accel.mode = accel; + st->conf.temp_en = temp; + +/* +* If a state change occurs from off to on, sleep for the startup +* time of the sensor, unless a sleep_ms is specified. Since more +* than one sensor can be transitioned from off to on, select the +* maximum time from each of the sensors changing from off to on. +*/ + sleepval_ms =0 ; +if (temp && !oldtemp) + sleepval_ms =max (sleepval_ms,INV_ICM42607_TEMP_STARTUP_TIME_MS ); + +if (accel && !oldaccel) + sleepval_ms =max (sleepval_ms,INV_ICM42607_ACCEL_STARTUP_TIME_MS ); + +if (gyro && !oldgyro) + sleepval_ms =max (sleepval_ms,INV_ICM42607_GYRO_STARTUP_TIME_MS ); + +if (sleep_ms) + *sleep_ms = sleepval_ms; +else if (sleepval_ms) +fsleep (sleepval_ms *USEC_PER_MSEC ); + +return 0 ; +} int inv_icm42607_core_probe(struct regmap *regmap,@@ -236,6 +305,8 @@ int inv_icm42607_core_probe(struct regmap *regmap,if (!st)return -ENOMEM ; +dev_set_drvdata (dev, st); + ret =devm_mutex_init (dev, &st->lock);if (ret)return ret;@@ -271,10 +342,78 @@ int inv_icm42607_core_probe(struct regmap *regmap,if (ret)return ret;
Quoted 11 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c int inv_icm42607_core_probe(struct regmap *regmap, · line 350
Quoted 6 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +6
-0+ ret =devm_pm_runtime_set_active_enabled (dev); +if (ret) +return ret; + +pm_runtime_set_autosuspend_delay (dev,INV_ICM42607_SUSPEND_DELAY_MS ); +pm_runtime_use_autosuspend (dev);Sashiko does put out some stuff here. Please take a look and work out or test if it is right (I think not but haven't checked that carefully!) From a quick look I think that the auto disabling of autosuspend does a
rpm_idle()that should result in it suspending...
I see a few other drivers adding one more call to devm_pm_runtime_enable() so I'm going to see how that works out.
Quoted 5 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c int inv_icm42607_core_probe(struct regmap *regmap, · line 354
Quoted 5 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +1
-0+return 0 ; }EXPORT_SYMBOL_NS_GPL (inv_icm42607_core_probe,"IIO_ICM42607" );
Thank you,
Chris
A message that is not in the archive (sent off-list or not yet received): [email protected]
Re: [PATCH V13 5/9] iio: imu: inv_icm42607: Add PM support for icm42607
Quoted 164 lines · Chris Morgan
Quoted 85 lines · Jonathan Cameron
Quoted 5 lines · On Mon, 15 Jun 2026 12:25:48 -0500 Chris Morgan <[email protected]> wrote:
From: Chris Morgan <[email protected]>
Add power management support for the ICM42607 device driver.
Signed-off-by Chris Morgan <[email protected]>A few things from taking a look at the sashiko report:
https://sashiko.dev/#/patchset/20260615172554.160910-1-macroalpha82%40gmail.comQuoted 13 lines
--- drivers/iio/imu/inv_icm42607/inv_icm42607.h | 18 +++ .../iio/imu/inv_icm42607/inv_icm42607_core.c | 139 ++++++++++++++++++ .../iio/imu/inv_icm42607/inv_icm42607_i2c.c | 1 + .../iio/imu/inv_icm42607/inv_icm42607_spi.c | 1 + 4 files changed, 159 insertions(+)drivers/iio/imu/inv_icm42607/inv_icm42607.h +0
-0drivers/iio/imu/inv_icm42607/inv_icm42607.h struct inv_icm42607_state { · line 352
Quoted 8 lines
drivers/iio/imu/inv_icm42607/inv_icm42607.h +5
-0@@ -334,11 +345,18 @@ struct inv_icm42607_state {#define INV_ICM42607_GYRO_STOP_TIME_MS 45#define INV_ICM42607_TEMP_STARTUP_TIME_MS 77 +/* +* Suspend delay assumed from other icm42600 series device, not +* documented in datasheet. +*/ +#define INV_ICM42607_SUSPEND_DELAY_MS (2 * USEC_PER_MSEC)Sashiko had a valid comment on this.
MSEC_PER_SECseems more appropriate given this is 2 seconds in milli seconds.Quoted 49 lines
drivers/iio/imu/inv_icm42607/inv_icm42607.h +2
-0+typedef int (*inv_icm42607_bus_setup )(struct inv_icm42607_state *);extern const struct regmap_config inv_icm42607_regmap_config;extern const struct inv_icm42607_hw inv_icm42607_hw_data;extern const struct inv_icm42607_hw inv_icm42607p_hw_data; +extern const struct dev_pm_ops inv_icm42607_pm_ops; int inv_icm42607_core_probe(struct regmap *regmap, const struct inv_icm42607_hw *hw,drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +17
-0@@ -4,6 +4,7 @@*/ #include <linux/bitfield.h> +#include <linux/cleanup.h> #include <linux/delay.h> #include <linux/dev_printk.h> #include <linux/device/devres.h> @@ -11,6 +12,7 @@#include <linux/iio/iio.h> #include <linux/module.h> #include <linux/mutex.h> +#include <linux/pm_runtime.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> #include <linux/time.h> @@ -103,6 +105,63 @@ const struct inv_icm42607_hw inv_icm42607p_hw_data = { };EXPORT_SYMBOL_NS_GPL (inv_icm42607p_hw_data,"IIO_ICM42607" ); +static int inv_icm42607_set_pwr_mgmt0 (struct inv_icm42607_state *st, +enum inv_icm42607_sensor_mode gyro, +enum inv_icm42607_sensor_mode accel, +bool temp,unsigned int *sleep_ms) +{ +enum inv_icm42607_sensor_mode oldaccel = st->conf.accel.mode; +enum inv_icm42607_sensor_mode oldgyro = st->conf.gyro.mode; +bool oldtemp = st->conf.temp_en; +unsigned int sleepval_ms; +unsigned int val; +int ret; + +if (gyro == oldgyro && accel == oldaccel && temp == oldtemp) +return 0 ; +Quoted 8 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c const struct inv_icm42607_hw inv_icm42607p_hw_data = { · line 126
Quoted 4 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +4
-0+/* +* Datasheet on page 14.26 says we need to ensure the gyro sensor is on +* for a minimum of 45ms. So if we transition from an on state to an +* off state wait 45ms to ensure a sufficient pause before power off. Sashiko commented on this.. I think what we could do with adding to the comment is what the path is that didn't pass through this function which would ensure we have been on for 30 of this msecs already.
I'm going to track whatever time the gyro started, and then if less than 45ms has elapsed just pause the remaining amount of time.
Quoted 54 lines
Quoted 54 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +39
-0+*/ +if (!gyro && oldgyro) +fsleep (INV_ICM42607_GYRO_STOP_TIME_MS *USEC_PER_MSEC ); + + val =FIELD_PREP (INV_ICM42607_PWR_MGMT0_GYRO_MODE_MASK , gyro); + val |=FIELD_PREP (INV_ICM42607_PWR_MGMT0_ACCEL_MODE_MASK , accel); + ret =regmap_write (st->map,INV_ICM42607_REG_PWR_MGMT0 , val); +if (ret) +return ret; + + st->conf.gyro.mode = gyro; + st->conf.accel.mode = accel; + st->conf.temp_en = temp; + +/* +* If a state change occurs from off to on, sleep for the startup +* time of the sensor, unless a sleep_ms is specified. Since more +* than one sensor can be transitioned from off to on, select the +* maximum time from each of the sensors changing from off to on. +*/ + sleepval_ms =0 ; +if (temp && !oldtemp) + sleepval_ms =max (sleepval_ms,INV_ICM42607_TEMP_STARTUP_TIME_MS ); + +if (accel && !oldaccel) + sleepval_ms =max (sleepval_ms,INV_ICM42607_ACCEL_STARTUP_TIME_MS ); + +if (gyro && !oldgyro) + sleepval_ms =max (sleepval_ms,INV_ICM42607_GYRO_STARTUP_TIME_MS ); + +if (sleep_ms) + *sleep_ms = sleepval_ms; +else if (sleepval_ms) +fsleep (sleepval_ms *USEC_PER_MSEC ); + +return 0 ; +} int inv_icm42607_core_probe(struct regmap *regmap,@@ -236,6 +305,8 @@ int inv_icm42607_core_probe(struct regmap *regmap,if (!st)return -ENOMEM ; +dev_set_drvdata (dev, st); + ret =devm_mutex_init (dev, &st->lock);if (ret)return ret;@@ -271,10 +342,78 @@ int inv_icm42607_core_probe(struct regmap *regmap,if (ret)return ret;Quoted 11 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c int inv_icm42607_core_probe(struct regmap *regmap, · line 350
Quoted 6 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +6
-0+ ret =devm_pm_runtime_set_active_enabled (dev); +if (ret) +return ret; + +pm_runtime_set_autosuspend_delay (dev,INV_ICM42607_SUSPEND_DELAY_MS ); +pm_runtime_use_autosuspend (dev);Sashiko does put out some stuff here. Please take a look and work out or test if it is right (I think not but haven't checked that carefully!) From a quick look I think that the auto disabling of autosuspend does a
rpm_idle()that should result in it suspending...
Quoted 2 lines
I see a few other drivers adding one more call to
devm_pm_runtime_enable()so I'm going to see how that works out.
Obviously that didn't work, but digging in much deeper into the PM code I see that devm_pm_runtime_set_active_enabled() returns devm_pm_runtime_enable(), which sets devm_add_action_or_reset() on pm_runtime_disable_action(), which calls pm_runtime_dont_use_autosuspend() and pm_runtime_disable(). Shouldn't this work, or am I missing something? Basically when the driver detaches shouldn't this chain end up calling pm_runtime_dont_use_autosuspend()?
Thank you,
Chris
Quoted 9 lines
Quoted 6 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c int inv_icm42607_core_probe(struct regmap *regmap, · line 354
Quoted 6 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +1
-0+return 0 ; }EXPORT_SYMBOL_NS_GPL (inv_icm42607_core_probe,"IIO_ICM42607" );Thank you,
Chris
Jonathan Cameron
maintainerRe: [PATCH V13 5/9] iio: imu: inv_icm42607: Add PM support for icm42607
Quoted 168 lines · On Tue, 23 Jun 2026 13:08:02 -0500 Chris Morgan <[email protected]> wrote:
Quoted 164 lines · Chris Morgan
Quoted 85 lines · Jonathan Cameron
Quoted 5 lines · On Mon, 15 Jun 2026 12:25:48 -0500 Chris Morgan <[email protected]> wrote:
From: Chris Morgan <[email protected]>
Add power management support for the ICM42607 device driver.
Signed-off-by Chris Morgan <[email protected]>A few things from taking a look at the sashiko report:
https://sashiko.dev/#/patchset/20260615172554.160910-1-macroalpha82%40gmail.comQuoted 13 lines
--- drivers/iio/imu/inv_icm42607/inv_icm42607.h | 18 +++ .../iio/imu/inv_icm42607/inv_icm42607_core.c | 139 ++++++++++++++++++ .../iio/imu/inv_icm42607/inv_icm42607_i2c.c | 1 + .../iio/imu/inv_icm42607/inv_icm42607_spi.c | 1 + 4 files changed, 159 insertions(+)drivers/iio/imu/inv_icm42607/inv_icm42607.h +0
-0drivers/iio/imu/inv_icm42607/inv_icm42607.h struct inv_icm42607_state { · line 352
Quoted 8 lines
drivers/iio/imu/inv_icm42607/inv_icm42607.h +5
-0@@ -334,11 +345,18 @@ struct inv_icm42607_state {#define INV_ICM42607_GYRO_STOP_TIME_MS 45#define INV_ICM42607_TEMP_STARTUP_TIME_MS 77 +/* +* Suspend delay assumed from other icm42600 series device, not +* documented in datasheet. +*/ +#define INV_ICM42607_SUSPEND_DELAY_MS (2 * USEC_PER_MSEC)Sashiko had a valid comment on this.
MSEC_PER_SECseems more appropriate given this is 2 seconds in milli seconds.Quoted 49 lines
drivers/iio/imu/inv_icm42607/inv_icm42607.h +2
-0+typedef int (*inv_icm42607_bus_setup )(struct inv_icm42607_state *);extern const struct regmap_config inv_icm42607_regmap_config;extern const struct inv_icm42607_hw inv_icm42607_hw_data;extern const struct inv_icm42607_hw inv_icm42607p_hw_data; +extern const struct dev_pm_ops inv_icm42607_pm_ops; int inv_icm42607_core_probe(struct regmap *regmap, const struct inv_icm42607_hw *hw,drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +17
-0@@ -4,6 +4,7 @@*/ #include <linux/bitfield.h> +#include <linux/cleanup.h> #include <linux/delay.h> #include <linux/dev_printk.h> #include <linux/device/devres.h> @@ -11,6 +12,7 @@#include <linux/iio/iio.h> #include <linux/module.h> #include <linux/mutex.h> +#include <linux/pm_runtime.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> #include <linux/time.h> @@ -103,6 +105,63 @@ const struct inv_icm42607_hw inv_icm42607p_hw_data = { };EXPORT_SYMBOL_NS_GPL (inv_icm42607p_hw_data,"IIO_ICM42607" ); +static int inv_icm42607_set_pwr_mgmt0 (struct inv_icm42607_state *st, +enum inv_icm42607_sensor_mode gyro, +enum inv_icm42607_sensor_mode accel, +bool temp,unsigned int *sleep_ms) +{ +enum inv_icm42607_sensor_mode oldaccel = st->conf.accel.mode; +enum inv_icm42607_sensor_mode oldgyro = st->conf.gyro.mode; +bool oldtemp = st->conf.temp_en; +unsigned int sleepval_ms; +unsigned int val; +int ret; + +if (gyro == oldgyro && accel == oldaccel && temp == oldtemp) +return 0 ; +Quoted 8 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c const struct inv_icm42607_hw inv_icm42607p_hw_data = { · line 126
Quoted 4 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +4
-0+/* +* Datasheet on page 14.26 says we need to ensure the gyro sensor is on +* for a minimum of 45ms. So if we transition from an on state to an +* off state wait 45ms to ensure a sufficient pause before power off. Sashiko commented on this.. I think what we could do with adding to the comment is what the path is that didn't pass through this function which would ensure we have been on for 30 of this msecs already.
I'm going to track whatever time the gyro started, and then if less than 45ms has elapsed just pause the remaining amount of time.
Quoted 54 lines
Quoted 54 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +39
-0+*/ +if (!gyro && oldgyro) +fsleep (INV_ICM42607_GYRO_STOP_TIME_MS *USEC_PER_MSEC ); + + val =FIELD_PREP (INV_ICM42607_PWR_MGMT0_GYRO_MODE_MASK , gyro); + val |=FIELD_PREP (INV_ICM42607_PWR_MGMT0_ACCEL_MODE_MASK , accel); + ret =regmap_write (st->map,INV_ICM42607_REG_PWR_MGMT0 , val); +if (ret) +return ret; + + st->conf.gyro.mode = gyro; + st->conf.accel.mode = accel; + st->conf.temp_en = temp; + +/* +* If a state change occurs from off to on, sleep for the startup +* time of the sensor, unless a sleep_ms is specified. Since more +* than one sensor can be transitioned from off to on, select the +* maximum time from each of the sensors changing from off to on. +*/ + sleepval_ms =0 ; +if (temp && !oldtemp) + sleepval_ms =max (sleepval_ms,INV_ICM42607_TEMP_STARTUP_TIME_MS ); + +if (accel && !oldaccel) + sleepval_ms =max (sleepval_ms,INV_ICM42607_ACCEL_STARTUP_TIME_MS ); + +if (gyro && !oldgyro) + sleepval_ms =max (sleepval_ms,INV_ICM42607_GYRO_STARTUP_TIME_MS ); + +if (sleep_ms) + *sleep_ms = sleepval_ms; +else if (sleepval_ms) +fsleep (sleepval_ms *USEC_PER_MSEC ); + +return 0 ; +} int inv_icm42607_core_probe(struct regmap *regmap,@@ -236,6 +305,8 @@ int inv_icm42607_core_probe(struct regmap *regmap,if (!st)return -ENOMEM ; +dev_set_drvdata (dev, st); + ret =devm_mutex_init (dev, &st->lock);if (ret)return ret;@@ -271,10 +342,78 @@ int inv_icm42607_core_probe(struct regmap *regmap,if (ret)return ret;Quoted 11 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c int inv_icm42607_core_probe(struct regmap *regmap, · line 350
Quoted 6 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +6
-0+ ret =devm_pm_runtime_set_active_enabled (dev); +if (ret) +return ret; + +pm_runtime_set_autosuspend_delay (dev,INV_ICM42607_SUSPEND_DELAY_MS ); +pm_runtime_use_autosuspend (dev);Sashiko does put out some stuff here. Please take a look and work out or test if it is right (I think not but haven't checked that carefully!) From a quick look I think that the auto disabling of autosuspend does a
rpm_idle()that should result in it suspending...Quoted 2 lines
I see a few other drivers adding one more call to
devm_pm_runtime_enable()so I'm going to see how that works out.
Quoted 8 lines
Obviously that didn't work, but digging in much deeper into the PM code I see that
devm_pm_runtime_set_active_enabled()returnsdevm_pm_runtime_enable(), which setsdevm_add_action_or_reset()onpm_runtime_disable_action(), which callspm_runtime_dont_use_autosuspend()andpm_runtime_disable(). Shouldn't this work, or am I missing something? Basically when the driver detaches shouldn't this chain end up callingpm_runtime_dont_use_autosuspend()?
Agreed. That was how I read things. The only thing I didn't entirely confirm (states involved were fiddly enough I'd want to check it with the actual driver!) was that pm_runtime_dont_use_autosuspend() ends up calling rpm_idle() in this case.
Jonathan
Quoted 13 lines
Thank you,
ChrisQuoted 9 lines
Quoted 6 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c int inv_icm42607_core_probe(struct regmap *regmap, · line 354
Quoted 6 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +1
-0+return 0 ; }EXPORT_SYMBOL_NS_GPL (inv_icm42607_core_probe,"IIO_ICM42607" );Thank you,
Chris
Re: [PATCH V13 5/9] iio: imu: inv_icm42607: Add PM support for icm42607
Quoted 179 lines · Jonathan Cameron
Quoted 168 lines · On Tue, 23 Jun 2026 13:08:02 -0500 Chris Morgan <[email protected]> wrote:
Quoted 164 lines · Chris Morgan
Quoted 85 lines · Jonathan Cameron
Quoted 5 lines · On Mon, 15 Jun 2026 12:25:48 -0500 Chris Morgan <[email protected]> wrote:
From: Chris Morgan <[email protected]>
Add power management support for the ICM42607 device driver.
Signed-off-by Chris Morgan <[email protected]>A few things from taking a look at the sashiko report:
https://sashiko.dev/#/patchset/20260615172554.160910-1-macroalpha82%40gmail.comQuoted 13 lines
--- drivers/iio/imu/inv_icm42607/inv_icm42607.h | 18 +++ .../iio/imu/inv_icm42607/inv_icm42607_core.c | 139 ++++++++++++++++++ .../iio/imu/inv_icm42607/inv_icm42607_i2c.c | 1 + .../iio/imu/inv_icm42607/inv_icm42607_spi.c | 1 + 4 files changed, 159 insertions(+)drivers/iio/imu/inv_icm42607/inv_icm42607.h +0
-0drivers/iio/imu/inv_icm42607/inv_icm42607.h struct inv_icm42607_state { · line 352
Quoted 8 lines
drivers/iio/imu/inv_icm42607/inv_icm42607.h +5
-0@@ -334,11 +345,18 @@ struct inv_icm42607_state {#define INV_ICM42607_GYRO_STOP_TIME_MS 45#define INV_ICM42607_TEMP_STARTUP_TIME_MS 77 +/* +* Suspend delay assumed from other icm42600 series device, not +* documented in datasheet. +*/ +#define INV_ICM42607_SUSPEND_DELAY_MS (2 * USEC_PER_MSEC)Sashiko had a valid comment on this.
MSEC_PER_SECseems more appropriate given this is 2 seconds in milli seconds.Quoted 49 lines
drivers/iio/imu/inv_icm42607/inv_icm42607.h +2
-0+typedef int (*inv_icm42607_bus_setup )(struct inv_icm42607_state *);extern const struct regmap_config inv_icm42607_regmap_config;extern const struct inv_icm42607_hw inv_icm42607_hw_data;extern const struct inv_icm42607_hw inv_icm42607p_hw_data; +extern const struct dev_pm_ops inv_icm42607_pm_ops; int inv_icm42607_core_probe(struct regmap *regmap, const struct inv_icm42607_hw *hw,drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +17
-0@@ -4,6 +4,7 @@*/ #include <linux/bitfield.h> +#include <linux/cleanup.h> #include <linux/delay.h> #include <linux/dev_printk.h> #include <linux/device/devres.h> @@ -11,6 +12,7 @@#include <linux/iio/iio.h> #include <linux/module.h> #include <linux/mutex.h> +#include <linux/pm_runtime.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> #include <linux/time.h> @@ -103,6 +105,63 @@ const struct inv_icm42607_hw inv_icm42607p_hw_data = { };EXPORT_SYMBOL_NS_GPL (inv_icm42607p_hw_data,"IIO_ICM42607" ); +static int inv_icm42607_set_pwr_mgmt0 (struct inv_icm42607_state *st, +enum inv_icm42607_sensor_mode gyro, +enum inv_icm42607_sensor_mode accel, +bool temp,unsigned int *sleep_ms) +{ +enum inv_icm42607_sensor_mode oldaccel = st->conf.accel.mode; +enum inv_icm42607_sensor_mode oldgyro = st->conf.gyro.mode; +bool oldtemp = st->conf.temp_en; +unsigned int sleepval_ms; +unsigned int val; +int ret; + +if (gyro == oldgyro && accel == oldaccel && temp == oldtemp) +return 0 ; +Quoted 8 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c const struct inv_icm42607_hw inv_icm42607p_hw_data = { · line 126
Quoted 4 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +4
-0+/* +* Datasheet on page 14.26 says we need to ensure the gyro sensor is on +* for a minimum of 45ms. So if we transition from an on state to an +* off state wait 45ms to ensure a sufficient pause before power off. Sashiko commented on this.. I think what we could do with adding to the comment is what the path is that didn't pass through this function which would ensure we have been on for 30 of this msecs already.
I'm going to track whatever time the gyro started, and then if less than 45ms has elapsed just pause the remaining amount of time.
Quoted 54 lines
Quoted 54 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +39
-0+*/ +if (!gyro && oldgyro) +fsleep (INV_ICM42607_GYRO_STOP_TIME_MS *USEC_PER_MSEC ); + + val =FIELD_PREP (INV_ICM42607_PWR_MGMT0_GYRO_MODE_MASK , gyro); + val |=FIELD_PREP (INV_ICM42607_PWR_MGMT0_ACCEL_MODE_MASK , accel); + ret =regmap_write (st->map,INV_ICM42607_REG_PWR_MGMT0 , val); +if (ret) +return ret; + + st->conf.gyro.mode = gyro; + st->conf.accel.mode = accel; + st->conf.temp_en = temp; + +/* +* If a state change occurs from off to on, sleep for the startup +* time of the sensor, unless a sleep_ms is specified. Since more +* than one sensor can be transitioned from off to on, select the +* maximum time from each of the sensors changing from off to on. +*/ + sleepval_ms =0 ; +if (temp && !oldtemp) + sleepval_ms =max (sleepval_ms,INV_ICM42607_TEMP_STARTUP_TIME_MS ); + +if (accel && !oldaccel) + sleepval_ms =max (sleepval_ms,INV_ICM42607_ACCEL_STARTUP_TIME_MS ); + +if (gyro && !oldgyro) + sleepval_ms =max (sleepval_ms,INV_ICM42607_GYRO_STARTUP_TIME_MS ); + +if (sleep_ms) + *sleep_ms = sleepval_ms; +else if (sleepval_ms) +fsleep (sleepval_ms *USEC_PER_MSEC ); + +return 0 ; +} int inv_icm42607_core_probe(struct regmap *regmap,@@ -236,6 +305,8 @@ int inv_icm42607_core_probe(struct regmap *regmap,if (!st)return -ENOMEM ; +dev_set_drvdata (dev, st); + ret =devm_mutex_init (dev, &st->lock);if (ret)return ret;@@ -271,10 +342,78 @@ int inv_icm42607_core_probe(struct regmap *regmap,if (ret)return ret;Quoted 11 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c int inv_icm42607_core_probe(struct regmap *regmap, · line 350
Quoted 6 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +6
-0+ ret =devm_pm_runtime_set_active_enabled (dev); +if (ret) +return ret; + +pm_runtime_set_autosuspend_delay (dev,INV_ICM42607_SUSPEND_DELAY_MS ); +pm_runtime_use_autosuspend (dev);Sashiko does put out some stuff here. Please take a look and work out or test if it is right (I think not but haven't checked that carefully!) From a quick look I think that the auto disabling of autosuspend does a
rpm_idle()that should result in it suspending...Quoted 2 lines
I see a few other drivers adding one more call to
devm_pm_runtime_enable()so I'm going to see how that works out.Quoted 8 lines
Obviously that didn't work, but digging in much deeper into the PM code I see that
devm_pm_runtime_set_active_enabled()returnsdevm_pm_runtime_enable(), which setsdevm_add_action_or_reset()onpm_runtime_disable_action(), which callspm_runtime_dont_use_autosuspend()andpm_runtime_disable(). Shouldn't this work, or am I missing something? Basically when the driver detaches shouldn't this chain end up callingpm_runtime_dont_use_autosuspend()?
Quoted 6 lines
Agreed. That was how I read things. The only thing I didn't entirely confirm (states involved were fiddly enough I'd want to check it with the actual driver!) was that
pm_runtime_dont_use_autosuspend()ends up callingrpm_idle()in this case.Jonathan
I dropped in a dev_warn on the rpm_idle() and can confirm when I unbound the driver it called rpm_idle(). So... yes?
Chris
Quoted 15 lines
Quoted 14 lines
Thank you,
ChrisQuoted 9 lines
Quoted 6 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c int inv_icm42607_core_probe(struct regmap *regmap, · line 354
Quoted 6 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +1
-0+return 0 ; }EXPORT_SYMBOL_NS_GPL (inv_icm42607_core_probe,"IIO_ICM42607" );Thank you,
Chris
PATCH v13 6/9 iio: imu: inv_icm42607: Add Temp Support in icm42607
In reply to Chris MorganFrom: Chris Morgan <[email protected]>
Add functions for reading temperature sensor data.
--- drivers/iio/imu/inv_icm42607/Makefile | 1 + drivers/iio/imu/inv_icm42607/inv_icm42607.h | 3 + .../iio/imu/inv_icm42607/inv_icm42607_core.c | 18 +++++ .../iio/imu/inv_icm42607/inv_icm42607_temp.c | 81 +++++++++++++++++++ .../iio/imu/inv_icm42607/inv_icm42607_temp.h | 37 +++++++++ 5 files changed, 140 insertions(+) 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/inv_icm42607/Makefile +1 -0
@@ -2,6 +2,7 @@ obj-$(CONFIG_INV_ICM42607) += inv-icm42607.o inv-icm42607-y += inv_icm42607_core.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
drivers/iio/imu/inv_icm42607/inv_icm42607.h +3 -0
@@ -358,6 +358,9 @@ extern const struct inv_icm42607_hw inv_icm42607_hw_data;extern const struct inv_icm42607_hw inv_icm42607p_hw_data;extern const struct dev_pm_ops inv_icm42607_pm_ops; +int inv_icm42607_set_temp_conf (struct inv_icm42607_state *st,bool enable, +unsigned int *sleep_ms); +int inv_icm42607_core_probe (struct regmap *regmap,const struct inv_icm42607_hw *hw,inv_icm42607_bus_setup bus_setup);
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +18 -0
@@ -162,6 +162,24 @@ static int inv_icm42607_set_pwr_mgmt0(struct inv_icm42607_state *st,return 0 ; } +int inv_icm42607_set_temp_conf (struct inv_icm42607_state *st,bool enable, +unsigned int *sleep_ms) +{ +unsigned int val; +int ret; + + val =FIELD_PREP (INV_ICM42607_TEMP_CONFIG0_FILTER_MASK , +INV_ICM42607_FILTER_BW_34HZ ); + ret =regmap_update_bits (st->map,INV_ICM42607_REG_TEMP_CONFIG0 , +INV_ICM42607_TEMP_CONFIG0_FILTER_MASK , val); +if (ret) +return ret; + +return inv_icm42607_set_pwr_mgmt0 (st, st->conf.gyro.mode, + st->conf.accel.mode, enable, + sleep_ms); +} +static int inv_icm42607_set_conf (struct inv_icm42607_state *st,const struct inv_icm42607_conf *conf) {
drivers/iio/imu/inv_icm42607/inv_icm42607_temp.c new file +81 -0
81 lines not on this page · raw message
drivers/iio/imu/inv_icm42607/inv_icm42607_temp.h new file +37 -0
@@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* +* Copyright (C) 2026 InvenSense, Inc. +*/ + +#ifndef INV_ICM42607_TEMP_H_ +#define INV_ICM42607_TEMP_H_ + +#include <linux/bitops.h> + +struct iio_dev ; +struct iio_chan_spec ; + +#define INV_ICM42607_TEMP_CHAN (_index) \ +{ \ + .type = IIO_TEMP, \ + .info_mask_separate = \ + BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_OFFSET) | \ + BIT(IIO_CHAN_INFO_SCALE), \ + .info_mask_shared_by_all = \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .info_mask_shared_by_all_available = \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .scan_index = _index, \ + .scan_type = { \ + .sign = 's', \ + .realbits = 16, \ + .storagebits = 16, \ + }, \ +} + +int inv_icm42607_temp_read_raw (struct iio_dev *indio_dev, +struct iio_chan_spec const *chan, +int *val,int *val2,long mask); + +#endif
Signature · 1 line
2.43.0
[email protected]
AI reviewRe: [PATCH V13 6/9] iio: imu: inv_icm42607: Add Temp Support in icm42607
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
New issues:
- [High] Prematurely mutating the temperature software state before calling the power management configuration bypasses state change detection, skipping the mandatory startup delay and causing reads of uninitialized data.
Pre-existing issues:
- [High] The temperature sensor read fails (returns -EINVAL) when the gyroscope and accelerometer are off because the device is placed in Sleep mode instead of Idle mode, disabling the internal RC oscillator. --
commit d36f0c461ef9d5076de90b75b6238be45c35148d
Author: Chris Morgan <[email protected]>
Subject: iio: imu: inv_icm42607: Add Temp Support in icm42607
Add functions for reading temperature sensor data.
[ ... ]
Quoted 4 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +0
-0
[ ... ]
Quoted 10 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +6
-0@@ -162,6 +162,24 @@ static int inv_icm42607_set_pwr_mgmt0(struct inv_icm42607_state *st,return 0 ; } +int inv_icm42607_set_temp_conf (struct inv_icm42607_state *st,bool enable, +unsigned int *sleep_ms) +{ +unsigned int val; +int ret; +
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c static int inv_icm42607_set_pwr_mgmt0(struct inv_icm42607_state *st, · line 180
Quoted 10 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +10
-0+ val =FIELD_PREP (INV_ICM42607_TEMP_CONFIG0_FILTER_MASK , +INV_ICM42607_FILTER_BW_34HZ ); + ret =regmap_update_bits (st->map,INV_ICM42607_REG_TEMP_CONFIG0 , +INV_ICM42607_TEMP_CONFIG0_FILTER_MASK , val); +if (ret) +return ret; + +return inv_icm42607_set_pwr_mgmt0 (st, st->conf.gyro.mode, + st->conf.accel.mode, enable, + sleep_ms);
[Severity: High]
This is a pre-existing issue, but will this temperature read fail with -EINVAL if the gyroscope and accelerometer are off?
Looking at inv_icm42607_set_pwr_mgmt0(), it constructs the PWR_MGMT0 register value using only the gyro and accel mode masks:
val = FIELD_PREP(INV_ICM42607_PWR_MGMT0_GYRO_MODE_MASK, gyro);
val |= FIELD_PREP(INV_ICM42607_PWR_MGMT0_ACCEL_MODE_MASK, accel);
ret = regmap_write(st->map, INV_ICM42607_REG_PWR_MGMT0, val);If both gyro and accel are off, val is 0, which places the device in Sleep mode instead of Idle mode. The internal RC oscillator required for temperature reads is disabled, causing the data register to return 0x8000 (INV_ICM42607_DATA_INVALID).
Should the IDLE bit be set when temp is true and the other sensors are inactive?
Quoted 2 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +2
-0+} +
[ ... ]
Quoted 5 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_temp.c new file +0
-0
[ ... ]
Quoted 5 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_temp.c new file +5
-0+static int inv_icm42607_temp_read (struct inv_icm42607_state *st,s16 *temp) +{ +struct device *dev =regmap_get_device (st->map); +u8 raw[2 ]; +int ret;
drivers/iio/imu/inv_icm42607/inv_icm42607_temp.c line 33
Quoted 10 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_temp.c new file +10
-0+ +PM_RUNTIME_ACQUIRE_AUTOSUSPEND (dev, pm); + ret =PM_RUNTIME_ACQUIRE_ERR (&pm); +if (ret) +return ret; + +guard (mutex)(&st->lock); + + st->conf.temp_en = true; + ret =inv_icm42607_set_temp_conf (st, st->conf.temp_en,NULL );
[Severity: High]
Does setting st->conf.temp_en to true before this call bypass the hardware configuration and startup delay?
Because st->conf.temp_en is mutated before the call, when inv_icm42607_set_temp_conf() calls inv_icm42607_set_pwr_mgmt0(), it will evaluate the state transition like this:
bool oldtemp = st->conf.temp_en;
...
if (gyro == oldgyro && accel == oldaccel && temp == oldtemp)
return 0;Since temp and oldtemp are now both true, the function returns early without writing to the power management register or waiting for the startup delay. Could this lead to reading uninitialized or desynchronized data?
Quoted 8 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_temp.c new file +8
-0+ st->conf.temp_en = false; +if (ret) +return ret; + + ret =regmap_bulk_read (st->map,INV_ICM42607_REG_TEMP_DATA1 , + raw,sizeof (raw)); +if (ret) +return ret;
[ ... ]
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=6
Jonathan Cameron
maintainerRe: [PATCH V13 6/9] iio: imu: inv_icm42607: Add Temp Support in icm42607
In reply to Chris MorganQuoted 5 lines · On Mon, 15 Jun 2026 12:25:49 -0500 Chris Morgan <[email protected]> wrote:
From: Chris Morgan <[email protected]>
Add functions for reading temperature sensor data.
Signed-off-by Chris Morgan <[email protected]>
Another sashiko reported thing. I'd definitely have missed this one and I think it is correct.
When I get caught up I'll post a thread to see if people feel we should generally just ask for Sashiko to reply on list.
Jonathan
Quoted 36 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +17
-0@@ -162,6 +162,24 @@ static int inv_icm42607_set_pwr_mgmt0(struct inv_icm42607_state *st,return 0 ; } +int inv_icm42607_set_temp_conf (struct inv_icm42607_state *st,bool enable, +unsigned int *sleep_ms) +{ +unsigned int val; +int ret; + + val =FIELD_PREP (INV_ICM42607_TEMP_CONFIG0_FILTER_MASK , +INV_ICM42607_FILTER_BW_34HZ ); + ret =regmap_update_bits (st->map,INV_ICM42607_REG_TEMP_CONFIG0 , +INV_ICM42607_TEMP_CONFIG0_FILTER_MASK , val); +if (ret) +return ret; + +return inv_icm42607_set_pwr_mgmt0 (st, st->conf.gyro.mode, + st->conf.accel.mode, enable, + sleep_ms); +}drivers/iio/imu/inv_icm42607/inv_icm42607_temp.c new file +4
-0+static int inv_icm42607_temp_read (struct inv_icm42607_state *st,s16 *temp) +{ +struct device *dev =regmap_get_device (st->map); +u8 raw[2 ];
drivers/iio/imu/inv_icm42607/inv_icm42607_temp.c line 32
Quoted 10 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_temp.c new file +10
-0+int ret; + +PM_RUNTIME_ACQUIRE_AUTOSUSPEND (dev, pm); + ret =PM_RUNTIME_ACQUIRE_ERR (&pm); +if (ret) +return ret; + +guard (mutex)(&st->lock); + + st->conf.temp_en = true;
Sashiko points out (seems right) that this sets the internal state before the power management routine expects it to be set. So why is this here as opposed to just passing true into the function that follows?
Quoted 16 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_temp.c new file +16
-0+ ret =inv_icm42607_set_temp_conf (st, st->conf.temp_en,NULL ); + st->conf.temp_en = false; +if (ret) +return ret; + + ret =regmap_bulk_read (st->map,INV_ICM42607_REG_TEMP_DATA1 , + raw,sizeof (raw)); +if (ret) +return ret; + + *temp =get_unaligned_be16 (raw); +if (*temp ==INV_ICM42607_DATA_INVALID ) +return -EINVAL ; + +return 0 ; +}
Re: [PATCH V13 6/9] iio: imu: inv_icm42607: Add Temp Support in icm42607
Quoted 60 lines · Jonathan Cameron
Quoted 5 lines · On Mon, 15 Jun 2026 12:25:49 -0500 Chris Morgan <[email protected]> wrote:
From: Chris Morgan <[email protected]>
Add functions for reading temperature sensor data.
Signed-off-by Chris Morgan <[email protected]>Another sashiko reported thing. I'd definitely have missed this one and I think it is correct.
When I get caught up I'll post a thread to see if people feel we should generally just ask for Sashiko to reply on list.
Jonathan
Quoted 43 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +17
-0@@ -162,6 +162,24 @@ static int inv_icm42607_set_pwr_mgmt0(struct inv_icm42607_state *st,return 0 ; } +int inv_icm42607_set_temp_conf (struct inv_icm42607_state *st,bool enable, +unsigned int *sleep_ms) +{ +unsigned int val; +int ret; + + val =FIELD_PREP (INV_ICM42607_TEMP_CONFIG0_FILTER_MASK , +INV_ICM42607_FILTER_BW_34HZ ); + ret =regmap_update_bits (st->map,INV_ICM42607_REG_TEMP_CONFIG0 , +INV_ICM42607_TEMP_CONFIG0_FILTER_MASK , val); +if (ret) +return ret; + +return inv_icm42607_set_pwr_mgmt0 (st, st->conf.gyro.mode, + st->conf.accel.mode, enable, + sleep_ms); +}drivers/iio/imu/inv_icm42607/inv_icm42607_temp.c new file +11
-0+static int inv_icm42607_temp_read (struct inv_icm42607_state *st,s16 *temp) +{ +struct device *dev =regmap_get_device (st->map); +u8 raw[2 ]; +int ret; + +PM_RUNTIME_ACQUIRE_AUTOSUSPEND (dev, pm); + ret =PM_RUNTIME_ACQUIRE_ERR (&pm); +if (ret) +return ret; +
Quoted 8 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_temp.c line 32
Quoted 3 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_temp.c new file +3
-0+guard (mutex)(&st->lock); + + st->conf.temp_en = true;Sashiko points out (seems right) that this sets the internal state before the power management routine expects it to be set. So why is this here as opposed to just passing true into the function that follows?
I'm going to take setting of state out of the power management function entirely, as well as killing off any "temp_en" since technically there is nothing to enable on the temp sensor. I'll do a check when you try to read the temp to see if any sensors are on and if none are then I will power up the accel sensor (since it uses about 5x less power than the gyro per the datasheet).
Quoted 17 lines
Quoted 7 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_temp.c new file +6
-0+ ret =inv_icm42607_set_temp_conf (st, st->conf.temp_en,NULL ); + st->conf.temp_en = false; +if (ret) +return ret; + + ret = regmap_bulk_read(st->map, INV_ICM42607_REG_TEMP_DATA1,drivers/iio/imu/inv_icm42607/inv_icm42607_temp.c line 48
Quoted 10 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_temp.c new file +10
-0+ raw, sizeof(raw)); +if (ret) +return ret; + + *temp =get_unaligned_be16 (raw); +if (*temp ==INV_ICM42607_DATA_INVALID ) +return -EINVAL ; + +return 0 ; +}
Thank you,
Chris
PATCH v13 7/9 iio: imu: inv_icm42607: Add Accelerometer for icm42607
In reply to Chris MorganFrom: Chris Morgan <[email protected]>
Add icm42607 accelerometer sensor for icm42607.
--- drivers/iio/imu/inv_icm42607/Makefile | 1 + drivers/iio/imu/inv_icm42607/inv_icm42607.h | 34 ++ .../iio/imu/inv_icm42607/inv_icm42607_accel.c | 373 ++++++++++++++++++ .../iio/imu/inv_icm42607/inv_icm42607_core.c | 61 +++ 4 files changed, 469 insertions(+) create mode 100644 drivers/iio/imu/inv_icm42607/inv_icm42607_accel.c
drivers/iio/imu/inv_icm42607/Makefile +1 -0
@@ -2,6 +2,7 @@ obj-$(CONFIG_INV_ICM42607) += inv-icm42607.o inv-icm42607-y += inv_icm42607_core.o +inv-icm42607-y += inv_icm42607_accel.o inv-icm42607-y += inv_icm42607_temp.o obj-$(CONFIG_INV_ICM42607_I2C) += inv-icm42607-i2c.o
drivers/iio/imu/inv_icm42607/inv_icm42607.h +34 -0
@@ -86,6 +86,17 @@ enum inv_icm42607_filter_bw {INV_ICM42607_FILTER_BW_NB }; +/* Low-Power mode sensor data filter (averaging) */ +enum inv_icm42607_filter_avg { +INV_ICM42607_FILTER_AVG_2X =0 , +INV_ICM42607_FILTER_AVG_4X =1 , +INV_ICM42607_FILTER_AVG_8X =2 , +INV_ICM42607_FILTER_AVG_16X =3 , +INV_ICM42607_FILTER_AVG_32X =4 , +INV_ICM42607_FILTER_AVG_64X =5 , +/* values 6 and 7 also correspond to 64x. */ +}; +/* Signed so that negative values can signify an invalid condition. */ struct inv_icm42607_sensor_conf {int mode;
@@ -93,6 +104,7 @@ struct inv_icm42607_sensor_conf {int odr;int filter; }; +#define INV_ICM42607_SENSOR_CONF_INIT { -1, -1, -1, -1 }struct inv_icm42607_conf {struct inv_icm42607_sensor_conf gyro;
@@ -117,6 +129,7 @@ struct inv_icm42607_suspended {* @hw: Hardware specific data. * @lock: lock for serializing multiple registers access. * @map: regmap pointer. +* @indio_accel: accelerometer IIO device. * @vddio_supply: I/O voltage regulator for the chip. * @vddio_en: I/O voltage status for runtime PM. * @suspended: suspended sensors configuration.
@@ -127,6 +140,7 @@ struct inv_icm42607_state {const struct inv_icm42607_hw *hw;struct mutex lock;struct regmap *map; +struct iio_dev *indio_accel;struct regulator *vddio_supply;bool vddio_en;struct inv_icm42607_suspended suspended;
@@ -134,6 +148,16 @@ struct inv_icm42607_state {struct iio_mount_matrix orientation; }; +/** +* struct inv_icm42607_sensor_state - sensor state variables +* @power_mode: sensor requested power mode (for common frequencies) +* @filter: sensor filter. +*/ +struct inv_icm42607_sensor_state { +enum inv_icm42607_sensor_mode power_mode; +int filter; +}; +/* Virtual register addresses: @bank on MSB (4 upper bits), @address on LSB */ /* Register Map for User Bank 0 */
@@ -358,6 +382,14 @@ extern const struct inv_icm42607_hw inv_icm42607_hw_data;extern const struct inv_icm42607_hw inv_icm42607p_hw_data;extern const struct dev_pm_ops inv_icm42607_pm_ops; +const struct iio_mount_matrix * +inv_icm42607_get_mount_matrix (struct iio_dev *indio_dev, +const struct iio_chan_spec *chan); + +int inv_icm42607_set_accel_conf (struct inv_icm42607_state *st, +struct inv_icm42607_sensor_conf *conf, +unsigned int *sleep_ms); +int inv_icm42607_set_temp_conf (struct inv_icm42607_state *st,bool enable,unsigned int *sleep_ms);
@@ -365,4 +397,6 @@ int inv_icm42607_core_probe(struct regmap *regmap,const struct inv_icm42607_hw *hw, inv_icm42607_bus_setup bus_setup); +struct iio_dev *inv_icm42607_accel_init (struct inv_icm42607_state *st); +#endif
drivers/iio/imu/inv_icm42607/inv_icm42607_accel.c new file +373 -0
373 lines not on this page · raw message
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +61 -0
79 lines not on this page · raw message
Signature · 1 line
2.43.0
Re: [PATCH V13 7/9] iio: imu: inv_icm42607: Add Accelerometer for icm42607
Quoted 1 line · Chris Morgan
Add icm42607 accelerometer sensor for icm42607.
...
drivers/iio/imu/inv_icm42607/inv_icm42607_accel.c line 195
Quoted 11 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_accel.c new file +11
-0+static int inv_icm42607_accel_read_odr (struct inv_icm42607_state *st, +int *val,int *val2) +{ +unsigned int odr; +unsigned int i; + +guard (mutex)(&st->lock); + + odr = st->conf.accel.odr; + +for (i =5 ; i <ARRAY_SIZE (inv_icm42607_accel_odr); ++i) {
Same comment stays. Why pre-increment?
Quoted 11 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_accel.c new file +11
-0+if (i == odr) +break ; + } +if (i >=ARRAY_SIZE (inv_icm42607_accel_odr)) +return -EINVAL ; + + *val = inv_icm42607_accel_odr[i][0 ]; + *val2 = inv_icm42607_accel_odr[i][1 ]; + +return IIO_VAL_INT_PLUS_MICRO ; +}
...
drivers/iio/imu/inv_icm42607/inv_icm42607_accel.c line 217
Quoted 10 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_accel.c new file +10
-0+static int inv_icm42607_accel_write_odr (struct iio_dev *indio_dev, +int val,int val2) +{ +struct inv_icm42607_sensor_conf conf =INV_ICM42607_SENSOR_CONF_INIT ; +struct inv_icm42607_state *st =iio_device_get_drvdata (indio_dev); +struct device *dev =regmap_get_device (st->map); +unsigned int idx; +int ret; + +for (idx =5 ; idx <ARRAY_SIZE (inv_icm42607_accel_odr); ++idx) {
Ditto.
Quoted 18 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_accel.c new file +18
-0+if (val == inv_icm42607_accel_odr[idx][0 ] && + val2 == inv_icm42607_accel_odr[idx][1 ]) +break ; + } +if (idx >=ARRAY_SIZE (inv_icm42607_accel_odr)) +return -EINVAL ; + + conf.odr = idx; + +PM_RUNTIME_ACQUIRE_AUTOSUSPEND (dev, pm); + ret =PM_RUNTIME_ACQUIRE_ERR (&pm); +if (ret) +return ret; + +guard (mutex)(&st->lock); + +return inv_icm42607_set_accel_conf (st, &conf,NULL ); +}
...
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c static int inv_icm42607_set_pwr_mgmt0(struct inv_icm42607_state *st, · line 183
Quoted 10 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +10
-0+int inv_icm42607_set_accel_conf (struct inv_icm42607_state *st, +struct inv_icm42607_sensor_conf *conf, +unsigned int *sleep_ms) +{ +struct inv_icm42607_sensor_conf *oldconf = &st->conf.accel; +unsigned int val; +int ret; + +if (conf->mode <0 ) + conf->mode = oldconf->mode;
Also as per below.
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c static int inv_icm42607_set_pwr_mgmt0(struct inv_icm42607_state *st, · line 189
Quoted 7 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +6
-0+if (conf->fs <0 ) + conf->fs = oldconf->fs; +if (conf->odr <0 ) + conf->odr = oldconf->odr; +if (conf->filter <0 ) + conf->filter = oldconf->filter;
This conditional is not immediately used below...
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c static int inv_icm42607_set_pwr_mgmt0(struct inv_icm42607_state *st, · line 199
Quoted 9 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +9
-0+if (conf->fs != oldconf->fs || conf->odr != oldconf->odr) { + val =FIELD_PREP (INV_ICM42607_ACCEL_CONFIG0_FS_SEL_MASK , conf->fs); + val |=FIELD_PREP (INV_ICM42607_ACCEL_CONFIG0_ODR_MASK , conf->odr); + ret =regmap_write (st->map,INV_ICM42607_REG_ACCEL_CONFIG0 , val); +if (ret) +return ret; + oldconf->fs = conf->fs; + oldconf->odr = conf->odr; + }
...you can move it here.
Quoted 19 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +19
-0+if (conf->filter != oldconf->filter) { +if (conf->mode ==INV_ICM42607_SENSOR_MODE_LOW_POWER ) { + val =FIELD_PREP (INV_ICM42607_ACCEL_CONFIG1_AVG_MASK , conf->filter); + ret =regmap_update_bits (st->map,INV_ICM42607_REG_ACCEL_CONFIG1 , +INV_ICM42607_ACCEL_CONFIG1_AVG_MASK , val); + }else { + val =FIELD_PREP (INV_ICM42607_ACCEL_CONFIG1_FILTER_MASK , + conf->filter); + ret =regmap_update_bits (st->map,INV_ICM42607_REG_ACCEL_CONFIG1 , +INV_ICM42607_ACCEL_CONFIG1_FILTER_MASK , val); + } +if (ret) +return ret; + oldconf->filter = conf->filter; + } + +return inv_icm42607_set_pwr_mgmt0 (st, st->conf.gyro.mode, conf->mode, + st->conf.temp_en, sleep_ms); +}
Signature · 2 lines
With Best Regards, Andy Shevchenko
Jonathan Cameron
maintainerRe: [PATCH V13 7/9] iio: imu: inv_icm42607: Add Accelerometer for icm42607
In reply to Chris MorganQuoted 5 lines · On Mon, 15 Jun 2026 12:25:50 -0500 Chris Morgan <[email protected]> wrote:
From: Chris Morgan <[email protected]>
Add icm42607 accelerometer sensor for icm42607.
Signed-off-by Chris Morgan <[email protected]>
FWIW I think this has the same issue as the gyro patch around management of the cache of what is enabled, but this one sashiko gave a clean bill of health...
:)
PATCH v13 8/9 iio: imu: inv_icm42607: Add Gyroscope to icm42607
In reply to Chris MorganFrom: Chris Morgan <[email protected]>
Add gyroscope functions to the icm42607 driver.
--- drivers/iio/imu/inv_icm42607/Makefile | 1 + drivers/iio/imu/inv_icm42607/inv_icm42607.h | 8 + .../iio/imu/inv_icm42607/inv_icm42607_core.c | 48 +++ .../iio/imu/inv_icm42607/inv_icm42607_gyro.c | 369 ++++++++++++++++++ 4 files changed, 426 insertions(+) create mode 100644 drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c
drivers/iio/imu/inv_icm42607/Makefile +1 -0
@@ -2,6 +2,7 @@ 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_temp.o
drivers/iio/imu/inv_icm42607/inv_icm42607.h +8 -0
@@ -130,6 +130,7 @@ struct inv_icm42607_suspended {* @lock: lock for serializing multiple registers access. * @map: regmap pointer. * @indio_accel: accelerometer IIO device. +* @indio_gyro: gyroscope IIO device. * @vddio_supply: I/O voltage regulator for the chip. * @vddio_en: I/O voltage status for runtime PM. * @suspended: suspended sensors configuration.
@@ -141,6 +142,7 @@ struct inv_icm42607_state {struct mutex lock;struct regmap *map;struct iio_dev *indio_accel; +struct iio_dev *indio_gyro;struct regulator *vddio_supply;bool vddio_en;struct inv_icm42607_suspended suspended;
@@ -390,6 +392,10 @@ int inv_icm42607_set_accel_conf(struct inv_icm42607_state *st,struct inv_icm42607_sensor_conf *conf, unsigned int *sleep_ms); +int inv_icm42607_set_gyro_conf (struct inv_icm42607_state *st, +struct inv_icm42607_sensor_conf *conf, +unsigned int *sleep_ms); +int inv_icm42607_set_temp_conf (struct inv_icm42607_state *st,bool enable,unsigned int *sleep_ms);
@@ -397,6 +403,8 @@ int inv_icm42607_core_probe(struct regmap *regmap,const struct inv_icm42607_hw *hw, inv_icm42607_bus_setup bus_setup); +struct iio_dev *inv_icm42607_gyro_init (struct inv_icm42607_state *st); +struct iio_dev *inv_icm42607_accel_init (struct inv_icm42607_state *st);#endif
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +48 -0
60 lines not on this page · raw message
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +369 -0
369 lines not on this page · raw message
Signature · 1 line
2.43.0
[email protected]
AI reviewRe: [PATCH V13 8/9] iio: imu: inv_icm42607: Add Gyroscope to icm42607
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [Medium] The gyro sensor state is not reverted after a raw read, causing it to remain permanently enabled…
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The gyro sensor state is not reverted after a raw read, causing it to remain permanently enabled during all future active PM states. --
commit 608315b9e755ed3de8730d6f1fc3e2dc0c68b7a5
Author: Chris Morgan <[email protected]>
iio: imu: inv_icm42607: Add Gyroscope to icm42607
This commit adds gyroscope functions and IIO device registration to the icm42607 driver.
Quoted 5 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +0
-0
[ ... ]
Quoted 11 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +11
-0+static int inv_icm42607_gyro_read_sensor (struct iio_dev *indio_dev, +struct iio_chan_spec const *chan, +s16 *val) +{ +struct inv_icm42607_sensor_conf conf =INV_ICM42607_SENSOR_CONF_INIT ; +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 reg; +u8 data[2 ]; +int ret;
[ ... ]
Quoted 15 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +15
-0+PM_RUNTIME_ACQUIRE_AUTOSUSPEND (dev, pm); + ret =PM_RUNTIME_ACQUIRE_ERR (&pm); +if (ret) +return ret; + +guard (mutex)(&st->lock); + +/* enable gyro sensor */ + conf.mode = gyro_st->power_mode; + conf.filter = gyro_st->filter; + ret =inv_icm42607_set_gyro_conf (st, &conf,NULL ); +if (ret) +return ret; + +/* read gyro register data */
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c line 116
Quoted 10 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +10
-0+ ret =regmap_bulk_read (st->map, reg, data,sizeof (data)); +if (ret) +return ret; + + *val =get_unaligned_be16 (data); +if (*val ==INV_ICM42607_DATA_INVALID ) +return -EINVAL ; + +return 0 ; +}
[Severity: Medium]
Does this leave the gyroscope permanently enabled after a raw read?
The function enables the gyro by setting conf.mode = gyro_st->power_mode and calling inv_icm42607_set_gyro_conf(), but does not appear to revert it to an off state before returning.
When the device later autosuspends, inv_icm42607_runtime_suspend() saves this active state into st->suspended.gyro. On every subsequent PM resume, inv_icm42607_runtime_resume() will restore the gyro to ON.
Could this cause an unnecessary 45ms startup delay and waste power during all future active PM states?
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=8
Re: [PATCH V13 8/9] iio: imu: inv_icm42607: Add Gyroscope to icm42607
In reply to Chris MorganQuoted 1 line · Chris Morgan
Add gyroscope functions to the icm42607 driver.
...
Quoted 6 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +6
-0+int inv_icm42607_set_gyro_conf (struct inv_icm42607_state *st, +struct inv_icm42607_sensor_conf *conf, +unsigned int *sleep_ms) +{ +struct inv_icm42607_sensor_conf *oldconf = &st->conf.gyro; +unsigned int val;
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c int inv_icm42607_set_accel_conf(struct inv_icm42607_state *st, · line 236
Quoted 10 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +10
-0+int ret; + +if (conf->mode <0 ) + conf->mode = oldconf->mode; +if (conf->fs <0 ) + conf->fs = oldconf->fs; +if (conf->odr <0 ) + conf->odr = oldconf->odr; +if (conf->filter <0 ) + conf->filter = oldconf->filter;
Same comment as per previous patch. But looking at this, can you rather have a helper that answers the below two questions? Something like
void _assign_conf(..., bool *write_odr, bool *write_filter)
{
...
}EXPORT_...
in the core driver? But wight both approaches and choose either existing one (as in this patch series) or what I suggested.
Quoted 25 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +25
-0+if (conf->fs != oldconf->fs || conf->odr != oldconf->odr) { + val =FIELD_PREP (INV_ICM42607_GYRO_CONFIG0_FS_SEL_MASK , + conf->fs); + val |=FIELD_PREP (INV_ICM42607_GYRO_CONFIG0_ODR_MASK , + conf->odr); + ret =regmap_write (st->map,INV_ICM42607_REG_GYRO_CONFIG0 , val); +if (ret) +return ret; + oldconf->fs = conf->fs; + oldconf->odr = conf->odr; + } + +if (conf->filter != oldconf->filter) { + val =FIELD_PREP (INV_ICM42607_GYRO_CONFIG1_FILTER_MASK , + conf->filter); + ret =regmap_update_bits (st->map,INV_ICM42607_REG_GYRO_CONFIG1 , +INV_ICM42607_GYRO_CONFIG1_FILTER_MASK , val); +if (ret) +return ret; + oldconf->filter = conf->filter; + } + +return inv_icm42607_set_pwr_mgmt0 (st, conf->mode, st->conf.accel.mode, + st->conf.temp_en, sleep_ms); +}
...
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c line 191
Quoted 9 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +9
-0+{ +unsigned int odr; +unsigned int i; + +guard (mutex)(&st->lock); + + odr = st->conf.gyro.odr; + +for (i =5 ; i <ARRAY_SIZE (inv_icm42607_gyro_odr); ++i) {
Same comment, why pre-increment?
Quoted 12 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +12
-0+if (i == odr) +break ; + } +if (i >=ARRAY_SIZE (inv_icm42607_gyro_odr)) +return -EINVAL ; + + *val = inv_icm42607_gyro_odr[i][0 ]; + *val2 = inv_icm42607_gyro_odr[i][1 ]; + +return IIO_VAL_INT_PLUS_MICRO ; +} +
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c line 213
Quoted 10 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +10
-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); +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 =5 ; idx <ARRAY_SIZE (inv_icm42607_gyro_odr); ++idx) {
Ditto.
Quoted 8 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +8
-0+if (val == inv_icm42607_gyro_odr[idx][0 ] && + val2 == inv_icm42607_gyro_odr[idx][1 ]) +break ; + } +if (idx >=ARRAY_SIZE (inv_icm42607_gyro_odr)) +return -EINVAL ; + + conf.odr = idx;
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c line 231
Quoted 10 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +10
-0+ +PM_RUNTIME_ACQUIRE_AUTOSUSPEND (dev, pm); + ret =PM_RUNTIME_ACQUIRE_ERR (&pm); +if (ret) +return ret; + +guard (mutex)(&st->lock); + +return inv_icm42607_set_gyro_conf (st, &conf,NULL ); +}
Can be some of the code deduplicated between gyro and accel?
Signature · 2 lines
With Best Regards, Andy Shevchenko
Re: [PATCH V13 8/9] iio: imu: inv_icm42607: Add Gyroscope to icm42607
Quoted 26 lines · Andy Shevchenko
Quoted 1 line · Chris Morgan
Add gyroscope functions to the icm42607 driver.
...
Quoted 6 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +6
-0+int inv_icm42607_set_gyro_conf (struct inv_icm42607_state *st, +struct inv_icm42607_sensor_conf *conf, +unsigned int *sleep_ms) +{ +struct inv_icm42607_sensor_conf *oldconf = &st->conf.gyro; +unsigned int val;drivers/iio/imu/inv_icm42607/inv_icm42607_core.c int inv_icm42607_set_accel_conf(struct inv_icm42607_state *st, · line 236
Quoted 10 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +10
-0+int ret; + +if (conf->mode <0 ) + conf->mode = oldconf->mode; +if (conf->fs <0 ) + conf->fs = oldconf->fs; +if (conf->odr <0 ) + conf->odr = oldconf->odr; +if (conf->filter <0 ) + conf->filter = oldconf->filter;Same comment as per previous patch. But looking at this, can you rather have a helper that answers the below two questions? Something like
Quoted 8 lines
void
_assign_conf(..., bool *write_odr, bool *write_filter){ ... }
EXPORT_...in the core driver? But wight both approaches and choose either existing one (as in this patch series) or what I suggested.
In the core driver, I was going to do something like this:
static void inv_icm42607_update_config(struct inv_icm42607_sensor_conf *conf,
struct inv_icm42607_sensor_conf *oldconf, bool *config0, bool *config1)
{
if (conf->mode < 0)
conf->mode = oldconf->mode;
if (conf->fs < 0)
conf->fs = oldconf->fs;
if (conf->odr < 0)
conf->odr = oldconf->odr;
if (conf->filter < 0)
conf->filter = oldconf->filter;
if (conf->fs != oldconf->fs || conf->odr != oldconf->odr)
*config0 = true;
if (conf->filter != oldconf->filter)
*config1 = true;
}So the step of copying stuff for sanity checking as well as checking if I need to update config0 or config1 registers is handled here, and I can simply check the values of config0 and config1 with an if to determine if I need to call to write to the registers.
Quoted 29 lines
Quoted 26 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +25
-0+if (conf->fs != oldconf->fs || conf->odr != oldconf->odr) { + val =FIELD_PREP (INV_ICM42607_GYRO_CONFIG0_FS_SEL_MASK , + conf->fs); + val |=FIELD_PREP (INV_ICM42607_GYRO_CONFIG0_ODR_MASK , + conf->odr); + ret =regmap_write (st->map,INV_ICM42607_REG_GYRO_CONFIG0 , val); +if (ret) +return ret; + oldconf->fs = conf->fs; + oldconf->odr = conf->odr; + } + +if (conf->filter != oldconf->filter) { + val =FIELD_PREP (INV_ICM42607_GYRO_CONFIG1_FILTER_MASK , + conf->filter); + ret =regmap_update_bits (st->map,INV_ICM42607_REG_GYRO_CONFIG1 , +INV_ICM42607_GYRO_CONFIG1_FILTER_MASK , val); +if (ret) +return ret; + oldconf->filter = conf->filter; + } + +return inv_icm42607_set_pwr_mgmt0 (st, conf->mode, st->conf.accel.mode, + st->conf.temp_en, sleep_ms); +}...
Quoted 11 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c line 191
Quoted 9 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +9
-0+{ +unsigned int odr; +unsigned int i; + +guard (mutex)(&st->lock); + + odr = st->conf.gyro.odr; + +for (i =5 ; i <ARRAY_SIZE (inv_icm42607_gyro_odr); ++i) {Same comment, why pre-increment?
I could not brain on this day, I had the dumb.
I'll fix it. :-)
Quoted 38 lines
Quoted 13 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +12
-0+if (i == odr) +break ; + } +if (i >=ARRAY_SIZE (inv_icm42607_gyro_odr)) +return -EINVAL ; + + *val = inv_icm42607_gyro_odr[i][0 ]; + *val2 = inv_icm42607_gyro_odr[i][1 ]; + +return IIO_VAL_INT_PLUS_MICRO ; +} +drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c line 213
Quoted 10 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +10
-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); +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 =5 ; idx <ARRAY_SIZE (inv_icm42607_gyro_odr); ++idx) {Ditto.
Quoted 12 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +12
-0+if (val == inv_icm42607_gyro_odr[idx][0 ] && + val2 == inv_icm42607_gyro_odr[idx][1 ]) +break ; + } +if (idx >=ARRAY_SIZE (inv_icm42607_gyro_odr)) +return -EINVAL ; + + conf.odr = idx; + +PM_RUNTIME_ACQUIRE_AUTOSUSPEND (dev, pm); + ret =PM_RUNTIME_ACQUIRE_ERR (&pm); +if (ret)
Quoted 8 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c line 168
Quoted 6 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +6
-0+return ret; + +guard (mutex)(&st->lock); + +return inv_icm42607_set_gyro_conf (st, &conf,NULL ); +}Can be some of the code deduplicated between gyro and accel?
Probably a fair amount, but the deduplication will likely need to be undone somewhat if we get buffer, WoM or apex support added back (I don't have any devices with such functionality, so if anyone will do it then it won't be me). I can refactor more if you want, or we can keep it split like this to make it easy if someone else wants to tackle the buffers/IRQs stuff later? Your call.
Quoted 6 lines
Signature · 3 lines
-- With Best Regards, Andy Shevchenko
Thank you,
Chris
Re: [PATCH V13 8/9] iio: imu: inv_icm42607: Add Gyroscope to icm42607
Quoted 2 lines · Chris Morgan
Quoted 1 line · Andy Shevchenko
On Mon, Jun 15, 2026 at 12:25:51PM -0500, Chris Morgan wrote:
...
Quoted 8 lines
Quoted 1 line
Can be some of the code deduplicated between gyro and accel?
Probably a fair amount, but the deduplication will likely need to be undone somewhat if we get buffer, WoM or apex support added back (I don't have any devices with such functionality, so if anyone will do it then it won't be me). I can refactor more if you want, or we can keep it split like this to make it easy if someone else wants to tackle the buffers/IRQs stuff later? Your call.
Just asking. Jonathan, David, Nuno, what's your opinion on this? Personal opinion is to avoid solving the issues that do not exist. If you are not committing into those features, let's not prepare driver for them right now.
Signature · 2 lines
With Best Regards, Andy Shevchenko
Jonathan Cameron
maintainerRe: [PATCH V13 8/9] iio: imu: inv_icm42607: Add Gyroscope to icm42607
Quoted 15 lines · On Tue, 23 Jun 2026 09:52:36 +0300 Andy Shevchenko…
Quoted 2 lines · Chris Morgan
Quoted 1 line · Andy Shevchenko
On Mon, Jun 15, 2026 at 12:25:51PM -0500, Chris Morgan wrote:
...
Quoted 8 lines
Quoted 1 line
Can be some of the code deduplicated between gyro and accel?
Probably a fair amount, but the deduplication will likely need to be undone somewhat if we get buffer, WoM or apex support added back (I don't have any devices with such functionality, so if anyone will do it then it won't be me). I can refactor more if you want, or we can keep it split like this to make it easy if someone else wants to tackle the buffers/IRQs stuff later? Your call.
Quoted 5 lines
Just asking. Jonathan, David, Nuno, what's your opinion on this? Personal opinion is to avoid solving the issues that do not exist. If you are not committing into those features, let's not prepare driver for them right now.
Agreed. My only exception to this is normally when someone tells me they have the code and plan to post a follow up set very shortly. Then I get a bit more relaxed as they chances of 'preparing' for the future being relevant become much higher!
Jonathan
Re: [PATCH V13 8/9] iio: imu: inv_icm42607: Add Gyroscope to icm42607
Quoted 23 lines · Jonathan Cameron
Quoted 15 lines · On Tue, 23 Jun 2026 09:52:36 +0300 Andy Shevchenko…
Quoted 2 lines · Chris Morgan
Quoted 1 line · Andy Shevchenko
On Mon, Jun 15, 2026 at 12:25:51PM -0500, Chris Morgan wrote:
...
Quoted 8 lines
Quoted 1 line
Can be some of the code deduplicated between gyro and accel?
Probably a fair amount, but the deduplication will likely need to be undone somewhat if we get buffer, WoM or apex support added back (I don't have any devices with such functionality, so if anyone will do it then it won't be me). I can refactor more if you want, or we can keep it split like this to make it easy if someone else wants to tackle the buffers/IRQs stuff later? Your call.
Quoted 5 lines
Just asking. Jonathan, David, Nuno, what's your opinion on this? Personal opinion is to avoid solving the issues that do not exist. If you are not committing into those features, let's not prepare driver for them right now.
Quoted 6 lines
Agreed. My only exception to this is normally when someone tells me they have the code and plan to post a follow up set very shortly. Then I get a bit more relaxed as they chances of 'preparing' for the future being relevant become much higher!
Jonathan
Okay, I'll refactor a bit more then and resubmit in another week or two.
Thanks,
Chris
Jonathan Cameron
maintainerRe: [PATCH V13 8/9] iio: imu: inv_icm42607: Add Gyroscope to icm42607
In reply to Chris MorganQuoted 5 lines · On Mon, 15 Jun 2026 12:25:51 -0500 Chris Morgan <[email protected]> wrote:
From: Chris Morgan <[email protected]>
Add gyroscope functions to the icm42607 driver.
Signed-off-by Chris Morgan <[email protected]>
There is another bit of sashiko stuff in here. Please take a look
https://sashiko.dev/#/patchset/20260615172554.160910-1-macroalpha82%40gmail.com
I think it is correct about there being a path in which the gyro ends up always enabled along side anything else after the first read.
In general there seems to be a bit of mix on whether the caller or the power management function should be responsible for the caching of state.
I know you look at Sashiko so I could just have waited a bit, but I was reviewing anyway so took a look and having done that might as well highlight some stuff!
Jonathan
Quoted 87 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +42
-0@@ -218,6 +218,49 @@ int inv_icm42607_set_accel_conf(struct inv_icm42607_state *st, st->conf.temp_en, sleep_ms); } +int inv_icm42607_set_gyro_conf (struct inv_icm42607_state *st, +struct inv_icm42607_sensor_conf *conf, +unsigned int *sleep_ms) +{ +struct inv_icm42607_sensor_conf *oldconf = &st->conf.gyro; +unsigned int val; +int ret; + +if (conf->mode <0 ) + conf->mode = oldconf->mode; +if (conf->fs <0 ) + conf->fs = oldconf->fs; +if (conf->odr <0 ) + conf->odr = oldconf->odr; +if (conf->filter <0 ) + conf->filter = oldconf->filter; + +if (conf->fs != oldconf->fs || conf->odr != oldconf->odr) { + val =FIELD_PREP (INV_ICM42607_GYRO_CONFIG0_FS_SEL_MASK , + conf->fs); + val |=FIELD_PREP (INV_ICM42607_GYRO_CONFIG0_ODR_MASK , + conf->odr); + ret =regmap_write (st->map,INV_ICM42607_REG_GYRO_CONFIG0 , val); +if (ret) +return ret; + oldconf->fs = conf->fs; + oldconf->odr = conf->odr; + } + +if (conf->filter != oldconf->filter) { + val =FIELD_PREP (INV_ICM42607_GYRO_CONFIG1_FILTER_MASK , + conf->filter); + ret =regmap_update_bits (st->map,INV_ICM42607_REG_GYRO_CONFIG1 , +INV_ICM42607_GYRO_CONFIG1_FILTER_MASK , val); +if (ret) +return ret; + oldconf->filter = conf->filter; + } + +return inv_icm42607_set_pwr_mgmt0 (st, conf->mode, st->conf.accel.mode, + st->conf.temp_en, sleep_ms); +}drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +30
-0+static int inv_icm42607_gyro_read_sensor (struct iio_dev *indio_dev, +struct iio_chan_spec const *chan, +s16 *val) +{ +struct inv_icm42607_sensor_conf conf =INV_ICM42607_SENSOR_CONF_INIT ; +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 reg; +u8 data[2 ]; +int ret; + +if (chan->type !=IIO_ANGL_VEL ) +return -EINVAL ; + +switch (chan->channel2) { +case IIO_MOD_X : + reg =INV_ICM42607_REG_GYRO_DATA_X1 ; +break ; +case IIO_MOD_Y : + reg =INV_ICM42607_REG_GYRO_DATA_Y1 ; +break ; +case IIO_MOD_Z : + reg =INV_ICM42607_REG_GYRO_DATA_Z1 ; +break ; +default : +return -EINVAL ; + } + +PM_RUNTIME_ACQUIRE_AUTOSUSPEND (dev, pm);
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c line 102
Quoted 10 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +10
-0+ ret =PM_RUNTIME_ACQUIRE_ERR (&pm); +if (ret) +return ret; + +guard (mutex)(&st->lock); + +/* enable gyro sensor */ + conf.mode = gyro_st->power_mode; + conf.filter = gyro_st->filter; + ret =inv_icm42607_set_gyro_conf (st, &conf,NULL );
The sashiko report is basically:
This turns it on, and runtime pm will turn it off but the state cached ends up such that it is turned on again for any runtime pm resume.
Quoted 14 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +14
-0+if (ret) +return ret; + +/* read gyro register data */ + ret =regmap_bulk_read (st->map, reg, data,sizeof (data)); +if (ret) +return ret; + + *val =get_unaligned_be16 (data); +if (*val ==INV_ICM42607_DATA_INVALID ) +return -EINVAL ; + +return 0 ; +}
Re: [PATCH V13 8/9] iio: imu: inv_icm42607: Add Gyroscope to icm42607
Quoted 125 lines · Jonathan Cameron
Quoted 5 lines · On Mon, 15 Jun 2026 12:25:51 -0500 Chris Morgan <[email protected]> wrote:
From: Chris Morgan <[email protected]>
Add gyroscope functions to the icm42607 driver.
Signed-off-by Chris Morgan <[email protected]>There is another bit of sashiko stuff in here. Please take a look
https://sashiko.dev/#/patchset/20260615172554.160910-1-macroalpha82%40gmail.comI think it is correct about there being a path in which the gyro ends up always enabled along side anything else after the first read.
In general there seems to be a bit of mix on whether the caller or the power management function should be responsible for the caching of state.
I know you look at Sashiko so I could just have waited a bit, but I was reviewing anyway so took a look and having done that might as well highlight some stuff!
Jonathan
Quoted 87 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_core.c +42
-0@@ -218,6 +218,49 @@ int inv_icm42607_set_accel_conf(struct inv_icm42607_state *st, st->conf.temp_en, sleep_ms); } +int inv_icm42607_set_gyro_conf (struct inv_icm42607_state *st, +struct inv_icm42607_sensor_conf *conf, +unsigned int *sleep_ms) +{ +struct inv_icm42607_sensor_conf *oldconf = &st->conf.gyro; +unsigned int val; +int ret; + +if (conf->mode <0 ) + conf->mode = oldconf->mode; +if (conf->fs <0 ) + conf->fs = oldconf->fs; +if (conf->odr <0 ) + conf->odr = oldconf->odr; +if (conf->filter <0 ) + conf->filter = oldconf->filter; + +if (conf->fs != oldconf->fs || conf->odr != oldconf->odr) { + val =FIELD_PREP (INV_ICM42607_GYRO_CONFIG0_FS_SEL_MASK , + conf->fs); + val |=FIELD_PREP (INV_ICM42607_GYRO_CONFIG0_ODR_MASK , + conf->odr); + ret =regmap_write (st->map,INV_ICM42607_REG_GYRO_CONFIG0 , val); +if (ret) +return ret; + oldconf->fs = conf->fs; + oldconf->odr = conf->odr; + } + +if (conf->filter != oldconf->filter) { + val =FIELD_PREP (INV_ICM42607_GYRO_CONFIG1_FILTER_MASK , + conf->filter); + ret =regmap_update_bits (st->map,INV_ICM42607_REG_GYRO_CONFIG1 , +INV_ICM42607_GYRO_CONFIG1_FILTER_MASK , val); +if (ret) +return ret; + oldconf->filter = conf->filter; + } + +return inv_icm42607_set_pwr_mgmt0 (st, conf->mode, st->conf.accel.mode, + st->conf.temp_en, sleep_ms); +}drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +30
-0+static int inv_icm42607_gyro_read_sensor (struct iio_dev *indio_dev, +struct iio_chan_spec const *chan, +s16 *val) +{ +struct inv_icm42607_sensor_conf conf =INV_ICM42607_SENSOR_CONF_INIT ; +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 reg; +u8 data[2 ]; +int ret; + +if (chan->type !=IIO_ANGL_VEL ) +return -EINVAL ; + +switch (chan->channel2) { +case IIO_MOD_X : + reg =INV_ICM42607_REG_GYRO_DATA_X1 ; +break ; +case IIO_MOD_Y : + reg =INV_ICM42607_REG_GYRO_DATA_Y1 ; +break ; +case IIO_MOD_Z : + reg =INV_ICM42607_REG_GYRO_DATA_Z1 ; +break ; +default : +return -EINVAL ; + } + +PM_RUNTIME_ACQUIRE_AUTOSUSPEND (dev, pm);drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c line 102
Quoted 10 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +10
-0+ ret =PM_RUNTIME_ACQUIRE_ERR (&pm); +if (ret) +return ret; + +guard (mutex)(&st->lock); + +/* enable gyro sensor */ + conf.mode = gyro_st->power_mode; + conf.filter = gyro_st->filter; + ret =inv_icm42607_set_gyro_conf (st, &conf,NULL );The sashiko report is basically:
Quoted 3 lines
This turns it on, and runtime pm will turn it off but the state cached ends up such that it is turned on again for any runtime pm resume.
Yep, for this and for the accel sensor it looks like it gets stuck on. I've revamped this code for the next round and so far it looks like the sensor is powering down correctly.
Quoted 16 lines
Quoted 5 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +4
-0+if (ret) +return ret; + +/* read gyro register data */ drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c line 116
Quoted 10 lines
drivers/iio/imu/inv_icm42607/inv_icm42607_gyro.c new file +10
-0+ ret =regmap_bulk_read (st->map, reg, data,sizeof (data)); +if (ret) +return ret; + + *val =get_unaligned_be16 (data); +if (*val ==INV_ICM42607_DATA_INVALID ) +return -EINVAL ; + +return 0 ; +}
Thank you,
Chris
PATCH v13 9/9 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.
--- arch/arm64/boot/dts/rockchip/rk3568-anbernic-rg-ds.dts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
arch/arm64/boot/dts/rockchip/rk3568-anbernic-rg-ds.dts +7 -1
@@ -871,7 +871,13 @@ aw87391_pa_r: audio-codec@5b { sound-name-prefix = "Right Amp"; }; - /* invensense,icm42607p at 0x68 */ + icm42607p: imu@68 { + compatible = "invensense,icm42607p"; + reg = <0x68>; + mount-matrix = "-1", "0", "0", + "0", "1", "0", + "0", "0", "-1"; + }; }; &i2c3 {
Signature · 1 line
2.43.0