1 /* adxl362.c - ADXL362 Three-Axis Digital Accelerometers */
2
3 /*
4 * Copyright (c) 2017 IpTronix S.r.l.
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
8
9 #define DT_DRV_COMPAT adi_adxl362
10
11 #include <zephyr/kernel.h>
12 #include <zephyr/devicetree.h>
13 #include <string.h>
14 #include <zephyr/drivers/sensor.h>
15 #include <zephyr/init.h>
16 #include <zephyr/drivers/gpio.h>
17 #include <zephyr/sys/byteorder.h>
18 #include <zephyr/sys/__assert.h>
19 #include <zephyr/drivers/spi.h>
20 #include <zephyr/logging/log.h>
21
22 #include "adxl362.h"
23
24 LOG_MODULE_REGISTER(ADXL362, CONFIG_SENSOR_LOG_LEVEL);
25
adxl362_reg_access(const struct device * dev,uint8_t cmd,uint8_t reg_addr,void * data,size_t length)26 int adxl362_reg_access(const struct device *dev, uint8_t cmd,
27 uint8_t reg_addr, void *data, size_t length)
28 {
29 const struct adxl362_config *cfg = dev->config;
30 uint8_t access[2] = { cmd, reg_addr };
31 const struct spi_buf buf[2] = {
32 {
33 .buf = access,
34 .len = 2
35 },
36 {
37 .buf = data,
38 .len = length
39 }
40 };
41 struct spi_buf_set tx = {
42 .buffers = buf,
43 };
44
45 if (cmd == ADXL362_READ_REG) {
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(&cfg->bus, &tx, &rx);
54 }
55
56 tx.count = 2;
57
58 return spi_write_dt(&cfg->bus, &tx);
59 }
60
adxl362_set_reg(const struct device * dev,uint16_t register_value,uint8_t register_address,uint8_t count)61 static inline int adxl362_set_reg(const struct device *dev,
62 uint16_t register_value,
63 uint8_t register_address, uint8_t count)
64 {
65 return adxl362_reg_access(dev, ADXL362_WRITE_REG,
66 register_address, ®ister_value, count);
67 }
68
adxl362_reg_write_mask(const struct device * dev,uint8_t register_address,uint8_t mask,uint8_t data)69 int adxl362_reg_write_mask(const struct device *dev, uint8_t register_address,
70 uint8_t mask, uint8_t data)
71 {
72 int ret;
73 uint8_t tmp;
74
75 ret = adxl362_reg_access(dev, ADXL362_READ_REG,
76 register_address, &tmp, 1);
77
78 if (ret) {
79 return ret;
80 }
81
82 tmp &= ~mask;
83 tmp |= data;
84
85 return adxl362_reg_access(dev, ADXL362_WRITE_REG,
86 register_address, &tmp, 1);
87 }
88
adxl362_get_reg(const struct device * dev,uint8_t * read_buf,uint8_t register_address,uint8_t count)89 static inline int adxl362_get_reg(const struct device *dev, uint8_t *read_buf,
90 uint8_t register_address, uint8_t count)
91 {
92
93 return adxl362_reg_access(dev, ADXL362_READ_REG,
94 register_address, read_buf, count);
95 }
96
97 #if defined(CONFIG_ADXL362_TRIGGER)
adxl362_interrupt_config(const struct device * dev,uint8_t int1,uint8_t int2)98 static int adxl362_interrupt_config(const struct device *dev,
99 uint8_t int1,
100 uint8_t int2)
101 {
102 int ret;
103
104 ret = adxl362_reg_access(dev, ADXL362_WRITE_REG,
105 ADXL362_REG_INTMAP1, &int1, 1);
106
107 if (ret) {
108 return ret;
109 }
110
111 return ret = adxl362_reg_access(dev, ADXL362_WRITE_REG,
112 ADXL362_REG_INTMAP2, &int2, 1);
113 }
114
adxl362_get_status(const struct device * dev,uint8_t * status)115 int adxl362_get_status(const struct device *dev, uint8_t *status)
116 {
117 return adxl362_get_reg(dev, status, ADXL362_REG_STATUS, 1);
118 }
119
adxl362_clear_data_ready(const struct device * dev)120 int adxl362_clear_data_ready(const struct device *dev)
121 {
122 uint8_t buf;
123 /* Reading any data register clears the data ready interrupt */
124 return adxl362_get_reg(dev, &buf, ADXL362_REG_XDATA, 1);
125 }
126 #endif
127
adxl362_software_reset(const struct device * dev)128 static int adxl362_software_reset(const struct device *dev)
129 {
130 return adxl362_set_reg(dev, ADXL362_RESET_KEY,
131 ADXL362_REG_SOFT_RESET, 1);
132 }
133
134 #if defined(CONFIG_ADXL362_ACCEL_ODR_RUNTIME)
135 /*
136 * Output data rate map with allowed frequencies:
137 * freq = freq_int + freq_milli / 1000
138 *
139 * Since we don't need a finer frequency resolution than milliHz, use uint16_t
140 * to save some flash.
141 */
142 static const struct {
143 uint16_t freq_int;
144 uint16_t freq_milli; /* User should convert to uHz before setting the
145 * SENSOR_ATTR_SAMPLING_FREQUENCY attribute.
146 */
147 } adxl362_odr_map[] = {
148 { 12, 500 },
149 { 25, 0 },
150 { 50, 0 },
151 { 100, 0 },
152 { 200, 0 },
153 { 400, 0 },
154 };
155
adxl362_freq_to_odr_val(uint16_t freq_int,uint16_t freq_milli)156 static int adxl362_freq_to_odr_val(uint16_t freq_int, uint16_t freq_milli)
157 {
158 size_t i;
159
160 /* An ODR of 0 Hz is not allowed */
161 if (freq_int == 0U && freq_milli == 0U) {
162 return -EINVAL;
163 }
164
165 for (i = 0; i < ARRAY_SIZE(adxl362_odr_map); i++) {
166 if (freq_int < adxl362_odr_map[i].freq_int ||
167 (freq_int == adxl362_odr_map[i].freq_int &&
168 freq_milli <= adxl362_odr_map[i].freq_milli)) {
169 return i;
170 }
171 }
172
173 return -EINVAL;
174 }
175 #endif /* CONFIG_ADXL362_ACCEL_ODR_RUNTIME */
176
177 #if defined(CONFIG_ADXL362_ACCEL_RANGE_RUNTIME)
178 static const struct adxl362_range {
179 uint16_t range;
180 uint8_t reg_val;
181 } adxl362_acc_range_map[] = {
182 {2, ADXL362_RANGE_2G},
183 {4, ADXL362_RANGE_4G},
184 {8, ADXL362_RANGE_8G},
185 };
186
adxl362_range_to_reg_val(uint16_t range)187 static int32_t adxl362_range_to_reg_val(uint16_t range)
188 {
189 int i;
190
191 for (i = 0; i < ARRAY_SIZE(adxl362_acc_range_map); i++) {
192 if (range <= adxl362_acc_range_map[i].range) {
193 return adxl362_acc_range_map[i].reg_val;
194 }
195 }
196
197 return -EINVAL;
198 }
199 #endif /* CONFIG_ADXL362_ACCEL_RANGE_RUNTIME */
200
adxl362_set_range(const struct device * dev,uint8_t range)201 static int adxl362_set_range(const struct device *dev, uint8_t range)
202 {
203 struct adxl362_data *adxl362_data = dev->data;
204 uint8_t old_filter_ctl;
205 uint8_t new_filter_ctl;
206 int ret;
207
208 ret = adxl362_get_reg(dev, &old_filter_ctl, ADXL362_REG_FILTER_CTL, 1);
209 if (ret) {
210 return ret;
211 }
212
213 new_filter_ctl = old_filter_ctl & ~ADXL362_FILTER_CTL_RANGE(0x3);
214 new_filter_ctl = new_filter_ctl | ADXL362_FILTER_CTL_RANGE(range);
215 ret = adxl362_set_reg(dev, new_filter_ctl, ADXL362_REG_FILTER_CTL, 1);
216 if (ret) {
217 return ret;
218 }
219
220 adxl362_data->selected_range = range;
221 return 0;
222 }
223
adxl362_set_output_rate(const struct device * dev,uint8_t out_rate)224 static int adxl362_set_output_rate(const struct device *dev, uint8_t out_rate)
225 {
226 int ret;
227 uint8_t old_filter_ctl;
228 uint8_t new_filter_ctl;
229 struct adxl362_data *adxl362_data = dev->data;
230
231 ret = adxl362_get_reg(dev, &old_filter_ctl, ADXL362_REG_FILTER_CTL, 1);
232 if (ret) {
233 return ret;
234 }
235
236 new_filter_ctl = old_filter_ctl & ~ADXL362_FILTER_CTL_ODR(0x7);
237 new_filter_ctl = new_filter_ctl | ADXL362_FILTER_CTL_ODR(out_rate);
238 adxl362_data->accel_odr = out_rate;
239 return adxl362_set_reg(dev, new_filter_ctl, ADXL362_REG_FILTER_CTL, 1);
240 }
241
242
axl362_acc_config(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,const struct sensor_value * val)243 static int axl362_acc_config(const struct device *dev,
244 enum sensor_channel chan,
245 enum sensor_attribute attr,
246 const struct sensor_value *val)
247 {
248 switch (attr) {
249 #if defined(CONFIG_ADXL362_ACCEL_RANGE_RUNTIME)
250 case SENSOR_ATTR_FULL_SCALE:
251 {
252 int range_reg;
253
254 range_reg = adxl362_range_to_reg_val(sensor_ms2_to_g(val));
255 if (range_reg < 0) {
256 LOG_DBG("invalid range requested.");
257 return -ENOTSUP;
258 }
259
260 return adxl362_set_range(dev, range_reg);
261 }
262 break;
263 #endif
264 #if defined(CONFIG_ADXL362_ACCEL_ODR_RUNTIME)
265 case SENSOR_ATTR_SAMPLING_FREQUENCY:
266 {
267 int out_rate;
268
269 out_rate = adxl362_freq_to_odr_val(val->val1,
270 val->val2 / 1000);
271 if (out_rate < 0) {
272 LOG_DBG("invalid output rate.");
273 return -ENOTSUP;
274 }
275
276 return adxl362_set_output_rate(dev, out_rate);
277 }
278 break;
279 #endif
280 default:
281 LOG_DBG("Accel attribute not supported.");
282 return -ENOTSUP;
283 }
284
285 return 0;
286 }
287
adxl362_attr_set_thresh(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,const struct sensor_value * val)288 static int adxl362_attr_set_thresh(const struct device *dev,
289 enum sensor_channel chan,
290 enum sensor_attribute attr,
291 const struct sensor_value *val)
292 {
293 uint8_t reg;
294 uint16_t threshold = val->val1;
295 size_t ret;
296
297 if (chan != SENSOR_CHAN_ACCEL_X &&
298 chan != SENSOR_CHAN_ACCEL_Y &&
299 chan != SENSOR_CHAN_ACCEL_Z) {
300 return -EINVAL;
301 }
302
303 if (threshold > 2047) {
304 return -EINVAL;
305 }
306
307 /* Configure motion threshold. */
308 if (attr == SENSOR_ATTR_UPPER_THRESH) {
309 reg = ADXL362_REG_THRESH_ACT_L;
310 } else {
311 reg = ADXL362_REG_THRESH_INACT_L;
312 }
313
314 ret = adxl362_set_reg(dev, (threshold & 0x7FF), reg, 2);
315
316 return ret;
317 }
318
adxl362_attr_set(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,const struct sensor_value * val)319 static int adxl362_attr_set(const struct device *dev,
320 enum sensor_channel chan,
321 enum sensor_attribute attr,
322 const struct sensor_value *val)
323 {
324 switch (attr) {
325 case SENSOR_ATTR_UPPER_THRESH:
326 case SENSOR_ATTR_LOWER_THRESH:
327 return adxl362_attr_set_thresh(dev, chan, attr, val);
328 case SENSOR_ATTR_HYSTERESIS:
329 {
330 uint16_t timeout = val->val1;
331
332 return adxl362_set_reg(dev, timeout, ADXL362_REG_TIME_INACT_L, 2);
333 }
334 default:
335 /* Do nothing */
336 break;
337 }
338
339 switch (chan) {
340 case SENSOR_CHAN_ACCEL_X:
341 case SENSOR_CHAN_ACCEL_Y:
342 case SENSOR_CHAN_ACCEL_Z:
343 case SENSOR_CHAN_ACCEL_XYZ:
344 return axl362_acc_config(dev, chan, attr, val);
345 default:
346 LOG_DBG("attr_set() not supported on this channel.");
347 return -ENOTSUP;
348 }
349
350 return 0;
351 }
352
353 #ifdef CONFIG_ADXL362_STREAM
adxl362_fifo_setup(const struct device * dev,uint8_t mode,uint16_t water_mark_lvl,uint8_t en_temp_read)354 int adxl362_fifo_setup(const struct device *dev, uint8_t mode,
355 uint16_t water_mark_lvl, uint8_t en_temp_read)
356 #else
357 static int adxl362_fifo_setup(const struct device *dev, uint8_t mode,
358 uint16_t water_mark_lvl, uint8_t en_temp_read)
359 #endif /* CONFIG_ADXL362_STREAM */
360 {
361 uint8_t write_val;
362 int ret;
363 #ifdef CONFIG_ADXL362_STREAM
364 struct adxl362_data *data = (struct adxl362_data *)dev->data;
365
366 data->fifo_mode = mode;
367 data->water_mark_lvl = water_mark_lvl;
368 data->en_temp_read = en_temp_read;
369 #endif /* CONFIG_ADXL362_STREAM */
370
371 write_val = ADXL362_FIFO_CTL_FIFO_MODE(mode) |
372 (en_temp_read * ADXL362_FIFO_CTL_FIFO_TEMP);
373
374 if (water_mark_lvl & 0x100) {
375 write_val |= ADXL362_FIFO_CTL_AH;
376 }
377
378 ret = adxl362_set_reg(dev, write_val, ADXL362_REG_FIFO_CTL, 1);
379 if (ret) {
380 return ret;
381 }
382
383 ret = adxl362_set_reg(dev, water_mark_lvl, ADXL362_REG_FIFO_SAMPLES, 1);
384 if (ret) {
385 return ret;
386 }
387
388 return 0;
389 }
390
adxl362_setup_activity_detection(const struct device * dev,uint8_t ref_or_abs,uint16_t threshold,uint8_t time)391 static int adxl362_setup_activity_detection(const struct device *dev,
392 uint8_t ref_or_abs,
393 uint16_t threshold,
394 uint8_t time)
395 {
396 uint8_t old_act_inact_reg;
397 uint8_t new_act_inact_reg;
398 int ret;
399
400 /**
401 * mode
402 * must be one of the following:
403 * ADXL362_FIFO_DISABLE - FIFO is disabled.
404 * ADXL362_FIFO_OLDEST_SAVED - Oldest saved mode.
405 * ADXL362_FIFO_STREAM - Stream mode.
406 * ADXL362_FIFO_TRIGGERED - Triggered mode.
407 * water_mark_lvl
408 * Specifies the number of samples to store in the FIFO.
409 * en_temp_read
410 * Store Temperature Data to FIFO.
411 * 1 - temperature data is stored in the FIFO
412 * together with x-, y- and x-axis data.
413 * 0 - temperature data is skipped.
414 */
415
416 /* Configure motion threshold and activity timer. */
417 ret = adxl362_set_reg(dev, (threshold & 0x7FF),
418 ADXL362_REG_THRESH_ACT_L, 2);
419 if (ret) {
420 return ret;
421 }
422
423 ret = adxl362_set_reg(dev, time, ADXL362_REG_TIME_ACT, 1);
424 if (ret) {
425 return ret;
426 }
427
428 /* Enable activity interrupt and select a referenced or absolute
429 * configuration.
430 */
431 ret = adxl362_get_reg(dev, &old_act_inact_reg,
432 ADXL362_REG_ACT_INACT_CTL, 1);
433 if (ret) {
434 return ret;
435 }
436
437 new_act_inact_reg = old_act_inact_reg & ~ADXL362_ACT_INACT_CTL_ACT_REF;
438 new_act_inact_reg |= ADXL362_ACT_INACT_CTL_ACT_EN |
439 (ref_or_abs * ADXL362_ACT_INACT_CTL_ACT_REF);
440 ret = adxl362_set_reg(dev, new_act_inact_reg,
441 ADXL362_REG_ACT_INACT_CTL, 1);
442 if (ret) {
443 return ret;
444 }
445
446 return 0;
447 }
448
adxl362_setup_inactivity_detection(const struct device * dev,uint8_t ref_or_abs,uint16_t threshold,uint16_t time)449 static int adxl362_setup_inactivity_detection(const struct device *dev,
450 uint8_t ref_or_abs,
451 uint16_t threshold,
452 uint16_t time)
453 {
454 uint8_t old_act_inact_reg;
455 uint8_t new_act_inact_reg;
456 int ret;
457
458 /* Configure motion threshold and inactivity timer. */
459 ret = adxl362_set_reg(dev, (threshold & 0x7FF),
460 ADXL362_REG_THRESH_INACT_L, 2);
461 if (ret) {
462 return ret;
463 }
464
465 ret = adxl362_set_reg(dev, time, ADXL362_REG_TIME_INACT_L, 2);
466 if (ret) {
467 return ret;
468 }
469
470 /* Enable inactivity interrupt and select a referenced or
471 * absolute configuration.
472 */
473 ret = adxl362_get_reg(dev, &old_act_inact_reg,
474 ADXL362_REG_ACT_INACT_CTL, 1);
475 if (ret) {
476 return ret;
477 }
478
479 new_act_inact_reg = old_act_inact_reg &
480 ~ADXL362_ACT_INACT_CTL_INACT_REF;
481 new_act_inact_reg |= ADXL362_ACT_INACT_CTL_INACT_EN |
482 (ref_or_abs * ADXL362_ACT_INACT_CTL_INACT_REF);
483 ret = adxl362_set_reg(dev, new_act_inact_reg,
484 ADXL362_REG_ACT_INACT_CTL, 1);
485 if (ret) {
486 return ret;
487 }
488
489 return 0;
490 }
491
adxl362_set_interrupt_mode(const struct device * dev,uint8_t mode)492 int adxl362_set_interrupt_mode(const struct device *dev, uint8_t mode)
493 {
494 uint8_t old_act_inact_reg;
495 uint8_t new_act_inact_reg;
496 int ret;
497
498 LOG_DBG("Mode: %d", mode);
499
500 if (mode != ADXL362_MODE_DEFAULT &&
501 mode != ADXL362_MODE_LINK &&
502 mode != ADXL362_MODE_LOOP) {
503 LOG_ERR("Wrong mode");
504 return -EINVAL;
505 }
506
507 /* Select desired interrupt mode. */
508 ret = adxl362_get_reg(dev, &old_act_inact_reg,
509 ADXL362_REG_ACT_INACT_CTL, 1);
510 if (ret) {
511 return ret;
512 }
513
514 new_act_inact_reg = old_act_inact_reg &
515 ~ADXL362_ACT_INACT_CTL_LINKLOOP(3);
516 new_act_inact_reg |= old_act_inact_reg |
517 ADXL362_ACT_INACT_CTL_LINKLOOP(mode);
518
519 ret = adxl362_set_reg(dev, new_act_inact_reg,
520 ADXL362_REG_ACT_INACT_CTL, 1);
521
522 if (ret) {
523 return ret;
524 }
525
526 return 0;
527 }
528
adxl362_sample_fetch(const struct device * dev,enum sensor_channel chan)529 static int adxl362_sample_fetch(const struct device *dev,
530 enum sensor_channel chan)
531 {
532 struct adxl362_data *data = dev->data;
533 int16_t buf[4];
534 int ret;
535
536 __ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL);
537
538 ret = adxl362_get_reg(dev, (uint8_t *)buf, ADXL362_REG_XDATA_L,
539 sizeof(buf));
540 if (ret) {
541 return ret;
542 }
543
544 data->acc_x = sys_le16_to_cpu(buf[0]);
545 data->acc_y = sys_le16_to_cpu(buf[1]);
546 data->acc_z = sys_le16_to_cpu(buf[2]);
547 data->temp = sys_le16_to_cpu(buf[3]);
548
549 return 0;
550 }
551
552 #ifdef CONFIG_SENSOR_ASYNC_API
adxl362_rtio_fetch(const struct device * dev,struct adxl362_sample_data * sample_data)553 int adxl362_rtio_fetch(const struct device *dev,
554 struct adxl362_sample_data *sample_data)
555 {
556 struct adxl362_data *data = dev->data;
557 int16_t buf[4];
558 int ret;
559
560 ret = adxl362_get_reg(dev, (uint8_t *)buf, ADXL362_REG_XDATA_L,
561 sizeof(buf));
562 if (ret) {
563 return ret;
564 }
565
566 #ifdef CONFIG_ADXL362_STREAM
567 sample_data->is_fifo = 0;
568 #endif /*CONFIG_ADXL362_STREAM*/
569
570 sample_data->acc_x = sys_le16_to_cpu(buf[0]);
571 sample_data->acc_y = sys_le16_to_cpu(buf[1]);
572 sample_data->acc_z = sys_le16_to_cpu(buf[2]);
573 sample_data->temp = sys_le16_to_cpu(buf[3]);
574 sample_data->selected_range = data->selected_range;
575
576 return 0;
577 }
578 #endif /*CONFIG_SENSOR_ASYNC_API*/
579
adxl362_range_to_scale(int range)580 static inline int adxl362_range_to_scale(int range)
581 {
582 /* See table 1 in specifications section of datasheet */
583 switch (range) {
584 case ADXL362_RANGE_2G:
585 return ADXL362_ACCEL_2G_LSB_PER_G;
586 case ADXL362_RANGE_4G:
587 return ADXL362_ACCEL_4G_LSB_PER_G;
588 case ADXL362_RANGE_8G:
589 return ADXL362_ACCEL_8G_LSB_PER_G;
590 default:
591 return -EINVAL;
592 }
593 }
594
595 #ifdef CONFIG_SENSOR_ASYNC_API
adxl362_accel_convert(struct sensor_value * val,int accel,int range)596 void adxl362_accel_convert(struct sensor_value *val, int accel,
597 int range)
598 #else
599 static void adxl362_accel_convert(struct sensor_value *val, int accel,
600 int range)
601 #endif /*CONFIG_SENSOR_ASYNC_API*/
602 {
603 int scale = adxl362_range_to_scale(range);
604 long micro_ms2 = accel * SENSOR_G / scale;
605
606 __ASSERT_NO_MSG(scale != -EINVAL);
607
608 val->val1 = micro_ms2 / 1000000;
609 val->val2 = micro_ms2 % 1000000;
610 }
611
612 #ifdef CONFIG_SENSOR_ASYNC_API
adxl362_temp_convert(struct sensor_value * val,int temp)613 void adxl362_temp_convert(struct sensor_value *val, int temp)
614 #else
615 static void adxl362_temp_convert(struct sensor_value *val, int temp)
616 #endif /*CONFIG_SENSOR_ASYNC_API*/
617 {
618 /* See sensitivity and bias specifications in table 1 of datasheet */
619 int milli_c = (temp - ADXL362_TEMP_BIAS_LSB) * ADXL362_TEMP_MC_PER_LSB +
620 (ADXL362_TEMP_BIAS_TEST_CONDITION * 1000);
621
622 val->val1 = milli_c / 1000;
623 val->val2 = (milli_c % 1000) * 1000;
624 }
625
adxl362_channel_get(const struct device * dev,enum sensor_channel chan,struct sensor_value * val)626 static int adxl362_channel_get(const struct device *dev,
627 enum sensor_channel chan,
628 struct sensor_value *val)
629 {
630 struct adxl362_data *data = dev->data;
631
632 switch (chan) {
633 case SENSOR_CHAN_ACCEL_X: /* Acceleration on the X axis, in m/s^2. */
634 adxl362_accel_convert(val, data->acc_x, data->selected_range);
635 break;
636 case SENSOR_CHAN_ACCEL_Y: /* Acceleration on the Y axis, in m/s^2. */
637 adxl362_accel_convert(val, data->acc_y, data->selected_range);
638 break;
639 case SENSOR_CHAN_ACCEL_Z: /* Acceleration on the Z axis, in m/s^2. */
640 adxl362_accel_convert(val, data->acc_z, data->selected_range);
641 break;
642 case SENSOR_CHAN_ACCEL_XYZ: /* Acceleration on the XYZ axis, in m/s^2. */
643 for (size_t i = 0; i < 3; i++) {
644 adxl362_accel_convert(&val[i], data->acc_xyz[i], data->selected_range);
645 }
646 break;
647 case SENSOR_CHAN_DIE_TEMP: /* Temperature in degrees Celsius. */
648 adxl362_temp_convert(val, data->temp);
649 break;
650 default:
651 return -ENOTSUP;
652 }
653
654 return 0;
655 }
656
657 static DEVICE_API(sensor, adxl362_api_funcs) = {
658 .attr_set = adxl362_attr_set,
659 .sample_fetch = adxl362_sample_fetch,
660 .channel_get = adxl362_channel_get,
661 #ifdef CONFIG_ADXL362_TRIGGER
662 .trigger_set = adxl362_trigger_set,
663 #endif
664 #ifdef CONFIG_SENSOR_ASYNC_API
665 .submit = adxl362_submit,
666 .get_decoder = adxl362_get_decoder,
667 #endif /* CONFIG_SENSOR_ASYNC_API */
668 };
669
adxl362_chip_init(const struct device * dev)670 static int adxl362_chip_init(const struct device *dev)
671 {
672 const struct adxl362_config *config = dev->config;
673 int ret;
674
675 /* Configures activity detection.
676 * Referenced/Absolute Activity or Inactivity Select.
677 * 0 - absolute mode.
678 * 1 - referenced mode.
679 * threshold
680 * 11-bit unsigned value that the adxl362 samples are
681 * compared to.
682 * time
683 * 8-bit value written to the activity timer register.
684 * The amount of time (in seconds) is:
685 * time / ODR,
686 * where ODR - is the output data rate.
687 */
688 ret =
689 adxl362_setup_activity_detection(dev,
690 CONFIG_ADXL362_ABS_REF_MODE,
691 CONFIG_ADXL362_ACTIVITY_THRESHOLD,
692 CONFIG_ADXL362_ACTIVITY_TIME);
693 if (ret) {
694 return ret;
695 }
696
697 /* Configures inactivity detection.
698 * Referenced/Absolute Activity or Inactivity Select.
699 * 0 - absolute mode.
700 * 1 - referenced mode.
701 * threshold
702 * 11-bit unsigned value that the adxl362 samples are
703 * compared to.
704 * time
705 * 16-bit value written to the activity timer register.
706 * The amount of time (in seconds) is:
707 * time / ODR,
708 * where ODR - is the output data rate.
709 */
710 ret =
711 adxl362_setup_inactivity_detection(dev,
712 CONFIG_ADXL362_ABS_REF_MODE,
713 CONFIG_ADXL362_INACTIVITY_THRESHOLD,
714 CONFIG_ADXL362_INACTIVITY_TIME);
715 if (ret) {
716 return ret;
717 }
718
719 /* Configures the FIFO feature. */
720 ret = adxl362_fifo_setup(dev, ADXL362_FIFO_DISABLE, 0, 0);
721 if (ret) {
722 return ret;
723 }
724
725 /* Selects the measurement range.
726 * options are:
727 * ADXL362_RANGE_2G - +-2 g
728 * ADXL362_RANGE_4G - +-4 g
729 * ADXL362_RANGE_8G - +-8 g
730 */
731 ret = adxl362_set_range(dev, ADXL362_DEFAULT_RANGE_ACC);
732 if (ret) {
733 return ret;
734 }
735
736 /* Selects the Output Data Rate of the device.
737 * Options are:
738 * ADXL362_ODR_12_5_HZ - 12.5Hz
739 * ADXL362_ODR_25_HZ - 25Hz
740 * ADXL362_ODR_50_HZ - 50Hz
741 * ADXL362_ODR_100_HZ - 100Hz
742 * ADXL362_ODR_200_HZ - 200Hz
743 * ADXL362_ODR_400_HZ - 400Hz
744 */
745 ret = adxl362_set_output_rate(dev, ADXL362_DEFAULT_ODR_ACC);
746 if (ret) {
747 return ret;
748 }
749
750 /* Places the device into measure mode, enable wakeup mode and autosleep if desired. */
751 LOG_DBG("setting pwrctl: 0x%02x", config->power_ctl);
752 ret = adxl362_set_reg(dev, config->power_ctl, ADXL362_REG_POWER_CTL, 1);
753 if (ret) {
754 return ret;
755 }
756
757 return 0;
758 }
759
760 /**
761 * @brief Initializes communication with the device and checks if the part is
762 * present by reading the device id.
763 *
764 * @return 0 - the initialization was successful and the device is present;
765 * -1 - an error occurred.
766 *
767 */
adxl362_init(const struct device * dev)768 static int adxl362_init(const struct device *dev)
769 {
770 const struct adxl362_config *config = dev->config;
771 uint8_t value = 0;
772 int err;
773
774 if (!spi_is_ready_dt(&config->bus)) {
775 LOG_DBG("spi device not ready: %s", config->bus.bus->name);
776 return -EINVAL;
777 }
778
779 err = adxl362_software_reset(dev);
780
781 if (err) {
782 LOG_ERR("adxl362_software_reset failed, error %d", err);
783 return -ENODEV;
784 }
785
786 k_sleep(K_MSEC(5));
787
788 (void)adxl362_get_reg(dev, &value, ADXL362_REG_PARTID, 1);
789 if (value != ADXL362_PART_ID) {
790 LOG_ERR("wrong part_id: %d", value);
791 return -ENODEV;
792 }
793
794 if (adxl362_chip_init(dev) < 0) {
795 return -ENODEV;
796 }
797
798 #if defined(CONFIG_ADXL362_TRIGGER)
799 if (config->interrupt.port) {
800 if (adxl362_init_interrupt(dev) < 0) {
801 LOG_ERR("Failed to initialize interrupt!");
802 return -EIO;
803 }
804
805 if (adxl362_interrupt_config(dev,
806 config->int1_config,
807 config->int2_config) < 0) {
808 LOG_ERR("Failed to configure interrupt");
809 return -EIO;
810 }
811 }
812 #endif
813
814 return 0;
815 }
816
817 #define ADXL362_SPI_CFG SPI_WORD_SET(8) | SPI_TRANSFER_MSB
818
819 #define ADXL362_RTIO_DEFINE(inst) \
820 SPI_DT_IODEV_DEFINE(adxl362_iodev_##inst, DT_DRV_INST(inst), \
821 ADXL362_SPI_CFG, 0U); \
822 RTIO_DEFINE(adxl362_rtio_ctx_##inst, 8, 8);
823
824 #define ADXL362_DEFINE(inst) \
825 IF_ENABLED(CONFIG_ADXL362_STREAM, (ADXL362_RTIO_DEFINE(inst))); \
826 static struct adxl362_data adxl362_data_##inst = { \
827 IF_ENABLED(CONFIG_ADXL362_STREAM, (.rtio_ctx = &adxl362_rtio_ctx_##inst, \
828 .iodev = &adxl362_iodev_##inst,)) \
829 }; \
830 static const struct adxl362_config adxl362_config_##inst = { \
831 .bus = SPI_DT_SPEC_INST_GET(inst, ADXL362_SPI_CFG, 0), \
832 .power_ctl = ADXL362_POWER_CTL_MEASURE(ADXL362_MEASURE_ON) | \
833 (DT_INST_PROP(inst, wakeup_mode) * ADXL362_POWER_CTL_WAKEUP) | \
834 (DT_INST_PROP(inst, autosleep) * ADXL362_POWER_CTL_AUTOSLEEP), \
835 IF_ENABLED(CONFIG_ADXL362_TRIGGER, \
836 (.interrupt = GPIO_DT_SPEC_INST_GET_OR(inst, int1_gpios, { 0 }),)) \
837 }; \
838 \
839 SENSOR_DEVICE_DT_INST_DEFINE(inst, adxl362_init, NULL, &adxl362_data_##inst, \
840 &adxl362_config_##inst, POST_KERNEL, \
841 CONFIG_SENSOR_INIT_PRIORITY, &adxl362_api_funcs); \
842
843 DT_INST_FOREACH_STATUS_OKAY(ADXL362_DEFINE)
844