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 = ®,
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