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, &register_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