1 /*
2  * Copyright (c) 2017 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_DRIVERS_SENSOR_LIS2DH_LIS2DH_H_
8 #define ZEPHYR_DRIVERS_SENSOR_LIS2DH_LIS2DH_H_
9 
10 #include <zephyr/kernel.h>
11 #include <zephyr/device.h>
12 #include <zephyr/sys/util.h>
13 #include <stdint.h>
14 #include <zephyr/drivers/gpio.h>
15 #include <zephyr/drivers/sensor.h>
16 #include <string.h>
17 
18 #define LIS2DH_REG_WAI			0x0f
19 #define LIS2DH_CHIP_ID			0x33
20 
21 #if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
22 #include <zephyr/drivers/spi.h>
23 #endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) */
24 
25 #if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c)
26 #include <zephyr/drivers/i2c.h>
27 #endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) */
28 
29 #define LIS2DH_AUTOINCREMENT_ADDR	BIT(7)
30 
31 #define LIS2DH_REG_CTRL0		0x1e
32 #define LIS2DH_SDO_PU_DISC_MASK		BIT(7)
33 
34 #define LIS2DH_REG_CTRL1		0x20
35 #define LIS2DH_ACCEL_X_EN_BIT		BIT(0)
36 #define LIS2DH_ACCEL_Y_EN_BIT		BIT(1)
37 #define LIS2DH_ACCEL_Z_EN_BIT		BIT(2)
38 #define LIS2DH_ACCEL_EN_BITS		(LIS2DH_ACCEL_X_EN_BIT | \
39 					LIS2DH_ACCEL_Y_EN_BIT | \
40 					LIS2DH_ACCEL_Z_EN_BIT)
41 #define LIS2DH_ACCEL_XYZ_MASK		BIT_MASK(3)
42 
43 #define LIS2DH_LP_EN_BIT_MASK		BIT(3)
44 #if defined(CONFIG_LIS2DH_OPER_MODE_LOW_POWER)
45 	#define LIS2DH_LP_EN_BIT	BIT(3)
46 #else
47 	#define LIS2DH_LP_EN_BIT	0
48 #endif
49 
50 #define LIS2DH_SUSPEND			0
51 
52 #define LIS2DH_ODR_1			1
53 #define LIS2DH_ODR_2			2
54 #define LIS2DH_ODR_3			3
55 #define LIS2DH_ODR_4			4
56 #define LIS2DH_ODR_5			5
57 #define LIS2DH_ODR_6			6
58 #define LIS2DH_ODR_7			7
59 #define LIS2DH_ODR_8			8
60 #define LIS2DH_ODR_9			9
61 
62 #if defined(CONFIG_LIS2DH_ODR_1)
63 	#define LIS2DH_ODR_IDX		LIS2DH_ODR_1
64 #elif defined(CONFIG_LIS2DH_ODR_2)
65 	#define LIS2DH_ODR_IDX		LIS2DH_ODR_2
66 #elif defined(CONFIG_LIS2DH_ODR_3)
67 	#define LIS2DH_ODR_IDX		LIS2DH_ODR_3
68 #elif defined(CONFIG_LIS2DH_ODR_4) || defined(CONFIG_LIS2DH_ODR_RUNTIME)
69 	#define LIS2DH_ODR_IDX		LIS2DH_ODR_4
70 #elif defined(CONFIG_LIS2DH_ODR_5)
71 	#define LIS2DH_ODR_IDX		LIS2DH_ODR_5
72 #elif defined(CONFIG_LIS2DH_ODR_6)
73 	#define LIS2DH_ODR_IDX		LIS2DH_ODR_6
74 #elif defined(CONFIG_LIS2DH_ODR_7)
75 	#define LIS2DH_ODR_IDX		LIS2DH_ODR_7
76 #elif defined(CONFIG_LIS2DH_ODR_8)
77 	#define LIS2DH_ODR_IDX		LIS2DH_ODR_8
78 #elif defined(CONFIG_LIS2DH_ODR_9_NORMAL) || defined(CONFIG_LIS2DH_ODR_9_LOW)
79 	#define LIS2DH_ODR_IDX		LIS2DH_ODR_9
80 #endif
81 
82 #define LIS2DH_ODR_SHIFT		4
83 #define LIS2DH_ODR_RATE(r)		((r) << LIS2DH_ODR_SHIFT)
84 #define LIS2DH_ODR_BITS			(LIS2DH_ODR_RATE(LIS2DH_ODR_IDX))
85 #define LIS2DH_ODR_MASK			(BIT_MASK(4) << LIS2DH_ODR_SHIFT)
86 
87 #define LIS2DH_REG_CTRL2		0x21
88 #define LIS2DH_HPIS1_EN_BIT		BIT(0)
89 #define LIS2DH_HPIS2_EN_BIT		BIT(1)
90 #define LIS2DH_HPCLICK_EN_BIT		BIT(2)
91 #define LIS2DH_FDS_EN_BIT		BIT(3)
92 #define LIS2DH_HPCF0_EN_BIT		BIT(4)
93 #define LIS2DH_HPCF1_EN_BIT		BIT(5)
94 #define LIS2DH_HPM0_EN_BIT		BIT(6)
95 #define LIS2DH_HPM1_EN_BIT		BIT(7)
96 
97 #define LIS2DH_REG_CTRL3		0x22
98 #define LIS2DH_EN_CLICK_INT1		BIT(7)
99 #define LIS2DH_EN_IA_INT1		BIT(6)
100 #define LIS2DH_EN_DRDY1_INT1		BIT(4)
101 
102 #define LIS2DH_REG_CTRL4		0x23
103 #define LIS2DH_CTRL4_BDU_BIT		BIT(7)
104 #define LIS2DH_FS_SHIFT			4
105 #define LIS2DH_FS_MASK			(BIT_MASK(2) << LIS2DH_FS_SHIFT)
106 
107 #if defined(CONFIG_LIS2DH_ACCEL_RANGE_2G) ||\
108 	defined(CONFIG_LIS2DH_ACCEL_RANGE_RUNTIME)
109 	#define LIS2DH_FS_IDX		0
110 #elif defined(CONFIG_LIS2DH_ACCEL_RANGE_4G)
111 	#define LIS2DH_FS_IDX		1
112 #elif defined(CONFIG_LIS2DH_ACCEL_RANGE_8G)
113 	#define LIS2DH_FS_IDX		2
114 #elif defined(CONFIG_LIS2DH_ACCEL_RANGE_16G)
115 	#define LIS2DH_FS_IDX		3
116 #endif
117 
118 #define LIS2DH_FS_SELECT(fs)		((fs) << LIS2DH_FS_SHIFT)
119 #define LIS2DH_FS_BITS			(LIS2DH_FS_SELECT(LIS2DH_FS_IDX))
120 #if defined(CONFIG_LIS2DH_OPER_MODE_HIGH_RES)
121 	#define LIS2DH_HR_BIT		BIT(3)
122 #else
123 	#define LIS2DH_HR_BIT		0
124 #endif
125 
126 #define LIS2DH_REG_CTRL5		0x24
127 #define LIS2DH_EN_LIR_INT2		BIT(1)
128 #define LIS2DH_EN_LIR_INT1		BIT(3)
129 
130 #define LIS2DH_REG_CTRL6		0x25
131 #define LIS2DH_EN_CLICK_INT2		BIT(7)
132 #define LIS2DH_EN_IA_INT2		BIT(5)
133 
134 #define LIS2DH_REG_REFERENCE		0x26
135 
136 #define LIS2DH_REG_STATUS		0x27
137 #define LIS2DH_STATUS_ZYZ_OVR		BIT(7)
138 #define LIS2DH_STATUS_Z_OVR		BIT(6)
139 #define LIS2DH_STATUS_Y_OVR		BIT(5)
140 #define LIS2DH_STATUS_X_OVR		BIT(4)
141 #define LIS2DH_STATUS_OVR_MASK		(BIT_MASK(4) << 4)
142 #define LIS2DH_STATUS_ZYX_DRDY		BIT(3)
143 #define LIS2DH_STATUS_Z_DRDY		BIT(2)
144 #define LIS2DH_STATUS_Y_DRDY		BIT(1)
145 #define LIS2DH_STATUS_X_DRDY		BIT(0)
146 #define LIS2DH_STATUS_DRDY_MASK		BIT_MASK(4)
147 
148 #define LIS2DH_REG_ACCEL_X_LSB		0x28
149 #define LIS2DH_REG_ACCEL_Y_LSB		0x2A
150 #define LIS2DH_REG_ACCEL_Z_LSB		0x2C
151 #define LIS2DH_REG_ACCEL_X_MSB		0x29
152 #define LIS2DH_REG_ACCEL_Y_MSB		0x2B
153 #define LIS2DH_REG_ACCEL_Z_MSB		0x2D
154 
155 #define LIS2DH_REG_INT1_CFG		0x30
156 #define LIS2DH_REG_INT1_SRC		0x31
157 #define LIS2DH_REG_INT1_THS		0x32
158 #define LIS2DH_REG_INT1_DUR		0x33
159 #define LIS2DH_REG_INT2_CFG		0x34
160 #define LIS2DH_REG_INT2_SRC		0x35
161 #define LIS2DH_REG_INT2_THS		0x36
162 #define LIS2DH_REG_INT2_DUR		0x37
163 
164 #define LIS2DH_INT_CFG_MODE_SHIFT	6
165 #define LIS2DH_INT_CFG_AOI_CFG		BIT(7)
166 #define LIS2DH_INT_CFG_6D_CFG		BIT(6)
167 #define LIS2DH_INT_CFG_ZHIE_ZUPE	BIT(5)
168 #define LIS2DH_INT_CFG_ZLIE_ZDOWNE	BIT(4)
169 #define LIS2DH_INT_CFG_YHIE_YUPE	BIT(3)
170 #define LIS2DH_INT_CFG_YLIE_YDOWNE	BIT(2)
171 #define LIS2DH_INT_CFG_XHIE_XUPE	BIT(1)
172 #define LIS2DH_INT_CFG_XLIE_XDOWNE	BIT(0)
173 
174 #define LIS2DH_REG_CFG_CLICK		0x38
175 #define LIS2DH_EN_CLICK_ZD		BIT(5)
176 #define LIS2DH_EN_CLICK_ZS		BIT(4)
177 #define LIS2DH_EN_CLICK_YD		BIT(3)
178 #define LIS2DH_EN_CLICK_YS		BIT(2)
179 #define LIS2DH_EN_CLICK_XD		BIT(1)
180 #define LIS2DH_EN_CLICK_XS		BIT(0)
181 
182 #define LIS2DH_REG_CLICK_SRC		0x39
183 #define LIS2DH_CLICK_SRC_DCLICK		BIT(5)
184 #define LIS2DH_CLICK_SRC_SCLICK		BIT(4)
185 
186 #define LIS2DH_REG_CFG_CLICK_THS	0x3A
187 #define LIS2DH_CLICK_LIR		BIT(7)
188 
189 #define LIS2DH_REG_TIME_LIMIT		0x3B
190 
191 /* sample buffer size includes status register */
192 #define LIS2DH_BUF_SZ			7
193 
194 union lis2dh_sample {
195 	uint8_t raw[LIS2DH_BUF_SZ];
196 	struct {
197 		uint8_t status;
198 		int16_t xyz[3];
199 	} __packed;
200 };
201 
202 union lis2dh_bus_cfg {
203 #if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c)
204 	struct i2c_dt_spec i2c;
205 #endif
206 
207 #if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
208 	struct spi_dt_spec spi;
209 #endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) */
210 };
211 
212 struct temperature {
213 	uint8_t cfg_addr;
214 	uint8_t enable_mask;
215 	uint8_t dout_addr;
216 	uint8_t fractional_bits;
217 };
218 
219 struct lis2dh_config {
220 	int (*bus_init)(const struct device *dev);
221 	const union lis2dh_bus_cfg bus_cfg;
222 #ifdef CONFIG_LIS2DH_TRIGGER
223 	const struct gpio_dt_spec gpio_drdy;
224 	const struct gpio_dt_spec gpio_int;
225 	const uint8_t int1_mode;
226 	const uint8_t int2_mode;
227 #endif /* CONFIG_LIS2DH_TRIGGER */
228 	struct {
229 		bool is_lsm303agr_dev : 1;
230 		bool disc_pull_up : 1;
231 		bool anym_on_int1 : 1;
232 		bool anym_latch : 1;
233 		uint8_t anym_mode : 2;
234 	} hw;
235 #ifdef CONFIG_LIS2DH_MEASURE_TEMPERATURE
236 	const struct temperature temperature;
237 #endif
238 };
239 
240 struct lis2dh_transfer_function {
241 	int (*read_data)(const struct device *dev, uint8_t reg_addr,
242 			 uint8_t *value, uint8_t len);
243 	int (*write_data)(const struct device *dev, uint8_t reg_addr,
244 			  uint8_t *value, uint8_t len);
245 	int (*read_reg)(const struct device *dev, uint8_t reg_addr,
246 			uint8_t *value);
247 	int (*write_reg)(const struct device *dev, uint8_t reg_addr,
248 			 uint8_t value);
249 	int (*update_reg)(const struct device *dev, uint8_t reg_addr,
250 			  uint8_t mask, uint8_t value);
251 };
252 
253 struct lis2dh_data {
254 	const struct device *bus;
255 	const struct lis2dh_transfer_function *hw_tf;
256 
257 	union lis2dh_sample sample;
258 	/* current scaling factor, in micro m/s^2 / lsb */
259 	uint32_t scale;
260 
261 #ifdef CONFIG_LIS2DH_MEASURE_TEMPERATURE
262 	struct sensor_value temperature;
263 #endif
264 
265 #ifdef CONFIG_PM_DEVICE
266 	uint8_t reg_ctrl1_active_val;
267 #endif
268 
269 #ifdef CONFIG_LIS2DH_TRIGGER
270 	const struct device *dev;
271 	struct gpio_callback gpio_int1_cb;
272 	struct gpio_callback gpio_int2_cb;
273 
274 	sensor_trigger_handler_t handler_drdy;
275 	const struct sensor_trigger *trig_drdy;
276 	sensor_trigger_handler_t handler_anymotion;
277 	const struct sensor_trigger *trig_anymotion;
278 	sensor_trigger_handler_t handler_tap;
279 	const struct sensor_trigger *trig_tap;
280 	atomic_t trig_flags;
281 	enum sensor_channel chan_drdy;
282 
283 #if defined(CONFIG_LIS2DH_TRIGGER_OWN_THREAD)
284 	K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_LIS2DH_THREAD_STACK_SIZE);
285 	struct k_thread thread;
286 	struct k_sem gpio_sem;
287 #elif defined(CONFIG_LIS2DH_TRIGGER_GLOBAL_THREAD)
288 	struct k_work work;
289 #endif
290 
291 #endif /* CONFIG_LIS2DH_TRIGGER */
292 };
293 
294 #if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
295 int lis2dh_spi_access(struct lis2dh_data *ctx, uint8_t cmd,
296 		      void *data, size_t length);
297 #endif
298 
299 #ifdef CONFIG_LIS2DH_TRIGGER
300 int lis2dh_trigger_set(const struct device *dev,
301 		       const struct sensor_trigger *trig,
302 		       sensor_trigger_handler_t handler);
303 
304 int lis2dh_init_interrupt(const struct device *dev);
305 
306 int lis2dh_acc_slope_config(const struct device *dev,
307 			    enum sensor_attribute attr,
308 			    const struct sensor_value *val);
309 #endif
310 
311 int lis2dh_spi_init(const struct device *dev);
312 int lis2dh_i2c_init(const struct device *dev);
313 
314 
315 #endif /* __SENSOR_LIS2DH__ */
316