[PATCH] iio: imu: inv_icm42600: force accel odr change when switching power mode
From: Jean-Baptiste Maneyrol via B4 Relay
Date: Mon Sep 14 2026 - 10:50:51 EST
From: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@xxxxxxx>
When accel must switch from low-power mode to low-noise due to a change in
ODR, there is an hardware bug that sometimes prevent the ODR change flag
to be set in the FIFO header. If this happens, the driver is stuck waiting
for the ODR change flag that is never happening.
Fix this by using accel_force_odr flag set when switching mode for forcing
apply of ODR change. Do the apply after parsing FIFO data to let the flag
do the job if it is here.
Fixes: ec74ae9fd37c ("iio: imu: inv_icm42600: add accurate timestamping")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@xxxxxxx>
---
drivers/iio/imu/inv_icm42600/inv_icm42600.h | 1 +
drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c | 9 ++++++++-
drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c | 2 ++
drivers/iio/imu/inv_icm42600/inv_icm42600_core.c | 9 +++++++++
4 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600.h b/drivers/iio/imu/inv_icm42600/inv_icm42600.h
index f6c7c84c7e45..e56943931b6a 100644
--- a/drivers/iio/imu/inv_icm42600/inv_icm42600.h
+++ b/drivers/iio/imu/inv_icm42600/inv_icm42600.h
@@ -179,6 +179,7 @@ struct inv_icm42600_state {
struct {
s64 gyro;
s64 accel;
+ bool accel_force_odr;
} timestamp;
struct inv_icm42600_apex apex;
struct inv_icm42600_fifo fifo;
diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c
index 65d29de8ecf9..cc8c074777c9 100644
--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c
+++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c
@@ -1236,9 +1236,11 @@ int inv_icm42600_accel_parse_fifo(struct iio_dev *indio_dev)
return size;
/* update odr */
- if (odr & INV_ICM42600_SENSOR_ACCEL)
+ if (odr & INV_ICM42600_SENSOR_ACCEL) {
inv_sensors_timestamp_apply_odr(ts, st->fifo.period,
st->fifo.nb.total, no);
+ st->timestamp.accel_force_odr = false;
+ }
/* skip packet if no accel data or data is invalid */
if (accel == NULL || !inv_icm42600_fifo_is_data_valid(accel))
@@ -1251,5 +1253,10 @@ int inv_icm42600_accel_parse_fifo(struct iio_dev *indio_dev)
iio_push_to_buffers_with_timestamp(indio_dev, &buffer, ts_val);
}
+ if (st->timestamp.accel_force_odr) {
+ inv_sensors_timestamp_apply_odr(ts, 0, 0, 0);
+ st->timestamp.accel_force_odr = false;
+ }
+
return 0;
}
diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c
index ded45dfe46a2..2bf9fc29d7d2 100644
--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c
+++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c
@@ -384,6 +384,8 @@ static int inv_icm42600_buffer_postdisable(struct iio_dev *indio_dev)
mutex_lock(&st->lock);
inv_sensors_timestamp_apply_odr(ts, 0, 0, 0);
+ if (sensor == INV_ICM42600_SENSOR_ACCEL)
+ st->timestamp.accel_force_odr = false;
ret = inv_icm42600_buffer_set_fifo_en(st, st->fifo.en & ~sensor);
if (ret)
diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c
index be8cbecdd92e..cd2e53416f5b 100644
--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c
+++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c
@@ -325,6 +325,15 @@ int inv_icm42600_set_accel_conf(struct inv_icm42600_state *st,
break;
}
+ /*
+ * If we change mode from low-power to low-noise because of odr,
+ * we need to force odr change.
+ */
+ if (oldconf->mode == INV_ICM42600_SENSOR_MODE_LOW_POWER &&
+ conf->mode == INV_ICM42600_SENSOR_MODE_LOW_NOISE &&
+ conf->odr != oldconf->odr)
+ st->timestamp.accel_force_odr = true;
+
/* set ACCEL_CONFIG0 register (accel fullscale & odr) */
if (conf->fs != oldconf->fs || conf->odr != oldconf->odr) {
val = INV_ICM42600_ACCEL_CONFIG0_FS(conf->fs) |
---
base-commit: a7c07602e00596a45de8a4a700af96392953ed38
change-id: 20260911-iio-imu-inv-icm42600-fix-odr-change-event-issue-when-switching-power-mode-813d7807fe5c
Best regards,
--
Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@xxxxxxx>