Skip to content

Commit 0a4d86c

Browse files
ubiedakartben
authored andcommitted
sensor: icm45686: Add I2C bus support
Validated for read/decode APIs, as well as Streaming mode (FIFO). Signed-off-by: Luis Ubieda <[email protected]>
1 parent b22299d commit 0a4d86c

File tree

6 files changed

+94
-7
lines changed

6 files changed

+94
-7
lines changed

drivers/sensor/tdk/icm45686/Kconfig

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ menuconfig ICM45686
66
bool "ICM45686 High-precision 6-Axis Motion Tracking Device"
77
default y
88
depends on DT_HAS_INVENSENSE_ICM45686_ENABLED
9-
select SPI
10-
select SPI_RTIO
9+
select SPI if $(dt_compat_on_bus,$(DT_COMPAT_INVENSENSE_ICM45686),spi)
10+
select SPI_RTIO if $(dt_compat_on_bus,$(DT_COMPAT_INVENSENSE_ICM45686),spi)
11+
select I2C if $(dt_compat_on_bus,$(DT_COMPAT_INVENSENSE_ICM45686),i2c)
12+
select I2C_RTIO if $(dt_compat_on_bus,$(DT_COMPAT_INVENSENSE_ICM45686),i2c)
1113
help
1214
Enable driver for ICM45686 High-precision 6-axis motion
1315
tracking device.

drivers/sensor/tdk/icm45686/icm45686.c

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include <zephyr/drivers/sensor.h>
1212
#include <zephyr/drivers/spi.h>
13+
#include <zephyr/drivers/i2c.h>
1314
#include <zephyr/drivers/gpio.h>
1415
#include <zephyr/rtio/rtio.h>
1516

@@ -199,6 +200,9 @@ static inline void icm45686_submit_one_shot(const struct device *dev,
199200
edata->payload.buf,
200201
sizeof(edata->payload.buf),
201202
NULL);
203+
if (data->rtio.type == ICM45686_BUS_I2C) {
204+
read_sqe->iodev_flags |= RTIO_IODEV_I2C_STOP | RTIO_IODEV_I2C_RESTART;
205+
}
202206
read_sqe->flags |= RTIO_SQE_CHAINED;
203207

