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 static 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
230 ret = adxl362_get_reg(dev, &old_filter_ctl, ADXL362_REG_FILTER_CTL, 1);
231 if (ret) {
232 return ret;
233 }
234
235 new_filter_ctl = old_filter_ctl & ~ADXL362_FILTER_CTL_ODR(0x7);
236 new_filter_ctl = new_filter_ctl | ADXL362_FILTER_CTL_ODR(out_rate);
237 return adxl362_set_reg(dev, new_filter_ctl, ADXL362_REG_FILTER_CTL, 1);
238 }
239
240
axl362_acc_config(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,const struct sensor_value * val)241 static int axl362_acc_config(const struct device *dev,
242 enum sensor_channel chan,
243 enum sensor_attribute attr,
244 const struct sensor_value *val)
245 {
246 switch (attr) {
247 #if defined(CONFIG_ADXL362_ACCEL_RANGE_RUNTIME)
248 case SENSOR_ATTR_FULL_SCALE:
249 {
250 int range_reg;
251
252 range_reg = adxl362_range_to_reg_val(sensor_ms2_to_g(val));
253 if (range_reg < 0) {
254 LOG_DBG("invalid range requested.");
255 return -ENOTSUP;
256 }
257
258 return adxl362_set_range(dev, range_reg);
259 }
260 break;
261 #endif
262 #if defined(CONFIG_ADXL362_ACCEL_ODR_RUNTIME)
263 case SENSOR_ATTR_SAMPLING_FREQUENCY:
264 {
265 int out_rate;
266
267 out_rate = adxl362_freq_to_odr_val(val->val1,
268 val->val2 / 1000);
269 if (out_rate < 0) {
270 LOG_DBG("invalid output rate.");
271 return -ENOTSUP;
272 }
273
274 return adxl362_set_output_rate(dev, out_rate);
275 }
276 break;
277 #endif
278 default:
279 LOG_DBG("Accel attribute not supported.");
280 return -ENOTSUP;
281 }
282
283 return 0;
284 }
285
adxl362_attr_set_thresh(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,const struct sensor_value * val)286 static int adxl362_attr_set_thresh(const struct device *dev,
287 enum sensor_channel chan,
288 enum sensor_attribute attr,
289 const struct sensor_value *val)
290 {
291 uint8_t reg;
292 uint16_t threshold = val->val1;
293 size_t ret;
294
295 if (chan != SENSOR_CHAN_ACCEL_X &&
296 chan != SENSOR_CHAN_ACCEL_Y &&
297 chan != SENSOR_CHAN_ACCEL_Z) {
298 return -EINVAL;
299 }
300
301 if (threshold > 2047) {
302 return -EINVAL;
303 }
304
305 /* Configure motion threshold. */
306 if (attr == SENSOR_ATTR_UPPER_THRESH) {
307 reg = ADXL362_REG_THRESH_ACT_L;
308 } else {
309 reg = ADXL362_REG_THRESH_INACT_L;
310 }
311
312 ret = adxl362_set_reg(dev, (threshold & 0x7FF), reg, 2);
313
314 return ret;
315 }
316
adxl362_attr_set(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,const struct sensor_value * val)317 static int adxl362_attr_set(const struct device *dev,
318 enum sensor_channel chan,
319 enum sensor_attribute attr,
320 const struct sensor_value *val)
321 {
322 switch (attr) {
323 case SENSOR_ATTR_UPPER_THRESH:
324 case SENSOR_ATTR_LOWER_THRESH:
325 return adxl362_attr_set_thresh(dev, chan, attr, val);
326 case SENSOR_ATTR_HYSTERESIS:
327 {
328 uint16_t timeout = val->val1;
329
330 return adxl362_set_reg(dev, timeout, ADXL362_REG_TIME_INACT_L, 2);
331 }
332 default:
333 /* Do nothing */
334 break;
335 }
336
337 switch (chan) {
338 case SENSOR_CHAN_ACCEL_X:
339 case SENSOR_CHAN_ACCEL_Y:
340 case SENSOR_CHAN_ACCEL_Z:
341 case SENSOR_CHAN_ACCEL_XYZ:
342 return axl362_acc_config(dev, chan, attr, val);
343 default:
344 LOG_DBG("attr_set() not supported on this channel.");
345 return -ENOTSUP;
346 }
347
348 return 0;
349 }
350
adxl362_fifo_setup(const struct device * dev,uint8_t mode,uint16_t water_mark_lvl,uint8_t en_temp_read)351 static int adxl362_fifo_setup(const struct device *dev, uint8_t mode,
352 uint16_t water_mark_lvl, uint8_t en_temp_read)
353 {
354 uint8_t write_val;
355 int ret;
356
357 write_val = ADXL362_FIFO_CTL_FIFO_MODE(mode) |
358 (en_temp_read * ADXL362_FIFO_CTL_FIFO_TEMP) |
359 ADXL362_FIFO_CTL_AH;
360 ret = adxl362_set_reg(dev, write_val, ADXL362_REG_FIFO_CTL, 1);
361 if (ret) {
362 return ret;
363 }
364
365 ret = adxl362_set_reg(dev, water_mark_lvl, ADXL362_REG_FIFO_SAMPLES, 1);
366 if (ret) {
367 return ret;
368 }
369
370 return 0;
371 }
372
adxl362_setup_activity_detection(const struct device * dev,uint8_t ref_or_abs,uint16_t threshold,uint8_t time)373 static int adxl362_setup_activity_detection(const struct device *dev,
374 uint8_t ref_or_abs,
375 uint16_t threshold,
376 uint8_t time)
377 {
378 uint8_t old_act_inact_reg;
379 uint8_t new_act_inact_reg;
380 int ret;
381
382 /**
383 * mode
384 * must be one of the following:
385 * ADXL362_FIFO_DISABLE - FIFO is disabled.
386 * ADXL362_FIFO_OLDEST_SAVED - Oldest saved mode.
387 * ADXL362_FIFO_STREAM - Stream mode.
388 * ADXL362_FIFO_TRIGGERED - Triggered mode.
389 * water_mark_lvl
390 * Specifies the number of samples to store in the FIFO.
391 * en_temp_read
392 * Store Temperature Data to FIFO.
393 * 1 - temperature data is stored in the FIFO
394 * together with x-, y- and x-axis data.
395 * 0 - temperature data is skipped.
396 */
397
398 /* Configure motion threshold and activity timer. */
399 ret = adxl362_set_reg(dev, (threshold & 0x7FF),
400 ADXL362_REG_THRESH_ACT_L, 2);
401 if (ret) {
402 return ret;
403 }
404
405 ret = adxl362_set_reg(dev, time, ADXL362_REG_TIME_ACT, 1);
406 if (ret) {
407 return ret;
408 }
409
410 /* Enable activity interrupt and select a referenced or absolute
411 * configuration.
412 */
413 ret = adxl362_get_reg(dev, &old_act_inact_reg,
414 ADXL362_REG_ACT_INACT_CTL, 1);
415 if (ret) {
416 return ret;
417 }
418
419 new_act_inact_reg = old_act_inact_reg & ~ADXL362_ACT_INACT_CTL_ACT_REF;
420 new_act_inact_reg |= ADXL362_ACT_INACT_CTL_ACT_EN |
421 (ref_or_abs * ADXL362_ACT_INACT_CTL_ACT_REF);
422 ret = adxl362_set_reg(dev, new_act_inact_reg,
423 ADXL362_REG_ACT_INACT_CTL, 1);
424 if (ret) {
425 return ret;
426 }
427
428 return 0;
429 }
430
adxl362_setup_inactivity_detection(const struct device * dev,uint8_t ref_or_abs,uint16_t threshold,uint16_t time)431 static int adxl362_setup_inactivity_detection(const struct device *dev,
432 uint8_t ref_or_abs,
433 uint16_t threshold,
434 uint16_t time)
435 {
436 uint8_t old_act_inact_reg;
437 uint8_t new_act_inact_reg;
438 int ret;
439
440 /* Configure motion threshold and inactivity timer. */
441 ret = adxl362_set_reg(dev, (threshold & 0x7FF),
442 ADXL362_REG_THRESH_INACT_L, 2);
443 if (ret) {
444 return ret;
445 }
446
447 ret = adxl362_set_reg(dev, time, ADXL362_REG_TIME_INACT_L, 2);
448 if (ret) {
449 return ret;
450 }
451
452 /* Enable inactivity interrupt and select a referenced or
453 * absolute configuration.
454 */
455 ret = adxl362_get_reg(dev, &old_act_inact_reg,
456 ADXL362_REG_ACT_INACT_CTL, 1);
457 if (ret) {
458 return ret;
459 }
460
461 new_act_inact_reg = old_act_inact_reg &
462 ~ADXL362_ACT_INACT_CTL_INACT_REF;
463 new_act_inact_reg |= ADXL362_ACT_INACT_CTL_INACT_EN |
464 (ref_or_abs * ADXL362_ACT_INACT_CTL_INACT_REF);
465 ret = adxl362_set_reg(dev, new_act_inact_reg,
466 ADXL362_REG_ACT_INACT_CTL, 1);
467 if (ret) {
468 return ret;
469 }
470
471 return 0;
472 }
473
adxl362_set_interrupt_mode(const struct device * dev,uint8_t mode)474 int adxl362_set_interrupt_mode(const struct device *dev, uint8_t mode)
475 {
476 uint8_t old_act_inact_reg;
477 uint8_t new_act_inact_reg;
478 int ret;
479
480 LOG_DBG("Mode: %d", mode);
481
482 if (mode != ADXL362_MODE_DEFAULT &&
483 mode != ADXL362_MODE_LINK &&
484 mode != ADXL362_MODE_LOOP) {
485 LOG_ERR("Wrong mode");
486 return -EINVAL;
487 }
488
489 /* Select desired interrupt mode. */
490 ret = adxl362_get_reg(dev, &old_act_inact_reg,
491 ADXL362_REG_ACT_INACT_CTL, 1);
492 if (ret) {
493 return ret;
494 }
495
496 new_act_inact_reg = old_act_inact_reg &
497 ~ADXL362_ACT_INACT_CTL_LINKLOOP(3);
498 new_act_inact_reg |= old_act_inact_reg |
499 ADXL362_ACT_INACT_CTL_LINKLOOP(mode);
500
501 ret = adxl362_set_reg(dev, new_act_inact_reg,
502 ADXL362_REG_ACT_INACT_CTL, 1);
503
504 if (ret) {
505 return ret;
506 }
507
508 return 0;
509 }
510
adxl362_sample_fetch(const struct device * dev,enum sensor_channel chan)511 static int adxl362_sample_fetch(const struct device *dev,
512 enum sensor_channel chan)
513 {
514 struct adxl362_data *data = dev->data;
515 int16_t buf[4];
516 int ret;
517
518 __ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL);
519
520 ret = adxl362_get_reg(dev, (uint8_t *)buf, ADXL362_REG_XDATA_L,
521 sizeof(buf));
522 if (ret) {
523 return ret;
524 }
525
526 data->acc_x = sys_le16_to_cpu(buf[0]);
527 data->acc_y = sys_le16_to_cpu(buf[1]);
528 data->acc_z = sys_le16_to_cpu(buf[2]);
529 data->temp = sys_le16_to_cpu(buf[3]);
530
531 return 0;
532 }
533
adxl362_range_to_scale(int range)534 static inline int adxl362_range_to_scale(int range)
535 {
536 /* See table 1 in specifications section of datasheet */
537 switch (range) {
538 case ADXL362_RANGE_2G:
539 return ADXL362_ACCEL_2G_LSB_PER_G;
540 case ADXL362_RANGE_4G:
541 return ADXL362_ACCEL_4G_LSB_PER_G;
542 case ADXL362_RANGE_8G:
543 return ADXL362_ACCEL_8G_LSB_PER_G;
544 default:
545 return -EINVAL;
546 }
547 }
548
adxl362_accel_convert(struct sensor_value * val,int accel,int range)549 static void adxl362_accel_convert(struct sensor_value *val, int accel,
550 int range)
551 {
552 int scale = adxl362_range_to_scale(range);
553 long micro_ms2 = accel * SENSOR_G / scale;
554
555 __ASSERT_NO_MSG(scale != -EINVAL);
556
557 val->val1 = micro_ms2 / 1000000;
558 val->val2 = micro_ms2 % 1000000;
559 }
560
adxl362_temp_convert(struct sensor_value * val,int temp)561 static void adxl362_temp_convert(struct sensor_value *val, int temp)
562 {
563 /* See sensitivity and bias specifications in table 1 of datasheet */
564 int milli_c = (temp - ADXL362_TEMP_BIAS_LSB) * ADXL362_TEMP_MC_PER_LSB;
565
566 val->val1 = milli_c / 1000;
567 val->val2 = (milli_c % 1000) * 1000;
568 }
569
adxl362_channel_get(const struct device * dev,enum sensor_channel chan,struct sensor_value * val)570 static int adxl362_channel_get(const struct device *dev,
571 enum sensor_channel chan,
572 struct sensor_value *val)
573 {
574 struct adxl362_data *data = dev->data;
575
576 switch (chan) {
577 case SENSOR_CHAN_ACCEL_X: /* Acceleration on the X axis, in m/s^2. */
578 adxl362_accel_convert(val, data->acc_x, data->selected_range);
579 break;
580 case SENSOR_CHAN_ACCEL_Y: /* Acceleration on the Y axis, in m/s^2. */
581 adxl362_accel_convert(val, data->acc_y, data->selected_range);
582 break;
583 case SENSOR_CHAN_ACCEL_Z: /* Acceleration on the Z axis, in m/s^2. */
584 adxl362_accel_convert(val, data->acc_z, data->selected_range);
585 break;
586 case SENSOR_CHAN_ACCEL_XYZ: /* Acceleration on the XYZ axis, in m/s^2. */
587 for (size_t i = 0; i < 3; i++) {
588 adxl362_accel_convert(&val[i], data->acc_xyz[i], data->selected_range);
589 }
590 break;
591 case SENSOR_CHAN_DIE_TEMP: /* Temperature in degrees Celsius. */
592 adxl362_temp_convert(val, data->temp);
593 break;
594 default:
595 return -ENOTSUP;
596 }
597
598 return 0;
599 }
600
601 static const struct sensor_driver_api adxl362_api_funcs = {
602 .attr_set = adxl362_attr_set,
603 .sample_fetch = adxl362_sample_fetch,
604 .channel_get = adxl362_channel_get,
605 #ifdef CONFIG_ADXL362_TRIGGER
606 .trigger_set = adxl362_trigger_set,
607 #endif
608 };
609
adxl362_chip_init(const struct device * dev)610 static int adxl362_chip_init(const struct device *dev)
611 {
612 const struct adxl362_config *config = dev->config;
613 int ret;
614
615 /* Configures activity detection.
616 * Referenced/Absolute Activity or Inactivity Select.
617 * 0 - absolute mode.
618 * 1 - referenced mode.
619 * threshold
620 * 11-bit unsigned value that the adxl362 samples are
621 * compared to.
622 * time
623 * 8-bit value written to the activity timer register.
624 * The amount of time (in seconds) is:
625 * time / ODR,
626 * where ODR - is the output data rate.
627 */
628 ret =
629 adxl362_setup_activity_detection(dev,
630 CONFIG_ADXL362_ABS_REF_MODE,
631 CONFIG_ADXL362_ACTIVITY_THRESHOLD,
632 CONFIG_ADXL362_ACTIVITY_TIME);
633 if (ret) {
634 return ret;
635 }
636
637 /* Configures inactivity detection.
638 * Referenced/Absolute Activity or Inactivity Select.
639 * 0 - absolute mode.
640 * 1 - referenced mode.
641 * threshold
642 * 11-bit unsigned value that the adxl362 samples are
643 * compared to.
644 * time
645 * 16-bit value written to the activity timer register.
646 * The amount of time (in seconds) is:
647 * time / ODR,
648 * where ODR - is the output data rate.
649 */
650 ret =
651 adxl362_setup_inactivity_detection(dev,
652 CONFIG_ADXL362_ABS_REF_MODE,
653 CONFIG_ADXL362_INACTIVITY_THRESHOLD,
654 CONFIG_ADXL362_INACTIVITY_TIME);
655 if (ret) {
656 return ret;
657 }
658
659 /* Configures the FIFO feature. */
660 ret = adxl362_fifo_setup(dev, ADXL362_FIFO_DISABLE, 0, 0);
661 if (ret) {
662 return ret;
663 }
664
665 /* Selects the measurement range.
666 * options are:
667 * ADXL362_RANGE_2G - +-2 g
668 * ADXL362_RANGE_4G - +-4 g
669 * ADXL362_RANGE_8G - +-8 g
670 */
671 ret = adxl362_set_range(dev, ADXL362_DEFAULT_RANGE_ACC);
672 if (ret) {
673 return ret;
674 }
675
676 /* Selects the Output Data Rate of the device.
677 * Options are:
678 * ADXL362_ODR_12_5_HZ - 12.5Hz
679 * ADXL362_ODR_25_HZ - 25Hz
680 * ADXL362_ODR_50_HZ - 50Hz
681 * ADXL362_ODR_100_HZ - 100Hz
682 * ADXL362_ODR_200_HZ - 200Hz
683 * ADXL362_ODR_400_HZ - 400Hz
684 */
685 ret = adxl362_set_output_rate(dev, ADXL362_DEFAULT_ODR_ACC);
686 if (ret) {
687 return ret;
688 }
689
690 /* Places the device into measure mode, enable wakeup mode and autosleep if desired. */
691 LOG_DBG("setting pwrctl: 0x%02x", config->power_ctl);
692 ret = adxl362_set_reg(dev, config->power_ctl, ADXL362_REG_POWER_CTL, 1);
693 if (ret) {
694 return ret;
695 }
696
697 return 0;
698 }
699
700 /**
701 * @brief Initializes communication with the device and checks if the part is
702 * present by reading the device id.
703 *
704 * @return 0 - the initialization was successful and the device is present;
705 * -1 - an error occurred.
706 *
707 */
adxl362_init(const struct device * dev)708 static int adxl362_init(const struct device *dev)
709 {
710 const struct adxl362_config *config = dev->config;
711 uint8_t value = 0;
712 int err;
713
714 if (!spi_is_ready_dt(&config->bus)) {
715 LOG_DBG("spi device not ready: %s", config->bus.bus->name);
716 return -EINVAL;
717 }
718
719 err = adxl362_software_reset(dev);
720
721 if (err) {
722 LOG_ERR("adxl362_software_reset failed, error %d", err);
723 return -ENODEV;
724 }
725
726 k_sleep(K_MSEC(5));
727
728 (void)adxl362_get_reg(dev, &value, ADXL362_REG_PARTID, 1);
729 if (value != ADXL362_PART_ID) {
730 LOG_ERR("wrong part_id: %d", value);
731 return -ENODEV;
732 }
733
734 if (adxl362_chip_init(dev) < 0) {
735 return -ENODEV;
736 }
737
738 #if defined(CONFIG_ADXL362_TRIGGER)
739 if (config->interrupt.port) {
740 if (adxl362_init_interrupt(dev) < 0) {
741 LOG_ERR("Failed to initialize interrupt!");
742 return -EIO;
743 }
744
745 if (adxl362_interrupt_config(dev,
746 config->int1_config,
747 config->int2_config) < 0) {
748 LOG_ERR("Failed to configure interrupt");
749 return -EIO;
750 }
751 }
752 #endif
753
754 return 0;
755 }
756
757 #define ADXL362_DEFINE(inst) \
758 static struct adxl362_data adxl362_data_##inst; \
759 \
760 static const struct adxl362_config adxl362_config_##inst = { \
761 .bus = SPI_DT_SPEC_INST_GET(inst, SPI_WORD_SET(8) | SPI_TRANSFER_MSB, 0), \
762 .power_ctl = ADXL362_POWER_CTL_MEASURE(ADXL362_MEASURE_ON) | \
763 (DT_INST_PROP(inst, wakeup_mode) * ADXL362_POWER_CTL_WAKEUP) | \
764 (DT_INST_PROP(inst, autosleep) * ADXL362_POWER_CTL_AUTOSLEEP), \
765 IF_ENABLED(CONFIG_ADXL362_TRIGGER, \
766 (.interrupt = GPIO_DT_SPEC_INST_GET_OR(inst, int1_gpios, { 0 }),)) \
767 }; \
768 \
769 SENSOR_DEVICE_DT_INST_DEFINE(inst, adxl362_init, NULL, &adxl362_data_##inst, \
770 &adxl362_config_##inst, POST_KERNEL, \
771 CONFIG_SENSOR_INIT_PRIORITY, &adxl362_api_funcs); \
772
773 DT_INST_FOREACH_STATUS_OKAY(ADXL362_DEFINE)
774