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 	uint8_t mms;
117 	uint8_t address;
118 	uint16_t value;
119 } oa_mem_map_t;
120 
121 /**
122  * @brief Calculate parity bit from data
123  *
124  * @param x data to calculate parity
125  *
126  * @return 0 if number of ones is odd, 1 otherwise.
127  */
oa_tc6_get_parity(const uint32_t x)128 static inline bool oa_tc6_get_parity(const uint32_t x)
129 {
130 	uint32_t y;
131 
132 	y = x ^ (x >> 1);
133 	y = y ^ (y >> 2);
134 	y = y ^ (y >> 4);
135 	y = y ^ (y >> 8);
136 	y = y ^ (y >> 16);
137 
138 	return !(y & 1);
139 }
140 
141 /**
142  * @brief Read OA TC6 compliant device single register
143  *
144  * @param tc6 OA TC6 specific data
145  *
146  * @param reg register to read
147 
148  * @param val pointer to variable to store read value
149  *
150  * @return 0 if read was successful, <0 otherwise.
151  */
152 int oa_tc6_reg_read(struct oa_tc6 *tc6, const uint32_t reg, uint32_t *val);
153 
154 /**
155  * @brief Write to OA TC6 compliant device a single register
156  *
157  * @param tc6 OA TC6 specific data
158  *
159  * @param reg register to read
160 
161  * @param val data to send to device
162  *
163  * @return 0 if write was successful, <0 otherwise.
164  */
165 int oa_tc6_reg_write(struct oa_tc6 *tc6, const uint32_t reg, uint32_t val);
166 
167 /**
168  * @brief Enable or disable the protected mode for control transactions
169  *
170  * @param tc6 OA TC6 specific data
171  *
172  * @param prote enable or disable protected control transactions
173  *
174  * @return 0 if operation was successful, <0 otherwise.
175  */
176 int oa_tc6_set_protected_ctrl(struct oa_tc6 *tc6, bool prote);
177 
178 /**
179  * @brief Send OA TC6 data chunks to the device
180  *
181  * @param tc6 OA TC6 specific data
182  *
183  * @param pkt network packet to be send
184  *
185  * @return 0 if data send was successful, <0 otherwise.
186  */
187 int oa_tc6_send_chunks(struct oa_tc6 *tc6, struct net_pkt *pkt);
188 
189 /**
190  * @brief Read data chunks from OA TC6 device
191  *
192  * @param tc6 OA TC6 specific data
193  *
194  * @param pkt network packet to store received data
195  *
196  * @return 0 if read was successful, <0 otherwise.
197  */
198 int oa_tc6_read_chunks(struct oa_tc6 *tc6, struct net_pkt *pkt);
199 
200 /**
201  * @brief Perform SPI transfer of single chunk from/to OA TC6 device
202  *
203  * @param tc6 OA TC6 specific data
204  *
205  * @param buf_rx buffer to store read data
206  *
207  * @param buf_tx buffer with data to send
208  *
209  * @param hdr OA TC6 data transmission header value
210  *
211  * @param ftr poniter to OA TC6 data received footer
212  *
213  * @return 0 if transmission was successful, <0 otherwise.
214  */
215 int oa_tc6_chunk_spi_transfer(struct oa_tc6 *tc6, uint8_t *buf_rx, uint8_t *buf_tx,
216 			      uint32_t hdr, uint32_t *ftr);
217 
218 /**
219  * @brief Read status from OA TC6 device
220  *
221  * @param tc6 OA TC6 specific data
222  *
223  * @param ftr poniter to OA TC6 data received footer
224  *
225  * @return 0 if successful, <0 otherwise.
226  */
227 int oa_tc6_read_status(struct oa_tc6 *tc6, uint32_t *ftr);
228 
229 /**
230  * @brief Read, modify and write control register from OA TC6 device
231  *
232  * @param tc6 OA TC6 specific data
233  *
234  * @param reg register to modify
235  *
236  * @param mask bit mask for modified register
237  *
238  * @param value to be stored in the register
239  *
240  * @return 0 if successful, <0 otherwise.
241  */
242 int oa_tc6_reg_rmw(struct oa_tc6 *tc6, const uint32_t reg,
243 		   uint32_t mask, uint32_t val);
244 
245 /**
246  * @brief Check the status of OA TC6 device
247  *
248  * @param tc6 OA TC6 specific data
249  *
250  * @return 0 if successful, <0 otherwise.
251  */
252 int oa_tc6_check_status(struct oa_tc6 *tc6);
253 #endif /* OA_TC6_CFG_H__ */
254