iio: imu: inv_icm42600: add support of ICM-42686-P
authorJean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
Mon, 22 Apr 2024 15:22:40 +0000 (15:22 +0000)
committerJonathan Cameron <Jonathan.Cameron@huawei.com>
Mon, 29 Apr 2024 19:53:25 +0000 (20:53 +0100)
Add ICM-42686-P chip supporting high FSRs (32G, 4000dps).

Create accel and gyro iio device states with dynamic scales table
set at device init.

Signed-off-by: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
Link: https://lore.kernel.org/r/20240422152240.85974-3-inv.git-commit@tdk.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
drivers/iio/imu/inv_icm42600/inv_icm42600.h
drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c
drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c
drivers/iio/imu/inv_icm42600/inv_icm42600_core.c
drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c
drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c
drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c

index 0566340b2660490e4459a604c141df8f42953f48..c4ac91f6bafea9eff513854923160d844b665fc1 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/regulator/consumer.h>
 #include <linux/pm.h>
 #include <linux/iio/iio.h>
+#include <linux/iio/common/inv_sensors_timestamp.h>
 
 #include "inv_icm42600_buffer.h"
 
@@ -21,6 +22,7 @@ enum inv_icm42600_chip {
        INV_CHIP_ICM42600,
        INV_CHIP_ICM42602,
        INV_CHIP_ICM42605,
+       INV_CHIP_ICM42686,
        INV_CHIP_ICM42622,
        INV_CHIP_ICM42688,
        INV_CHIP_ICM42631,
@@ -57,6 +59,17 @@ enum inv_icm42600_gyro_fs {
        INV_ICM42600_GYRO_FS_15_625DPS,
        INV_ICM42600_GYRO_FS_NB,
 };
+enum inv_icm42686_gyro_fs {
+       INV_ICM42686_GYRO_FS_4000DPS,
+       INV_ICM42686_GYRO_FS_2000DPS,
+       INV_ICM42686_GYRO_FS_1000DPS,
+       INV_ICM42686_GYRO_FS_500DPS,
+       INV_ICM42686_GYRO_FS_250DPS,
+       INV_ICM42686_GYRO_FS_125DPS,
+       INV_ICM42686_GYRO_FS_62_5DPS,
+       INV_ICM42686_GYRO_FS_31_25DPS,
+       INV_ICM42686_GYRO_FS_NB,
+};
 
 /* accelerometer fullscale values */
 enum inv_icm42600_accel_fs {
@@ -66,6 +79,14 @@ enum inv_icm42600_accel_fs {
        INV_ICM42600_ACCEL_FS_2G,
        INV_ICM42600_ACCEL_FS_NB,
 };
+enum inv_icm42686_accel_fs {
+       INV_ICM42686_ACCEL_FS_32G,
+       INV_ICM42686_ACCEL_FS_16G,
+       INV_ICM42686_ACCEL_FS_8G,
+       INV_ICM42686_ACCEL_FS_4G,
+       INV_ICM42686_ACCEL_FS_2G,
+       INV_ICM42686_ACCEL_FS_NB,
+};
 
 /* ODR suffixed by LN or LP are Low-Noise or Low-Power mode only */
 enum inv_icm42600_odr {
@@ -151,6 +172,19 @@ struct inv_icm42600_state {
        } timestamp;
 };
 
+
+/**
+ * struct inv_icm42600_sensor_state - sensor state variables
+ * @scales:            table of scales.
+ * @scales_len:                length (nb of items) of the scales table.
+ * @ts:                        timestamp module states.
+ */
+struct inv_icm42600_sensor_state {
+       const int *scales;
+       size_t scales_len;
+       struct inv_sensors_timestamp ts;
+};
+
 /* Virtual register addresses: @bank on MSB (4 upper bits), @address on LSB */
 
 /* Bank selection register, available in all banks */
@@ -304,6 +338,7 @@ struct inv_icm42600_state {
 #define INV_ICM42600_WHOAMI_ICM42600                   0x40
 #define INV_ICM42600_WHOAMI_ICM42602                   0x41
 #define INV_ICM42600_WHOAMI_ICM42605                   0x42
+#define INV_ICM42600_WHOAMI_ICM42686                   0x44
 #define INV_ICM42600_WHOAMI_ICM42622                   0x46
 #define INV_ICM42600_WHOAMI_ICM42688                   0x47
 #define INV_ICM42600_WHOAMI_ICM42631                   0x5C
index f67bd5a39beb3441114ec5f500bf0bd086917872..83d8504ebfff43d8a11fc4d0636754e635361cbd 100644 (file)
@@ -99,7 +99,8 @@ 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_sensors_timestamp *ts = iio_priv(indio_dev);
+       struct inv_icm42600_sensor_state *accel_st = iio_priv(indio_dev);
+       struct inv_sensors_timestamp *ts = &accel_st->ts;
        struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT;
        unsigned int fifo_en = 0;
        unsigned int sleep_temp = 0;
@@ -210,33 +211,54 @@ static const int inv_icm42600_accel_scale[] = {
        [2 * INV_ICM42600_ACCEL_FS_2G] = 0,
        [2 * INV_ICM42600_ACCEL_FS_2G + 1] = 598550,
 };
+static const int inv_icm42686_accel_scale[] = {
+       /* +/- 32G => 0.009576807 m/s-2 */
+       [2 * INV_ICM42686_ACCEL_FS_32G] = 0,
+       [2 * INV_ICM42686_ACCEL_FS_32G + 1] = 9576807,
+       /* +/- 16G => 0.004788403 m/s-2 */
+       [2 * INV_ICM42686_ACCEL_FS_16G] = 0,
+       [2 * INV_ICM42686_ACCEL_FS_16G + 1] = 4788403,
+       /* +/- 8G => 0.002394202 m/s-2 */
+       [2 * INV_ICM42686_ACCEL_FS_8G] = 0,
+       [2 * INV_ICM42686_ACCEL_FS_8G + 1] = 2394202,
+       /* +/- 4G => 0.001197101 m/s-2 */
+       [2 * INV_ICM42686_ACCEL_FS_4G] = 0,
+       [2 * INV_ICM42686_ACCEL_FS_4G + 1] = 1197101,
+       /* +/- 2G => 0.000598550 m/s-2 */
+       [2 * INV_ICM42686_ACCEL_FS_2G] = 0,
+       [2 * INV_ICM42686_ACCEL_FS_2G + 1] = 598550,
+};
 
-static int inv_icm42600_accel_read_scale(struct inv_icm42600_state *st,
+static int inv_icm42600_accel_read_scale(struct iio_dev *indio_dev,
                                         int *val, int *val2)
 {
+       struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
+       struct inv_icm42600_sensor_state *accel_st = iio_priv(indio_dev);
        unsigned int idx;
 
        idx = st->conf.accel.fs;
 
-       *val = inv_icm42600_accel_scale[2 * idx];
-       *val2 = inv_icm42600_accel_scale[2 * idx + 1];
+       *val = accel_st->scales[2 * idx];
+       *val2 = accel_st->scales[2 * idx + 1];
        return IIO_VAL_INT_PLUS_NANO;
 }
 
-static int inv_icm42600_accel_write_scale(struct inv_icm42600_state *st,
+static int inv_icm42600_accel_write_scale(struct iio_dev *indio_dev,
                                          int val, int val2)
 {
+       struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
+       struct inv_icm42600_sensor_state *accel_st = 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;
        int ret;
 
-       for (idx = 0; idx < ARRAY_SIZE(inv_icm42600_accel_scale); idx += 2) {
-               if (val == inv_icm42600_accel_scale[idx] &&
-                   val2 == inv_icm42600_accel_scale[idx + 1])
+       for (idx = 0; idx < accel_st->scales_len; idx += 2) {
+               if (val == accel_st->scales[idx] &&
+                   val2 == accel_st->scales[idx + 1])
                        break;
        }
-       if (idx >= ARRAY_SIZE(inv_icm42600_accel_scale))
+       if (idx >= accel_st->scales_len)
                return -EINVAL;
 
        conf.fs = idx / 2;
@@ -309,7 +331,8 @@ 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_sensors_timestamp *ts = iio_priv(indio_dev);
+       struct inv_icm42600_sensor_state *accel_st = iio_priv(indio_dev);
+       struct inv_sensors_timestamp *ts = &accel_st->ts;
        struct device *dev = regmap_get_device(st->map);
        unsigned int idx;
        struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT;
@@ -565,7 +588,7 @@ static int inv_icm42600_accel_read_raw(struct iio_dev *indio_dev,
                *val = data;
                return IIO_VAL_INT;
        case IIO_CHAN_INFO_SCALE:
-               return inv_icm42600_accel_read_scale(st, val, val2);
+               return inv_icm42600_accel_read_scale(indio_dev, val, val2);
        case IIO_CHAN_INFO_SAMP_FREQ:
                return inv_icm42600_accel_read_odr(st, val, val2);
        case IIO_CHAN_INFO_CALIBBIAS:
@@ -580,14 +603,16 @@ static int inv_icm42600_accel_read_avail(struct iio_dev *indio_dev,
                                         const int **vals,
                                         int *type, int *length, long mask)
 {
+       struct inv_icm42600_sensor_state *accel_st = iio_priv(indio_dev);
+
        if (chan->type != IIO_ACCEL)
                return -EINVAL;
 
        switch (mask) {
        case IIO_CHAN_INFO_SCALE:
-               *vals = inv_icm42600_accel_scale;
+               *vals = accel_st->scales;
                *type = IIO_VAL_INT_PLUS_NANO;
-               *length = ARRAY_SIZE(inv_icm42600_accel_scale);
+               *length = accel_st->scales_len;
                return IIO_AVAIL_LIST;
        case IIO_CHAN_INFO_SAMP_FREQ:
                *vals = inv_icm42600_accel_odr;
@@ -618,7 +643,7 @@ static int inv_icm42600_accel_write_raw(struct iio_dev *indio_dev,
                ret = iio_device_claim_direct_mode(indio_dev);
                if (ret)
                        return ret;
-               ret = inv_icm42600_accel_write_scale(st, val, val2);
+               ret = inv_icm42600_accel_write_scale(indio_dev, val, val2);
                iio_device_release_direct_mode(indio_dev);
                return ret;
        case IIO_CHAN_INFO_SAMP_FREQ:
@@ -705,8 +730,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_sensor_state *accel_st;
        struct inv_sensors_timestamp_chip ts_chip;
-       struct inv_sensors_timestamp *ts;
        struct iio_dev *indio_dev;
        int ret;
 
@@ -714,9 +739,21 @@ struct iio_dev *inv_icm42600_accel_init(struct inv_icm42600_state *st)
        if (!name)
                return ERR_PTR(-ENOMEM);
 
-       indio_dev = devm_iio_device_alloc(dev, sizeof(*ts));
+       indio_dev = devm_iio_device_alloc(dev, sizeof(*accel_st));
        if (!indio_dev)
                return ERR_PTR(-ENOMEM);
+       accel_st = iio_priv(indio_dev);
+
+       switch (st->chip) {
+       case INV_CHIP_ICM42686:
+               accel_st->scales = inv_icm42686_accel_scale;
+               accel_st->scales_len = ARRAY_SIZE(inv_icm42686_accel_scale);
+               break;
+       default:
+               accel_st->scales = inv_icm42600_accel_scale;
+               accel_st->scales_len = ARRAY_SIZE(inv_icm42600_accel_scale);
+               break;
+       }
 
        /*
         * clock period is 32kHz (31250ns)
@@ -725,8 +762,7 @@ struct iio_dev *inv_icm42600_accel_init(struct inv_icm42600_state *st)
        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_sensors_timestamp_init(ts, &ts_chip);
+       inv_sensors_timestamp_init(&accel_st->ts, &ts_chip);
 
        iio_device_set_drvdata(indio_dev, st);
        indio_dev->name = name;
@@ -751,7 +787,8 @@ 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_sensors_timestamp *ts = iio_priv(indio_dev);
+       struct inv_icm42600_sensor_state *accel_st = iio_priv(indio_dev);
+       struct inv_sensors_timestamp *ts = &accel_st->ts;
        ssize_t i, size;
        unsigned int no;
        const void *accel, *gyro, *timestamp;
index b52f328fd26ce7ab130b40a21c5ba8c317920fbb..cfb4a41ab7c11e9ee6f39a74aa30c726a4b12717 100644 (file)
@@ -276,7 +276,8 @@ 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_sensors_timestamp *ts = iio_priv(indio_dev);
+       struct inv_icm42600_sensor_state *sensor_st = iio_priv(indio_dev);
+       struct inv_sensors_timestamp *ts = &sensor_st->ts;
 
        pm_runtime_get_sync(dev);
 
@@ -502,6 +503,8 @@ 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_sensor_state *gyro_st = iio_priv(st->indio_gyro);
+       struct inv_icm42600_sensor_state *accel_st = iio_priv(st->indio_accel);
        struct inv_sensors_timestamp *ts;
        int ret;
 
@@ -509,7 +512,7 @@ int inv_icm42600_buffer_fifo_parse(struct inv_icm42600_state *st)
                return 0;
 
        /* handle gyroscope timestamp and FIFO data parsing */
-       ts = iio_priv(st->indio_gyro);
+       ts = &gyro_st->ts;
        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) {
@@ -519,7 +522,7 @@ int inv_icm42600_buffer_fifo_parse(struct inv_icm42600_state *st)
        }
 
        /* handle accelerometer timestamp and FIFO data parsing */
-       ts = iio_priv(st->indio_accel);
+       ts = &accel_st->ts;
        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) {
@@ -534,6 +537,8 @@ 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_sensor_state *gyro_st = iio_priv(st->indio_gyro);
+       struct inv_icm42600_sensor_state *accel_st = iio_priv(st->indio_accel);
        struct inv_sensors_timestamp *ts;
        int64_t gyro_ts, accel_ts;
        int ret;
@@ -549,7 +554,7 @@ int inv_icm42600_buffer_hwfifo_flush(struct inv_icm42600_state *st,
                return 0;
 
        if (st->fifo.nb.gyro > 0) {
-               ts = iio_priv(st->indio_gyro);
+               ts = &gyro_st->ts;
                inv_sensors_timestamp_interrupt(ts, st->fifo.period,
                                                st->fifo.nb.total, st->fifo.nb.gyro,
                                                gyro_ts);
@@ -559,7 +564,7 @@ int inv_icm42600_buffer_hwfifo_flush(struct inv_icm42600_state *st,
        }
 
        if (st->fifo.nb.accel > 0) {
-               ts = iio_priv(st->indio_accel);
+               ts = &accel_st->ts;
                inv_sensors_timestamp_interrupt(ts, st->fifo.period,
                                                st->fifo.nb.total, st->fifo.nb.accel,
                                                accel_ts);
index 82e0a2e2ad706cc80d1c8d03a9ef3bfa74e89b3f..96116a68ab291bc541f8b84c5853662cc9a3cf50 100644 (file)
@@ -66,6 +66,22 @@ static const struct inv_icm42600_conf inv_icm42600_default_conf = {
        .temp_en = false,
 };
 
+static const struct inv_icm42600_conf inv_icm42686_default_conf = {
+       .gyro = {
+               .mode = INV_ICM42600_SENSOR_MODE_OFF,
+               .fs = INV_ICM42686_GYRO_FS_4000DPS,
+               .odr = INV_ICM42600_ODR_50HZ,
+               .filter = INV_ICM42600_FILTER_BW_ODR_DIV_2,
+       },
+       .accel = {
+               .mode = INV_ICM42600_SENSOR_MODE_OFF,
+               .fs = INV_ICM42686_ACCEL_FS_32G,
+               .odr = INV_ICM42600_ODR_50HZ,
+               .filter = INV_ICM42600_FILTER_BW_ODR_DIV_2,
+       },
+       .temp_en = false,
+};
+
 static const struct inv_icm42600_hw inv_icm42600_hw[INV_CHIP_NB] = {
        [INV_CHIP_ICM42600] = {
                .whoami = INV_ICM42600_WHOAMI_ICM42600,
@@ -82,6 +98,11 @@ static const struct inv_icm42600_hw inv_icm42600_hw[INV_CHIP_NB] = {
                .name = "icm42605",
                .conf = &inv_icm42600_default_conf,
        },
+       [INV_CHIP_ICM42686] = {
+               .whoami = INV_ICM42600_WHOAMI_ICM42686,
+               .name = "icm42686",
+               .conf = &inv_icm42686_default_conf,
+       },
        [INV_CHIP_ICM42622] = {
                .whoami = INV_ICM42600_WHOAMI_ICM42622,
                .name = "icm42622",
index 3df0a715e8856039fc185f69ed193ae9dcbabb0a..e6f8de80128c4f8afeef4e1e2205dcfa880caa6b 100644 (file)
@@ -99,7 +99,8 @@ 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_sensors_timestamp *ts = iio_priv(indio_dev);
+       struct inv_icm42600_sensor_state *gyro_st = iio_priv(indio_dev);
+       struct inv_sensors_timestamp *ts = &gyro_st->ts;
        struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT;
        unsigned int fifo_en = 0;
        unsigned int sleep_gyro = 0;
@@ -222,33 +223,63 @@ static const int inv_icm42600_gyro_scale[] = {
        [2 * INV_ICM42600_GYRO_FS_15_625DPS] = 0,
        [2 * INV_ICM42600_GYRO_FS_15_625DPS + 1] = 8322,
 };
+static const int inv_icm42686_gyro_scale[] = {
+       /* +/- 4000dps => 0.002130529 rad/s */
+       [2 * INV_ICM42686_GYRO_FS_4000DPS] = 0,
+       [2 * INV_ICM42686_GYRO_FS_4000DPS + 1] = 2130529,
+       /* +/- 2000dps => 0.001065264 rad/s */
+       [2 * INV_ICM42686_GYRO_FS_2000DPS] = 0,
+       [2 * INV_ICM42686_GYRO_FS_2000DPS + 1] = 1065264,
+       /* +/- 1000dps => 0.000532632 rad/s */
+       [2 * INV_ICM42686_GYRO_FS_1000DPS] = 0,
+       [2 * INV_ICM42686_GYRO_FS_1000DPS + 1] = 532632,
+       /* +/- 500dps => 0.000266316 rad/s */
+       [2 * INV_ICM42686_GYRO_FS_500DPS] = 0,
+       [2 * INV_ICM42686_GYRO_FS_500DPS + 1] = 266316,
+       /* +/- 250dps => 0.000133158 rad/s */
+       [2 * INV_ICM42686_GYRO_FS_250DPS] = 0,
+       [2 * INV_ICM42686_GYRO_FS_250DPS + 1] = 133158,
+       /* +/- 125dps => 0.000066579 rad/s */
+       [2 * INV_ICM42686_GYRO_FS_125DPS] = 0,
+       [2 * INV_ICM42686_GYRO_FS_125DPS + 1] = 66579,
+       /* +/- 62.5dps => 0.000033290 rad/s */
+       [2 * INV_ICM42686_GYRO_FS_62_5DPS] = 0,
+       [2 * INV_ICM42686_GYRO_FS_62_5DPS + 1] = 33290,
+       /* +/- 31.25dps => 0.000016645 rad/s */
+       [2 * INV_ICM42686_GYRO_FS_31_25DPS] = 0,
+       [2 * INV_ICM42686_GYRO_FS_31_25DPS + 1] = 16645,
+};
 
-static int inv_icm42600_gyro_read_scale(struct inv_icm42600_state *st,
+static int inv_icm42600_gyro_read_scale(struct iio_dev *indio_dev,
                                        int *val, int *val2)
 {
+       struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
+       struct inv_icm42600_sensor_state *gyro_st = iio_priv(indio_dev);
        unsigned int idx;
 
        idx = st->conf.gyro.fs;
 
-       *val = inv_icm42600_gyro_scale[2 * idx];
-       *val2 = inv_icm42600_gyro_scale[2 * idx + 1];
+       *val = gyro_st->scales[2 * idx];
+       *val2 = gyro_st->scales[2 * idx + 1];
        return IIO_VAL_INT_PLUS_NANO;
 }
 
-static int inv_icm42600_gyro_write_scale(struct inv_icm42600_state *st,
+static int inv_icm42600_gyro_write_scale(struct iio_dev *indio_dev,
                                         int val, int val2)
 {
+       struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
+       struct inv_icm42600_sensor_state *gyro_st = 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;
        int ret;
 
-       for (idx = 0; idx < ARRAY_SIZE(inv_icm42600_gyro_scale); idx += 2) {
-               if (val == inv_icm42600_gyro_scale[idx] &&
-                   val2 == inv_icm42600_gyro_scale[idx + 1])
+       for (idx = 0; idx < gyro_st->scales_len; idx += 2) {
+               if (val == gyro_st->scales[idx] &&
+                   val2 == gyro_st->scales[idx + 1])
                        break;
        }
-       if (idx >= ARRAY_SIZE(inv_icm42600_gyro_scale))
+       if (idx >= gyro_st->scales_len)
                return -EINVAL;
 
        conf.fs = idx / 2;
@@ -321,7 +352,8 @@ 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_sensors_timestamp *ts = iio_priv(indio_dev);
+       struct inv_icm42600_sensor_state *gyro_st = iio_priv(indio_dev);
+       struct inv_sensors_timestamp *ts = &gyro_st->ts;
        struct device *dev = regmap_get_device(st->map);
        unsigned int idx;
        struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT;
@@ -576,7 +608,7 @@ static int inv_icm42600_gyro_read_raw(struct iio_dev *indio_dev,
                *val = data;
                return IIO_VAL_INT;
        case IIO_CHAN_INFO_SCALE:
-               return inv_icm42600_gyro_read_scale(st, val, val2);
+               return inv_icm42600_gyro_read_scale(indio_dev, val, val2);
        case IIO_CHAN_INFO_SAMP_FREQ:
                return inv_icm42600_gyro_read_odr(st, val, val2);
        case IIO_CHAN_INFO_CALIBBIAS:
@@ -591,14 +623,16 @@ static int inv_icm42600_gyro_read_avail(struct iio_dev *indio_dev,
                                        const int **vals,
                                        int *type, int *length, long mask)
 {
+       struct inv_icm42600_sensor_state *gyro_st = iio_priv(indio_dev);
+
        if (chan->type != IIO_ANGL_VEL)
                return -EINVAL;
 
        switch (mask) {
        case IIO_CHAN_INFO_SCALE:
-               *vals = inv_icm42600_gyro_scale;
+               *vals = gyro_st->scales;
                *type = IIO_VAL_INT_PLUS_NANO;
-               *length = ARRAY_SIZE(inv_icm42600_gyro_scale);
+               *length = gyro_st->scales_len;
                return IIO_AVAIL_LIST;
        case IIO_CHAN_INFO_SAMP_FREQ:
                *vals = inv_icm42600_gyro_odr;
@@ -629,7 +663,7 @@ static int inv_icm42600_gyro_write_raw(struct iio_dev *indio_dev,
                ret = iio_device_claim_direct_mode(indio_dev);
                if (ret)
                        return ret;
-               ret = inv_icm42600_gyro_write_scale(st, val, val2);
+               ret = inv_icm42600_gyro_write_scale(indio_dev, val, val2);
                iio_device_release_direct_mode(indio_dev);
                return ret;
        case IIO_CHAN_INFO_SAMP_FREQ:
@@ -716,8 +750,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_sensor_state *gyro_st;
        struct inv_sensors_timestamp_chip ts_chip;
-       struct inv_sensors_timestamp *ts;
        struct iio_dev *indio_dev;
        int ret;
 
@@ -725,9 +759,21 @@ struct iio_dev *inv_icm42600_gyro_init(struct inv_icm42600_state *st)
        if (!name)
                return ERR_PTR(-ENOMEM);
 
-       indio_dev = devm_iio_device_alloc(dev, sizeof(*ts));
+       indio_dev = devm_iio_device_alloc(dev, sizeof(*gyro_st));
        if (!indio_dev)
                return ERR_PTR(-ENOMEM);
+       gyro_st = iio_priv(indio_dev);
+
+       switch (st->chip) {
+       case INV_CHIP_ICM42686:
+               gyro_st->scales = inv_icm42686_gyro_scale;
+               gyro_st->scales_len = ARRAY_SIZE(inv_icm42686_gyro_scale);
+               break;
+       default:
+               gyro_st->scales = inv_icm42600_gyro_scale;
+               gyro_st->scales_len = ARRAY_SIZE(inv_icm42600_gyro_scale);
+               break;
+       }
 
        /*
         * clock period is 32kHz (31250ns)
@@ -736,8 +782,7 @@ struct iio_dev *inv_icm42600_gyro_init(struct inv_icm42600_state *st)
        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_sensors_timestamp_init(ts, &ts_chip);
+       inv_sensors_timestamp_init(&gyro_st->ts, &ts_chip);
 
        iio_device_set_drvdata(indio_dev, st);
        indio_dev->name = name;
@@ -763,7 +808,8 @@ 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_sensors_timestamp *ts = iio_priv(indio_dev);
+       struct inv_icm42600_sensor_state *gyro_st = iio_priv(indio_dev);
+       struct inv_sensors_timestamp *ts = &gyro_st->ts;
        ssize_t i, size;
        unsigned int no;
        const void *accel, *gyro, *timestamp;
index ebb28f84ba98536638e5e61b639f3258d70cba64..8d33504d770f7b6798f7929dbea217d418cc8fab 100644 (file)
@@ -81,6 +81,9 @@ static const struct of_device_id inv_icm42600_of_matches[] = {
        }, {
                .compatible = "invensense,icm42605",
                .data = (void *)INV_CHIP_ICM42605,
+       }, {
+               .compatible = "invensense,icm42686",
+               .data = (void *)INV_CHIP_ICM42686,
        }, {
                .compatible = "invensense,icm42622",
                .data = (void *)INV_CHIP_ICM42622,
index 50217a10e0bbf3647b11db7650781b0133d6bb72..cc2bf1799a46532f88f690b1c07eefa34df86b86 100644 (file)
@@ -77,6 +77,9 @@ static const struct of_device_id inv_icm42600_of_matches[] = {
        }, {
                .compatible = "invensense,icm42605",
                .data = (void *)INV_CHIP_ICM42605,
+       }, {
+               .compatible = "invensense,icm42686",
+               .data = (void *)INV_CHIP_ICM42686,
        }, {
                .compatible = "invensense,icm42622",
                .data = (void *)INV_CHIP_ICM42622,