1 /* ST Microelectronics LSM6DSO 6-axis IMU sensor driver
2  *
3  * Copyright (c) 2019 STMicroelectronics
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  *
7  * Datasheet:
8  * https://www.st.com/resource/en/datasheet/lsm6dso.pdf
9  */
10 
11 #ifndef ZEPHYR_DRIVERS_SENSOR_LSM6DSO_LSM6DSO_H_
12 #define ZEPHYR_DRIVERS_SENSOR_LSM6DSO_LSM6DSO_H_
13 
14 #include <zephyr/drivers/sensor.h>
15 #include <zephyr/types.h>
16 #include <zephyr/drivers/gpio.h>
17 #include <zephyr/drivers/spi.h>
18 #include <zephyr/sys/util.h>
19 #include <stmemsc.h>
20 #include "lsm6dso_reg.h"
21 
22 #if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lsm6dso, spi) || \
23 	DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lsm6dso32, spi)
24 #include <zephyr/drivers/spi.h>
25 #endif
26 
27 #if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lsm6dso, i2c) || \
28 	DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lsm6dso32, i2c)
29 #include <zephyr/drivers/i2c.h>
30 #endif
31 
32 #define LSM6DSO_EN_BIT					0x01
33 #define LSM6DSO_DIS_BIT					0x00
34 
35 /* Accel sensor sensitivity grain is 61 ug/LSB */
36 #define GAIN_UNIT_XL				(61LL)
37 
38 /* Gyro sensor sensitivity grain is 4.375 udps/LSB */
39 #define GAIN_UNIT_G				(4375LL)
40 
41 struct lsm6dso_config {
42 	stmdev_ctx_t ctx;
43 	union {
44 #if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lsm6dso, i2c) || \
45 	DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lsm6dso32, i2c)
46 		const struct i2c_dt_spec i2c;
47 #endif
48 #if DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lsm6dso, spi) || \
49 	DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lsm6dso32, spi)
50 		const struct spi_dt_spec spi;
51 #endif
52 	} stmemsc_cfg;
53 	uint8_t accel_pm;
54 	uint8_t accel_odr;
55 #define ACCEL_RANGE_DOUBLE	BIT(7)
56 #define ACCEL_RANGE_MASK	BIT_MASK(6)
57 	uint8_t accel_range;
58 	uint8_t gyro_pm;
59 	uint8_t gyro_odr;
60 	uint8_t gyro_range;
61 	uint8_t drdy_pulsed;
62 #ifdef CONFIG_LSM6DSO_TRIGGER
63 	const struct gpio_dt_spec gpio_drdy;
64 	uint8_t int_pin;
65 	bool trig_enabled;
66 #endif /* CONFIG_LSM6DSO_TRIGGER */
67 };
68 
69 #define LSM6DSO_SHUB_MAX_NUM_TARGETS			3
70 
71 struct lsm6dso_data {
72 	const struct device *dev;
73 	int16_t acc[3];
74 	uint32_t acc_gain;
75 	int16_t gyro[3];
76 	uint32_t gyro_gain;
77 #if defined(CONFIG_LSM6DSO_ENABLE_TEMP)
78 	int16_t temp_sample;
79 #endif
80 #if defined(CONFIG_LSM6DSO_SENSORHUB)
81 	uint8_t ext_data[LSM6DSO_SHUB_MAX_NUM_TARGETS][6];
82 	uint16_t magn_gain;
83 
84 	struct hts221_data {
85 		int16_t x0;
86 		int16_t x1;
87 		int16_t y0;
88 		int16_t y1;
89 	} hts221;
90 	bool shub_inited;
91 	uint8_t num_ext_dev;
92 	uint8_t shub_ext[LSM6DSO_SHUB_MAX_NUM_TARGETS];
93 #endif /* CONFIG_LSM6DSO_SENSORHUB */
94 
95 	uint16_t accel_freq;
96 	uint8_t accel_fs;
97 	uint16_t gyro_freq;
98 	uint8_t gyro_fs;
99 
100 #ifdef CONFIG_LSM6DSO_TRIGGER
101 	struct gpio_callback gpio_cb;
102 	sensor_trigger_handler_t handler_drdy_acc;
103 	const struct sensor_trigger *trig_drdy_acc;
104 	sensor_trigger_handler_t handler_drdy_gyr;
105 	const struct sensor_trigger *trig_drdy_gyr;
106 	sensor_trigger_handler_t handler_drdy_temp;
107 	const struct sensor_trigger *trig_drdy_temp;
108 
109 #if defined(CONFIG_LSM6DSO_TRIGGER_OWN_THREAD)
110 	K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_LSM6DSO_THREAD_STACK_SIZE);
111 	struct k_thread thread;
112 	struct k_sem gpio_sem;
113 #elif defined(CONFIG_LSM6DSO_TRIGGER_GLOBAL_THREAD)
114 	struct k_work work;
115 #endif
116 #endif /* CONFIG_LSM6DSO_TRIGGER */
117 };
118 
119 #if defined(CONFIG_LSM6DSO_SENSORHUB)
120 int lsm6dso_shub_init(const struct device *dev);
121 int lsm6dso_shub_fetch_external_devs(const struct device *dev);
122 int lsm6dso_shub_get_idx(const struct device *dev, enum sensor_channel type);
123 int lsm6dso_shub_config(const struct device *dev, enum sensor_channel chan,
124 			enum sensor_attribute attr,
125 			const struct sensor_value *val);
126 #endif /* CONFIG_LSM6DSO_SENSORHUB */
127 
128 #ifdef CONFIG_LSM6DSO_TRIGGER
129 int lsm6dso_trigger_set(const struct device *dev,
130 			const struct sensor_trigger *trig,
131 			sensor_trigger_handler_t handler);
132 
133 int lsm6dso_init_interrupt(const struct device *dev);
134 #endif
135 
136 #endif /* ZEPHYR_DRIVERS_SENSOR_LSM6DSO_LSM6DSO_H_ */
137