summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>2026-07-20 12:38:34 +0200
committerJonathan Cameron <jonathan.cameron@oss.qualcomm.com>2026-07-24 01:01:01 +0100
commit82bd09ce4fd3b15680735eaeafe2e688901e3b00 (patch)
tree86b2ffde945dd5b8212f949294fd68d47a52b920
parent8f4b627656fa1767d8337a95849fe7c895b6f68a (diff)
downloadlinux-next-82bd09ce4fd3b15680735eaeafe2e688901e3b00.tar.gz
linux-next-82bd09ce4fd3b15680735eaeafe2e688901e3b00.zip
iio: inv_sensors: improve period measurement by using a longer delay
Period measurement can be difficult when using high sampling frequency where the jitter criteria is hard to meet because of the system jitter. This new version is using the delta time between 2 distant interrupts to measure an interval of at least 20ms. 20ms is a good compromise between the mitigation of system jitter and the delay to update period. This way we decorrelate the period measurement from the interrupt timestamps syncing using only the 2 last interrupts. Signed-off-by: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com> Signed-off-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
-rw-r--r--drivers/iio/common/inv_sensors/inv_sensors_timestamp.c26
-rw-r--r--include/linux/iio/common/inv_sensors_timestamp.h6
2 files changed, 29 insertions, 3 deletions
diff --git a/drivers/iio/common/inv_sensors/inv_sensors_timestamp.c b/drivers/iio/common/inv_sensors/inv_sensors_timestamp.c
index 2aaaa8df6d03..88a82d1370c5 100644
--- a/drivers/iio/common/inv_sensors/inv_sensors_timestamp.c
+++ b/drivers/iio/common/inv_sensors/inv_sensors_timestamp.c
@@ -16,6 +16,9 @@
#define INV_SENSORS_TIMESTAMP_MAX(_val, _jitter) \
(((_val) * (1000 + (_jitter))) / 1000)
+/* minimum timestamp delta between 2 interrupts for measuring period (20ms) */
+#define INV_SENSORS_MIN_IT_DELTA (20 * NSEC_PER_MSEC)
+
/* Add a new value inside an accumulator and update the estimate value */
static void inv_update_acc(struct inv_sensors_timestamp_acc *acc, u32 val)
{
@@ -122,7 +125,7 @@ void inv_sensors_timestamp_interrupt(struct inv_sensors_timestamp *ts,
size_t sample_nb, s64 timestamp)
{
struct inv_sensors_timestamp_interval *it;
- s64 delta, interval;
+ s64 delta, delta_threshold, interval;
u32 period;
bool valid = false;
@@ -136,15 +139,32 @@ void inv_sensors_timestamp_interrupt(struct inv_sensors_timestamp *ts,
ts->timestamp = timestamp - interval;
}
+ /* update delta timestamps and estimated period */
+ it = &ts->delta;
+ ts->delta_counter += sample_nb;
+ delta = timestamp - it->up;
+ delta_threshold = INV_SENSORS_TIMESTAMP_MIN(INV_SENSORS_MIN_IT_DELTA, ts->chip.jitter);
+ if (delta >= delta_threshold) {
+ it->lo = it->up;
+ it->up = timestamp;
+ if (it->lo != 0) {
+ /* compute period: delta time divided by number of samples */
+ delta = it->up - it->lo;
+ period = div_s64(delta, ts->delta_counter);
+ inv_update_chip_period(ts, period);
+ }
+ ts->delta_counter = 0;
+ }
+
/* update interrupt timestamp and compute chip and sensor periods */
it = &ts->it;
it->lo = it->up;
it->up = timestamp;
delta = it->up - it->lo;
if (it->lo != 0) {
- /* compute period: delta time divided by number of samples */
+ /* compute period and check validity */
period = div_s64(delta, sample_nb);
- valid = inv_update_chip_period(ts, period);
+ valid = inv_validate_period(ts, period);
}
/* if interrupt interval is valid, sync with interrupt timestamp */
diff --git a/include/linux/iio/common/inv_sensors_timestamp.h b/include/linux/iio/common/inv_sensors_timestamp.h
index e4e720e6f4b7..4f08204ede3b 100644
--- a/include/linux/iio/common/inv_sensors_timestamp.h
+++ b/include/linux/iio/common/inv_sensors_timestamp.h
@@ -46,6 +46,8 @@ struct inv_sensors_timestamp_acc {
* @min_period: minimal acceptable clock period
* @max_period: maximal acceptable clock period
* @it: interrupts interval timestamps
+ * @delta: interval timestamps between several interrupts
+ * @delta_counter: number of data samples in the delta interval
* @timestamp: store last timestamp for computing next data timestamp
* @mult: current internal period multiplier
* @new_mult: new set internal period multiplier (not yet effective)
@@ -57,6 +59,8 @@ struct inv_sensors_timestamp {
u32 min_period;
u32 max_period;
struct inv_sensors_timestamp_interval it;
+ struct inv_sensors_timestamp_interval delta;
+ u32 delta_counter;
s64 timestamp;
u32 mult;
u32 new_mult;
@@ -88,6 +92,8 @@ static inline void inv_sensors_timestamp_reset(struct inv_sensors_timestamp *ts)
const struct inv_sensors_timestamp_interval interval_init = {0LL, 0LL};
ts->it = interval_init;
+ ts->delta = interval_init;
+ ts->delta_counter = 0;
ts->timestamp = 0;
}