Skip to contentSkip to conversation

iio: imu: inv_icm42600: add support of ICM-42686-P

PATCH Applied [email protected] 3 participants 5 messages Apr 22, 2024 – Apr 28, 2024

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

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
#1 lore raw

PATCH 1/2 dt-bindings: iio: imu: add icm42686 inside inv_icm42600

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
index 5e0bed2c45de..3769f8e8e98c 100644
@@ -32,6 +32,7 @@ properties:
       - invensense,icm42605
       - invensense,icm42622
       - invensense,icm42631
+      - invensense,icm42686
       - invensense,icm42688
 
   reg:
Signature · 1 line
2.34.1
maintainer Acked-by on v1 1/2
#2 lore raw

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.

---
 .../devicetree/bindings/iio/imu/invensense,icm42600.yaml         | 1 +
 1 file changed, 1 insertion(+)
#3 lore raw

PATCH 2/2 iio: imu: inv_icm42600: add support of ICM-42686-P

In reply to [email protected]

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
index 0566340b2660..c4ac91f6bafe 100644
@@ -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
index b52f328fd26c..cfb4a41ab7c1 100644
@@ -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
index 82e0a2e2ad70..42316fb72674 100644
@@ -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
index ebb28f84ba98..8d33504d770f 100644
@@ -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
index 50217a10e0bb..cc2bf1799a46 100644
@@ -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
maintainer Applied
#4 lore raw
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.

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
index 82e0a2e2ad70..42316fb72674 100644
@@ -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
index 3df0a715e885..e6f8de80128c 100644
@@ -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;
+	}