1 /*
2  * Copyright 2022 The Chromium OS Authors
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT st_stm32_ucpd
8 
9 #include <zephyr/logging/log.h>
10 LOG_MODULE_REGISTER(ucpd_stm32, CONFIG_USBC_LOG_LEVEL);
11 
12 #include <zephyr/device.h>
13 #include <zephyr/sys/util.h>
14 #include <zephyr/kernel.h>
15 #include <soc.h>
16 #include <stddef.h>
17 #include <zephyr/math/ilog2.h>
18 #include <stm32_ll_system.h>
19 #include <zephyr/irq.h>
20 
21 #include "ucpd_stm32_priv.h"
22 
23 static void config_tcpc_irq(void);
24 
25 /**
26  * @brief UCPD TX ORDSET values
27  */
28 static int ucpd_txorderset[] = {
29 	/* SOP ORDSET */
30 	LL_UCPD_ORDERED_SET_SOP,
31 	/* SOP PRIME ORDSET */
32 	LL_UCPD_ORDERED_SET_SOP1,
33 	/* SOP PRIME PRIME ORDSET */
34 	LL_UCPD_ORDERED_SET_SOP2,
35 	/* SOP PRIME DEBUG ORDSET */
36 	LL_UCPD_ORDERED_SET_SOP1_DEBUG,
37 	/* SOP PRIME PRIME DEBUG ORDSET */
38 	LL_UCPD_ORDERED_SET_SOP2_DEBUG,
39 	/* HARD RESET ORDSET */
40 	LL_UCPD_ORDERED_SET_HARD_RESET,
41 	/* CABLE RESET ORDSET */
42 	LL_UCPD_ORDERED_SET_CABLE_RESET,
43 };
44 
45 /**
46  * @brief Test for a goodCRC message
47  *
48  * @retval true if message is goodCRC, else false
49  */
ucpd_msg_is_good_crc(union pd_header header)50 static bool ucpd_msg_is_good_crc(union pd_header header)
51 {
52 	/*
53 	 * Good CRC is a control message (no data objects) with GOOD_CRC
54 	 * message type in the header.
55 	 */
56 	return (header.number_of_data_objects == 0 &&
57 		header.extended == 0 &&
58 		header.message_type == PD_CTRL_GOOD_CRC);
59 }
60 
61 #ifdef CONFIG_SOC_SERIES_STM32G0X
62 /**
63  * @brief Apply the UCPD CC1 and CC2 pin configurations.
64  *
65  *        UCPDx_STROBE: UCPDx pull-down configuration strobe:
66  *                      when UCPDx is enabled, with CC1 and CC2 pin UCPD
67  *                      control bits configured: apply that configuration.
68  */
update_stm32g0x_cc_line(UCPD_TypeDef * ucpd_port)69 static void update_stm32g0x_cc_line(UCPD_TypeDef *ucpd_port)
70 {
71 	if ((uint32_t)(ucpd_port) == UCPD1_BASE) {
72 		SYSCFG->CFGR1 |= SYSCFG_CFGR1_UCPD1_STROBE_Msk;
73 	} else {
74 		SYSCFG->CFGR1 |= SYSCFG_CFGR1_UCPD2_STROBE_Msk;
75 	}
76 }
77 #endif
78 
79 /**
80  * @brief Transmits a data byte from the TX data buffer
81  */
ucpd_tx_data_byte(const struct device * dev)82 static void ucpd_tx_data_byte(const struct device *dev)
83 {
84 	struct tcpc_data *data = dev->data;
85 	const struct tcpc_config *const config = dev->config;
86 	int index = data->ucpd_tx_active_buffer->msg_index++;
87 
88 	LL_UCPD_WriteData(config->ucpd_port,
89 			  data->ucpd_tx_active_buffer->data.msg[index]);
90 }
91 
92 /**
93  * @brief Receives a data byte and store it in the RX data buffer
94  */
ucpd_rx_data_byte(const struct device * dev)95 static void ucpd_rx_data_byte(const struct device *dev)
96 {
97 	struct tcpc_data *data = dev->data;
98 	const struct tcpc_config *const config = dev->config;
99 
100 	if (data->ucpd_rx_byte_count < UCPD_BUF_LEN) {
101 		data->ucpd_rx_buffer[data->ucpd_rx_byte_count++] =
102 			LL_UCPD_ReadData(config->ucpd_port);
103 	}
104 }
105 
106 /**
107  * @brief Enables or Disables TX interrupts
108  */
ucpd_tx_interrupts_enable(const struct device * dev,bool enable)109 static void ucpd_tx_interrupts_enable(const struct device *dev, bool enable)
110 {
111 	const struct tcpc_config *const config = dev->config;
112 	uint32_t imr;
113 
114 	imr = LL_UCPD_ReadReg(config->ucpd_port, IMR);
115 
116 	if (enable) {
117 		LL_UCPD_WriteReg(config->ucpd_port, ICR, UCPD_ICR_TX_INT_MASK);
118 		LL_UCPD_WriteReg(config->ucpd_port, IMR,
119 				 imr | UCPD_IMR_TX_INT_MASK);
120 	} else {
121 		LL_UCPD_WriteReg(config->ucpd_port, IMR,
122 				 imr & ~UCPD_IMR_TX_INT_MASK);
123 	}
124 }
125 
126 /**
127  * @brief Initializes the RX and TX state machine variables
128  */
stm32_ucpd_state_init(const struct device * dev)129 static void stm32_ucpd_state_init(const struct device *dev)
130 {
131 	struct tcpc_data *data = dev->data;
132 
133 	/* Init variables used to manage tx process */
134 	data->ucpd_tx_request = 0;
135 	data->tx_retry_count = 0;
136 	data->ucpd_tx_state = STATE_IDLE;
137 
138 	/* Init variables used to manage rx */
139 	data->ucpd_rx_sop_prime_enabled = false;
140 	data->ucpd_rx_msg_active = false;
141 	data->ucpd_rx_bist_mode = false;
142 
143 	/* Vconn tracking variable */
144 	data->ucpd_vconn_enable = false;
145 }
146 
147 /**
148  * @brief Get the CC enable mask. The mask indicates which CC line
149  *        is enabled.
150  *
151  * @retval CC Enable mask (bit 0: CC1, bit 1: CC2)
152  */
ucpd_get_cc_enable_mask(const struct device * dev)153 static uint32_t ucpd_get_cc_enable_mask(const struct device *dev)
154 {
155 	struct tcpc_data *data = dev->data;
156 	const struct tcpc_config *const config = dev->config;
157 	uint32_t mask = UCPD_CR_CCENABLE_Msk;
158 
159 	/*
160 	 * When VCONN is enabled, it is supplied on the CC line that's
161 	 * not being used for Power Delivery messages.
162 	 */
163 	if (data->ucpd_vconn_enable) {
164 		uint32_t cr = LL_UCPD_ReadReg(config->ucpd_port, CR);
165 		int pol = (cr & UCPD_CR_PHYCCSEL);
166 
167 		/* Dissable CC line that's used for VCONN */
168 		mask &= ~BIT(UCPD_CR_CCENABLE_Pos + !pol);
169 	}
170 
171 	return mask;
172 }
173 
174 /**
175  * @brief Get the state of the CC1 and CC2 lines
176  *
177  * @retval 0 on success
178  * @retval -EIO on failure
179  */
ucpd_get_cc(const struct device * dev,enum tc_cc_voltage_state * cc1,enum tc_cc_voltage_state * cc2)180 static int ucpd_get_cc(const struct device *dev,
181 		       enum tc_cc_voltage_state *cc1,
182 		       enum tc_cc_voltage_state *cc2)
183 {
184 	const struct tcpc_config *const config = dev->config;
185 	int vstate_cc1;
186 	int vstate_cc2;
187 	int anamode;
188 	uint32_t sr;
189 	uint32_t cc_msk;
190 
191 	/*
192 	 * cc_voltage_state is determined from vstate_cc bit field in the
193 	 * status register. The meaning of the value vstate_cc depends on
194 	 * current value of ANAMODE (src/snk).
195 	 *
196 	 * vstate_cc maps directly to cc_state from tcpci spec when
197 	 * ANAMODE(snk) = 1, but needs to be modified slightly for case
198 	 * ANAMODE(src) = 0.
199 	 *
200 	 * If presenting Rp (source), then need to do a circular shift of
201 	 * vstate_ccx value:
202 	 *     vstate_cc | cc_state
203 	 *     ------------------
204 	 *        0     ->    1
205 	 *        1     ->    2
206 	 *        2     ->    0
207 	 */
208 
209 	/* Get vstate_ccx values and power role */
210 	sr = LL_UCPD_ReadReg(config->ucpd_port, SR);
211 
212 	/* Get Rp or Rd active */
213 	anamode = LL_UCPD_GetRole(config->ucpd_port);
214 	vstate_cc1 = (sr & UCPD_SR_TYPEC_VSTATE_CC1_Msk) >>
215 		     UCPD_SR_TYPEC_VSTATE_CC1_Pos;
216 
217 	vstate_cc2 = (sr & UCPD_SR_TYPEC_VSTATE_CC2_Msk) >>
218 		     UCPD_SR_TYPEC_VSTATE_CC2_Pos;
219 
220 	/* Do circular shift if port == source */
221 	if (anamode) {
222 		if (vstate_cc1 != STM32_UCPD_SR_VSTATE_RA) {
223 			vstate_cc1 += 4;
224 		}
225 		if (vstate_cc2 != STM32_UCPD_SR_VSTATE_RA) {
226 			vstate_cc2 += 4;
227 		}
228 	} else {
229 		if (vstate_cc1 != STM32_UCPD_SR_VSTATE_OPEN) {
230 			vstate_cc1 = (vstate_cc1 + 1) % 3;
231 		}
232 		if (vstate_cc2 != STM32_UCPD_SR_VSTATE_OPEN) {
233 			vstate_cc2 = (vstate_cc2 + 1) % 3;
234 		}
235 	}
236 
237 	/* CC connection detection */
238 	cc_msk = ucpd_get_cc_enable_mask(dev);
239 
240 	/* CC1 connection detection */
241 	if (cc_msk & UCPD_CR_CCENABLE_0) {
242 		*cc1 = vstate_cc1;
243 	} else {
244 		*cc1 = TC_CC_VOLT_OPEN;
245 	}
246 
247 	/* CC2 connection detection */
248 	if (cc_msk & UCPD_CR_CCENABLE_1) {
249 		*cc2 = vstate_cc2;
250 	} else {
251 		*cc2 = TC_CC_VOLT_OPEN;
252 	}
253 
254 	return 0;
255 }
256 
257 /**
258  * @brief Enable or Disable VCONN
259  *
260  * @retval 0 on success
261  * @retval -EIO on failure
262  * @retval -ENOTSUP if not supported
263  */
ucpd_set_vconn(const struct device * dev,bool enable)264 static int ucpd_set_vconn(const struct device *dev, bool enable)
265 {
266 	struct tcpc_data *data = dev->data;
267 	const struct tcpc_config *const config = dev->config;
268 	int cr;
269 	int ret;
270 
271 	if (data->vconn_cb == NULL) {
272 		return -ENOTSUP;
273 	}
274 
275 	/* Update VCONN on/off status. Do this before getting cc enable mask */
276 	data->ucpd_vconn_enable = enable;
277 
278 	cr = LL_UCPD_ReadReg(config->ucpd_port, CR);
279 	cr &= ~UCPD_CR_CCENABLE_Msk;
280 	cr |= ucpd_get_cc_enable_mask(dev);
281 
282 	/* Apply cc pull resistor change */
283 	LL_UCPD_WriteReg(config->ucpd_port, CR, cr);
284 
285 #ifdef CONFIG_SOC_SERIES_STM32G0X
286 	update_stm32g0x_cc_line(config->ucpd_port);
287 #endif
288 
289 	/* Get CC line that VCONN is active on */
290 	data->ucpd_vconn_cc = (cr & UCPD_CR_CCENABLE_0) ?
291 				TC_POLARITY_CC2 : TC_POLARITY_CC1;
292 
293 	/* Call user supplied callback to set vconn */
294 	ret = data->vconn_cb(dev, data->ucpd_vconn_cc, enable);
295 
296 	return ret;
297 }
298 
299 /**
300  * @brief Discharge VCONN
301  *
302  * @retval 0 on success
303  * @retval -EIO on failure
304  * @retval -ENOTSUP if not supported
305  */
ucpd_vconn_discharge(const struct device * dev,bool enable)306 static int ucpd_vconn_discharge(const struct device *dev, bool enable)
307 {
308 	struct tcpc_data *data = dev->data;
309 	const struct tcpc_config *const config = dev->config;
310 
311 	/* VCONN should not be discharged while it's enabled */
312 	if (data->ucpd_vconn_enable) {
313 		return -EIO;
314 	}
315 
316 	if (data->vconn_discharge_cb) {
317 		/* Use DPM supplied VCONN Discharge */
318 		return data->vconn_discharge_cb(dev, data->ucpd_vconn_cc, enable);
319 	}
320 
321 	/* Use TCPC VCONN Discharge */
322 	if (enable) {
323 		LL_UCPD_VconnDischargeEnable(config->ucpd_port);
324 	} else {
325 		LL_UCPD_VconnDischargeDisable(config->ucpd_port);
326 	}
327 
328 #ifdef CONFIG_SOC_SERIES_STM32G0X
329 	update_stm32g0x_cc_line(config->ucpd_port);
330 #endif
331 
332 	return 0;
333 }
334 
335 /**
336  * @brief Sets the value of the CC pull up resistor used when operating as a Source
337  *
338  * @retval 0 on success
339  */
ucpd_select_rp_value(const struct device * dev,enum tc_rp_value rp)340 static int ucpd_select_rp_value(const struct device *dev, enum tc_rp_value rp)
341 {
342 	struct tcpc_data *data = dev->data;
343 
344 	data->rp = rp;
345 
346 	return 0;
347 }
348 
349 /**
350  * @brief Gets the value of the CC pull up resistor used when operating as a Source
351  *
352  * @retval 0 on success
353  */
ucpd_get_rp_value(const struct device * dev,enum tc_rp_value * rp)354 static int ucpd_get_rp_value(const struct device *dev, enum tc_rp_value *rp)
355 {
356 	struct tcpc_data *data = dev->data;
357 
358 	*rp = data->rp;
359 
360 	return 0;
361 }
362 
363 /**
364  * @brief Enable or disable Dead Battery resistors
365  */
dead_battery(const struct device * dev,bool en)366 static void dead_battery(const struct device *dev, bool en)
367 {
368 	struct tcpc_data *data = dev->data;
369 
370 #ifdef CONFIG_SOC_SERIES_STM32G0X
371 	const struct tcpc_config *const config = dev->config;
372 	uint32_t cr;
373 
374 	cr = LL_UCPD_ReadReg(config->ucpd_port, CR);
375 
376 	if (en) {
377 		cr |= UCPD_CR_DBATTEN;
378 	} else {
379 		cr &= ~UCPD_CR_DBATTEN;
380 	}
381 
382 	LL_UCPD_WriteReg(config->ucpd_port, CR, cr);
383 	update_stm32g0x_cc_line(config->ucpd_port);
384 #else
385 	if (en) {
386 		CLEAR_BIT(PWR->CR3, PWR_CR3_UCPD_DBDIS);
387 	} else {
388 		SET_BIT(PWR->CR3, PWR_CR3_UCPD_DBDIS);
389 	}
390 #endif
391 	data->dead_battery_active = en;
392 }
393 
394 /**
395  * @brief Set the CC pull up or pull down resistors
396  *
397  * @retval 0 on success
398  * @retval -EIO on failure
399  */
ucpd_set_cc(const struct device * dev,enum tc_cc_pull cc_pull)400 static int ucpd_set_cc(const struct device *dev,
401 		       enum tc_cc_pull cc_pull)
402 {
403 	const struct tcpc_config *const config = dev->config;
404 	struct tcpc_data *data = dev->data;
405 	uint32_t cr;
406 
407 	/* Disable dead battery if it's active */
408 	if (data->dead_battery_active) {
409 		dead_battery(dev, false);
410 	}
411 
412 	cr = LL_UCPD_ReadReg(config->ucpd_port, CR);
413 
414 	/*
415 	 * Always set ANASUBMODE to match desired Rp. TCPM layer has a valid
416 	 * range of 0, 1, or 2. This range maps to 1, 2, or 3 in ucpd for
417 	 * ANASUBMODE.
418 	 */
419 	cr &= ~UCPD_CR_ANASUBMODE_Msk;
420 	cr |= STM32_UCPD_CR_ANASUBMODE_VAL(UCPD_RP_TO_ANASUB(data->rp));
421 
422 	/* Disconnect both pull from both CC lines for R_open case */
423 	cr &= ~UCPD_CR_CCENABLE_Msk;
424 	/* Set ANAMODE if cc_pull is Rd */
425 	if (cc_pull == TC_CC_RD) {
426 		cr |= (UCPD_CR_ANAMODE | UCPD_CR_CCENABLE_Msk);
427 		/* Clear ANAMODE if cc_pull is Rp */
428 	} else if (cc_pull == TC_CC_RP) {
429 		cr &= ~(UCPD_CR_ANAMODE);
430 		cr |= ucpd_get_cc_enable_mask(dev);
431 	}
432 
433 	/* Update pull values */
434 	LL_UCPD_WriteReg(config->ucpd_port, CR, cr);
435 
436 #ifdef CONFIG_SOC_SERIES_STM32G0X
437 	update_stm32g0x_cc_line(config->ucpd_port);
438 #endif
439 
440 	return 0;
441 }
442 
443 /**
444  * @brief Set the polarity of the CC line, which is the active CC line
445  *        used for power delivery.
446  *
447  * @retval 0 on success
448  * @retval -EIO on failure
449  * @retval -ENOTSUP if polarity is not supported
450  */
ucpd_cc_set_polarity(const struct device * dev,enum tc_cc_polarity polarity)451 static int ucpd_cc_set_polarity(const struct device *dev,
452 				enum tc_cc_polarity polarity)
453 {
454 	const struct tcpc_config *const config = dev->config;
455 	uint32_t cr;
456 
457 	cr = LL_UCPD_ReadReg(config->ucpd_port, CR);
458 
459 	/*
460 	 * Polarity impacts the PHYCCSEL, CCENABLE, and CCxTCDIS fields. This
461 	 * function is called when polarity is updated at TCPM layer. STM32Gx
462 	 * only supports POLARITY_CC1 or POLARITY_CC2 and this is stored in the
463 	 * PHYCCSEL bit in the CR register.
464 	 */
465 
466 	if (polarity == TC_POLARITY_CC1) {
467 		cr &= ~UCPD_CR_PHYCCSEL;
468 	} else if (polarity == TC_POLARITY_CC2) {
469 		cr |= UCPD_CR_PHYCCSEL;
470 	} else {
471 		return -ENOTSUP;
472 	}
473 
474 	/* Update polarity */
475 	LL_UCPD_WriteReg(config->ucpd_port, CR, cr);
476 
477 	return 0;
478 }
479 
480 /**
481  * @brief Enable or Disable Power Delivery
482  *
483  * @retval 0 on success
484  * @retval -EIO on failure
485  */
ucpd_set_rx_enable(const struct device * dev,bool enable)486 static int ucpd_set_rx_enable(const struct device *dev, bool enable)
487 {
488 	const struct tcpc_config *const config = dev->config;
489 	uint32_t imr;
490 	uint32_t cr;
491 
492 	imr = LL_UCPD_ReadReg(config->ucpd_port, IMR);
493 	cr = LL_UCPD_ReadReg(config->ucpd_port, CR);
494 
495 	/*
496 	 * USB PD receiver enable is controlled by the bit PHYRXEN in
497 	 * UCPD_CR. Enable Rx interrupts when RX PD decoder is active.
498 	 */
499 	if (enable) {
500 		/* Clear the RX alerts bits */
501 		LL_UCPD_WriteReg(config->ucpd_port, ICR, UCPD_ICR_RX_INT_MASK);
502 		imr |= UCPD_IMR_RX_INT_MASK;
503 		cr |= UCPD_CR_PHYRXEN;
504 		LL_UCPD_WriteReg(config->ucpd_port, IMR, imr);
505 		LL_UCPD_WriteReg(config->ucpd_port, CR, cr);
506 	} else {
507 		imr &= ~UCPD_IMR_RX_INT_MASK;
508 		cr &= ~UCPD_CR_PHYRXEN;
509 		LL_UCPD_WriteReg(config->ucpd_port, CR, cr);
510 		LL_UCPD_WriteReg(config->ucpd_port, IMR, imr);
511 	}
512 
513 	return 0;
514 }
515 
516 /**
517  * @brief Set the Power and Data role used when sending goodCRC messages
518  *
519  * @retval 0 on success
520  * @retval -EIO on failure
521  */
ucpd_set_roles(const struct device * dev,enum tc_power_role power_role,enum tc_data_role data_role)522 static int ucpd_set_roles(const struct device *dev,
523 			  enum tc_power_role power_role,
524 			  enum tc_data_role data_role)
525 {
526 	struct tcpc_data *data = dev->data;
527 
528 	data->msg_header.pr = power_role;
529 	data->msg_header.dr = data_role;
530 
531 	return 0;
532 }
533 
534 /**
535  * @brief Enable the reception of SOP Prime messages
536  *
537  * @retval 0 on success
538  * @retval -EIO on failure
539  */
ucpd_sop_prime_enable(const struct device * dev,bool enable)540 static int ucpd_sop_prime_enable(const struct device *dev, bool enable)
541 {
542 	struct tcpc_data *data = dev->data;
543 
544 	/* Update static variable used to filter SOP//SOP'' messages */
545 	data->ucpd_rx_sop_prime_enabled = enable;
546 
547 	return 0;
548 }
549 
550 /**
551  * @brief State transmitting a message
552  */
ucpd_start_transmit(const struct device * dev,enum ucpd_tx_msg msg_type)553 static void ucpd_start_transmit(const struct device *dev,
554 				enum ucpd_tx_msg msg_type)
555 {
556 	struct tcpc_data *data = dev->data;
557 	const struct tcpc_config *const config = dev->config;
558 	enum pd_packet_type type;
559 	uint32_t cr;
560 	uint32_t imr;
561 
562 	cr = LL_UCPD_ReadReg(config->ucpd_port, CR);
563 
564 	/* Select the correct tx descriptor */
565 	data->ucpd_tx_active_buffer = &data->ucpd_tx_buffers[msg_type];
566 	type = data->ucpd_tx_active_buffer->type;
567 
568 	if (type == PD_PACKET_TX_HARD_RESET) {
569 		/*
570 		 * From RM0440 45.4.4:
571 		 * In order to facilitate generation of a Hard Reset, a special
572 		 * code of TXMODE field is used. No other fields need to be
573 		 * written. On writing the correct code, the hardware forces
574 		 * Hard Reset Tx under the correct (optimal) timings with
575 		 * respect to an on-going Tx message, which (if still in
576 		 * progress) is cleanly terminated by truncating the current
577 		 * sequence and directly appending an EOP K-code sequence. No
578 		 * specific interrupt is generated relating to this truncation
579 		 * event.
580 		 *
581 		 * Because Hard Reset can interrupt ongoing Tx operations, it is
582 		 * started differently than all other tx messages. Only need to
583 		 * enable hard reset interrupts, and then set a bit in the CR
584 		 * register to initiate.
585 		 */
586 		/* Enable interrupt for Hard Reset sent/discarded */
587 		LL_UCPD_WriteReg(config->ucpd_port, ICR,
588 				 UCPD_ICR_HRSTDISCCF | UCPD_ICR_HRSTSENTCF);
589 
590 		imr = LL_UCPD_ReadReg(config->ucpd_port, IMR);
591 		imr |= UCPD_IMR_HRSTDISCIE | UCPD_IMR_HRSTSENTIE;
592 		LL_UCPD_WriteReg(config->ucpd_port, IMR, imr);
593 
594 		/* Initiate Hard Reset */
595 		cr |= UCPD_CR_TXHRST;
596 		LL_UCPD_WriteReg(config->ucpd_port, CR, cr);
597 	} else if (type != PD_PACKET_MSG_INVALID) {
598 		int msg_len = 0;
599 		int mode;
600 
601 		/*
602 		 * These types are normal transmission, TXMODE = 0. To transmit
603 		 * regular message, control or data, requires the following:
604 		 *     1. Set TXMODE:
605 		 *          Normal -> 0
606 		 *          Cable Reset -> 1
607 		 *          Bist -> 2
608 		 *     2. Set TX_ORDSETR based on message type
609 		 *     3. Set TX_PAYSZR which must account for 2 bytes of header
610 		 *     4. Configure DMA (optional if DMA is desired)
611 		 *     5. Enable transmit interrupts
612 		 *     6. Start TX by setting TXSEND in CR
613 		 *
614 		 */
615 
616 		/*
617 		 * Set tx length parameter (in bytes). Note the count field in
618 		 * the header is number of 32 bit objects. Also, the length
619 		 * field must account for the 2 header bytes.
620 		 */
621 		if (type == PD_PACKET_TX_BIST_MODE_2) {
622 			mode = LL_UCPD_TXMODE_BIST_CARRIER2;
623 		} else if (type == PD_PACKET_CABLE_RESET) {
624 			mode = LL_UCPD_TXMODE_CABLE_RESET;
625 		} else {
626 			mode = LL_UCPD_TXMODE_NORMAL;
627 			msg_len = data->ucpd_tx_active_buffer->msg_len;
628 		}
629 
630 		LL_UCPD_WriteTxPaySize(config->ucpd_port, msg_len);
631 
632 		/* Set tx mode */
633 		cr &= ~UCPD_CR_TXMODE_Msk;
634 		cr |= mode;
635 		LL_UCPD_WriteReg(config->ucpd_port, CR, cr);
636 
637 		/* Index into ordset enum for start of packet */
638 		if (type <= PD_PACKET_CABLE_RESET) {
639 			LL_UCPD_WriteTxOrderSet(config->ucpd_port,
640 						ucpd_txorderset[type]);
641 		}
642 
643 		/* Reset msg byte index */
644 		data->ucpd_tx_active_buffer->msg_index = 0;
645 
646 		/* Enable interrupts */
647 		ucpd_tx_interrupts_enable(dev, 1);
648 
649 		/* Trigger ucpd peripheral to start pd message transmit */
650 		LL_UCPD_SendMessage(config->ucpd_port);
651 	}
652 }
653 
654 /**
655  * @brief Set the current state of the TX state machine
656  */
ucpd_set_tx_state(const struct device * dev,enum ucpd_state state)657 static void ucpd_set_tx_state(const struct device *dev, enum ucpd_state state)
658 {
659 	struct tcpc_data *data = dev->data;
660 
661 	data->ucpd_tx_state = state;
662 }
663 
664 /**
665  * @brief Wrapper function for calling alert handler
666  */
ucpd_notify_handler(struct alert_info * info,enum tcpc_alert alert)667 static void ucpd_notify_handler(struct alert_info *info, enum tcpc_alert alert)
668 {
669 	if (info->handler) {
670 		info->handler(info->dev, info->data, alert);
671 	}
672 }
673 
674 /**
675  * @brief This is the TX state machine
676  */
ucpd_manage_tx(struct alert_info * info)677 static void ucpd_manage_tx(struct alert_info *info)
678 {
679 	struct tcpc_data *data = info->dev->data;
680 	enum ucpd_tx_msg msg_src = TX_MSG_NONE;
681 	union pd_header hdr;
682 
683 	if (atomic_test_and_clear_bit(&info->evt, UCPD_EVT_HR_REQ)) {
684 		/*
685 		 * Hard reset control messages are treated as a priority. The
686 		 * control message will already be set up as it comes from the
687 		 * PRL layer like any other PD ctrl/data message. So just need
688 		 * to indicate the correct message source and set the state to
689 		 * hard reset here.
690 		 */
691 		ucpd_set_tx_state(info->dev, STATE_HARD_RESET);
692 		msg_src = TX_MSG_TCPM;
693 		data->ucpd_tx_request &= ~BIT(msg_src);
694 	}
695 
696 	switch (data->ucpd_tx_state) {
697 	case STATE_IDLE:
698 		if (data->ucpd_tx_request & MSG_GOOD_CRC_MASK) {
699 			ucpd_set_tx_state(info->dev, STATE_ACTIVE_CRC);
700 			msg_src = TX_MSG_GOOD_CRC;
701 		} else if (data->ucpd_tx_request & MSG_TCPM_MASK) {
702 			if (atomic_test_and_clear_bit(&info->evt, UCPD_EVT_RX_MSG)) {
703 				/*
704 				 * USB-PD Specification rev 3.0, section 6.10
705 				 * On receiving a received message, the protocol
706 				 * layer shall discard any pending message.
707 				 *
708 				 * Since the pending message from the PRL has
709 				 * not been sent yet, it needs to be discarded
710 				 * based on the received message event.
711 				 */
712 				ucpd_notify_handler(info, TCPC_ALERT_TRANSMIT_MSG_DISCARDED);
713 				data->ucpd_tx_request &= ~MSG_TCPM_MASK;
714 			} else if (!data->ucpd_rx_msg_active) {
715 				ucpd_set_tx_state(info->dev, STATE_ACTIVE_TCPM);
716 				msg_src = TX_MSG_TCPM;
717 				/* Save msgID required for GoodCRC check */
718 				hdr.raw_value =
719 					data->ucpd_tx_buffers[TX_MSG_TCPM].data.header;
720 				data->msg_id_match = hdr.message_id;
721 				data->tx_retry_max = hdr.specification_revision == PD_REV30 ?
722 						     UCPD_N_RETRY_COUNT_REV30 :
723 						     UCPD_N_RETRY_COUNT_REV20;
724 			}
725 		}
726 
727 		/* If state is not idle, then start tx message */
728 		if (data->ucpd_tx_state != STATE_IDLE) {
729 			data->ucpd_tx_request &= ~BIT(msg_src);
730 			data->tx_retry_count = 0;
731 		}
732 		break;
733 
734 	case STATE_ACTIVE_TCPM:
735 		/*
736 		 * Check if tx msg has finished. For TCPM messages
737 		 * transmit is not complete until a GoodCRC message
738 		 * matching the msgID just sent is received. But, a tx
739 		 * message can fail due to collision or underrun,
740 		 * etc. If that failure occurs, dont' wait for GoodCrc
741 		 * and just go to failure path.
742 		 */
743 		if (atomic_test_and_clear_bit(&info->evt, UCPD_EVT_TX_MSG_SUCCESS)) {
744 			ucpd_set_tx_state(info->dev, STATE_WAIT_CRC_ACK);
745 			/* Start the GoodCRC RX Timer */
746 			k_timer_start(&data->goodcrc_rx_timer, K_USEC(1000), K_NO_WAIT);
747 		} else if (atomic_test_and_clear_bit(&info->evt, UCPD_EVT_TX_MSG_DISC) ||
748 			  atomic_test_and_clear_bit(&info->evt, UCPD_EVT_TX_MSG_FAIL)) {
749 			if (data->tx_retry_count < data->tx_retry_max) {
750 				if (atomic_test_and_clear_bit(&info->evt, UCPD_EVT_RX_MSG)) {
751 					/*
752 					 * A message was received so there is no
753 					 * need to retry this tx message which
754 					 * had failed to send previously.
755 					 * Likely, due to the wire
756 					 * being active from the message that
757 					 * was just received.
758 					 */
759 					ucpd_set_tx_state(info->dev,
760 							  STATE_IDLE);
761 					ucpd_notify_handler(info,
762 							TCPC_ALERT_TRANSMIT_MSG_DISCARDED);
763 					ucpd_set_tx_state(info->dev,
764 							  STATE_IDLE);
765 				} else {
766 					/*
767 					 * Tx attempt failed. Remain in this
768 					 * state, but trigger new tx attempt.
769 					 */
770 					msg_src = TX_MSG_TCPM;
771 					data->tx_retry_count++;
772 				}
773 			} else {
774 				enum tcpc_alert status;
775 
776 				status = (atomic_test_and_clear_bit(&info->evt,
777 								UCPD_EVT_TX_MSG_FAIL)) ?
778 					 TCPC_ALERT_TRANSMIT_MSG_FAILED :
779 					 TCPC_ALERT_TRANSMIT_MSG_DISCARDED;
780 				ucpd_set_tx_state(info->dev, STATE_IDLE);
781 				ucpd_notify_handler(info, status);
782 			}
783 		}
784 		break;
785 
786 	case STATE_ACTIVE_CRC:
787 		if (atomic_test_bit(&info->evt, UCPD_EVT_TX_MSG_SUCCESS) ||
788 				atomic_test_bit(&info->evt, UCPD_EVT_TX_MSG_FAIL) ||
789 				atomic_test_bit(&info->evt, UCPD_EVT_TX_MSG_DISC)) {
790 			atomic_clear_bit(&info->evt, UCPD_EVT_TX_MSG_SUCCESS);
791 			atomic_clear_bit(&info->evt, UCPD_EVT_TX_MSG_FAIL);
792 			atomic_clear_bit(&info->evt, UCPD_EVT_TX_MSG_DISC);
793 			ucpd_set_tx_state(info->dev, STATE_IDLE);
794 			if (atomic_test_and_clear_bit(&info->evt, UCPD_EVT_TX_MSG_FAIL)) {
795 				LOG_INF("ucpd: Failed to send GoodCRC!");
796 			} else if (atomic_test_and_clear_bit(&info->evt, UCPD_EVT_TX_MSG_DISC)) {
797 				LOG_INF("ucpd: GoodCRC message discarded!");
798 			}
799 		}
800 		break;
801 
802 	case STATE_WAIT_CRC_ACK:
803 		if (atomic_test_and_clear_bit(&info->evt, UCPD_EVT_RX_GOOD_CRC) &&
804 		    data->ucpd_crc_id == data->msg_id_match) {
805 			/* GoodCRC with matching ID was received */
806 			ucpd_notify_handler(info, TCPC_ALERT_TRANSMIT_MSG_SUCCESS);
807 			ucpd_set_tx_state(info->dev, STATE_IDLE);
808 		} else if (k_timer_status_get(&data->goodcrc_rx_timer)) {
809 			/* Stop the GoodCRC RX Timer */
810 			k_timer_stop(&data->goodcrc_rx_timer);
811 
812 			/* GoodCRC w/out match or timeout waiting */
813 			if (data->tx_retry_count < data->tx_retry_max) {
814 				ucpd_set_tx_state(info->dev, STATE_ACTIVE_TCPM);
815 				msg_src = TX_MSG_TCPM;
816 				data->tx_retry_count++;
817 			} else {
818 				ucpd_set_tx_state(info->dev, STATE_IDLE);
819 				ucpd_notify_handler(info, TCPC_ALERT_TRANSMIT_MSG_FAILED);
820 			}
821 		} else if (atomic_test_and_clear_bit(&info->evt, UCPD_EVT_RX_MSG)) {
822 			/*
823 			 * In the case of a collision, it's possible the port
824 			 * partner may not send a GoodCRC and instead send the
825 			 * message that was colliding. If a message is received
826 			 * in this state, then treat it as a discard from an
827 			 * incoming message.
828 			 */
829 			ucpd_notify_handler(info, TCPC_ALERT_TRANSMIT_MSG_DISCARDED);
830 			ucpd_set_tx_state(info->dev, STATE_IDLE);
831 		}
832 		break;
833 
834 	case STATE_HARD_RESET:
835 		if (atomic_test_bit(&info->evt, UCPD_EVT_HR_DONE) ||
836 		    atomic_test_bit(&info->evt, UCPD_EVT_HR_FAIL)) {
837 			atomic_clear_bit(&info->evt, UCPD_EVT_HR_DONE);
838 			atomic_clear_bit(&info->evt, UCPD_EVT_HR_FAIL);
839 			/* HR complete, reset tx state values */
840 			ucpd_set_tx_state(info->dev, STATE_IDLE);
841 			data->ucpd_tx_request = 0;
842 			data->tx_retry_count = 0;
843 		}
844 		break;
845 	}
846 
847 	/*
848 	 * NOTE: TX_MSG_GOOD_CRC messages are sent from the ISR to reduce latency
849 	 * when sending those messages, so don't resend them here.
850 	 *
851 	 * If msg_src is valid and not a TX_MSG_GOOD_CRC, then start transmit.
852 	 */
853 	if (msg_src != TX_MSG_GOOD_CRC && msg_src > TX_MSG_NONE) {
854 		ucpd_start_transmit(info->dev, msg_src);
855 	}
856 }
857 
858 /**
859  * @brief Alert handler
860  */
ucpd_alert_handler(struct k_work * item)861 static void ucpd_alert_handler(struct k_work *item)
862 {
863 	struct alert_info *info = CONTAINER_OF(item, struct alert_info, work);
864 	struct tcpc_data *data = info->dev->data;
865 
866 	if (atomic_test_and_clear_bit(&info->evt, UCPD_EVT_EVENT_CC)) {
867 		ucpd_notify_handler(info, TCPC_ALERT_CC_STATUS);
868 	}
869 
870 	if (atomic_test_and_clear_bit(&info->evt, UCPD_EVT_HARD_RESET_RECEIVED)) {
871 		ucpd_notify_handler(info, TCPC_ALERT_HARD_RESET_RECEIVED);
872 	}
873 
874 	if (atomic_test_and_clear_bit(&info->evt, UCPD_EVT_RX_MSG)) {
875 		ucpd_notify_handler(info, TCPC_ALERT_MSG_STATUS);
876 	}
877 
878 	/*
879 	 * USB-PD messages are initiated in TCPM stack (PRL
880 	 * layer). However, GoodCRC messages are initiated within the
881 	 * UCPD driver based on USB-PD rx messages. These 2 types of
882 	 * transmit paths are managed via events.
883 	 *
884 	 * UCPD generated GoodCRC messages, are the priority path as
885 	 * they must be sent immediately following a successful USB-PD
886 	 * rx message. As long as a transmit operation is not underway,
887 	 * then a transmit message will be started upon request. The ISR
888 	 * routine sets the event to indicate that the transmit
889 	 * operation is complete.
890 	 *
891 	 * Hard reset requests are sent as a TCPM message, but in terms
892 	 * of the ucpd transmitter, they are treated as a 3rd tx msg
893 	 * source since they can interrupt an ongoing tx msg, and there
894 	 * is no requirement to wait for a GoodCRC reply message.
895 	 */
896 
897 	if (atomic_test_and_clear_bit(&info->evt, UCPD_EVT_GOOD_CRC_REQ)) {
898 		data->ucpd_tx_request |= MSG_GOOD_CRC_MASK;
899 	}
900 
901 	if (atomic_test_and_clear_bit(&info->evt, UCPD_EVT_TCPM_MSG_REQ)) {
902 		data->ucpd_tx_request |= MSG_TCPM_MASK;
903 	}
904 
905 	/*
906 	 * Manage PD tx messages. The state machine may need to be
907 	 * called more than once. For instance, if
908 	 * the task is woken at the completion of sending a GoodCRC,
909 	 * there may be a TCPM message request pending and just changing
910 	 * the state back to idle would not trigger start of transmit.
911 	 */
912 	do {
913 		ucpd_manage_tx(info);
914 	} while (data->ucpd_tx_state != STATE_IDLE);
915 }
916 
917 /**
918  * @brief Sends a goodCRC message
919  */
ucpd_send_good_crc(const struct device * dev,union pd_header rx_header)920 static void ucpd_send_good_crc(const struct device *dev,
921 			       union pd_header rx_header)
922 {
923 	struct tcpc_data *data = dev->data;
924 	const struct tcpc_config *const config = dev->config;
925 	union pd_header tx_header;
926 	enum pd_packet_type tx_type;
927 	struct alert_info *info = &data->alert_info;
928 
929 	/*
930 	 * A GoodCRC message shall be sent by receiver to ack that the previous
931 	 * message was correctly received. The GoodCRC message shall return the
932 	 * rx message's msg_id field. The one exception is for GoodCRC messages,
933 	 * which do not generate a GoodCRC response
934 	 */
935 	if (ucpd_msg_is_good_crc(rx_header)) {
936 		return;
937 	}
938 
939 	/*
940 	 * Get the rx ordered set code just detected. SOP -> SOP''_Debug are in
941 	 * the same order as enum tcpc_packet_type and so can be used
942 	 * directly.
943 	 */
944 	tx_type = LL_UCPD_ReadRxOrderSet(config->ucpd_port);
945 
946 	/*
947 	 * PD Header(SOP):
948 	 *   Extended   b15    -> set to 0 for control messages
949 	 *   Count      b14:12 -> number of 32 bit data objects = 0 for ctrl msg
950 	 *   MsgID      b11:9  -> running byte counter (extracted from rx msg)
951 	 *   Power Role b8     -> stored in static, from set_msg_header()
952 	 *   Spec Rev   b7:b6  -> PD spec revision (extracted from rx msg)
953 	 *   Data Role  b5     -> stored in static, from set_msg_header
954 	 *   Msg Type   b4:b0  -> data or ctrl type = PD_CTRL_GOOD_CRC
955 	 */
956 	/* construct header message */
957 	tx_header.message_type = PD_CTRL_GOOD_CRC;
958 	if (tx_type == PD_PACKET_SOP) {
959 		tx_header.port_power_role = data->msg_header.pr;
960 		tx_header.port_data_role = data->msg_header.dr;
961 	} else {
962 		tx_header.port_power_role = 0;
963 		tx_header.port_data_role = 0;
964 	}
965 	tx_header.message_id = rx_header.message_id;
966 	tx_header.number_of_data_objects = 0;
967 	tx_header.specification_revision = rx_header.specification_revision;
968 	tx_header.extended = 0;
969 
970 	/* Good CRC is header with no other objects */
971 	data->ucpd_tx_buffers[TX_MSG_GOOD_CRC].msg_len = MSG_HEADER_SIZE;
972 	data->ucpd_tx_buffers[TX_MSG_GOOD_CRC].data.header =
973 		tx_header.raw_value;
974 	data->ucpd_tx_buffers[TX_MSG_GOOD_CRC].type = tx_type;
975 
976 	/* Notify ucpd task that a GoodCRC message tx request is pending */
977 	atomic_set_bit(&info->evt, UCPD_EVT_GOOD_CRC_REQ);
978 
979 	/* Send TX_MSG_GOOD_CRC message here to reduce latency */
980 	ucpd_start_transmit(dev, TX_MSG_GOOD_CRC);
981 }
982 
983 /**
984  * @brief Transmit a power delivery message
985  *
986  * @retval 0 on success
987  * @retval -EFAULT on failure
988  */
ucpd_transmit_data(const struct device * dev,struct pd_msg * msg)989 static int ucpd_transmit_data(const struct device *dev,
990 			      struct pd_msg *msg)
991 {
992 	struct tcpc_data *data = dev->data;
993 
994 	/* Length in bytes = (4 * object len) + 2 header bytes */
995 	int len = PD_CONVERT_PD_HEADER_COUNT_TO_BYTES(msg->header.number_of_data_objects) + 2;
996 
997 	if (len > UCPD_BUF_LEN) {
998 		return -EFAULT;
999 	}
1000 
1001 	/* Store tx msg info in TCPM msg descriptor */
1002 	data->ucpd_tx_buffers[TX_MSG_TCPM].msg_len = len;
1003 	data->ucpd_tx_buffers[TX_MSG_TCPM].type = msg->type;
1004 	data->ucpd_tx_buffers[TX_MSG_TCPM].data.header = msg->header.raw_value;
1005 
1006 	/* Copy msg objects to ucpd data buffer, after 2 header bytes */
1007 	memcpy(data->ucpd_tx_buffers[TX_MSG_TCPM].data.msg + 2,
1008 	       (uint8_t *)msg->data, len - 2);
1009 
1010 	/*
1011 	 * Check for hard reset message here. A different event is used for hard
1012 	 * resets as they are able to interrupt ongoing transmit, and should
1013 	 * have priority over any pending message.
1014 	 */
1015 	if (msg->type == PD_PACKET_TX_HARD_RESET) {
1016 		atomic_set_bit(&data->alert_info.evt, UCPD_EVT_HR_REQ);
1017 	} else {
1018 		atomic_set_bit(&data->alert_info.evt, UCPD_EVT_TCPM_MSG_REQ);
1019 	}
1020 
1021 	/* Start transmission */
1022 	k_work_submit(&data->alert_info.work);
1023 
1024 	return 0;
1025 }
1026 
1027 /**
1028  * @brief Tests if a received Power Delivery message is pending
1029  *
1030  * @retval true if message is pending, else false
1031  */
ucpd_is_rx_pending_msg(const struct device * dev,enum pd_packet_type * type)1032 static bool ucpd_is_rx_pending_msg(const struct device *dev,
1033 				   enum pd_packet_type *type)
1034 {
1035 	struct tcpc_data *data = dev->data;
1036 	bool ret;
1037 
1038 	ret = (*(uint32_t *)data->ucpd_rx_buffer > 0);
1039 
1040 	if (ret & (type != NULL)) {
1041 		*type = *(uint16_t *)data->ucpd_rx_buffer;
1042 	}
1043 
1044 	return ret;
1045 }
1046 
1047 /**
1048  * @brief Retrieves the Power Delivery message from the TCPC
1049  *
1050  * @retval number of bytes received
1051  * @retval -EIO on no message to retrieve
1052  * @retval -EFAULT on buf being NULL
1053  */
ucpd_receive_data(const struct device * dev,struct pd_msg * msg)1054 static int ucpd_receive_data(const struct device *dev, struct pd_msg *msg)
1055 {
1056 	struct tcpc_data *data = dev->data;
1057 	int ret = 0;
1058 
1059 	if (msg == NULL) {
1060 		return -EFAULT;
1061 	}
1062 
1063 	/* Make sure we have a message to retrieve */
1064 	if (!ucpd_is_rx_pending_msg(dev, NULL)) {
1065 		return -EIO;
1066 	}
1067 
1068 	msg->type = *(uint16_t *)data->ucpd_rx_buffer;
1069 	msg->header.raw_value = *((uint16_t *)data->ucpd_rx_buffer + 1);
1070 	msg->len = PD_CONVERT_PD_HEADER_COUNT_TO_BYTES(msg->header.number_of_data_objects);
1071 	memcpy(msg->data, (data->ucpd_rx_buffer +
1072 			   PACKET_TYPE_SIZE +
1073 			   MSG_HEADER_SIZE), msg->len);
1074 	ret = msg->len + MSG_HEADER_SIZE;
1075 
1076 	/* All done. Clear type and header */
1077 	*(uint32_t *)data->ucpd_rx_buffer = 0;
1078 
1079 	return ret;
1080 }
1081 
1082 /**
1083  * @brief Enable or Disable BIST Test mode
1084  *
1085  * return 0 on success
1086  * return -EIO on failure
1087  */
ucpd_set_bist_test_mode(const struct device * dev,bool enable)1088 static int ucpd_set_bist_test_mode(const struct device *dev,
1089 				   bool enable)
1090 {
1091 	struct tcpc_data *data = dev->data;
1092 
1093 	data->ucpd_rx_bist_mode = enable;
1094 	LOG_INF("ucpd: Bist test mode = %d", enable);
1095 
1096 	return 0;
1097 }
1098 
1099 /**
1100  * @brief UCPD interrupt handler
1101  */
ucpd_isr(const struct device * dev_inst[])1102 static void ucpd_isr(const struct device *dev_inst[])
1103 {
1104 	const struct device *dev;
1105 	const struct tcpc_config *config;
1106 	struct tcpc_data *data;
1107 	uint32_t sr;
1108 	struct alert_info *info;
1109 	uint32_t tx_done_mask = UCPD_SR_TXUND |
1110 				UCPD_SR_TXMSGSENT |
1111 				UCPD_SR_TXMSGABT |
1112 				UCPD_SR_TXMSGDISC |
1113 				UCPD_SR_HRSTSENT |
1114 				UCPD_SR_HRSTDISC;
1115 
1116 #if DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) > 1
1117 	/*
1118 	 * Multiple UCPD ports are available
1119 	 */
1120 
1121 	uint32_t sr0;
1122 	uint32_t sr1;
1123 
1124 	/*
1125 	 * Since the UCPD peripherals share the same interrupt line, determine
1126 	 * which one generated the interrupt.
1127 	 */
1128 
1129 	/* Read UCPD1 and UCPD2 Status Registers */
1130 
1131 	sr0 =
1132 	LL_UCPD_ReadReg(((const struct tcpc_config *)dev_inst[0]->config)->ucpd_port, SR);
1133 	sr1 =
1134 	LL_UCPD_ReadReg(((const struct tcpc_config *)dev_inst[1]->config)->ucpd_port, SR);
1135 
1136 	if (sr0) {
1137 		dev = dev_inst[0];
1138 	} else if (sr1) {
1139 		dev = dev_inst[1];
1140 	} else {
1141 		/*
1142 		 * The interrupt was triggered by some other device sharing this
1143 		 * interrupt line.
1144 		 */
1145 		return;
1146 	}
1147 #else
1148 	/*
1149 	 * Only one UCPD port available
1150 	 */
1151 
1152 	dev = dev_inst[0];
1153 #endif /* Get the UCPD port that initiated that interrupt  */
1154 
1155 	config = dev->config;
1156 	data = dev->data;
1157 	info = &data->alert_info;
1158 
1159 	/* Read the status register */
1160 	sr = LL_UCPD_ReadReg(config->ucpd_port, SR);
1161 
1162 	/* Check for CC events, set event to wake PD task */
1163 	if (sr & (UCPD_SR_TYPECEVT1 | UCPD_SR_TYPECEVT2)) {
1164 		/* Set CC event bit */
1165 		atomic_set_bit(&info->evt, UCPD_EVT_EVENT_CC);
1166 	}
1167 
1168 	/*
1169 	 * Check for Tx events. tx_mask includes all status bits related to the
1170 	 * end of a USB-PD tx message. If any of these bits are set, the
1171 	 * transmit attempt is completed. Set an event to notify ucpd tx state
1172 	 * machine that transmit operation is complete.
1173 	 */
1174 	if (sr & tx_done_mask) {
1175 		/* Check for tx message complete */
1176 		if (sr & UCPD_SR_TXMSGSENT) {
1177 			atomic_set_bit(&info->evt, UCPD_EVT_TX_MSG_SUCCESS);
1178 		} else if (sr & (UCPD_SR_TXMSGABT | UCPD_SR_TXUND)) {
1179 			atomic_set_bit(&info->evt, UCPD_EVT_TX_MSG_FAIL);
1180 		} else if (sr & (UCPD_SR_TXMSGDISC | UCPD_SR_HRSTDISC)) {
1181 			atomic_set_bit(&info->evt, UCPD_EVT_TX_MSG_DISC);
1182 		} else if (sr & UCPD_SR_HRSTSENT) {
1183 			atomic_set_bit(&info->evt, UCPD_EVT_HR_DONE);
1184 		} else if (sr & UCPD_SR_HRSTDISC) {
1185 			atomic_set_bit(&info->evt, UCPD_EVT_HR_FAIL);
1186 		}
1187 
1188 		/* Disable Tx interrupts */
1189 		ucpd_tx_interrupts_enable(dev, 0);
1190 	}
1191 
1192 	/* Check for data register empty */
1193 	if (sr & UCPD_SR_TXIS) {
1194 		ucpd_tx_data_byte(dev);
1195 	}
1196 
1197 	/* Check for Rx Events */
1198 	/* Check first for start of new message */
1199 	if (sr & UCPD_SR_RXORDDET) {
1200 		/* Add message type to pd message buffer */
1201 		*(uint16_t *)data->ucpd_rx_buffer =
1202 			LL_UCPD_ReadRxOrderSet(config->ucpd_port);
1203 
1204 		data->ucpd_rx_byte_count = 2;
1205 		data->ucpd_rx_msg_active = true;
1206 	}
1207 	/* Check for byte received */
1208 	if (sr & UCPD_SR_RXNE) {
1209 		ucpd_rx_data_byte(dev);
1210 	}
1211 
1212 	/* Check for end of message */
1213 	if (sr & UCPD_SR_RXMSGEND) {
1214 		data->ucpd_rx_msg_active = false;
1215 		/* Check for errors */
1216 		if (!(sr & UCPD_SR_RXERR)) {
1217 			enum pd_packet_type type;
1218 			union pd_header rx_header;
1219 			int good_crc;
1220 
1221 			type = *(uint16_t *)data->ucpd_rx_buffer;
1222 			rx_header.raw_value =
1223 				*((uint16_t *)data->ucpd_rx_buffer + 1);
1224 			good_crc = ucpd_msg_is_good_crc(rx_header);
1225 
1226 			/*
1227 			 * Don't pass GoodCRC control messages to the TCPM
1228 			 * layer. In addition, need to filter for SOP'/SOP''
1229 			 * packets if those are not enabled. SOP'/SOP''
1230 			 * reception is controlled by a static variable. The
1231 			 * hardware orderset detection pattern can't be changed
1232 			 * without disabling the ucpd peripheral.
1233 			 */
1234 			if (!good_crc && (data->ucpd_rx_sop_prime_enabled ||
1235 					  type == PD_PACKET_SOP)) {
1236 
1237 				/*
1238 				 * If BIST test mode is active, then still need
1239 				 * to send GoodCRC reply, but there is no need
1240 				 * to send the message up to the tcpm layer.
1241 				 */
1242 				if (!data->ucpd_rx_bist_mode) {
1243 					atomic_set_bit(&info->evt, UCPD_EVT_RX_MSG);
1244 				}
1245 				/* Send GoodCRC message (if required) */
1246 				ucpd_send_good_crc(dev, rx_header);
1247 			} else if (good_crc) {
1248 				atomic_set_bit(&info->evt, UCPD_EVT_RX_GOOD_CRC);
1249 				data->ucpd_crc_id = rx_header.message_id;
1250 			}
1251 		} else {
1252 			/* Rx message is complete, but there were bit errors */
1253 			LOG_ERR("ucpd: rx message error");
1254 		}
1255 	}
1256 	/* Check for fault conditions */
1257 	if (sr & UCPD_SR_RXHRSTDET) {
1258 		/* hard reset received */
1259 		atomic_set_bit(&info->evt, UCPD_EVT_HARD_RESET_RECEIVED);
1260 	}
1261 
1262 	/* Clear interrupts now that PD events have been set */
1263 	LL_UCPD_WriteReg(config->ucpd_port, ICR, sr & UCPD_ICR_ALL_INT_MASK);
1264 
1265 	/* Notify application of events */
1266 	k_work_submit(&info->work);
1267 }
1268 
1269 /**
1270  * @brief Dump a set of TCPC registers
1271  *
1272  * @retval 0 on success
1273  * @retval -EIO on failure
1274  */
ucpd_dump_std_reg(const struct device * dev)1275 static int ucpd_dump_std_reg(const struct device *dev)
1276 {
1277 	const struct tcpc_config *const config = dev->config;
1278 
1279 	LOG_INF("CFGR1: %08x", LL_UCPD_ReadReg(config->ucpd_port, CFG1));
1280 	LOG_INF("CFGR2: %08x", LL_UCPD_ReadReg(config->ucpd_port, CFG2));
1281 	LOG_INF("CR:    %08x", LL_UCPD_ReadReg(config->ucpd_port, CR));
1282 	LOG_INF("IMR:   %08x", LL_UCPD_ReadReg(config->ucpd_port, IMR));
1283 	LOG_INF("SR:    %08x", LL_UCPD_ReadReg(config->ucpd_port, SR));
1284 	LOG_INF("ICR:   %08x\n", LL_UCPD_ReadReg(config->ucpd_port, ICR));
1285 
1286 	return 0;
1287 }
1288 
1289 /**
1290  * @brief Sets the alert function that's called when an interrupt is triggered
1291  *        due to a TCPC alert
1292  *
1293  * @retval 0 on success
1294  * @retval -EINVAL on failure
1295  */
ucpd_set_alert_handler_cb(const struct device * dev,tcpc_alert_handler_cb_t handler,void * alert_data)1296 static int ucpd_set_alert_handler_cb(const struct device *dev,
1297 				     tcpc_alert_handler_cb_t handler, void *alert_data)
1298 {
1299 	struct tcpc_data *data = dev->data;
1300 
1301 	data->alert_info.handler = handler;
1302 	data->alert_info.data = alert_data;
1303 
1304 	return 0;
1305 }
1306 
1307 /**
1308  * @brief Sets a callback that can enable or disable VCONN if the TCPC is
1309  *        unable to or the system is configured in a way that does not use
1310  *        the VCONN control capabilities of the TCPC
1311  *
1312  */
ucpd_set_vconn_cb(const struct device * dev,tcpc_vconn_control_cb_t vconn_cb)1313 static void ucpd_set_vconn_cb(const struct device *dev,
1314 			      tcpc_vconn_control_cb_t vconn_cb)
1315 {
1316 	struct tcpc_data *data = dev->data;
1317 
1318 	data->vconn_cb = vconn_cb;
1319 }
1320 
1321 /**
1322  * @brief Sets a callback that can discharge VCONN if the TCPC is
1323  *        unable to or the system is configured in a way that does not use
1324  *        the VCONN discharge capabilities of the TCPC
1325  *
1326  */
ucpd_set_vconn_discharge_cb(const struct device * dev,tcpc_vconn_discharge_cb_t cb)1327 static void ucpd_set_vconn_discharge_cb(const struct device *dev,
1328 					tcpc_vconn_discharge_cb_t cb)
1329 {
1330 	struct tcpc_data *data = dev->data;
1331 
1332 	data->vconn_discharge_cb = cb;
1333 }
1334 
1335 /**
1336  * @brief UCPD interrupt init
1337  */
ucpd_isr_init(const struct device * dev)1338 static void ucpd_isr_init(const struct device *dev)
1339 {
1340 	const struct tcpc_config *const config = dev->config;
1341 	struct tcpc_data *data = dev->data;
1342 	struct alert_info *info = &data->alert_info;
1343 
1344 	/* Init GoodCRC Receive timer */
1345 	k_timer_init(&data->goodcrc_rx_timer, NULL, NULL);
1346 
1347 	/* Disable all alert bits */
1348 	LL_UCPD_WriteReg(config->ucpd_port, IMR, 0);
1349 
1350 	/* Clear all alert handler */
1351 	ucpd_set_alert_handler_cb(dev, NULL, NULL);
1352 
1353 	/* Save device structure for use in the alert handlers */
1354 	info->dev = dev;
1355 
1356 	/* Initialize the work handler */
1357 	k_work_init(&info->work, ucpd_alert_handler);
1358 
1359 	/* Configure CC change alerts */
1360 	LL_UCPD_WriteReg(config->ucpd_port, IMR,
1361 			 UCPD_IMR_TYPECEVT1IE | UCPD_IMR_TYPECEVT2IE);
1362 	LL_UCPD_WriteReg(config->ucpd_port, ICR,
1363 			 UCPD_ICR_TYPECEVT1CF | UCPD_ICR_TYPECEVT2CF);
1364 
1365 	/* SOP'/SOP'' must be enabled via TCPCI call */
1366 	data->ucpd_rx_sop_prime_enabled = false;
1367 
1368 	stm32_ucpd_state_init(dev);
1369 
1370 	/* Configure and enable the IRQ */
1371 	config_tcpc_irq();
1372 }
1373 
1374 /**
1375  * @brief Initializes the TCPC
1376  *
1377  * @retval 0 on success
1378  * @retval -EIO on failure
1379  */
ucpd_init(const struct device * dev)1380 static int ucpd_init(const struct device *dev)
1381 {
1382 	const struct tcpc_config *const config = dev->config;
1383 	struct tcpc_data *data = dev->data;
1384 	uint32_t cfg1;
1385 	int ret;
1386 
1387 	LOG_DBG("Pinctrl signals configuration");
1388 	ret = pinctrl_apply_state(config->ucpd_pcfg, PINCTRL_STATE_DEFAULT);
1389 	if (ret < 0) {
1390 		LOG_ERR("USB pinctrl setup failed (%d)", ret);
1391 		return ret;
1392 	}
1393 
1394 	/*
1395 	 * The UCPD port is disabled in the LL_UCPD_Init function
1396 	 *
1397 	 * NOTE: For proper Power Management operation, this function
1398 	 *       should not be used because it circumvents the zephyr
1399 	 *	 clock API. Instead, DTS clock settings and the zephyr
1400 	 *	 clock API should be used to enable clocks.
1401 	 */
1402 	ret = LL_UCPD_Init(config->ucpd_port,
1403 			   (LL_UCPD_InitTypeDef *)&config->ucpd_params);
1404 
1405 	if (ret == SUCCESS) {
1406 		/* Init Rp to USB */
1407 		data->rp = TC_RP_USB;
1408 
1409 		/*
1410 		 * Set RXORDSETEN field to control which types of ordered sets the PD
1411 		 * receiver must receive.
1412 		 */
1413 		cfg1 = LL_UCPD_ReadReg(config->ucpd_port, CFG1);
1414 		cfg1 |= LL_UCPD_ORDERSET_SOP | LL_UCPD_ORDERSET_SOP1 |
1415 			LL_UCPD_ORDERSET_SOP2 | LL_UCPD_ORDERSET_HARDRST;
1416 		LL_UCPD_WriteReg(config->ucpd_port, CFG1, cfg1);
1417 
1418 		/* Enable UCPD port */
1419 		LL_UCPD_Enable(config->ucpd_port);
1420 
1421 		/* Enable Dead Battery Support */
1422 		if (config->ucpd_dead_battery) {
1423 			dead_battery(dev, true);
1424 		} else {
1425 			/*
1426 			 * Some devices have dead battery enabled by default
1427 			 * after power up, so disable it
1428 			 */
1429 			dead_battery(dev, false);
1430 		}
1431 
1432 		/* Initialize the isr */
1433 		ucpd_isr_init(dev);
1434 	} else {
1435 		return -EIO;
1436 	}
1437 
1438 	return 0;
1439 }
1440 
1441 static const struct tcpc_driver_api driver_api = {
1442 	.init = ucpd_init,
1443 	.set_alert_handler_cb = ucpd_set_alert_handler_cb,
1444 	.get_cc = ucpd_get_cc,
1445 	.set_rx_enable = ucpd_set_rx_enable,
1446 	.is_rx_pending_msg = ucpd_is_rx_pending_msg,
1447 	.receive_data = ucpd_receive_data,
1448 	.transmit_data = ucpd_transmit_data,
1449 	.select_rp_value = ucpd_select_rp_value,
1450 	.get_rp_value = ucpd_get_rp_value,
1451 	.set_cc = ucpd_set_cc,
1452 	.set_roles = ucpd_set_roles,
1453 	.set_vconn_cb = ucpd_set_vconn_cb,
1454 	.set_vconn_discharge_cb = ucpd_set_vconn_discharge_cb,
1455 	.set_vconn = ucpd_set_vconn,
1456 	.vconn_discharge = ucpd_vconn_discharge,
1457 	.set_cc_polarity = ucpd_cc_set_polarity,
1458 	.dump_std_reg = ucpd_dump_std_reg,
1459 	.set_bist_test_mode = ucpd_set_bist_test_mode,
1460 	.sop_prime_enable = ucpd_sop_prime_enable,
1461 };
1462 
1463 #define DEV_INST_INIT(n) dev_inst[n] = DEVICE_DT_INST_GET(n);
config_tcpc_irq(void)1464 static void config_tcpc_irq(void)
1465 {
1466 	static int inst_num;
1467 	static const struct device
1468 	*dev_inst[DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT)];
1469 
1470 	/* Initialize and enable shared irq on last instance */
1471 	if (++inst_num == DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT)) {
1472 		DT_INST_FOREACH_STATUS_OKAY(DEV_INST_INIT)
1473 
1474 		IRQ_CONNECT(DT_INST_IRQN(0),
1475 			    DT_INST_IRQ(0, priority),
1476 			    ucpd_isr, dev_inst, 0);
1477 
1478 		irq_enable(DT_INST_IRQN(0));
1479 	}
1480 }
1481 
1482 BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) > 0,
1483 	     "No compatible STM32 TCPC instance found");
1484 
1485 #define TCPC_DRIVER_INIT(inst)								\
1486 	PINCTRL_DT_INST_DEFINE(inst);							\
1487 	static struct tcpc_data drv_data_##inst;					\
1488 	static const struct tcpc_config drv_config_##inst = {				\
1489 		.ucpd_pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst),			\
1490 		.ucpd_port = (UCPD_TypeDef *)DT_INST_REG_ADDR(inst),			\
1491 		.ucpd_params.psc_ucpdclk = ilog2(DT_INST_PROP(inst, psc_ucpdclk)),	\
1492 		.ucpd_params.transwin = DT_INST_PROP(inst, transwin) - 1,		\
1493 		.ucpd_params.IfrGap = DT_INST_PROP(inst, ifrgap) - 1,			\
1494 		.ucpd_params.HbitClockDiv = DT_INST_PROP(inst, hbitclkdiv) - 1,		\
1495 		.ucpd_dead_battery = DT_INST_PROP(inst, dead_battery),			\
1496 	};										\
1497 	DEVICE_DT_INST_DEFINE(inst,							\
1498 			      &ucpd_init,						\
1499 			      NULL,							\
1500 			      &drv_data_##inst,						\
1501 			      &drv_config_##inst,					\
1502 			      POST_KERNEL,						\
1503 			      CONFIG_USBC_TCPC_INIT_PRIORITY,				\
1504 			      &driver_api);
1505 
1506 DT_INST_FOREACH_STATUS_OKAY(TCPC_DRIVER_INIT)
1507