204208
rtio_sqe_prep_callback_no_cqe(complete_sqe,
@@ -245,10 +249,18 @@ static int icm45686_init(const struct device *dev)
245249
uint8_t val;
246250
int err;
247251

248-
if (!spi_is_ready_iodev(data->rtio.iodev)) {
252+
#if CONFIG_SPI_RTIO
253+
if ((data->rtio.type == ICM45686_BUS_SPI) && !spi_is_ready_iodev(data->rtio.iodev)) {
254+
LOG_ERR("Bus is not ready");
255+
return -ENODEV;
256+
}
257+
#endif
258+
#if CONFIG_I2C_RTIO
259+
if ((data->rtio.type == ICM45686_BUS_I2C) && !i2c_is_ready_iodev(data->rtio.iodev)) {
249260
LOG_ERR("Bus is not ready");
250261
return -ENODEV;
251262
}
263+
#endif
252264

253265
/* Soft-reset sensor to restore config to defaults */
254266

@@ -383,10 +395,18 @@ static int icm45686_init(const struct device *dev)
383395
#define ICM45686_INIT(inst) \
384396
\
385397
RTIO_DEFINE(icm45686_rtio_ctx_##inst, 8, 8); \
386-
SPI_DT_IODEV_DEFINE(icm45686_bus_##inst, \
387-
DT_DRV_INST(inst), \
388-
SPI_OP_MODE_MASTER | SPI_WORD_SET(8) | SPI_TRANSFER_MSB, \
389-
0U); \
398+
\
399+
COND_CODE_1(DT_INST_ON_BUS(inst, spi), \
400+
(SPI_DT_IODEV_DEFINE(icm45686_bus_##inst, \
401+
DT_DRV_INST(inst), \
402+
SPI_OP_MODE_MASTER | SPI_WORD_SET(8) | SPI_TRANSFER_MSB, \
403+
0U)), \
404+
()); \
405+
\
406+
COND_CODE_1(DT_INST_ON_BUS(inst, i2c), \
407+
(I2C_DT_IODEV_DEFINE(icm45686_bus_##inst, \
408+
DT_DRV_INST(inst))), \
409+
()); \
390410
\
391411
static const struct icm45686_config icm45686_cfg_##inst = { \
392412
.settings = { \
@@ -414,6 +434,10 @@ static int icm45686_init(const struct device *dev)
414434
.rtio = { \
415435
.iodev = &icm45686_bus_##inst, \
416436
.ctx = &icm45686_rtio_ctx_##inst, \
437+
COND_CODE_1(DT_INST_ON_BUS(inst, i2c), \
438+
(.type = ICM45686_BUS_I2C), ()) \
439+
COND_CODE_1(DT_INST_ON_BUS(inst, spi), \
440+
(.type = ICM45686_BUS_SPI), ()) \
417441
}, \
418442
}; \
419443
\

drivers/sensor/tdk/icm45686/icm45686.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,16 @@ struct icm45686_stream {
130130
} data;
131131
};
132132

133+
enum icm45686_bus_type {
134+
ICM45686_BUS_SPI,
135+
ICM45686_BUS_I2C,
136+
};
137+
133138
struct icm45686_data {
134139
struct {
135140
struct rtio_iodev *iodev;
136141
struct rtio *ctx;
142+
enum icm45686_bus_type type;
137143
} rtio;
138144
/** Single-shot encoded data instance to support fetch/get API */
139145
struct icm45686_encoded_data edata;

drivers/sensor/tdk/icm45686/icm45686_bus.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ static inline int icm45686_bus_read(const struct device *dev,
3636
rtio_sqe_prep_write(write_sqe, iodev, RTIO_PRIO_HIGH, &reg, 1, NULL);
3737
write_sqe->flags |= RTIO_SQE_TRANSACTION;
3838
rtio_sqe_prep_read(read_sqe, iodev, RTIO_PRIO_HIGH, buf, len, NULL);
39+
if (data->rtio.type == ICM45686_BUS_I2C) {
40+
read_sqe->iodev_flags |= RTIO_IODEV_I2C_STOP | RTIO_IODEV_I2C_RESTART;
41+
}
3942

4043
err = rtio_submit(ctx, 2);
4144
if (err) {
@@ -73,6 +76,9 @@ static inline int icm45686_bus_write(const struct device *dev,
7376
rtio_sqe_prep_write(write_reg_sqe, iodev, RTIO_PRIO_HIGH, &reg, 1, NULL);
7477
write_reg_sqe->flags |= RTIO_SQE_TRANSACTION;
7578
rtio_sqe_prep_write(write_buf_sqe, iodev, RTIO_PRIO_HIGH, buf, len, NULL);
79+
if (data->rtio.type == ICM45686_BUS_I2C) {
80+
write_buf_sqe->iodev_flags |= RTIO_IODEV_I2C_STOP;
81+
}
7682

7783
err = rtio_submit(ctx, 2);
7884
if (err) {

drivers/sensor/tdk/icm45686/icm45686_stream.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,9 @@ static void icm45686_handle_event_actions(struct rtio *ctx,
204204
(buf->header.fifo_count *
205205
sizeof(struct icm45686_encoded_fifo_payload)),
206206
NULL);
207+
if (data->rtio.type == ICM45686_BUS_I2C) {
208+
data_rd_sqe->iodev_flags |= RTIO_IODEV_I2C_STOP | RTIO_IODEV_I2C_RESTART;
209+
}
207210
data_rd_sqe->flags |= RTIO_SQE_CHAINED;
208211

209212
} else if (should_flush_fifo(read_cfg, int_status)) {
@@ -232,6 +235,9 @@ static void icm45686_handle_event_actions(struct rtio *ctx,
232235
write_reg,
233236
sizeof(write_reg),
234237
NULL);
238+
if (data->rtio.type == ICM45686_BUS_I2C) {
239+
write_sqe->iodev_flags |= RTIO_IODEV_I2C_STOP;
240+
}
235241
write_sqe->flags |= RTIO_SQE_CHAINED;
236242

237243
} else if (should_read_data(read_cfg, int_status)) {
@@ -269,6 +275,9 @@ static void icm45686_handle_event_actions(struct rtio *ctx,
269275
buf->payload.buf,
270276
sizeof(buf->payload.buf),
271277
NULL);
278+
if (data->rtio.type == ICM45686_BUS_I2C) {
279+
read_sqe->iodev_flags |= RTIO_IODEV_I2C_STOP | RTIO_IODEV_I2C_RESTART;
280+
}
272281
read_sqe->flags |= RTIO_SQE_CHAINED;
273282
}
274283

@@ -318,6 +327,9 @@ static void icm45686_event_handler(const struct device *dev)
318327
wr_data,
319328
sizeof(wr_data),
320329
NULL);
330+
if (data->rtio.type == ICM45686_BUS_I2C) {
331+
write_sqe->iodev_flags |= RTIO_IODEV_I2C_STOP;
332+
}
321333
rtio_submit(data->rtio.ctx, 0);
322334

323335
data->stream.settings.enabled.drdy = false;
@@ -375,8 +387,12 @@ static void icm45686_event_handler(const struct device *dev)
375387
&data->stream.data.int_status,
376388
1,
377389
NULL);
390+
if (data->rtio.type == ICM45686_BUS_I2C) {
391+
read_sqe->iodev_flags |= RTIO_IODEV_I2C_STOP | RTIO_IODEV_I2C_RESTART;
392+
}
378393
read_sqe->flags |= RTIO_SQE_CHAINED;
379394

395+
380396
/** Preemptively read FIFO count so we can decide on the next callback
381397
* how much FIFO data we'd read (if needed).
382398
*/
@@ -395,6 +411,9 @@ static void icm45686_event_handler(const struct device *dev)
395411
(uint8_t *)&data->stream.data.fifo_count,
396412
2,
397413
NULL);
414+
if (data->rtio.type == ICM45686_BUS_I2C) {
415+
read_fifo_ct_sqe->iodev_flags |= RTIO_IODEV_I2C_STOP | RTIO_IODEV_I2C_RESTART;
416+
}
398417
read_fifo_ct_sqe->flags |= RTIO_SQE_CHAINED;
399418

400419
rtio_sqe_prep_callback_no_cqe(complete_sqe,
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Copyright (c) 2025 Croxel Inc.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
description: |
5+
ICM45686 High-precision 6-axis motion tracking device
6+
When setting the accel-pm, accel-range, accel-odr, gyro-pm, gyro-range,
7+
gyro-odr properties in a .dts or .dtsi file you may include icm45686.h
8+
and use the macros defined there.
9+
10+
Example:
11+
#include <zephyr/dt-bindings/sensor/icm45686.h>
12+
13+
&i2c0 {
14+
...
15+
16+
icm42688: icm45686@68 {
17+
...
18+
19+
accel-pwr-mode = <ICM45686_DT_ACCEL_LN>;
20+
accel-fs = <ICM45686_DT_ACCEL_FS_32>;
21+
accel-odr = <ICM45686_DT_ACCEL_ODR_800>;
22+
gyro-pwr-mode= <ICM45686_DT_GYRO_LN>;
23+
gyro-fs = <ICM45686_DT_GYRO_FS_4000>;
24+
gyro-odr = <ICM45686_DT_GYRO_ODR_800>;
25+
};
26+
};
27+
28+
compatible: "invensense,icm45686"
29+
30+
include: ["i2c-device.yaml", "invensense,icm45686-common.yaml"]

0 commit comments

Comments
 (0)