1 /*
2  * Copyright (c) 2022  The Chromium OS Authors
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_DRIVERS_USBC_DEVICE_UCPD_STM32_PRIV_H_
8 #define ZEPHYR_DRIVERS_USBC_DEVICE_UCPD_STM32_PRIV_H_
9 
10 #include <zephyr/kernel.h>
11 #include <zephyr/sys/util.h>
12 #include <zephyr/drivers/usb_c/usbc_tcpc.h>
13 #include <zephyr/drivers/pinctrl.h>
14 #include <stm32_ll_ucpd.h>
15 
16 /**
17  * @brief The packet type(SOP*) consists of 2-bytes
18  */
19 #define PACKET_TYPE_SIZE 2
20 
21 /**
22  * @brief The message header consists of 2-bytes
23  */
24 #define MSG_HEADER_SIZE 2
25 
26 /**
27  * @brief USB PD message buffer length.
28  */
29 #define UCPD_BUF_LEN (PD_MAX_EXTENDED_MSG_LEN +	\
30 		      PACKET_TYPE_SIZE +	\
31 		      MSG_HEADER_SIZE)
32 
33 /**
34  * @brief UCPD alert mask used for enabling alerts
35  *        used to receive a message
36  */
37 #define UCPD_IMR_RX_INT_MASK (UCPD_IMR_RXNEIE |	     \
38 			      UCPD_IMR_RXORDDETIE |  \
39 			      UCPD_IMR_RXHRSTDETIE | \
40 			      UCPD_IMR_RXOVRIE |     \
41 			      UCPD_IMR_RXMSGENDIE)
42 /**
43  * @brief UCPD alert mask used for clearing alerts
44  *        used to receive a message
45  */
46 #define UCPD_ICR_RX_INT_MASK (UCPD_ICR_RXORDDETCF |  \
47 			      UCPD_ICR_RXHRSTDETCF | \
48 			      UCPD_ICR_RXOVRCF |     \
49 			      UCPD_ICR_RXMSGENDCF)
50 
51 /**
52  * @brief UCPD alert mask used for enabling alerts
53  *        used to transmit a message
54  */
55 #define UCPD_IMR_TX_INT_MASK (UCPD_IMR_TXISIE |	     \
56 			      UCPD_IMR_TXMSGDISCIE | \
57 			      UCPD_IMR_TXMSGSENTIE | \
58 			      UCPD_IMR_TXMSGABTIE |  \
59 			      UCPD_IMR_TXUNDIE)
60 
61 /**
62  * @brief UCPD alert mask used for clearing alerts
63  *        used to transmit a message
64  */
65 #define UCPD_ICR_TX_INT_MASK (UCPD_ICR_TXMSGDISCCF | \
66 			      UCPD_ICR_TXMSGSENTCF | \
67 			      UCPD_ICR_TXMSGABTCF |  \
68 			      UCPD_ICR_TXUNDCF)
69 
70 /**
71  * @brief UCPD alert mask for all alerts
72  */
73 #define UCPD_ICR_ALL_INT_MASK (UCPD_ICR_FRSEVTCF |    \
74 			       UCPD_ICR_TYPECEVT2CF | \
75 			       UCPD_ICR_TYPECEVT1CF | \
76 			       UCPD_ICR_RXMSGENDCF |  \
77 			       UCPD_ICR_RXOVRCF |     \
78 			       UCPD_ICR_RXHRSTDETCF | \
79 			       UCPD_ICR_RXORDDETCF |  \
80 			       UCPD_ICR_TXUNDCF |     \
81 			       UCPD_ICR_HRSTSENTCF |  \
82 			       UCPD_ICR_HRSTDISCCF |  \
83 			       UCPD_ICR_TXMSGABTCF |  \
84 			       UCPD_ICR_TXMSGSENTCF | \
85 			       UCPD_ICR_TXMSGDISCCF)
86 
87 /**
88  * @brief For STM32G0X devices, this macro enables
89  *	  Dead Battery functionality
90  */
91 #define UCPD_CR_DBATTEN BIT(15)
92 
93 /**
94  * @brief Map UCPD ANASUB value to TCPC RP value
95  *
96  * @param r UCPD ANASUB value
97  */
98 #define UCPD_ANASUB_TO_RP(r) ((r - 1) & 0x3)
99 
100 /**
101  * @brief Map TCPC RP value to UCPD ANASUB value
102  *
103  * @param r TCPC RP value
104  */
105 #define UCPD_RP_TO_ANASUB(r) ((r + 1) & 0x3)
106 
107 /**
108  * @brief Create value for writing to UCPD CR ANASUBMOD
109  */
110 #define STM32_UCPD_CR_ANASUBMODE_VAL(x) ((x) << UCPD_CR_ANASUBMODE_Pos)
111 
112 /**
113  * @brief UCPD VSTATE CCx open value when in source mode
114  */
115 #define STM32_UCPD_SR_VSTATE_OPEN 3
116 
117 /**
118  * @brief UCPD VSTATE CCx RA value when in source mode
119  */
120 #define STM32_UCPD_SR_VSTATE_RA 0
121 
122 /**
123  * @brief PD message send retry count for Rev 2.0
124  */
125 #define UCPD_N_RETRY_COUNT_REV20 3
126 
127 /**
128  * @brief PD message send retry count for Rev 3.0
129  */
130 #define UCPD_N_RETRY_COUNT_REV30 2
131 
132 /**
133  * @brief Events for ucpd_alert_handler
134  */
135 enum {
136 	/* Request to send a goodCRC message */
137 	UCPD_EVT_GOOD_CRC_REQ,
138 	/* Request to send a power delivery message */
139 	UCPD_EVT_TCPM_MSG_REQ,
140 	/* Request to send a Hard Reset message */
141 	UCPD_EVT_HR_REQ,
142 	/* Transmission of power delivery message failed */
143 	UCPD_EVT_TX_MSG_FAIL,
144 	/* Transmission of power delivery message was discarded */
145 	UCPD_EVT_TX_MSG_DISC,
146 	/* Transmission of power delivery message was successful */
147 	UCPD_EVT_TX_MSG_SUCCESS,
148 	/* Transmission of Hard Reset message was successful */
149 	UCPD_EVT_HR_DONE,
150 	/* Transmission of Hard Reset message failed */
151 	UCPD_EVT_HR_FAIL,
152 	/* A goodCRC message was received */
153 	UCPD_EVT_RX_GOOD_CRC,
154 	/* A power delivery message was received */
155 	UCPD_EVT_RX_MSG,
156 	/* A CC event occurred */
157 	UCPD_EVT_EVENT_CC,
158 	/* A Hard Reset message was received */
159 	UCPD_EVT_HARD_RESET_RECEIVED,
160 };
161 
162 /**
163  * @brief GoodCRC message header roles
164  */
165 struct msg_header_info {
166 	/* Power Role */
167 	enum tc_power_role pr;
168 	/* Data Role */
169 	enum tc_data_role dr;
170 };
171 
172 /**
173  * @brief States for managing TX messages
174  */
175 enum ucpd_state {
176 	/* Idle state */
177 	STATE_IDLE,
178 	/* Transmitting a message state */
179 	STATE_ACTIVE_TCPM,
180 	/* Transmitting a goodCRC message state */
181 	STATE_ACTIVE_CRC,
182 	/* Transmitting a Hard Reset message state */
183 	STATE_HARD_RESET,
184 	/* Waiting for a goodCRC message state */
185 	STATE_WAIT_CRC_ACK
186 };
187 
188 /**
189  * @brief Tx messages are initiated either by the application or from
190  *        the driver when a GoodCRC ack message needs to be sent.
191  */
192 enum ucpd_tx_msg {
193 	/* Default value for not sending a message */
194 	TX_MSG_NONE     = -1,
195 	/* Message initiated from the application */
196 	TX_MSG_TCPM     = 0,
197 	/* Message initiated from the driver */
198 	TX_MSG_GOOD_CRC = 1,
199 	/* Total number sources that can initiate a message */
200 	TX_MSG_TOTAL    = 2
201 };
202 
203 /**
204  * @brief Message from application mask
205  */
206 #define MSG_TCPM_MASK      BIT(TX_MSG_TCPM)
207 
208 /**
209  * @brief Message from driver mask
210  */
211 #define MSG_GOOD_CRC_MASK  BIT(TX_MSG_GOOD_CRC)
212 
213 /**
214  * @brief Buffer for holding the received message
215  */
216 union pd_buffer {
217 	/* Power Delivery message header */
218 	uint16_t header;
219 	/* Power Deliver message data including the message header */
220 	uint8_t msg[UCPD_BUF_LEN];
221 };
222 
223 /**
224  * @brief Struct used for transmitting a power delivery message
225  */
226 struct ucpd_tx_desc {
227 	/* Type of the message */
228 	enum pd_packet_type type;
229 	/* Length of the message */
230 	int msg_len;
231 	/* Index of the current byte to transmit */
232 	int msg_index;
233 	/* Power Delivery message to transmit */
234 	union pd_buffer data;
235 };
236 
237 /**
238  * @brief Alert handler information
239  */
240 struct alert_info {
241 	/* Runtime device structure */
242 	const struct device *dev;
243 	/* Application supplied data that's passed to the
244 	 * application's alert handler callback
245 	 **/
246 	void *data;
247 	/* Application's alert handler callback */
248 	tcpc_alert_handler_cb_t handler;
249 	/*
250 	 * Kernel worker used to call the application's
251 	 * alert handler callback
252 	 */
253 	struct k_work work;
254 	/* Event flags used in the kernel worker */
255 	atomic_t evt;
256 };
257 
258 /**
259  * @brief Driver config
260  */
261 struct tcpc_config {
262 	/* STM32 UCPC CC pin control */
263 	const struct pinctrl_dev_config *ucpd_pcfg;
264 	/* STM32 UCPD port */
265 	UCPD_TypeDef *ucpd_port;
266 	/* STM32 UCPD parameters */
267 	LL_UCPD_InitTypeDef ucpd_params;
268 	/* STM32 UCPD dead battery support */
269 	bool ucpd_dead_battery;
270 };
271 
272 /**
273  * @brief Driver data
274  */
275 struct tcpc_data {
276 	/* VCONN callback function */
277 	tcpc_vconn_control_cb_t vconn_cb;
278 	/* VCONN Discharge callback function */
279 	tcpc_vconn_discharge_cb_t vconn_discharge_cb;
280 	/* Alert information */
281 	struct alert_info alert_info;
282 
283 	/* CC Rp value */
284 	enum tc_rp_value rp;
285 
286 	/* PD Rx variables */
287 
288 	/* Number of RX bytes received */
289 	int ucpd_rx_byte_count;
290 	/* Buffer to hold the received bytes */
291 	uint8_t ucpd_rx_buffer[UCPD_BUF_LEN];
292 	/* GoodCRC message ID */
293 	int ucpd_crc_id;
294 	/* Flag to receive or ignore SOP Prime messages */
295 	bool ucpd_rx_sop_prime_enabled;
296 	/* Flag set to true when receiving a message */
297 	bool ucpd_rx_msg_active;
298 	/* Flag set to true when in RX BIST Mode */
299 	bool ucpd_rx_bist_mode;
300 
301 	/* Tx message variables */
302 
303 	/* Buffers to hold messages ready for transmission */
304 	struct ucpd_tx_desc ucpd_tx_buffers[TX_MSG_TOTAL];
305 	/* Current buffer being transmitted */
306 	struct ucpd_tx_desc *ucpd_tx_active_buffer;
307 	/* Request to send a transmission message */
308 	int ucpd_tx_request;
309 	/* State of the TX state machine */
310 	enum ucpd_state ucpd_tx_state;
311 	/* Transmission message ID */
312 	int msg_id_match;
313 	/* Retry count on failure to transmit a message */
314 	int tx_retry_count;
315 	/* Max number of reties before giving up */
316 	int tx_retry_max;
317 
318 	/* GoodCRC message Header */
319 	struct msg_header_info msg_header;
320 	/* Track VCONN on/off state */
321 	bool ucpd_vconn_enable;
322 	/* Track CC line that VCONN was active on */
323 	enum tc_cc_polarity ucpd_vconn_cc;
324 
325 	/* Dead Battery active */
326 	bool dead_battery_active;
327 
328 	/* Timer for amount of time to wait for receiving a GoodCRC */
329 	struct k_timer goodcrc_rx_timer;
330 };
331 
332 #endif /* ZEPHYR_DRIVERS_USBC_DEVICE_UCPD_STM32_PRIV_H_ */
333