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 = ®,
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 ®_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