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