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