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