iio: imu: inv_icm42600: add support of ICM-42686-P
Subsystems (3)
cover iio: imu: inv_icm42600: add support of ICM-42686-P
From: Jean-Baptiste Maneyrol <[email protected]>
ICM-42686-P is a special chip supporting high Full Scale Range (FSR) values. Up to +/-32G for accel and +/-4000dps for gyro.
For supporting this chip, we are using dynamic scales tables set at init. Introduce a new sensor state structure for olding pointer to the dynamic table plus the already used timestamp structure.
Jean-Baptiste Maneyrol (2):
dt-bindings: iio: imu: add icm42686 inside inv_icm42600
iio: imu: inv_icm42600: add support of ICM-42686-P
.../bindings/iio/imu/invensense,icm42600.yaml | 1 + drivers/iio/imu/inv_icm42600/inv_icm42600.h | 35 ++++++++ .../iio/imu/inv_icm42600/inv_icm42600_accel.c | 75 ++++++++++++----- .../imu/inv_icm42600/inv_icm42600_buffer.c | 15 ++-- .../iio/imu/inv_icm42600/inv_icm42600_core.c | 20 +++++ .../iio/imu/inv_icm42600/inv_icm42600_gyro.c | 84 ++++++++++++++----- .../iio/imu/inv_icm42600/inv_icm42600_i2c.c | 3 + .../iio/imu/inv_icm42600/inv_icm42600_spi.c | 3 + 8 files changed, 193 insertions(+), 43 deletions(-)
Signature · 1 line
2.34.1
PATCH 2/2 iio: imu: inv_icm42600: add support of ICM-42686-P
From: Jean-Baptiste Maneyrol <[email protected]>
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.
--- drivers/iio/imu/inv_icm42600/inv_icm42600.h | 35 ++++++++ .../iio/imu/inv_icm42600/inv_icm42600_accel.c | 75 ++++++++++++----- .../imu/inv_icm42600/inv_icm42600_buffer.c | 15 ++-- .../iio/imu/inv_icm42600/inv_icm42600_core.c | 20 +++++ .../iio/imu/inv_icm42600/inv_icm42600_gyro.c | 84 ++++++++++++++----- .../iio/imu/inv_icm42600/inv_icm42600_i2c.c | 3 + .../iio/imu/inv_icm42600/inv_icm42600_spi.c | 3 + 7 files changed, 192 insertions(+), 43 deletions(-)
drivers/iio/imu/inv_icm42600/inv_icm42600.h +35 -0
@@ -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
drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c +56 -19
163 lines not on this page · raw message
drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c +10 -5
@@ -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);
drivers/iio/imu/inv_icm42600/inv_icm42600_core.c +20 -0
@@ -65,6 +65,21 @@ 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 ] = {
@@ -82,6 +97,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",
drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c +65 -19
172 lines not on this page · raw message
drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c +3 -0
@@ -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,
drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c +3 -0
@@ -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,
Signature · 1 line
2.34.1
PATCH 1/2 dt-bindings: iio: imu: add icm42686 inside inv_icm42600
In reply to [email protected]From: Jean-Baptiste Maneyrol <[email protected]>
Add bindings for ICM-42686-P chip supporting high FSRs.
--- .../devicetree/bindings/iio/imu/invensense,icm42600.yaml | 1 + 1 file changed, 1 insertion(+)
Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml +1 -0
@@ -32,6 +32,7 @@ properties: - invensense,icm42605 - invensense,icm42622 - invensense,icm42631 + - invensense,icm42686 - invensense,icm42688 reg:
Signature · 1 line
2.34.1
Re: [PATCH 1/2] dt-bindings: iio: imu: add icm42686 inside inv_icm42600
Quoted 9 lines · On Mon, 22 Apr 2024 15:22:39 +0000, [email protected] wrote:
From: Jean-Baptiste Maneyrol <[email protected]>
Add bindings for ICM-42686-P chip supporting high FSRs.
Signed-off-by Jean-Baptiste Maneyrol <[email protected]>--- .../devicetree/bindings/iio/imu/invensense,icm42600.yaml | 1 + 1 file changed, 1 insertion(+)
Quoted 8 lines · On Mon, 22 Apr 2024 15:22:40 +0000 [email protected] wrote:
From: Jean-Baptiste Maneyrol <[email protected]>
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 <[email protected]>
Some comments inline, but given this is in line with the existing driver approaches, those can wait for another day. I'll tidy up the blank line comment.
Applied to the togreg branch of iio.git and pushed out initially as testing for all the normal boring reasons.
Jonathan
drivers/iio/imu/inv_icm42600/inv_icm42600_core.c static const struct inv_icm42600_conf inv_icm42600_default_conf = { · line 67
Quoted 8 lines
drivers/iio/imu/inv_icm42600/inv_icm42600_core.c +0
-0@@ -65,6 +65,21 @@ static const struct inv_icm42600_conf inv_icm42600_default_conf = { }, .temp_en = false, };
Blank line here.
Quoted 49 lines
drivers/iio/imu/inv_icm42600/inv_icm42600_core.c +20
-0+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 ] = {@@ -82,6 +97,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",drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c +1
-1@@ -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 );
drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c struct iio_dev *inv_icm42600_gyro_init(struct inv_icm42600_state *st) · line 770
Quoted 10 lines
drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c +7
-1- 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);
I'd have preferred this data being in the inv_icm42600_hw structures but that
is a more major refactor. Longer term having any cases like this be simple
'data' rather than code would make for a cleaner and more flexible driver.
Quoted 6 lines
drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c +6
-0+break ; +default : + gyro_st->scales = inv_icm42600_gyro_scale; + gyro_st->scales_len =ARRAY_SIZE (inv_icm42600_gyro_scale); +break ; + }