1 /*
2  * Copyright (c) 2018 Analog Devices Inc.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT adi_adxl372
8 
9 #include <zephyr/drivers/sensor.h>
10 #include <zephyr/kernel.h>
11 #include <zephyr/device.h>
12 #include <string.h>
13 #include <zephyr/init.h>
14 #include <zephyr/sys/printk.h>
15 #include <zephyr/sys/__assert.h>
16 #include <stdlib.h>
17 #include <zephyr/logging/log.h>
18 
19 #include "adxl372.h"
20 
21 LOG_MODULE_REGISTER(ADXL372, CONFIG_SENSOR_LOG_LEVEL);
22 
23 /**
24  * Set the threshold for activity detection for a single axis
25  * @param dev - The device structure.
26  * @param axis_reg_h - The high part of the activity register.
27  * @param act - The activity config structure.
28  * @return 0 in case of success, negative error code otherwise.
29  */
adxl372_set_activity_threshold(const struct device * dev,uint8_t axis_reg_h,const struct adxl372_activity_threshold * act)30 static int adxl372_set_activity_threshold(const struct device *dev,
31 					  uint8_t axis_reg_h,
32 					  const struct adxl372_activity_threshold *act)
33 {
34 	int ret;
35 	uint8_t val;
36 	struct adxl372_data *data = dev->data;
37 
38 	ret = data->hw_tf->write_reg(dev, axis_reg_h++, act->thresh >> 3);
39 	if (ret) {
40 		return ret;
41 	}
42 
43 	switch (axis_reg_h) {
44 	case ADXL372_X_THRESH_ACT_L:
45 	case ADXL372_X_THRESH_INACT_L:
46 	case ADXL372_X_THRESH_ACT2_L:
47 		val = (act->thresh << 5) | (act->referenced << 1) | act->enable;
48 		break;
49 	default:
50 		val = (act->thresh << 5) | act->enable;
51 	}
52 
53 	return data->hw_tf->write_reg(dev, axis_reg_h, val);
54 }
55 
56 /**
57  * Set the threshold for activity detection for all 3-axis
58  * @param dev - The device structure.
59  * @param axis_reg_h - The high part of the activity register.
60  * @param act - The activity config structure.
61  * @return 0 in case of success, negative error code otherwise.
62  */
adxl372_set_activity_threshold_xyz(const struct device * dev,uint8_t axis_reg_h,const struct adxl372_activity_threshold * act)63 static int adxl372_set_activity_threshold_xyz(const struct device *dev,
64 					      uint8_t axis_reg_h,
65 					      const struct adxl372_activity_threshold *act)
66 {
67 	int i, ret;
68 
69 	for (i = 0; i < 3; i++) {
70 		ret = adxl372_set_activity_threshold(dev, axis_reg_h, act);
71 		if (ret) {
72 			return ret;
73 		}
74 		axis_reg_h += 2U;
75 	}
76 
77 	return 0;
78 }
79 
80 /**
81  * Set the mode of operation.
82  * @param dev - The device structure.
83  * @param op_mode - Mode of operation.
84  *		Accepted values: ADXL372_STANDBY
85  *				 ADXL372_WAKE_UP
86  *				 ADXL372_INSTANT_ON
87  *				 ADXL372_FULL_BW_MEASUREMENT
88  * @return 0 in case of success, negative error code otherwise.
89  */
adxl372_set_op_mode(const struct device * dev,enum adxl372_op_mode op_mode)90 int adxl372_set_op_mode(const struct device *dev, enum adxl372_op_mode op_mode)
91 {
92 	struct adxl372_data *data = dev->data;
93 
94 	int ret = data->hw_tf->write_reg_mask(dev, ADXL372_POWER_CTL,
95 					   ADXL372_POWER_CTL_MODE_MSK,
96 					   ADXL372_POWER_CTL_MODE(op_mode));
97 
98 #ifdef CONFIG_ADXL372_STREAM
99 	if (ret == 0) {
100 		data->pwr_reg &= ~ADXL372_POWER_CTL_MODE_MSK;
101 		data->pwr_reg |= ADXL372_POWER_CTL_MODE(op_mode);
102 	}
103 #endif /* CONFIG_ADXL372_STREAM */
104 
105 	return ret;
106 }
107 
108 /**
109  * Autosleep. When set to 1, autosleep is enabled, and the device enters
110  * wake-up mode automatically upon detection of inactivity.
111  * @param dev - The device structure.
112  * @param enable - Accepted values: true
113  *				    false
114  * @return 0 in case of success, negative error code otherwise.
115  */
adxl372_set_autosleep(const struct device * dev,bool enable)116 static int adxl372_set_autosleep(const struct device *dev, bool enable)
117 {
118 	struct adxl372_data *data = dev->data;
119 
120 	return data->hw_tf->write_reg_mask(dev, ADXL372_MEASURE,
121 					   ADXL372_MEASURE_AUTOSLEEP_MSK,
122 					   ADXL372_MEASURE_AUTOSLEEP_MODE(enable));
123 }
124 
125 /**
126  * Select the desired output signal bandwidth.
127  * @param dev - The device structure.
128  * @param bw - bandwidth.
129  *		Accepted values: ADXL372_BW_200HZ
130  *				 ADXL372_BW_400HZ
131  *				 ADXL372_BW_800HZ
132  *				 ADXL372_BW_1600HZ
133  *				 ADXL372_BW_3200HZ
134  *				 ADXL372_BW_LPF_DISABLED
135  * @return 0 in case of success, negative error code otherwise.
136  */
adxl372_set_bandwidth(const struct device * dev,enum adxl372_bandwidth bw)137 static int adxl372_set_bandwidth(const struct device *dev,
138 				 enum adxl372_bandwidth bw)
139 {
140 	int ret;
141 	uint8_t mask;
142 	struct adxl372_data *data = dev->data;
143 
144 	if (bw == ADXL372_BW_LPF_DISABLED) {
145 		mask = ADXL372_POWER_CTL_LPF_DIS_MSK;
146 	} else {
147 		mask = 0U;
148 	}
149 
150 	ret = data->hw_tf->write_reg_mask(dev, ADXL372_POWER_CTL,
151 					  ADXL372_POWER_CTL_LPF_DIS_MSK, mask);
152 	if (ret) {
153 		return ret;
154 	}
155 
156 #ifdef CONFIG_ADXL372_STREAM
157 	data->pwr_reg &= ~ADXL372_POWER_CTL_LPF_DIS_MSK;
158 	data->pwr_reg |= mask;
159 #endif /* CONFIG_ADXL372_STREAM */
160 
161 	return data->hw_tf->write_reg_mask(dev, ADXL372_MEASURE,
162 					   ADXL372_MEASURE_BANDWIDTH_MSK,
163 					   ADXL372_MEASURE_BANDWIDTH_MODE(bw));
164 }
165 
166 /**
167  * Select the desired high-pass filter corner.
168  * @param dev - The device structure.
169  * @param c - bandwidth.
170  *		Accepted values: ADXL372_HPF_CORNER_0
171  *				 ADXL372_HPF_CORNER_1
172  *				 ADXL372_HPF_CORNER_2
173  *				 ADXL372_HPF_CORNER_3
174  *				 ADXL372_HPF_DISABLED
175  * @return 0 in case of success, negative error code otherwise.
176  */
adxl372_set_hpf_corner(const struct device * dev,enum adxl372_hpf_corner c)177 static int adxl372_set_hpf_corner(const struct device *dev,
178 				  enum adxl372_hpf_corner c)
179 {
180 
181 	int ret;
182 	uint8_t mask;
183 	struct adxl372_data *data = dev->data;
184 
185 	if (c == ADXL372_HPF_DISABLED) {
186 		mask = ADXL372_POWER_CTL_HPF_DIS_MSK;
187 	} else {
188 		mask = 0U;
189 	}
190 
191 	ret = data->hw_tf->write_reg_mask(dev, ADXL372_POWER_CTL,
192 					  ADXL372_POWER_CTL_HPF_DIS_MSK, mask);
193 	if (ret) {
194 		return ret;
195 	}
196 
197 #ifdef CONFIG_ADXL372_STREAM
198 	data->pwr_reg &= ~ADXL372_POWER_CTL_HPF_DIS_MSK;
199 	data->pwr_reg |= mask;
200 #endif /* CONFIG_ADXL372_STREAM */
201 
202 	return data->hw_tf->write_reg(dev, ADXL372_HPF, ADXL372_HPF_CORNER(c));
203 }
204 
205 
206 /**
207  * Link/Loop Activity Processing.
208  * @param dev - The device structure.
209  * @param mode - Mode of operation.
210  *		Accepted values: ADXL372_DEFAULT
211  *				 ADXL372_LINKED
212  *				 ADXL372_LOOPED
213  * @return 0 in case of success, negative error code otherwise.
214  */
adxl372_set_act_proc_mode(const struct device * dev,enum adxl372_act_proc_mode mode)215 static int adxl372_set_act_proc_mode(const struct device *dev,
216 				     enum adxl372_act_proc_mode mode)
217 {
218 	struct adxl372_data *data = dev->data;
219 
220 	return data->hw_tf->write_reg_mask(dev, ADXL372_MEASURE,
221 					   ADXL372_MEASURE_LINKLOOP_MSK,
222 					   ADXL372_MEASURE_LINKLOOP_MODE(mode));
223 }
224 
225 /**
226  * Set Output data rate.
227  * @param dev - The device structure.
228  * @param odr - Output data rate.
229  *		Accepted values: ADXL372_ODR_400HZ
230  *				 ADXL372_ODR_800HZ
231  *				 ADXL372_ODR_1600HZ
232  *				 ADXL372_ODR_3200HZ
233  *				 ADXL372_ODR_6400HZ
234  * @return 0 in case of success, negative error code otherwise.
235  */
adxl372_set_odr(const struct device * dev,enum adxl372_odr odr)236 static int adxl372_set_odr(const struct device *dev, enum adxl372_odr odr)
237 {
238 	struct adxl372_data *data = dev->data;
239 
240 	return data->hw_tf->write_reg_mask(dev, ADXL372_TIMING,
241 					   ADXL372_TIMING_ODR_MSK,
242 					   ADXL372_TIMING_ODR_MODE(odr));
243 }
244 
245 /**
246  * Select instant on threshold
247  * @param dev - The device structure.
248  * @param mode - 0 = low threshold, 1 = high threshold.
249  *		Accepted values: ADXL372_INSTANT_ON_LOW_TH
250  *				 ADXL372_INSTANT_ON_HIGH_TH
251  * @return 0 in case of success, negative error code otherwise.
252  */
adxl372_set_instant_on_th(const struct device * dev,enum adxl372_instant_on_th_mode mode)253 static int adxl372_set_instant_on_th(const struct device *dev,
254 				     enum adxl372_instant_on_th_mode mode)
255 {
256 	struct adxl372_data *data = dev->data;
257 
258 	int ret = data->hw_tf->write_reg_mask(dev, ADXL372_POWER_CTL,
259 					   ADXL372_POWER_CTL_INSTANT_ON_TH_MSK,
260 					   ADXL372_POWER_CTL_INSTANT_ON_TH_MODE(mode));
261 
262 #ifdef CONFIG_ADXL372_STREAM
263 	if (ret == 0) {
264 		data->pwr_reg &= ~ADXL372_POWER_CTL_INSTANT_ON_TH_MSK;
265 		data->pwr_reg |= ADXL372_POWER_CTL_INSTANT_ON_TH_MODE(mode);
266 	}
267 #endif /* CONFIG_ADXL372_STREAM */
268 
269 	return ret;
270 }
271 
272 /**
273  * Set the Timer Rate for Wake-Up Mode.
274  * @param dev - The device structure.
275  * @param wur - wake up mode rate
276  *		Accepted values: ADXL372_WUR_52ms
277  *				 ADXL372_WUR_104ms
278  *				 ADXL372_WUR_208ms
279  *				 ADXL372_WUR_512ms
280  *				 ADXL372_WUR_2048ms
281  *				 ADXL372_WUR_4096ms
282  *				 ADXL372_WUR_8192ms
283  *				 ADXL372_WUR_24576ms
284  * @return 0 in case of success, negative error code otherwise.
285  */
adxl372_set_wakeup_rate(const struct device * dev,enum adxl372_wakeup_rate wur)286 static int adxl372_set_wakeup_rate(const struct device *dev,
287 				   enum adxl372_wakeup_rate wur)
288 {
289 	struct adxl372_data *data = dev->data;
290 
291 	return data->hw_tf->write_reg_mask(dev, ADXL372_TIMING,
292 					   ADXL372_TIMING_WAKE_UP_RATE_MSK,
293 					   ADXL372_TIMING_WAKE_UP_RATE_MODE(wur));
294 }
295 
296 /**
297  * Set the activity timer
298  * @param dev - The device structure.
299  * @param time - The value set in this register.
300  * @return 0 in case of success, negative error code otherwise.
301  */
adxl372_set_activity_time(const struct device * dev,uint8_t time)302 static int adxl372_set_activity_time(const struct device *dev, uint8_t time)
303 {
304 	struct adxl372_data *data = dev->data;
305 
306 	return data->hw_tf->write_reg(dev, ADXL372_TIME_ACT, time);
307 }
308 
309 /**
310  * Set the inactivity timer
311  * @param dev - The device structure.
312  * @param time - is the 16-bit value set by the TIME_INACT_L register
313  *		 (eight LSBs) and the TIME_INACT_H register (eight MSBs).
314  * @return 0 in case of success, negative error code otherwise.
315  */
adxl372_set_inactivity_time(const struct device * dev,uint16_t time)316 static int adxl372_set_inactivity_time(const struct device *dev,
317 				       uint16_t time)
318 {
319 	int ret;
320 	struct adxl372_data *data = dev->data;
321 
322 	ret = data->hw_tf->write_reg(dev, ADXL372_TIME_INACT_H, time >> 8);
323 	if (ret) {
324 		return ret;
325 	}
326 
327 	return data->hw_tf->write_reg(dev, ADXL372_TIME_INACT_L, time & 0xFF);
328 }
329 
330 /**
331  * Set the filter settling period.
332  * @param dev - The device structure.
333  * @param mode - settle period
334  *		Accepted values: ADXL372_FILTER_SETTLE_370
335  *				 ADXL372_FILTER_SETTLE_16
336  * @return 0 in case of success, negative error code otherwise.
337  */
adxl372_set_filter_settle(const struct device * dev,enum adxl372_filter_settle mode)338 static int adxl372_set_filter_settle(const struct device *dev,
339 				     enum adxl372_filter_settle mode)
340 {
341 	struct adxl372_data *data = dev->data;
342 
343 	int ret = data->hw_tf->write_reg_mask(dev, ADXL372_POWER_CTL,
344 					   ADXL372_POWER_CTL_FIL_SETTLE_MSK,
345 					   ADXL372_POWER_CTL_FIL_SETTLE_MODE(mode));
346 
347 #ifdef CONFIG_ADXL372_STREAM
348 	if (ret == 0) {
349 		data->pwr_reg &= ~ADXL372_POWER_CTL_FIL_SETTLE_MSK;
350 		data->pwr_reg |= ADXL372_POWER_CTL_FIL_SETTLE_MODE(mode);
351 	}
352 #endif /* CONFIG_ADXL372_STREAM */
353 
354 	return ret;
355 }
356 
357 /**
358  * Configure the INT1 and INT2 interrupt pins.
359  * @param dev - The device structure.
360  * @param int1 -  INT1 interrupt pins.
361  * @param int2 -  INT2 interrupt pins.
362  * @return 0 in case of success, negative error code otherwise.
363  */
adxl372_interrupt_config(const struct device * dev,uint8_t int1,uint8_t int2)364 static int adxl372_interrupt_config(const struct device *dev,
365 				    uint8_t int1,
366 				    uint8_t int2)
367 {
368 	int ret;
369 	struct adxl372_data *data = dev->data;
370 
371 	ret = data->hw_tf->write_reg(dev, ADXL372_INT1_MAP, int1);
372 	if (ret) {
373 		return ret;
374 	}
375 
376 	return  data->hw_tf->write_reg(dev, ADXL372_INT2_MAP, int2);
377 
378 }
379 
380 /**
381  * Get the STATUS, STATUS2, FIFO_ENTRIES and FIFO_ENTRIES2 registers data
382  * @param dev - The device structure.
383  * @param status1 - Data stored in the STATUS1 register
384  * @param status2 - Data stored in the STATUS2 register
385  * @param fifo_entries - Number of valid data samples present in the
386  *			 FIFO buffer (0 to 512)
387  * @return 0 in case of success, negative error code otherwise.
388  */
adxl372_get_status(const struct device * dev,uint8_t * status1,uint8_t * status2,uint16_t * fifo_entries)389 int adxl372_get_status(const struct device *dev,
390 			   uint8_t *status1,
391 			   uint8_t *status2,
392 			   uint16_t *fifo_entries)
393 {
394 	struct adxl372_data *data = dev->data;
395 	uint8_t buf[4], length = 1U;
396 	int ret;
397 
398 	if (status2) {
399 		length++;
400 	}
401 
402 	if (fifo_entries) {
403 		if (status2) {
404 			length += 2U;
405 		} else {
406 			/* Registers STATUS1, STATUS2, FIFO_ENTRIES2 and FIFO_ENTRIES1
407 			 * are one after the other. If user wants fifo_entries and
408 			 * not status2, to get the correct values, STATUS2 register
409 			 * also must be read but read value will be ignored.
410 			 */
411 			length += 3U;
412 		}
413 	}
414 
415 	ret = data->hw_tf->read_reg_multiple(dev, ADXL372_STATUS_1, buf, length);
416 
417 	*status1 = buf[0];
418 
419 	if (status2) {
420 		*status2 = buf[1];
421 	}
422 
423 	if (fifo_entries) {
424 		*fifo_entries = ((buf[2] & 0x3) << 8) | buf[3];
425 	}
426 
427 	return ret;
428 }
429 
430 /**
431  * Software reset.
432  * @param dev - The device structure.
433  * @return 0 in case of success, negative error code otherwise.
434  */
adxl372_reset(const struct device * dev)435 static int adxl372_reset(const struct device *dev)
436 {
437 	int ret;
438 	struct adxl372_data *data = dev->data;
439 
440 	ret = adxl372_set_op_mode(dev, ADXL372_STANDBY);
441 	if (ret) {
442 		return ret;
443 	}
444 	/* Writing code 0x52 resets the device */
445 	ret = data->hw_tf->write_reg(dev, ADXL372_RESET, ADXL372_RESET_CODE);
446 	k_sleep(K_MSEC(1));
447 
448 	return ret;
449 }
450 
451 /**
452  * Configure the operating parameters for the FIFO.
453  * @param dev - The device structure.
454  * @param mode - FIFO Mode. Specifies FIFO operating mode.
455  *		Accepted values: ADXL372_FIFO_BYPASSED
456  *				 ADXL372_FIFO_STREAMED
457  *				 ADXL372_FIFO_TRIGGERED
458  *				 ADXL372_FIFO_OLD_SAVED
459  * @param format - FIFO Format. Specifies the data is stored in the FIFO buffer.
460  *		Accepted values: ADXL372_XYZ_FIFO
461  *				 ADXL372_X_FIFO
462  *				 ADXL372_Y_FIFO
463  *				 ADXL372_XY_FIFO
464  *				 ADXL372_Z_FIFO
465  *				 ADXL372_XZ_FIFO
466  *				 ADXL372_YZ_FIFO
467  *				 ADXL372_XYZ_PEAK_FIFO
468  * @param fifo_samples - FIFO Samples. Watermark number of FIFO samples that
469  *			triggers a FIFO_FULL condition when reached.
470  *			Values range from 0 to 512.
471  * @return 0 in case of success, negative error code otherwise.
472  */
adxl372_configure_fifo(const struct device * dev,enum adxl372_fifo_mode mode,enum adxl372_fifo_format format,uint16_t fifo_samples)473 int adxl372_configure_fifo(const struct device *dev, enum adxl372_fifo_mode mode,
474 			   enum adxl372_fifo_format format, uint16_t fifo_samples)
475 {
476 	struct adxl372_data *data = dev->data;
477 	uint8_t fifo_config;
478 	int ret;
479 
480 	if (fifo_samples > 512) {
481 		return -EINVAL;
482 	}
483 
484 	/*
485 	 * All FIFO modes must be configured while in standby mode.
486 	 */
487 	ret = adxl372_set_op_mode(dev, ADXL372_STANDBY);
488 	if (ret) {
489 		return ret;
490 	}
491 
492 	fifo_config = (ADXL372_FIFO_CTL_FORMAT_MODE(format) |
493 		       ADXL372_FIFO_CTL_MODE_MODE(mode) |
494 		       ADXL372_FIFO_CTL_SAMPLES_MODE(fifo_samples));
495 
496 	ret = data->hw_tf->write_reg(dev, ADXL372_FIFO_CTL, fifo_config);
497 	if (ret) {
498 		return ret;
499 	}
500 	ret = data->hw_tf->write_reg(dev, ADXL372_FIFO_SAMPLES, fifo_samples & 0xFF);
501 	if (ret) {
502 		return ret;
503 	}
504 
505 	data->fifo_config.fifo_format = format;
506 	data->fifo_config.fifo_mode = mode;
507 	data->fifo_config.fifo_samples = fifo_samples;
508 
509 	return 0;
510 }
511 
512 /**
513  * Retrieve 3-axis acceleration data
514  * @param dev - The device structure.
515  * @param maxpeak - Retrieve the highest magnitude (x, y, z) sample recorded
516  *		    since the last read of the MAXPEAK registers
517  * @param accel_data - pointer to a variable of type adxl372_xyz_accel_data
518  *		      where (x, y, z) acceleration data will be stored.
519  * @return 0 in case of success, negative error code otherwise.
520  */
adxl372_get_accel_data(const struct device * dev,bool maxpeak,struct adxl372_xyz_accel_data * accel_data)521 int adxl372_get_accel_data(const struct device *dev, bool maxpeak,
522 			   struct adxl372_xyz_accel_data *accel_data)
523 {
524 	struct adxl372_data *data = dev->data;
525 	uint8_t buf[6];
526 	uint8_t status1;
527 	int ret;
528 
529 	if (!IS_ENABLED(CONFIG_ADXL372_TRIGGER)) {
530 		do {
531 			adxl372_get_status(dev, &status1, NULL, NULL);
532 		} while (!(ADXL372_STATUS_1_DATA_RDY(status1)));
533 	}
534 
535 	ret = data->hw_tf->read_reg_multiple(dev, maxpeak ? ADXL372_X_MAXPEAK_H :
536 					     ADXL372_X_DATA_H, buf, 6);
537 #ifdef CONFIG_ADXL372_STREAM
538 	accel_data->is_fifo = 0;
539 #endif /* CONFIG_ADXL372_STREAM */
540 	accel_data->x = (buf[0] << 8) | (buf[1] & 0xF0);
541 	accel_data->y = (buf[2] << 8) | (buf[3] & 0xF0);
542 	accel_data->z = (buf[4] << 8) | (buf[5] & 0xF0);
543 
544 	return ret;
545 }
546 
adxl372_attr_set_odr(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,const struct sensor_value * val)547 static int adxl372_attr_set_odr(const struct device *dev,
548 				enum sensor_channel chan,
549 				enum sensor_attribute attr,
550 				const struct sensor_value *val)
551 {
552 	enum adxl372_odr odr;
553 	struct adxl372_dev_config *cfg = (struct adxl372_dev_config *)dev->config;
554 
555 	switch (val->val1) {
556 	case 400:
557 		odr = ADXL372_ODR_400HZ;
558 		break;
559 	case 800:
560 		odr = ADXL372_ODR_800HZ;
561 		break;
562 	case 1600:
563 		odr = ADXL372_ODR_1600HZ;
564 		break;
565 	case 3200:
566 		odr = ADXL372_ODR_3200HZ;
567 		break;
568 	case 6400:
569 		odr = ADXL372_ODR_6400HZ;
570 		break;
571 	default:
572 		return -EINVAL;
573 	}
574 
575 	int ret = adxl372_set_odr(dev, odr);
576 
577 	if (ret == 0) {
578 		cfg->odr = odr;
579 	}
580 
581 	return ret;
582 }
583 
adxl372_attr_set_thresh(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,const struct sensor_value * val)584 static int adxl372_attr_set_thresh(const struct device *dev,
585 				   enum sensor_channel chan,
586 				   enum sensor_attribute attr,
587 				   const struct sensor_value *val)
588 {
589 	const struct adxl372_dev_config *cfg = dev->config;
590 	struct adxl372_activity_threshold threshold;
591 	int64_t llvalue;
592 	int32_t value;
593 	int64_t micro_ms2 = val->val1 * 1000000LL + val->val2;
594 	uint8_t reg;
595 
596 	llvalue = llabs((micro_ms2 * 10) / SENSOR_G);
597 
598 	if (llvalue > 2047) {
599 		return -EINVAL;
600 	}
601 
602 	value = (int32_t) llvalue;
603 
604 	threshold.thresh = value;
605 	threshold.enable = cfg->activity_th.enable;
606 	threshold.referenced = cfg->activity_th.referenced;
607 
608 	if (attr ==  SENSOR_ATTR_UPPER_THRESH) {
609 		reg = ADXL372_X_THRESH_ACT_H;
610 	} else {
611 		reg = ADXL372_X_THRESH_INACT_H;
612 	}
613 
614 	switch (chan) {
615 	case SENSOR_CHAN_ACCEL_X:
616 		return adxl372_set_activity_threshold(dev, reg, &threshold);
617 	case SENSOR_CHAN_ACCEL_Y:
618 		return adxl372_set_activity_threshold(dev, reg + 2, &threshold);
619 	case SENSOR_CHAN_ACCEL_Z:
620 		return adxl372_set_activity_threshold(dev, reg + 4, &threshold);
621 	case SENSOR_CHAN_ACCEL_XYZ:
622 		return adxl372_set_activity_threshold_xyz(dev, reg, &threshold);
623 	default:
624 		LOG_ERR("attr_set() not supported on this channel");
625 		return -ENOTSUP;
626 	}
627 }
628 
adxl372_attr_set(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,const struct sensor_value * val)629 static int adxl372_attr_set(const struct device *dev,
630 			    enum sensor_channel chan,
631 			    enum sensor_attribute attr,
632 			    const struct sensor_value *val)
633 {
634 	switch (attr) {
635 	case SENSOR_ATTR_SAMPLING_FREQUENCY:
636 		return adxl372_attr_set_odr(dev, chan, attr, val);
637 	case SENSOR_ATTR_UPPER_THRESH:
638 	case SENSOR_ATTR_LOWER_THRESH:
639 		return adxl372_attr_set_thresh(dev, chan, attr, val);
640 	default:
641 		return -ENOTSUP;
642 	}
643 }
644 
adxl372_sample_fetch(const struct device * dev,enum sensor_channel chan)645 static int adxl372_sample_fetch(const struct device *dev,
646 				enum sensor_channel chan)
647 {
648 	const struct adxl372_dev_config *cfg = dev->config;
649 	struct adxl372_data *data = dev->data;
650 
651 	return adxl372_get_accel_data(dev, cfg->max_peak_detect_mode,
652 				      &data->sample);
653 }
654 
adxl372_accel_convert(struct sensor_value * val,int16_t value)655 void adxl372_accel_convert(struct sensor_value *val, int16_t value)
656 {
657 	/*
658 	 * Sensor resolution is 100mg/LSB, 12-bit value needs to be right
659 	 * shifted by 4 or divided by 16. Overall this results in a scale of 160
660 	 */
661 	int32_t micro_ms2 = value * (SENSOR_G / (16 * 1000 / 100));
662 
663 	val->val1 = micro_ms2 / 1000000;
664 	val->val2 = micro_ms2 % 1000000;
665 }
666 
adxl372_channel_get(const struct device * dev,enum sensor_channel chan,struct sensor_value * val)667 static int adxl372_channel_get(const struct device *dev,
668 			       enum sensor_channel chan,
669 			       struct sensor_value *val)
670 {
671 	struct adxl372_data *data = dev->data;
672 
673 	switch (chan) {
674 	case SENSOR_CHAN_ACCEL_X:
675 		adxl372_accel_convert(val, data->sample.x);
676 		break;
677 	case SENSOR_CHAN_ACCEL_Y:
678 		adxl372_accel_convert(val, data->sample.y);
679 		break;
680 	case SENSOR_CHAN_ACCEL_Z:
681 		adxl372_accel_convert(val, data->sample.z);
682 		break;
683 	case SENSOR_CHAN_ACCEL_XYZ:
684 		adxl372_accel_convert(val++, data->sample.x);
685 		adxl372_accel_convert(val++, data->sample.y);
686 		adxl372_accel_convert(val, data->sample.z);
687 		break;
688 	default:
689 		return -ENOTSUP;
690 	}
691 
692 	return 0;
693 }
694 
695 static DEVICE_API(sensor, adxl372_api_funcs) = {
696 	.attr_set = adxl372_attr_set,
697 	.sample_fetch = adxl372_sample_fetch,
698 	.channel_get = adxl372_channel_get,
699 #ifdef CONFIG_ADXL372_TRIGGER
700 	.trigger_set = adxl372_trigger_set,
701 #endif
702 #ifdef CONFIG_SENSOR_ASYNC_API
703 	.submit = adxl372_submit,
704 	.get_decoder = adxl372_get_decoder,
705 #endif /* CONFIG_SENSOR_ASYNC_API */
706 
707 };
708 
adxl372_probe(const struct device * dev)709 static int adxl372_probe(const struct device *dev)
710 {
711 	const struct adxl372_dev_config *cfg = dev->config;
712 	struct adxl372_data *data = dev->data;
713 	uint8_t dev_id, part_id;
714 	int ret;
715 
716 	ret = data->hw_tf->read_reg(dev, ADXL372_DEVID, &dev_id);
717 	if (ret) {
718 		return ret;
719 	}
720 	ret = data->hw_tf->read_reg(dev, ADXL372_PARTID, &part_id);
721 	if (ret) {
722 		return ret;
723 	}
724 
725 	if (dev_id != ADXL372_DEVID_VAL || part_id != ADXL372_PARTID_VAL) {
726 		LOG_ERR("failed to read id (0x%X:0x%X)", dev_id, part_id);
727 		return -ENODEV;
728 	}
729 
730 #ifdef CONFIG_ADXL372_TRIGGER
731 	data->act_proc_mode = ADXL372_LINKED,
732 #else
733 	data->act_proc_mode = ADXL372_LOOPED,
734 #endif
735 
736 	/* Device settings */
737 	ret = adxl372_set_op_mode(dev, ADXL372_STANDBY);
738 	if (ret) {
739 		return ret;
740 	}
741 
742 	ret = adxl372_reset(dev);
743 	if (ret) {
744 		return ret;
745 	}
746 
747 	ret = adxl372_set_hpf_corner(dev, cfg->hpf);
748 	if (ret) {
749 		return ret;
750 	}
751 
752 	ret = adxl372_set_bandwidth(dev, cfg->bw);
753 	if (ret) {
754 		return ret;
755 	}
756 
757 	ret = adxl372_set_odr(dev, cfg->odr);
758 	if (ret) {
759 		return ret;
760 	}
761 
762 	ret = adxl372_set_wakeup_rate(dev, cfg->wur);
763 	if (ret) {
764 		return ret;
765 	}
766 
767 	ret = adxl372_set_autosleep(dev, cfg->autosleep);
768 	if (ret) {
769 		return ret;
770 	}
771 
772 	ret = adxl372_set_instant_on_th(dev, cfg->th_mode);
773 	if (ret) {
774 		return ret;
775 	}
776 
777 	ret = adxl372_set_activity_threshold_xyz(dev, ADXL372_X_THRESH_ACT_H,
778 						 &cfg->activity_th);
779 	if (ret) {
780 		return ret;
781 	}
782 
783 	ret = adxl372_set_activity_threshold_xyz(dev, ADXL372_X_THRESH_INACT_H,
784 						 &cfg->inactivity_th);
785 	if (ret) {
786 		return ret;
787 	}
788 
789 	ret = adxl372_set_activity_time(dev, cfg->activity_time);
790 	if (ret) {
791 		return ret;
792 	}
793 
794 	ret = adxl372_set_inactivity_time(dev, cfg->inactivity_time);
795 	if (ret) {
796 		return ret;
797 	}
798 
799 	ret = adxl372_set_filter_settle(dev, cfg->filter_settle);
800 	if (ret) {
801 		return ret;
802 	}
803 
804 	ret = adxl372_configure_fifo(dev, cfg->fifo_config.fifo_mode,
805 				     cfg->fifo_config.fifo_format,
806 				     cfg->fifo_config.fifo_samples);
807 	if (ret) {
808 		return ret;
809 	}
810 
811 #ifdef CONFIG_ADXL372_TRIGGER
812 	if (adxl372_init_interrupt(dev) < 0) {
813 		LOG_ERR("Failed to initialize interrupt!");
814 		return -EIO;
815 	}
816 #endif
817 
818 	ret = adxl372_interrupt_config(dev, cfg->int1_config, cfg->int2_config);
819 	if (ret) {
820 		return ret;
821 	}
822 
823 	ret = adxl372_set_op_mode(dev, cfg->op_mode);
824 	if (ret) {
825 		return ret;
826 	}
827 
828 	return adxl372_set_act_proc_mode(dev, data->act_proc_mode);
829 }
830 
adxl372_init(const struct device * dev)831 static int adxl372_init(const struct device *dev)
832 {
833 	int ret;
834 	const struct adxl372_dev_config *cfg = dev->config;
835 
836 	ret = cfg->bus_init(dev);
837 	if (ret < 0) {
838 		LOG_ERR("Failed to initialize sensor bus");
839 		return ret;
840 	}
841 
842 	if (adxl372_probe(dev) < 0) {
843 		return -ENODEV;
844 	}
845 
846 	return 0;
847 }
848 
849 #if DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 0
850 #warning "ADXL372 driver enabled without any devices"
851 #endif
852 
853 /*
854  * Device creation macro, shared by ADXL372_DEFINE_SPI() and
855  * ADXL372_DEFINE_I2C().
856  */
857 
858 #define ADXL372_DEVICE_INIT(inst)					\
859 	SENSOR_DEVICE_DT_INST_DEFINE(inst,				\
860 			      adxl372_init,				\
861 			      NULL,					\
862 			      &adxl372_data_##inst,			\
863 			      &adxl372_config_##inst,			\
864 			      POST_KERNEL,				\
865 			      CONFIG_SENSOR_INIT_PRIORITY,		\
866 			      &adxl372_api_funcs);
867 
868 /*
869  * Instantiation macros used when a device is on a SPI bus.
870  */
871 #define ADXL372_SPI_CFG SPI_WORD_SET(8) | SPI_TRANSFER_MSB
872 
873 #define ADXL372_RTIO_DEFINE(inst)                                                                  \
874 	SPI_DT_IODEV_DEFINE(adxl372_iodev_##inst, DT_DRV_INST(inst), ADXL372_SPI_CFG, 0U);         \
875 	RTIO_DEFINE(adxl372_rtio_ctx_##inst, 16, 16);
876 
877 #ifdef CONFIG_ADXL372_TRIGGER
878 #define ADXL372_CFG_IRQ(inst) \
879 		.interrupt = GPIO_DT_SPEC_INST_GET(inst, int1_gpios),
880 #else
881 #define ADXL372_CFG_IRQ(inst)
882 #endif /* CONFIG_ADXL372_TRIGGER */
883 
884 #define ADXL372_CONFIG(inst)								\
885 		.bw = DT_INST_PROP(inst, bw),						\
886 		.hpf = DT_INST_PROP(inst, hpf),						\
887 		.odr = DT_INST_PROP(inst, odr),						\
888 		.max_peak_detect_mode = IS_ENABLED(CONFIG_ADXL372_PEAK_DETECT_MODE),	\
889 		.th_mode = ADXL372_INSTANT_ON_LOW_TH,					\
890 		.autosleep = false,							\
891 		.wur = ADXL372_WUR_52ms,						\
892 		.activity_th.thresh = CONFIG_ADXL372_ACTIVITY_THRESHOLD / 100,		\
893 		.activity_th.referenced =						\
894 			IS_ENABLED(CONFIG_ADXL372_REFERENCED_ACTIVITY_DETECTION_MODE),	\
895 		.activity_th.enable = 1,						\
896 		.activity_time = CONFIG_ADXL372_ACTIVITY_TIME,				\
897 		.inactivity_th.thresh = CONFIG_ADXL372_INACTIVITY_THRESHOLD / 100,	\
898 		.inactivity_th.referenced =						\
899 			IS_ENABLED(CONFIG_ADXL372_REFERENCED_ACTIVITY_DETECTION_MODE),	\
900 		.inactivity_th.enable = 1,						\
901 		.inactivity_time = CONFIG_ADXL372_INACTIVITY_TIME,			\
902 		.filter_settle = ADXL372_FILTER_SETTLE_370,				\
903 		.fifo_config.fifo_mode = ADXL372_FIFO_STREAMED,				\
904 		.fifo_config.fifo_format = ADXL372_XYZ_PEAK_FIFO,			\
905 		.fifo_config.fifo_samples = 128,					\
906 		.op_mode = ADXL372_FULL_BW_MEASUREMENT,					\
907 
908 #define ADXL372_CONFIG_SPI(inst)					\
909 	{								\
910 		.bus_init = adxl372_spi_init,				\
911 		.spi = SPI_DT_SPEC_INST_GET(inst, ADXL372_SPI_CFG, 0),		\
912 		ADXL372_CONFIG(inst)					\
913 		COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, int1_gpios),	\
914 		(ADXL372_CFG_IRQ(inst)), ())				\
915 	}
916 
917 #define ADXL372_DEFINE_SPI(inst)					\
918 	IF_ENABLED(CONFIG_ADXL372_STREAM, (ADXL372_RTIO_DEFINE(inst)));                          \
919 	static struct adxl372_data adxl372_data_##inst = {			\
920 	IF_ENABLED(CONFIG_ADXL372_STREAM, (.rtio_ctx = &adxl372_rtio_ctx_##inst,                  \
921 				.iodev = &adxl372_iodev_##inst,)) \
922 	};     \
923 	static const struct adxl372_dev_config adxl372_config_##inst =	\
924 		ADXL372_CONFIG_SPI(inst);				\
925 	ADXL372_DEVICE_INIT(inst)
926 
927 /*
928  * Instantiation macros used when a device is on an I2C bus.
929  */
930 
931 #define ADXL372_CONFIG_I2C(inst)					\
932 	{								\
933 		.bus_init = adxl372_i2c_init,				\
934 		.i2c = I2C_DT_SPEC_INST_GET(inst),			\
935 		ADXL372_CONFIG(inst)					\
936 		COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, int1_gpios),	\
937 		(ADXL372_CFG_IRQ(inst)), ())				\
938 	}
939 
940 #define ADXL372_DEFINE_I2C(inst)					\
941 	static struct adxl372_data adxl372_data_##inst;			\
942 	static const struct adxl372_dev_config adxl372_config_##inst =	\
943 		ADXL372_CONFIG_I2C(inst);				\
944 	ADXL372_DEVICE_INIT(inst)
945 /*
946  * Main instantiation macro. Use of COND_CODE_1() selects the right
947  * bus-specific macro at preprocessor time.
948  */
949 
950 #define ADXL372_DEFINE(inst)						\
951 	COND_CODE_1(DT_INST_ON_BUS(inst, spi),				\
952 		    (ADXL372_DEFINE_SPI(inst)),				\
953 		    (ADXL372_DEFINE_I2C(inst)))
954 
955 DT_INST_FOREACH_STATUS_OKAY(ADXL372_DEFINE)
956