1 /*
2  * Copyright (c) 2024 TDK Invensense
3  * Copyright (c) 2022 Esco Medical ApS
4  * Copyright (c) 2020 TDK Invensense
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #ifndef ZEPHYR_DRIVERS_SENSOR_ICM42670_H_
10 #define ZEPHYR_DRIVERS_SENSOR_ICM42670_H_
11 
12 #include <zephyr/drivers/gpio.h>
13 #include <zephyr/drivers/sensor.h>
14 #include <zephyr/drivers/spi.h>
15 #include <zephyr/drivers/i2c.h>
16 #include <zephyr/kernel.h>
17 
18 #include "imu/inv_imu_driver.h"
19 #ifdef CONFIG_TDK_APEX
20 #include "imu/inv_imu_apex.h"
21 #endif
22 
23 union icm42670_bus {
24 #if CONFIG_SPI
25 	struct spi_dt_spec spi;
26 #endif
27 #if CONFIG_I2C
28 	struct i2c_dt_spec i2c;
29 #endif
30 };
31 
32 typedef int (*icm42670_bus_check_fn)(const union icm42670_bus *bus);
33 typedef int (*icm42670_reg_read_fn)(const union icm42670_bus *bus, uint8_t reg, uint8_t *buf,
34 				    uint32_t size);
35 typedef int (*icm42670_reg_write_fn)(const union icm42670_bus *bus, uint8_t reg, uint8_t *buf,
36 				     uint32_t size);
37 
38 struct icm42670_bus_io {
39 	icm42670_bus_check_fn check;
40 	icm42670_reg_read_fn read;
41 	icm42670_reg_write_fn write;
42 };
43 
44 #if CONFIG_SPI
45 extern const struct icm42670_bus_io icm42670_bus_io_spi;
46 #endif
47 
48 #if CONFIG_I2C
49 extern const struct icm42670_bus_io icm42670_bus_io_i2c;
50 #endif
51 
52 struct icm42670_data {
53 	struct inv_imu_serif serif;
54 	struct inv_imu_device driver;
55 	uint8_t imu_whoami;
56 	char *imu_name;
57 	uint8_t chip_id;
58 	int32_t accel_x;
59 	int32_t accel_y;
60 	int32_t accel_z;
61 	uint16_t accel_hz;
62 	uint8_t accel_fs;
63 	uint8_t accel_pwr_mode;
64 	int32_t gyro_x;
65 	int32_t gyro_y;
66 	int32_t gyro_z;
67 	uint16_t gyro_hz;
68 	uint16_t gyro_fs;
69 	int32_t temp;
70 #ifdef CONFIG_TDK_APEX
71 	uint8_t dmp_odr_hz;
72 	uint64_t pedometer_cnt;
73 	uint8_t pedometer_activity;
74 	uint8_t pedometer_cadence;
75 	uint8_t apex_status;
76 #endif
77 
78 #ifdef CONFIG_ICM42670_TRIGGER
79 	const struct device *dev;
80 	struct gpio_callback gpio_cb;
81 	sensor_trigger_handler_t data_ready_handler;
82 	const struct sensor_trigger *data_ready_trigger;
83 	struct k_mutex mutex;
84 #endif
85 #ifdef CONFIG_ICM42670_TRIGGER_OWN_THREAD
86 	K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_ICM42670_THREAD_STACK_SIZE);
87 	struct k_thread thread;
88 	struct k_sem gpio_sem;
89 #endif
90 #ifdef CONFIG_ICM42670_TRIGGER_GLOBAL_THREAD
91 	struct k_work work;
92 #endif
93 };
94 
95 struct icm42670_config {
96 	union icm42670_bus bus;
97 	const struct icm42670_bus_io *bus_io;
98 	struct gpio_dt_spec gpio_int;
99 	uint8_t accel_fs;
100 	uint16_t accel_hz;
101 	uint16_t accel_avg;
102 	uint16_t accel_filt_bw;
103 	uint16_t gyro_fs;
104 	uint16_t gyro_hz;
105 	uint16_t gyro_filt_bw;
106 	uint8_t accel_pwr_mode;
107 	uint8_t apex;
108 };
109 
110 #ifdef CONFIG_TDK_APEX
111 
112 #define ICM42670_APEX_STATUS_MASK_TILT  BIT(0)
113 #define ICM42670_APEX_STATUS_MASK_SMD   BIT(1)
114 #define ICM42670_APEX_STATUS_MASK_WOM_X BIT(2)
115 #define ICM42670_APEX_STATUS_MASK_WOM_Y BIT(3)
116 #define ICM42670_APEX_STATUS_MASK_WOM_Z BIT(4)
117 
118 int icm42670_apex_enable(inv_imu_device_t *s);
119 int icm42670_apex_fetch_from_dmp(const struct device *dev);
120 void icm42670_apex_pedometer_cadence_convert(struct sensor_value *val, uint8_t raw_val,
121 					     uint8_t dmp_odr_hz);
122 int icm42670_apex_enable_pedometer(const struct device *dev, inv_imu_device_t *s);
123 int icm42670_apex_enable_tilt(inv_imu_device_t *s);
124 int icm42670_apex_enable_smd(inv_imu_device_t *s);
125 int icm42670_apex_enable_wom(inv_imu_device_t *s);
126 #endif
127 
128 #endif /* ZEPHYR_DRIVERS_SENSOR_ICM42670_H_ */
129