summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>2026-07-20 12:38:33 +0200
committerJonathan Cameron <jonathan.cameron@oss.qualcomm.com>2026-07-24 01:01:01 +0100
commit8f4b627656fa1767d8337a95849fe7c895b6f68a (patch)
treed4a2dd200df3e19da8aa6cc11514e900f89d3c63
parent1330597c7480611334977ff66878fd40b411fa41 (diff)
downloadlinux-next-8f4b627656fa1767d8337a95849fe7c895b6f68a.tar.gz
linux-next-8f4b627656fa1767d8337a95849fe7c895b6f68a.zip
iio: inv_sensors: better timestamp alignment when using watermark
Current interrupt timestamp alignment only changes the final timestamp. When the watermark is in use, we have a batch of samples for each interrupt. The current code doesn't manage to align the timestamp because the jitter is too high. Instead modify the estimated inter interrupt period and use that to adjust the timestamp alignment over the batch in a linear fashion. 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.c51
1 files changed, 19 insertions, 32 deletions
diff --git a/drivers/iio/common/inv_sensors/inv_sensors_timestamp.c b/drivers/iio/common/inv_sensors/inv_sensors_timestamp.c
index ecfd54ffe7e9..2aaaa8df6d03 100644
--- a/drivers/iio/common/inv_sensors/inv_sensors_timestamp.c
+++ b/drivers/iio/common/inv_sensors/inv_sensors_timestamp.c
@@ -10,9 +10,7 @@
#include <linux/iio/common/inv_sensors_timestamp.h>
-/* compute jitter, min and max following jitter in per mille */
-#define INV_SENSORS_TIMESTAMP_JITTER(_val, _jitter) \
- (div_s64((_val) * (_jitter), 1000))
+/* compute min and max following jitter in per mille */
#define INV_SENSORS_TIMESTAMP_MIN(_val, _jitter) \
(((_val) * (1000 - (_jitter))) / 1000)
#define INV_SENSORS_TIMESTAMP_MAX(_val, _jitter) \
@@ -102,34 +100,22 @@ static bool inv_update_chip_period(struct inv_sensors_timestamp *ts,
/* update chip internal period estimation */
new_chip_period = period / ts->mult;
inv_update_acc(&ts->chip_period, new_chip_period);
- ts->period = ts->mult * ts->chip_period.val;
return true;
}
-static void inv_align_timestamp_it(struct inv_sensors_timestamp *ts)
+static u32 inv_align_timestamp_it(struct inv_sensors_timestamp *ts,
+ unsigned int sample_nb)
{
const s64 period_min = (s64)ts->min_period * ts->mult;
const s64 period_max = (s64)ts->max_period * ts->mult;
- s64 add_max, sub_max;
- s64 delta, jitter;
- s64 adjust;
-
- /* delta time between last sample and last interrupt */
- delta = ts->it.lo - ts->timestamp;
-
- /* adjust timestamp while respecting jitter */
- add_max = period_max - (s64)ts->period;
- sub_max = period_min - (s64)ts->period;
- jitter = INV_SENSORS_TIMESTAMP_JITTER((s64)ts->period, ts->chip.jitter);
- if (delta > jitter)
- adjust = add_max;
- else if (delta < -jitter)
- adjust = sub_max;
- else
- adjust = 0;
+ s64 new_period;
+
+ /* compute new period aligning last timestamp with interrupt timestamp */
+ new_period = div_s64(ts->it.up - ts->timestamp, sample_nb);
- ts->timestamp += adjust;
+ /* ensure that period never overflows the jitter */
+ return clamp(new_period, period_min, period_max);
}
void inv_sensors_timestamp_interrupt(struct inv_sensors_timestamp *ts,
@@ -143,6 +129,13 @@ void inv_sensors_timestamp_interrupt(struct inv_sensors_timestamp *ts,
if (sample_nb == 0)
return;
+ /* no previous data, compute theoretical value from interrupt */
+ if (ts->timestamp == 0) {
+ /* elapsed time: sensor period * sensor samples number */
+ interval = (s64)ts->period * (s64)sample_nb;
+ ts->timestamp = timestamp - interval;
+ }
+
/* update interrupt timestamp and compute chip and sensor periods */
it = &ts->it;
it->lo = it->up;
@@ -154,17 +147,11 @@ void inv_sensors_timestamp_interrupt(struct inv_sensors_timestamp *ts,
valid = inv_update_chip_period(ts, period);
}
- /* no previous data, compute theoretical value from interrupt */
- if (ts->timestamp == 0) {
- /* elapsed time: sensor period * sensor samples number */
- interval = (s64)ts->period * (s64)sample_nb;
- ts->timestamp = it->up - interval;
- return;
- }
-
/* if interrupt interval is valid, sync with interrupt timestamp */
if (valid)
- inv_align_timestamp_it(ts);
+ ts->period = inv_align_timestamp_it(ts, sample_nb);
+ else
+ ts->period = ts->mult * ts->chip_period.val;
}
EXPORT_SYMBOL_NS_GPL(inv_sensors_timestamp_interrupt, "IIO_INV_SENSORS_TIMESTAMP");