diff options
Diffstat (limited to 'drivers/iio/imu/inv_icm42600')
-rw-r--r-- | drivers/iio/imu/inv_icm42600/Kconfig | 1 | ||||
-rw-r--r-- | drivers/iio/imu/inv_icm42600/Makefile | 1 | ||||
-rw-r--r-- | drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c | 35 | ||||
-rw-r--r-- | drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c | 33 | ||||
-rw-r--r-- | drivers/iio/imu/inv_icm42600/inv_icm42600_core.c | 14 | ||||
-rw-r--r-- | drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c | 35 | ||||
-rw-r--r-- | drivers/iio/imu/inv_icm42600/inv_icm42600_timestamp.c | 198 | ||||
-rw-r--r-- | drivers/iio/imu/inv_icm42600/inv_icm42600_timestamp.h | 85 |
8 files changed, 75 insertions, 327 deletions
diff --git a/drivers/iio/imu/inv_icm42600/Kconfig b/drivers/iio/imu/inv_icm42600/Kconfig index 50cbcfcb6cf1..f56b0816cc4d 100644 --- a/drivers/iio/imu/inv_icm42600/Kconfig +++ b/drivers/iio/imu/inv_icm42600/Kconfig @@ -3,6 +3,7 @@ config INV_ICM42600 tristate select IIO_BUFFER + select IIO_INV_SENSORS_TIMESTAMP config INV_ICM42600_I2C tristate "InvenSense ICM-426xx I2C driver" diff --git a/drivers/iio/imu/inv_icm42600/Makefile b/drivers/iio/imu/inv_icm42600/Makefile index 291714d9aa54..0f49f6df3647 100644 --- a/drivers/iio/imu/inv_icm42600/Makefile +++ b/drivers/iio/imu/inv_icm42600/Makefile @@ -6,7 +6,6 @@ inv-icm42600-y += inv_icm42600_gyro.o inv-icm42600-y += inv_icm42600_accel.o inv-icm42600-y += inv_icm42600_temp.o inv-icm42600-y += inv_icm42600_buffer.o -inv-icm42600-y += inv_icm42600_timestamp.o obj-$(CONFIG_INV_ICM42600_I2C) += inv-icm42600-i2c.o inv-icm42600-i2c-y += inv_icm42600_i2c.o diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c index c3f433ad3af6..b1e4fde27d25 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c @@ -10,14 +10,15 @@ #include <linux/regmap.h> #include <linux/delay.h> #include <linux/math64.h> -#include <linux/iio/iio.h> + #include <linux/iio/buffer.h> +#include <linux/iio/common/inv_sensors_timestamp.h> +#include <linux/iio/iio.h> #include <linux/iio/kfifo_buf.h> #include "inv_icm42600.h" #include "inv_icm42600_temp.h" #include "inv_icm42600_buffer.h" -#include "inv_icm42600_timestamp.h" #define INV_ICM42600_ACCEL_CHAN(_modifier, _index, _ext_info) \ { \ @@ -98,7 +99,7 @@ static int inv_icm42600_accel_update_scan_mode(struct iio_dev *indio_dev, const unsigned long *scan_mask) { struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); - struct inv_icm42600_timestamp *ts = iio_priv(indio_dev); + struct inv_sensors_timestamp *ts = iio_priv(indio_dev); struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT; unsigned int fifo_en = 0; unsigned int sleep_temp = 0; @@ -126,7 +127,7 @@ static int inv_icm42600_accel_update_scan_mode(struct iio_dev *indio_dev, } /* update data FIFO write */ - inv_icm42600_timestamp_apply_odr(ts, 0, 0, 0); + inv_sensors_timestamp_apply_odr(ts, 0, 0, 0); ret = inv_icm42600_buffer_set_fifo_en(st, fifo_en | st->fifo.en); if (ret) goto out_unlock; @@ -311,7 +312,7 @@ static int inv_icm42600_accel_write_odr(struct iio_dev *indio_dev, int val, int val2) { struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); - struct inv_icm42600_timestamp *ts = iio_priv(indio_dev); + struct inv_sensors_timestamp *ts = iio_priv(indio_dev); struct device *dev = regmap_get_device(st->map); unsigned int idx; struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT; @@ -330,8 +331,8 @@ static int inv_icm42600_accel_write_odr(struct iio_dev *indio_dev, pm_runtime_get_sync(dev); mutex_lock(&st->lock); - ret = inv_icm42600_timestamp_update_odr(ts, inv_icm42600_odr_to_period(conf.odr), - iio_buffer_enabled(indio_dev)); + ret = inv_sensors_timestamp_update_odr(ts, inv_icm42600_odr_to_period(conf.odr), + iio_buffer_enabled(indio_dev)); if (ret) goto out_unlock; @@ -707,7 +708,8 @@ struct iio_dev *inv_icm42600_accel_init(struct inv_icm42600_state *st) { struct device *dev = regmap_get_device(st->map); const char *name; - struct inv_icm42600_timestamp *ts; + struct inv_sensors_timestamp_chip ts_chip; + struct inv_sensors_timestamp *ts; struct iio_dev *indio_dev; int ret; @@ -719,8 +721,15 @@ struct iio_dev *inv_icm42600_accel_init(struct inv_icm42600_state *st) if (!indio_dev) return ERR_PTR(-ENOMEM); + /* + * clock period is 32kHz (31250ns) + * jitter is +/- 2% (20 per mille) + */ + ts_chip.clock_period = 31250; + ts_chip.jitter = 20; + ts_chip.init_period = inv_icm42600_odr_to_period(st->conf.accel.odr); ts = iio_priv(indio_dev); - inv_icm42600_timestamp_init(ts, inv_icm42600_odr_to_period(st->conf.accel.odr)); + inv_sensors_timestamp_init(ts, &ts_chip); iio_device_set_drvdata(indio_dev, st); indio_dev->name = name; @@ -745,7 +754,7 @@ struct iio_dev *inv_icm42600_accel_init(struct inv_icm42600_state *st) int inv_icm42600_accel_parse_fifo(struct iio_dev *indio_dev) { struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); - struct inv_icm42600_timestamp *ts = iio_priv(indio_dev); + struct inv_sensors_timestamp *ts = iio_priv(indio_dev); ssize_t i, size; unsigned int no; const void *accel, *gyro, *timestamp; @@ -768,15 +777,15 @@ int inv_icm42600_accel_parse_fifo(struct iio_dev *indio_dev) /* update odr */ if (odr & INV_ICM42600_SENSOR_ACCEL) - inv_icm42600_timestamp_apply_odr(ts, st->fifo.period, - st->fifo.nb.total, no); + inv_sensors_timestamp_apply_odr(ts, st->fifo.period, + st->fifo.nb.total, no); /* buffer is copied to userspace, zeroing it to avoid any data leak */ memset(&buffer, 0, sizeof(buffer)); memcpy(&buffer.accel, accel, sizeof(buffer.accel)); /* convert 8 bits FIFO temperature in high resolution format */ buffer.temp = temp ? (*temp * 64) : 0; - ts_val = inv_icm42600_timestamp_pop(ts); + ts_val = inv_sensors_timestamp_pop(ts); iio_push_to_buffers_with_timestamp(indio_dev, &buffer, ts_val); } diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c index 32d7f8364230..6ef1df9d60b7 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c @@ -9,11 +9,12 @@ #include <linux/pm_runtime.h> #include <linux/regmap.h> #include <linux/delay.h> -#include <linux/iio/iio.h> + #include <linux/iio/buffer.h> +#include <linux/iio/common/inv_sensors_timestamp.h> +#include <linux/iio/iio.h> #include "inv_icm42600.h" -#include "inv_icm42600_timestamp.h" #include "inv_icm42600_buffer.h" /* FIFO header: 1 byte */ @@ -275,12 +276,12 @@ static int inv_icm42600_buffer_preenable(struct iio_dev *indio_dev) { struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); struct device *dev = regmap_get_device(st->map); - struct inv_icm42600_timestamp *ts = iio_priv(indio_dev); + struct inv_sensors_timestamp *ts = iio_priv(indio_dev); pm_runtime_get_sync(dev); mutex_lock(&st->lock); - inv_icm42600_timestamp_reset(ts); + inv_sensors_timestamp_reset(ts); mutex_unlock(&st->lock); return 0; @@ -504,7 +505,7 @@ int inv_icm42600_buffer_fifo_read(struct inv_icm42600_state *st, int inv_icm42600_buffer_fifo_parse(struct inv_icm42600_state *st) { - struct inv_icm42600_timestamp *ts; + struct inv_sensors_timestamp *ts; int ret; if (st->fifo.nb.total == 0) @@ -512,8 +513,8 @@ int inv_icm42600_buffer_fifo_parse(struct inv_icm42600_state *st) /* handle gyroscope timestamp and FIFO data parsing */ ts = iio_priv(st->indio_gyro); - inv_icm42600_timestamp_interrupt(ts, st->fifo.period, st->fifo.nb.total, - st->fifo.nb.gyro, st->timestamp.gyro); + inv_sensors_timestamp_interrupt(ts, st->fifo.period, st->fifo.nb.total, + st->fifo.nb.gyro, st->timestamp.gyro); if (st->fifo.nb.gyro > 0) { ret = inv_icm42600_gyro_parse_fifo(st->indio_gyro); if (ret) @@ -522,8 +523,8 @@ int inv_icm42600_buffer_fifo_parse(struct inv_icm42600_state *st) /* handle accelerometer timestamp and FIFO data parsing */ ts = iio_priv(st->indio_accel); - inv_icm42600_timestamp_interrupt(ts, st->fifo.period, st->fifo.nb.total, - st->fifo.nb.accel, st->timestamp.accel); + inv_sensors_timestamp_interrupt(ts, st->fifo.period, st->fifo.nb.total, + st->fifo.nb.accel, st->timestamp.accel); if (st->fifo.nb.accel > 0) { ret = inv_icm42600_accel_parse_fifo(st->indio_accel); if (ret) @@ -536,7 +537,7 @@ int inv_icm42600_buffer_fifo_parse(struct inv_icm42600_state *st) int inv_icm42600_buffer_hwfifo_flush(struct inv_icm42600_state *st, unsigned int count) { - struct inv_icm42600_timestamp *ts; + struct inv_sensors_timestamp *ts; int64_t gyro_ts, accel_ts; int ret; @@ -552,9 +553,9 @@ int inv_icm42600_buffer_hwfifo_flush(struct inv_icm42600_state *st, if (st->fifo.nb.gyro > 0) { ts = iio_priv(st->indio_gyro); - inv_icm42600_timestamp_interrupt(ts, st->fifo.period, - st->fifo.nb.total, st->fifo.nb.gyro, - gyro_ts); + inv_sensors_timestamp_interrupt(ts, st->fifo.period, + st->fifo.nb.total, st->fifo.nb.gyro, + gyro_ts); ret = inv_icm42600_gyro_parse_fifo(st->indio_gyro); if (ret) return ret; @@ -562,9 +563,9 @@ int inv_icm42600_buffer_hwfifo_flush(struct inv_icm42600_state *st, if (st->fifo.nb.accel > 0) { ts = iio_priv(st->indio_accel); - inv_icm42600_timestamp_interrupt(ts, st->fifo.period, - st->fifo.nb.total, st->fifo.nb.accel, - accel_ts); + inv_sensors_timestamp_interrupt(ts, st->fifo.period, + st->fifo.nb.total, st->fifo.nb.accel, + accel_ts); ret = inv_icm42600_accel_parse_fifo(st->indio_accel); if (ret) return ret; diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c index 7b3a2a0dc2cb..a5e81906e37e 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c @@ -15,11 +15,11 @@ #include <linux/pm_runtime.h> #include <linux/property.h> #include <linux/regmap.h> + #include <linux/iio/iio.h> #include "inv_icm42600.h" #include "inv_icm42600_buffer.h" -#include "inv_icm42600_timestamp.h" static const struct regmap_range_cfg inv_icm42600_regmap_ranges[] = { { @@ -516,6 +516,17 @@ static int inv_icm42600_irq_init(struct inv_icm42600_state *st, int irq, "inv_icm42600", st); } +static int inv_icm42600_timestamp_setup(struct inv_icm42600_state *st) +{ + unsigned int val; + + /* enable timestamp register */ + val = INV_ICM42600_TMST_CONFIG_TMST_TO_REGS_EN | + INV_ICM42600_TMST_CONFIG_TMST_EN; + return regmap_update_bits(st->map, INV_ICM42600_REG_TMST_CONFIG, + INV_ICM42600_TMST_CONFIG_MASK, val); +} + static int inv_icm42600_enable_regulator_vddio(struct inv_icm42600_state *st) { int ret; @@ -788,3 +799,4 @@ EXPORT_NS_GPL_DEV_PM_OPS(inv_icm42600_pm_ops, IIO_ICM42600) = { MODULE_AUTHOR("InvenSense, Inc."); MODULE_DESCRIPTION("InvenSense ICM-426xx device driver"); MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS(IIO_INV_SENSORS_TIMESTAMP); diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c index 9d94a8518e3c..3bf946e56e1d 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c @@ -10,14 +10,15 @@ #include <linux/regmap.h> #include <linux/delay.h> #include <linux/math64.h> -#include <linux/iio/iio.h> + #include <linux/iio/buffer.h> +#include <linux/iio/common/inv_sensors_timestamp.h> +#include <linux/iio/iio.h> #include <linux/iio/kfifo_buf.h> #include "inv_icm42600.h" #include "inv_icm42600_temp.h" #include "inv_icm42600_buffer.h" -#include "inv_icm42600_timestamp.h" #define INV_ICM42600_GYRO_CHAN(_modifier, _index, _ext_info) \ { \ @@ -98,7 +99,7 @@ static int inv_icm42600_gyro_update_scan_mode(struct iio_dev *indio_dev, const unsigned long *scan_mask) { struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); - struct inv_icm42600_timestamp *ts = iio_priv(indio_dev); + struct inv_sensors_timestamp *ts = iio_priv(indio_dev); struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT; unsigned int fifo_en = 0; unsigned int sleep_gyro = 0; @@ -126,7 +127,7 @@ static int inv_icm42600_gyro_update_scan_mode(struct iio_dev *indio_dev, } /* update data FIFO write */ - inv_icm42600_timestamp_apply_odr(ts, 0, 0, 0); + inv_sensors_timestamp_apply_odr(ts, 0, 0, 0); ret = inv_icm42600_buffer_set_fifo_en(st, fifo_en | st->fifo.en); if (ret) goto out_unlock; @@ -323,7 +324,7 @@ static int inv_icm42600_gyro_write_odr(struct iio_dev *indio_dev, int val, int val2) { struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); - struct inv_icm42600_timestamp *ts = iio_priv(indio_dev); + struct inv_sensors_timestamp *ts = iio_priv(indio_dev); struct device *dev = regmap_get_device(st->map); unsigned int idx; struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT; @@ -342,8 +343,8 @@ static int inv_icm42600_gyro_write_odr(struct iio_dev *indio_dev, pm_runtime_get_sync(dev); mutex_lock(&st->lock); - ret = inv_icm42600_timestamp_update_odr(ts, inv_icm42600_odr_to_period(conf.odr), - iio_buffer_enabled(indio_dev)); + ret = inv_sensors_timestamp_update_odr(ts, inv_icm42600_odr_to_period(conf.odr), + iio_buffer_enabled(indio_dev)); if (ret) goto out_unlock; @@ -718,7 +719,8 @@ struct iio_dev *inv_icm42600_gyro_init(struct inv_icm42600_state *st) { struct device *dev = regmap_get_device(st->map); const char *name; - struct inv_icm42600_timestamp *ts; + struct inv_sensors_timestamp_chip ts_chip; + struct inv_sensors_timestamp *ts; struct iio_dev *indio_dev; int ret; @@ -730,8 +732,15 @@ struct iio_dev *inv_icm42600_gyro_init(struct inv_icm42600_state *st) if (!indio_dev) return ERR_PTR(-ENOMEM); + /* + * clock period is 32kHz (31250ns) + * jitter is +/- 2% (20 per mille) + */ + ts_chip.clock_period = 31250; + ts_chip.jitter = 20; + ts_chip.init_period = inv_icm42600_odr_to_period(st->conf.accel.odr); ts = iio_priv(indio_dev); - inv_icm42600_timestamp_init(ts, inv_icm42600_odr_to_period(st->conf.gyro.odr)); + inv_sensors_timestamp_init(ts, &ts_chip); iio_device_set_drvdata(indio_dev, st); indio_dev->name = name; @@ -757,7 +766,7 @@ struct iio_dev *inv_icm42600_gyro_init(struct inv_icm42600_state *st) int inv_icm42600_gyro_parse_fifo(struct iio_dev *indio_dev) { struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); - struct inv_icm42600_timestamp *ts = iio_priv(indio_dev); + struct inv_sensors_timestamp *ts = iio_priv(indio_dev); ssize_t i, size; unsigned int no; const void *accel, *gyro, *timestamp; @@ -780,15 +789,15 @@ int inv_icm42600_gyro_parse_fifo(struct iio_dev *indio_dev) /* update odr */ if (odr & INV_ICM42600_SENSOR_GYRO) - inv_icm42600_timestamp_apply_odr(ts, st->fifo.period, - st->fifo.nb.total, no); + inv_sensors_timestamp_apply_odr(ts, st->fifo.period, + st->fifo.nb.total, no); /* buffer is copied to userspace, zeroing it to avoid any data leak */ memset(&buffer, 0, sizeof(buffer)); memcpy(&buffer.gyro, gyro, sizeof(buffer.gyro)); /* convert 8 bits FIFO temperature in high resolution format */ buffer.temp = temp ? (*temp * 64) : 0; - ts_val = inv_icm42600_timestamp_pop(ts); + ts_val = inv_sensors_timestamp_pop(ts); iio_push_to_buffers_with_timestamp(indio_dev, &buffer, ts_val); } diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_timestamp.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_timestamp.c deleted file mode 100644 index 37cbf08acb3a..000000000000 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_timestamp.c +++ /dev/null @@ -1,198 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2020 Invensense, Inc. - */ - -#include <linux/kernel.h> -#include <linux/regmap.h> -#include <linux/math64.h> - -#include "inv_icm42600.h" -#include "inv_icm42600_timestamp.h" - -/* internal chip period is 32kHz, 31250ns */ -#define INV_ICM42600_TIMESTAMP_PERIOD 31250 -/* allow a jitter of +/- 2% */ -#define INV_ICM42600_TIMESTAMP_JITTER 2 -/* compute min and max periods accepted */ -#define INV_ICM42600_TIMESTAMP_MIN_PERIOD(_p) \ - (((_p) * (100 - INV_ICM42600_TIMESTAMP_JITTER)) / 100) -#define INV_ICM42600_TIMESTAMP_MAX_PERIOD(_p) \ - (((_p) * (100 + INV_ICM42600_TIMESTAMP_JITTER)) / 100) - -/* Add a new value inside an accumulator and update the estimate value */ -static void inv_update_acc(struct inv_icm42600_timestamp_acc *acc, uint32_t val) -{ - uint64_t sum = 0; - size_t i; - - acc->values[acc->idx++] = val; - if (acc->idx >= ARRAY_SIZE(acc->values)) - acc->idx = 0; - - /* compute the mean of all stored values, use 0 as empty slot */ - for (i = 0; i < ARRAY_SIZE(acc->values); ++i) { - if (acc->values[i] == 0) - break; - sum += acc->values[i]; - } - - acc->val = div_u64(sum, i); -} - -void inv_icm42600_timestamp_init(struct inv_icm42600_timestamp *ts, - uint32_t period) -{ - /* initial odr for sensor after reset is 1kHz */ - const uint32_t default_period = 1000000; - - /* current multiplier and period values after reset */ - ts->mult = default_period / INV_ICM42600_TIMESTAMP_PERIOD; - ts->period = default_period; - /* new set multiplier is the one from chip initialization */ - ts->new_mult = period / INV_ICM42600_TIMESTAMP_PERIOD; - - /* use theoretical value for chip period */ - inv_update_acc(&ts->chip_period, INV_ICM42600_TIMESTAMP_PERIOD); -} - -int inv_icm42600_timestamp_setup(struct inv_icm42600_state *st) -{ - unsigned int val; - - /* enable timestamp register */ - val = INV_ICM42600_TMST_CONFIG_TMST_TO_REGS_EN | - INV_ICM42600_TMST_CONFIG_TMST_EN; - return regmap_update_bits(st->map, INV_ICM42600_REG_TMST_CONFIG, - INV_ICM42600_TMST_CONFIG_MASK, val); -} - -int inv_icm42600_timestamp_update_odr(struct inv_icm42600_timestamp *ts, - uint32_t period, bool fifo) -{ - /* when FIFO is on, prevent odr change if one is already pending */ - if (fifo && ts->new_mult != 0) - return -EAGAIN; - - ts->new_mult = period / INV_ICM42600_TIMESTAMP_PERIOD; - - return 0; -} - -static bool inv_validate_period(uint32_t period, uint32_t mult) -{ - const uint32_t chip_period = INV_ICM42600_TIMESTAMP_PERIOD; - uint32_t period_min, period_max; - - /* check that period is acceptable */ - period_min = INV_ICM42600_TIMESTAMP_MIN_PERIOD(chip_period) * mult; - period_max = INV_ICM42600_TIMESTAMP_MAX_PERIOD(chip_period) * mult; - if (period > period_min && period < period_max) - return true; - else - return false; -} - -static bool inv_update_chip_period(struct inv_icm42600_timestamp *ts, - uint32_t mult, uint32_t period) -{ - uint32_t new_chip_period; - - if (!inv_validate_period(period, mult)) - return false; - - /* update chip internal period estimation */ - new_chip_period = period / 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_icm42600_timestamp *ts) -{ - int64_t delta, jitter; - int64_t adjust; - - /* delta time between last sample and last interrupt */ - delta = ts->it.lo - ts->timestamp; - - /* adjust timestamp while respecting jitter */ - jitter = div_s64((int64_t)ts->period * INV_ICM42600_TIMESTAMP_JITTER, 100); - if (delta > jitter) - adjust = jitter; - else if (delta < -jitter) - adjust = -jitter; - else - adjust = 0; - - ts->timestamp += adjust; -} - -void inv_icm42600_timestamp_interrupt(struct inv_icm42600_timestamp *ts, - uint32_t fifo_period, size_t fifo_nb, - size_t sensor_nb, int64_t timestamp) -{ - struct inv_icm42600_timestamp_interval *it; - int64_t delta, interval; - const uint32_t fifo_mult = fifo_period / INV_ICM42600_TIMESTAMP_PERIOD; - uint32_t period = ts->period; - bool valid = false; - - if (fifo_nb == 0) - return; - - /* 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 */ - period = div_s64(delta, fifo_nb); - valid = inv_update_chip_period(ts, fifo_mult, period); - } - - /* no previous data, compute theoritical value from interrupt */ - if (ts->timestamp == 0) { - /* elapsed time: sensor period * sensor samples number */ - interval = (int64_t)ts->period * (int64_t)sensor_nb; - ts->timestamp = it->up - interval; - return; - } - - /* if interrupt interval is valid, sync with interrupt timestamp */ - if (valid) - inv_align_timestamp_it(ts); -} - -void inv_icm42600_timestamp_apply_odr(struct inv_icm42600_timestamp *ts, - uint32_t fifo_period, size_t fifo_nb, - unsigned int fifo_no) -{ - int64_t interval; - uint32_t fifo_mult; - - if (ts->new_mult == 0) - return; - - /* update to new multiplier and update period */ - ts->mult = ts->new_mult; - ts->new_mult = 0; - ts->period = ts->mult * ts->chip_period.val; - - /* - * After ODR change the time interval with the previous sample is - * undertermined (depends when the change occures). So we compute the - * timestamp from the current interrupt using the new FIFO period, the - * total number of samples and the current sample numero. - */ - if (ts->timestamp != 0) { - /* compute measured fifo period */ - fifo_mult = fifo_period / INV_ICM42600_TIMESTAMP_PERIOD; - fifo_period = fifo_mult * ts->chip_period.val; - /* computes time interval between interrupt and this sample */ - interval = (int64_t)(fifo_nb - fifo_no) * (int64_t)fifo_period; - ts->timestamp = ts->it.up - interval; - } -} diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_timestamp.h b/drivers/iio/imu/inv_icm42600/inv_icm42600_timestamp.h deleted file mode 100644 index 4e4f331d4fe4..000000000000 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_timestamp.h +++ /dev/null @@ -1,85 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2020 Invensense, Inc. - */ - -#ifndef INV_ICM42600_TIMESTAMP_H_ -#define INV_ICM42600_TIMESTAMP_H_ - -#include <linux/kernel.h> - -struct inv_icm42600_state; - -/** - * struct inv_icm42600_timestamp_interval - timestamps interval - * @lo: interval lower bound - * @up: interval upper bound - */ -struct inv_icm42600_timestamp_interval { - int64_t lo; - int64_t up; -}; - -/** - * struct inv_icm42600_timestamp_acc - accumulator for computing an estimation - * @val: current estimation of the value, the mean of all values - * @idx: current index of the next free place in values table - * @values: table of all measured values, use for computing the mean - */ -struct inv_icm42600_timestamp_acc { - uint32_t val; - size_t idx; - uint32_t values[32]; -}; - -/** - * struct inv_icm42600_timestamp - timestamp management states - * @it: interrupts interval timestamps - * @timestamp: store last timestamp for computing next data timestamp - * @mult: current internal period multiplier - * @new_mult: new set internal period multiplier (not yet effective) - * @period: measured current period of the sensor - * @chip_period: accumulator for computing internal chip period - */ -struct inv_icm42600_timestamp { - struct inv_icm42600_timestamp_interval it; - int64_t timestamp; - uint32_t mult; - uint32_t new_mult; - uint32_t period; - struct inv_icm42600_timestamp_acc chip_period; -}; - -void inv_icm42600_timestamp_init(struct inv_icm42600_timestamp *ts, - uint32_t period); - -int inv_icm42600_timestamp_setup(struct inv_icm42600_state *st); - -int inv_icm42600_timestamp_update_odr(struct inv_icm42600_timestamp *ts, - uint32_t period, bool fifo); - -void inv_icm42600_timestamp_interrupt(struct inv_icm42600_timestamp *ts, - uint32_t fifo_period, size_t fifo_nb, - size_t sensor_nb, int64_t timestamp); - -static inline int64_t -inv_icm42600_timestamp_pop(struct inv_icm42600_timestamp *ts) -{ - ts->timestamp += ts->period; - return ts->timestamp; -} - -void inv_icm42600_timestamp_apply_odr(struct inv_icm42600_timestamp *ts, - uint32_t fifo_period, size_t fifo_nb, - unsigned int fifo_no); - -static inline void -inv_icm42600_timestamp_reset(struct inv_icm42600_timestamp *ts) -{ - const struct inv_icm42600_timestamp_interval interval_init = {0LL, 0LL}; - - ts->it = interval_init; - ts->timestamp = 0; -} - -#endif |