1 /*
2 * Copyright (c) 2023 DENX Software Engineering GmbH
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #ifndef OA_TC6_CFG_H__
7 #define OA_TC6_CFG_H__
8
9 #include <stdint.h>
10 #include <stdbool.h>
11 #include <zephyr/kernel.h>
12 #include <zephyr/sys/byteorder.h>
13 #include <zephyr/drivers/spi.h>
14 #include <zephyr/net/net_pkt.h>
15
16 #define MMS_REG(m, r) ((((m) & GENMASK(3, 0)) << 16) | ((r) & GENMASK(15, 0)))
17 /* Memory Map Sector (MMS) 0 */
18 #define OA_ID MMS_REG(0x0, 0x000) /* expect 0x11 */
19 #define OA_PHYID MMS_REG(0x0, 0x001)
20 #define OA_RESET MMS_REG(0x0, 0x003)
21 #define OA_RESET_SWRESET BIT(0)
22 #define OA_CONFIG0 MMS_REG(0x0, 0x004)
23 #define OA_CONFIG0_SYNC BIT(15)
24 #define OA_CONFIG0_RFA_ZARFE BIT(12)
25 #define OA_CONFIG0_PROTE BIT(5)
26 #define OA_STATUS0 MMS_REG(0x0, 0x008)
27 #define OA_STATUS0_RESETC BIT(6)
28 #define OA_STATUS1 MMS_REG(0x0, 0x009)
29 #define OA_BUFSTS MMS_REG(0x0, 0x00B)
30 #define OA_BUFSTS_TXC GENMASK(15, 8)
31 #define OA_BUFSTS_RCA GENMASK(7, 0)
32 #define OA_IMASK0 MMS_REG(0x0, 0x00C)
33 #define OA_IMASK0_TXPEM BIT(0)
34 #define OA_IMASK0_TXBOEM BIT(1)
35 #define OA_IMASK0_TXBUEM BIT(2)
36 #define OA_IMASK0_RXBOEM BIT(3)
37 #define OA_IMASK0_LOFEM BIT(4)
38 #define OA_IMASK0_HDREM BIT(5)
39 #define OA_IMASK1 MMS_REG(0x0, 0x00D)
40 #define OA_IMASK0_UV18M BIT(19)
41
42 /* OA Control header */
43 #define OA_CTRL_HDR_DNC BIT(31)
44 #define OA_CTRL_HDR_HDRB BIT(30)
45 #define OA_CTRL_HDR_WNR BIT(29)
46 #define OA_CTRL_HDR_AID BIT(28)
47 #define OA_CTRL_HDR_MMS GENMASK(27, 24)
48 #define OA_CTRL_HDR_ADDR GENMASK(23, 8)
49 #define OA_CTRL_HDR_LEN GENMASK(7, 1)
50 #define OA_CTRL_HDR_P BIT(0)
51
52 /* OA Data header */
53 #define OA_DATA_HDR_DNC BIT(31)
54 #define OA_DATA_HDR_SEQ BIT(30)
55 #define OA_DATA_HDR_NORX BIT(29)
56 #define OA_DATA_HDR_DV BIT(21)
57 #define OA_DATA_HDR_SV BIT(20)
58 #define OA_DATA_HDR_SWO GENMASK(19, 16)
59 #define OA_DATA_HDR_EV BIT(14)
60 #define OA_DATA_HDR_EBO GENMASK(13, 8)
61 #define OA_DATA_HDR_P BIT(0)
62
63 /* OA Data footer */
64 #define OA_DATA_FTR_EXST BIT(31)
65 #define OA_DATA_FTR_HDRB BIT(30)
66 #define OA_DATA_FTR_SYNC BIT(29)
67 #define OA_DATA_FTR_RCA GENMASK(28, 24)
68 #define OA_DATA_FTR_DV BIT(21)
69 #define OA_DATA_FTR_SV BIT(20)
70 #define OA_DATA_FTR_SWO GENMASK(19, 16)
71 #define OA_DATA_FTR_FD BIT(15)
72 #define OA_DATA_FTR_EV BIT(14)
73 #define OA_DATA_FTR_EBO GENMASK(13, 8)
74 #define OA_DATA_FTR_TXC GENMASK(5, 1)
75 #define OA_DATA_FTR_P BIT(0)
76
77 #define OA_TC6_HDR_SIZE 4
78 #define OA_TC6_FTR_SIZE 4
79 #define OA_TC6_BUF_ALLOC_TIMEOUT K_MSEC(10)
80 #define OA_TC6_FTR_RCA_MAX GENMASK(4, 0)
81 #define OA_TC6_FTR_TXC_MAX GENMASK(4, 0)
82
83 /**
84 * @brief OA TC6 data.
85 */
86 struct oa_tc6 {
87 /** Pointer to SPI device */
88 const struct spi_dt_spec *spi;
89
90 /** OA data payload (chunk) size */
91 uint8_t cps;
92
93 /**
94 * Number of available chunks buffers in OA TC6 device to store
95 * data for transmission
96 */
97 uint8_t txc;
98
99 /** Number of available chunks to read from OA TC6 device */
100 uint8_t rca;
101
102 /** Indication of pending interrupt in OA TC6 device */
103 bool exst;
104
105 /** Indication of OA TC6 device being ready for transmission */
106 bool sync;
107
108 /** Indication of protected control transmission mode */
109 bool protected;
110
111 /** Pointer to network buffer concatenated from received chunk */
112 struct net_buf *concat_buf;
113 };
114
115 typedef struct {
116 uint32_t address;
117 uint32_t value;
118 } oa_mem_map_t;
119
120 /**
121 * @brief Calculate parity bit from data
122 *
123 * @param x data to calculate parity
124 *
125 * @return 0 if number of ones is odd, 1 otherwise.
126 */
oa_tc6_get_parity(const uint32_t x)127 static inline bool oa_tc6_get_parity(const uint32_t x)
128 {
129 uint32_t y;
130
131 y = x ^ (x >> 1);
132 y = y ^ (y >> 2);
133 y = y ^ (y >> 4);
134 y = y ^ (y >> 8);
135 y = y ^ (y >> 16);
136
137 return !(y & 1);
138 }
139
140 /**
141 * @brief Read OA TC6 compliant device single register
142 *
143 * @param tc6 OA TC6 specific data
144 *
145 * @param reg register to read
146
147 * @param val pointer to variable to store read value
148 *
149 * @return 0 if read was successful, <0 otherwise.
150 */
151 int oa_tc6_reg_read(struct oa_tc6 *tc6, const uint32_t reg, uint32_t *val);
152
153 /**
154 * @brief Write to OA TC6 compliant device a single register
155 *
156 * @param tc6 OA TC6 specific data
157 *
158 * @param reg register to read
159
160 * @param val data to send to device
161 *
162 * @return 0 if write was successful, <0 otherwise.
163 */
164 int oa_tc6_reg_write(struct oa_tc6 *tc6, const uint32_t reg, uint32_t val);
165
166 /**
167 * @brief Enable or disable the protected mode for control transactions
168 *
169 * @param tc6 OA TC6 specific data
170 *
171 * @param prote enable or disable protected control transactions
172 *
173 * @return 0 if operation was successful, <0 otherwise.
174 */
175 int oa_tc6_set_protected_ctrl(struct oa_tc6 *tc6, bool prote);
176
177 /**
178 * @brief Send OA TC6 data chunks to the device
179 *
180 * @param tc6 OA TC6 specific data
181 *
182 * @param pkt network packet to be send
183 *
184 * @return 0 if data send was successful, <0 otherwise.
185 */
186 int oa_tc6_send_chunks(struct oa_tc6 *tc6, struct net_pkt *pkt);
187
188 /**
189 * @brief Read data chunks from OA TC6 device
190 *
191 * @param tc6 OA TC6 specific data
192 *
193 * @param pkt network packet to store received data
194 *
195 * @return 0 if read was successful, <0 otherwise.
196 */
197 int oa_tc6_read_chunks(struct oa_tc6 *tc6, struct net_pkt *pkt);
198
199 /**
200 * @brief Perform SPI transfer of single chunk from/to OA TC6 device
201 *
202 * @param tc6 OA TC6 specific data
203 *
204 * @param buf_rx buffer to store read data
205 *
206 * @param buf_tx buffer with data to send
207 *
208 * @param hdr OA TC6 data transmission header value
209 *
210 * @param ftr poniter to OA TC6 data received footer
211 *
212 * @return 0 if transmission was successful, <0 otherwise.
213 */
214 int oa_tc6_chunk_spi_transfer(struct oa_tc6 *tc6, uint8_t *buf_rx, uint8_t *buf_tx,
215 uint32_t hdr, uint32_t *ftr);
216
217 /**
218 * @brief Read status from OA TC6 device
219 *
220 * @param tc6 OA TC6 specific data
221 *
222 * @param ftr poniter to OA TC6 data received footer
223 *
224 * @return 0 if successful, <0 otherwise.
225 */
226 int oa_tc6_read_status(struct oa_tc6 *tc6, uint32_t *ftr);
227
228 /**
229 * @brief Read, modify and write control register from OA TC6 device
230 *
231 * @param tc6 OA TC6 specific data
232 *
233 * @param reg register to modify
234 *
235 * @param mask bit mask for modified register
236 *
237 * @param value to be stored in the register
238 *
239 * @return 0 if successful, <0 otherwise.
240 */
241 int oa_tc6_reg_rmw(struct oa_tc6 *tc6, const uint32_t reg,
242 uint32_t mask, uint32_t val);
243
244 /**
245 * @brief Check the status of OA TC6 device
246 *
247 * @param tc6 OA TC6 specific data
248 *
249 * @return 0 if successful, <0 otherwise.
250 */
251 int oa_tc6_check_status(struct oa_tc6 *tc6);
252 #endif /* OA_TC6_CFG_H__ */
253