1 /* adxl367_spi.c - SPI routines for ADXL367 driver
2  */
3 
4 /*
5  * Copyright (c) 2023 Analog Devices
6  *
7  * SPDX-License-Identifier: Apache-2.0
8  */
9 
10 #define DT_DRV_COMPAT adi_adxl367
11 
12 #include <string.h>
13 #include <zephyr/logging/log.h>
14 
15 #include "adxl367.h"
16 
17 #if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
18 
19 LOG_MODULE_DECLARE(ADXL367, CONFIG_SENSOR_LOG_LEVEL);
20 
adxl367_bus_access(const struct device * dev,uint8_t reg,void * data,size_t length)21 static int adxl367_bus_access(const struct device *dev, uint8_t reg,
22 			      void *data, size_t length)
23 {
24 	const struct adxl367_dev_config *config = dev->config;
25 	uint8_t rw_reg, addr_reg;
26 
27 	if ((reg & ADXL367_READ) != 0) {
28 		rw_reg = ADXL367_SPI_READ_REG;
29 	} else {
30 		rw_reg = ADXL367_SPI_WRITE_REG;
31 	}
32 
33 	addr_reg = ADXL367_TO_REG(reg);
34 
35 	const struct spi_buf buf[3] = {
36 		{
37 			.buf = &rw_reg,
38 			.len = 1
39 		}, {
40 			.buf = &addr_reg,
41 			.len = 1
42 		}, {
43 			.buf = data,
44 			.len = length
45 		}
46 	};
47 
48 	struct spi_buf_set tx = {
49 		.buffers = buf,
50 	};
51 
52 	if ((reg & ADXL367_READ) != 0) {
53 		const struct spi_buf_set rx = {
54 			.buffers = buf,
55 			.count = 3
56 		};
57 
58 		tx.count = 2;
59 
60 		return spi_transceive_dt(&config->spi, &tx, &rx);
61 	}
62 
63 	tx.count = 3;
64 
65 	return spi_write_dt(&config->spi, &tx);
66 }
67 
adxl367_spi_reg_read(const struct device * dev,uint8_t reg_addr,uint8_t * reg_data)68 static int adxl367_spi_reg_read(const struct device *dev, uint8_t reg_addr,
69 			    uint8_t *reg_data)
70 {
71 	return adxl367_bus_access(dev, ADXL367_REG_READ(reg_addr), reg_data, 1);
72 }
73 
adxl367_spi_reg_read_multiple(const struct device * dev,uint8_t reg_addr,uint8_t * reg_data,uint16_t count)74 static int adxl367_spi_reg_read_multiple(const struct device *dev,
75 					 uint8_t reg_addr,
76 					 uint8_t *reg_data,
77 					 uint16_t count)
78 {
79 	return adxl367_bus_access(dev, ADXL367_REG_READ(reg_addr),
80 				  reg_data, count);
81 }
82 
adxl367_spi_reg_write(const struct device * dev,uint8_t reg_addr,uint8_t reg_data)83 static int adxl367_spi_reg_write(const struct device *dev,
84 				 uint8_t reg_addr,
85 				 uint8_t reg_data)
86 {
87 	return adxl367_bus_access(dev, ADXL367_REG_WRITE(reg_addr),
88 				  &reg_data, 1);
89 }
90 
adxl367_spi_reg_write_mask(const struct device * dev,uint8_t reg_addr,uint32_t mask,uint8_t data)91 int adxl367_spi_reg_write_mask(const struct device *dev,
92 			       uint8_t reg_addr,
93 			       uint32_t mask,
94 			       uint8_t data)
95 {
96 	int ret;
97 	uint8_t tmp;
98 
99 	ret = adxl367_spi_reg_read(dev, reg_addr, &tmp);
100 	if (ret != 0) {
101 		return ret;
102 	}
103 
104 	tmp &= ~mask;
105 	tmp |= data;
106 
107 	return adxl367_spi_reg_write(dev, reg_addr, tmp);
108 }
109 
110 static const struct adxl367_transfer_function adxl367_spi_transfer_fn = {
111 	.read_reg_multiple = adxl367_spi_reg_read_multiple,
112 	.write_reg = adxl367_spi_reg_write,
113 	.read_reg = adxl367_spi_reg_read,
114 	.write_reg_mask = adxl367_spi_reg_write_mask,
115 };
116 
adxl367_spi_init(const struct device * dev)117 int adxl367_spi_init(const struct device *dev)
118 {
119 	struct adxl367_data *data = dev->data;
120 	const struct adxl367_dev_config *config = dev->config;
121 
122 	data->hw_tf = &adxl367_spi_transfer_fn;
123 
124 	if (!spi_is_ready_dt(&config->spi)) {
125 		return -ENODEV;
126 	}
127 
128 	return 0;
129 }
130 
131 #endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) */
132