summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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");