1 /*
2  * Copyright (c) 2022 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/sys/util.h>
8 #include "icm42688_spi.h"
9 #include "icm42688_reg.h"
10 
spi_write_register(const struct spi_dt_spec * bus,uint8_t reg,uint8_t data)11 static inline int spi_write_register(const struct spi_dt_spec *bus, uint8_t reg, uint8_t data)
12 {
13 	const struct spi_buf buf[2] = {
14 		{
15 			.buf = &reg,
16 			.len = 1,
17 		},
18 		{
19 			.buf = &data,
20 			.len = 1,
21 		}
22 	};
23 
24 	const struct spi_buf_set tx = {
25 		.buffers = buf,
26 		.count = 2,
27 	};
28 
29 	return spi_write_dt(bus, &tx);
30 }
31 
spi_read_register(const struct spi_dt_spec * bus,uint8_t reg,uint8_t * data,size_t len)32 static inline int spi_read_register(const struct spi_dt_spec *bus, uint8_t reg, uint8_t *data,
33 				    size_t len)
34 {
35 	uint8_t tx_buffer = REG_SPI_READ_BIT | reg;
36 
37 	const struct spi_buf tx_buf = {
38 		.buf = &tx_buffer,
39 		.len = 1,
40 	};
41 
42 	const struct spi_buf_set tx = {
43 		.buffers = &tx_buf,
44 		.count = 1,
45 	};
46 
47 	struct spi_buf rx_buf[2] = {
48 		{
49 			.buf = NULL,
50 			.len = 1,
51 		},
52 		{
53 			.buf = data,
54 			.len = len,
55 		}
56 	};
57 
58 	const struct spi_buf_set rx = {
59 		.buffers = rx_buf,
60 		.count = 2,
61 	};
62 
63 	return spi_transceive_dt(bus, &tx, &rx);
64 }
65 
icm42688_spi_read(const struct spi_dt_spec * bus,uint16_t reg,uint8_t * data,size_t len)66 int icm42688_spi_read(const struct spi_dt_spec *bus, uint16_t reg, uint8_t *data, size_t len)
67 {
68 	int res = 0;
69 	uint8_t address = FIELD_GET(REG_ADDRESS_MASK, reg);
70 
71 	res = spi_read_register(bus, address, data, len);
72 
73 	return res;
74 }
75 
icm42688_spi_update_register(const struct spi_dt_spec * bus,uint16_t reg,uint8_t mask,uint8_t data)76 int icm42688_spi_update_register(const struct spi_dt_spec *bus, uint16_t reg, uint8_t mask,
77 				 uint8_t data)
78 {
79 	uint8_t temp = 0;
80 	int res = icm42688_spi_read(bus, reg, &temp, 1);
81 
82 	if (res) {
83 		return res;
84 	}
85 
86 	temp &= ~mask;
87 	temp |= FIELD_PREP(mask, data);
88 
89 	return icm42688_spi_single_write(bus, reg, temp);
90 }
91 
icm42688_spi_single_write(const struct spi_dt_spec * bus,uint16_t reg,uint8_t data)92 int icm42688_spi_single_write(const struct spi_dt_spec *bus, uint16_t reg, uint8_t data)
93 {
94 	int res = 0;
95 	uint8_t address = FIELD_GET(REG_ADDRESS_MASK, reg);
96 
97 	res = spi_write_register(bus, address, data);
98 
99 	return res;
100 }
101