1 /*
2  * Copyright (c) 2021 Gerson Fernando Budke <nandojve@gmail.com>
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT atmel_sam_usbc
8 
9 #include <zephyr/logging/log.h>
10 LOG_MODULE_REGISTER(usb_dc_sam_usbc, CONFIG_USB_DRIVER_LOG_LEVEL);
11 
12 #include <zephyr/kernel.h>
13 #include <zephyr/usb/usb_device.h>
14 #include <soc.h>
15 #include <string.h>
16 #include <zephyr/sys/byteorder.h>
17 #include <zephyr/sys/barrier.h>
18 #include <zephyr/drivers/pinctrl.h>
19 #include <zephyr/irq.h>
20 
21 #define EP_UDINT_MASK           0x000FF000
22 
23 #define NUM_OF_EP_MAX           DT_INST_PROP(0, num_bidir_endpoints)
24 #define USBC_RAM_ADDR           DT_REG_ADDR(DT_NODELABEL(sram1))
25 #define USBC_RAM_SIZE           DT_REG_SIZE(DT_NODELABEL(sram1))
26 
27 /**
28  * @brief USB Driver Control Endpoint Finite State Machine states
29  *
30  * FSM states to keep tracking of control endpoint hidden states.
31  */
32 enum usb_dc_epctrl_state {
33 	/* Wait a SETUP packet */
34 	USB_EPCTRL_SETUP,
35 	/* Wait a OUT data packet */
36 	USB_EPCTRL_DATA_OUT,
37 	/* Wait a IN data packet */
38 	USB_EPCTRL_DATA_IN,
39 	/* Wait a IN ZLP packet */
40 	USB_EPCTRL_HANDSHAKE_WAIT_IN_ZLP,
41 	/* Wait a OUT ZLP packet */
42 	USB_EPCTRL_HANDSHAKE_WAIT_OUT_ZLP,
43 	/* STALL enabled on IN & OUT packet */
44 	USB_EPCTRL_STALL_REQ,
45 };
46 
47 struct sam_usbc_udesc_sizes {
48 	uint32_t byte_count:15;
49 	uint32_t reserved:1;
50 	uint32_t multi_packet_size:15;
51 	uint32_t auto_zlp:1;
52 };
53 
54 struct sam_usbc_udesc_bk_ctrl_stat {
55 	uint32_t stallrq:1;
56 	uint32_t reserved1:15;
57 	uint32_t crcerri:1;
58 	uint32_t overfi:1;
59 	uint32_t underfi:1;
60 	uint32_t reserved2:13;
61 };
62 
63 struct sam_usbc_udesc_ep_ctrl_stat {
64 	uint32_t pipe_dev_addr:7;
65 	uint32_t reserved1:1;
66 	uint32_t pipe_num:4;
67 	uint32_t pipe_error_cnt_max:4;
68 	uint32_t pipe_error_status:8;
69 	uint32_t reserved2:8;
70 };
71 
72 struct sam_usbc_desc_table {
73 	uint8_t *ep_pipe_addr;
74 	union {
75 		uint32_t sizes;
76 		struct sam_usbc_udesc_sizes udesc_sizes;
77 	};
78 	union {
79 		uint32_t bk_ctrl_stat;
80 		struct sam_usbc_udesc_bk_ctrl_stat udesc_bk_ctrl_stat;
81 	};
82 	union {
83 		uint32_t ep_ctrl_stat;
84 		struct sam_usbc_udesc_ep_ctrl_stat udesc_ep_ctrl_stat;
85 	};
86 };
87 
88 struct usb_device_ep_data {
89 	usb_dc_ep_callback cb_in;
90 	usb_dc_ep_callback cb_out;
91 	uint16_t mps;
92 	bool mps_x2;
93 	bool is_configured;
94 	uint32_t out_at;
95 };
96 
97 struct usb_device_data {
98 	usb_dc_status_callback status_cb;
99 	struct usb_device_ep_data ep_data[NUM_OF_EP_MAX];
100 };
101 
102 static struct sam_usbc_desc_table dev_desc[(NUM_OF_EP_MAX + 1) * 2];
103 static struct usb_device_data dev_data;
104 static volatile Usbc *regs = (Usbc *) DT_INST_REG_ADDR(0);
105 PINCTRL_DT_INST_DEFINE(0);
106 static const struct pinctrl_dev_config *pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0);
107 static enum usb_dc_epctrl_state epctrl_fsm;
108 static const char *const usb_dc_epctrl_state_string[] = {
109 	"STP",
110 	"DOUT",
111 	"DIN",
112 	"IN_ZLP",
113 	"OUT_ZLP",
114 	"STALL",
115 };
116 
117 #if defined(CONFIG_USB_DRIVER_LOG_LEVEL_DBG)
118 static uint32_t dev_ep_sta_dbg[2][NUM_OF_EP_MAX];
119 
usb_dc_sam_usbc_isr_sta_dbg(uint32_t ep_idx,uint32_t sr)120 static void usb_dc_sam_usbc_isr_sta_dbg(uint32_t ep_idx, uint32_t sr)
121 {
122 	if (regs->UESTA[ep_idx] != dev_ep_sta_dbg[0][ep_idx]) {
123 		dev_ep_sta_dbg[0][ep_idx] = regs->UESTA[ep_idx];
124 		dev_ep_sta_dbg[1][ep_idx] = 0;
125 
126 		LOG_INF("ISR[%d] CON=%08x INT=%08x INTE=%08x "
127 			"ECON=%08x ESTA=%08x%s", ep_idx,
128 			regs->UDCON, regs->UDINT, regs->UDINTE,
129 			regs->UECON[ep_idx], regs->UESTA[ep_idx],
130 			((sr & USBC_UESTA0_RXSTPI) ? " STP" : ""));
131 	} else if (dev_ep_sta_dbg[0][ep_idx] != dev_ep_sta_dbg[1][ep_idx]) {
132 		dev_ep_sta_dbg[1][ep_idx] = dev_ep_sta_dbg[0][ep_idx];
133 
134 		LOG_INF("ISR[%d] CON=%08x INT=%08x INTE=%08x "
135 			"ECON=%08x ESTA=%08x LOOP", ep_idx,
136 			regs->UDCON, regs->UDINT, regs->UDINTE,
137 			regs->UECON[ep_idx], regs->UESTA[ep_idx]);
138 	}
139 }
140 
usb_dc_sam_usbc_clean_sta_dbg(void)141 static void usb_dc_sam_usbc_clean_sta_dbg(void)
142 {
143 	for (int i = 0; i < NUM_OF_EP_MAX; i++) {
144 		dev_ep_sta_dbg[0][i] = 0;
145 		dev_ep_sta_dbg[1][i] = 0;
146 	}
147 }
148 #else
149 #define usb_dc_sam_usbc_isr_sta_dbg(ep_idx, sr)
150 #define usb_dc_sam_usbc_clean_sta_dbg()
151 #endif
152 
usb_dc_sam_usbc_is_frozen_clk(void)153 static ALWAYS_INLINE bool usb_dc_sam_usbc_is_frozen_clk(void)
154 {
155 	return USBC->USBCON & USBC_USBCON_FRZCLK;
156 }
157 
usb_dc_sam_usbc_freeze_clk(void)158 static ALWAYS_INLINE void usb_dc_sam_usbc_freeze_clk(void)
159 {
160 	USBC->USBCON |= USBC_USBCON_FRZCLK;
161 }
162 
usb_dc_sam_usbc_unfreeze_clk(void)163 static ALWAYS_INLINE void usb_dc_sam_usbc_unfreeze_clk(void)
164 {
165 	USBC->USBCON &= ~USBC_USBCON_FRZCLK;
166 
167 	while (USBC->USBCON & USBC_USBCON_FRZCLK) {
168 		;
169 	};
170 }
171 
usb_dc_sam_usbc_ep_curr_bank(uint8_t ep_idx)172 static uint8_t usb_dc_sam_usbc_ep_curr_bank(uint8_t ep_idx)
173 {
174 	uint8_t idx = ep_idx * 2;
175 
176 	if ((ep_idx > 0) &&
177 	    (regs->UESTA[ep_idx] & USBC_UESTA0_CURRBK(1)) > 0) {
178 		idx++;
179 	}
180 
181 	return idx;
182 }
183 
usb_dc_is_attached(void)184 static bool usb_dc_is_attached(void)
185 {
186 	return (regs->UDCON & USBC_UDCON_DETACH) == 0;
187 }
188 
usb_dc_ep_is_enabled(uint8_t ep_idx)189 static bool usb_dc_ep_is_enabled(uint8_t ep_idx)
190 {
191 	int reg = regs->UERST;
192 
193 	return (reg & BIT(USBC_UERST_EPEN0_Pos + ep_idx));
194 }
195 
usb_dc_sam_usbc_ep_alloc_buf(int ep_idx)196 static int usb_dc_sam_usbc_ep_alloc_buf(int ep_idx)
197 {
198 	struct sam_usbc_desc_table *ep_desc_bk;
199 	bool ep_enabled[NUM_OF_EP_MAX];
200 	int desc_mem_alloc;
201 	int mps;
202 
203 	if (ep_idx >= NUM_OF_EP_MAX) {
204 		return -EINVAL;
205 	}
206 
207 	desc_mem_alloc = 0;
208 
209 	mps = dev_data.ep_data[ep_idx].mps_x2
210 	    ? dev_data.ep_data[ep_idx].mps * 2
211 	    : dev_data.ep_data[ep_idx].mps;
212 
213 	/* Check if there are memory to all endpoints */
214 	for (int i = 0; i < NUM_OF_EP_MAX; i++) {
215 		if (!dev_data.ep_data[i].is_configured || i == ep_idx) {
216 			continue;
217 		}
218 
219 		desc_mem_alloc += dev_data.ep_data[i].mps_x2
220 				? dev_data.ep_data[i].mps * 2
221 				: dev_data.ep_data[i].mps;
222 	}
223 
224 	if ((desc_mem_alloc + mps) > USBC_RAM_SIZE) {
225 		memset(&dev_data.ep_data[ep_idx], 0,
226 		       sizeof(struct usb_device_ep_data));
227 		return -ENOMEM;
228 	}
229 
230 	for (int i = NUM_OF_EP_MAX - 1; i >= ep_idx; i--) {
231 		ep_enabled[i] = usb_dc_ep_is_enabled(i);
232 		if (ep_enabled[i]) {
233 			usb_dc_ep_disable(i);
234 		}
235 	}
236 
237 	desc_mem_alloc = 0U;
238 	for (int i = 0; i < ep_idx; i++) {
239 		if (!dev_data.ep_data[i].is_configured) {
240 			continue;
241 		}
242 
243 		desc_mem_alloc += dev_data.ep_data[i].mps_x2
244 				? dev_data.ep_data[i].mps * 2
245 				: dev_data.ep_data[i].mps;
246 	}
247 
248 	ep_desc_bk = ((struct sam_usbc_desc_table *) &dev_desc)
249 		   + (ep_idx * 2);
250 	for (int i = ep_idx; i < NUM_OF_EP_MAX; i++) {
251 		if (!dev_data.ep_data[i].is_configured && (i != ep_idx)) {
252 			ep_desc_bk += 2;
253 			continue;
254 		}
255 
256 		/* Alloc bank 0 */
257 		ep_desc_bk->ep_pipe_addr = ((uint8_t *) USBC_RAM_ADDR)
258 					 + desc_mem_alloc;
259 		ep_desc_bk->sizes = 0;
260 		ep_desc_bk->bk_ctrl_stat = 0;
261 		ep_desc_bk->ep_ctrl_stat = 0;
262 		ep_desc_bk++;
263 
264 		/**
265 		 * Alloc bank 1
266 		 *
267 		 * if dual bank,
268 		 * then ep_pipe_addr[1] = ep_pipe_addr[0] address + mps size
269 		 * else ep_pipe_addr[1] = ep_pipe_addr[0] address
270 		 */
271 		ep_desc_bk->ep_pipe_addr = ((uint8_t *) USBC_RAM_ADDR)
272 					 + desc_mem_alloc
273 					 + (dev_data.ep_data[i].mps_x2
274 					 ?  dev_data.ep_data[i].mps
275 					 :  0);
276 		ep_desc_bk->sizes = 0;
277 		ep_desc_bk->bk_ctrl_stat = 0;
278 		ep_desc_bk->ep_ctrl_stat = 0;
279 		ep_desc_bk++;
280 
281 		desc_mem_alloc += dev_data.ep_data[i].mps_x2
282 				? dev_data.ep_data[i].mps * 2
283 				: dev_data.ep_data[i].mps;
284 	}
285 
286 	ep_enabled[ep_idx] = false;
287 	for (int i = ep_idx; i < NUM_OF_EP_MAX; i++) {
288 		if (ep_enabled[i]) {
289 			usb_dc_ep_enable(i);
290 		}
291 	}
292 	return 0;
293 }
294 
usb_dc_ep_enable_interrupts(uint8_t ep_idx)295 static void usb_dc_ep_enable_interrupts(uint8_t ep_idx)
296 {
297 	if (ep_idx == 0U) {
298 		/* Control endpoint: enable SETUP */
299 		regs->UECONSET[ep_idx] = USBC_UECON0SET_RXSTPES;
300 	} else if (regs->UECFG[ep_idx] & USBC_UECFG0_EPDIR_IN) {
301 		/* TX - IN direction: acknowledge FIFO empty interrupt */
302 		regs->UESTACLR[ep_idx] = USBC_UESTA0CLR_TXINIC;
303 		regs->UECONSET[ep_idx] = USBC_UECON0SET_TXINES;
304 	} else {
305 		/* RX - OUT direction */
306 		regs->UECONSET[ep_idx] = USBC_UECON0SET_RXOUTES;
307 	}
308 }
309 
usb_dc_ep_isr_sta(uint8_t ep_idx)310 static void usb_dc_ep_isr_sta(uint8_t ep_idx)
311 {
312 	uint32_t sr = regs->UESTA[ep_idx];
313 
314 	usb_dc_sam_usbc_isr_sta_dbg(ep_idx, sr);
315 
316 	if (sr & USBC_UESTA0_RAMACERI) {
317 		regs->UESTACLR[ep_idx] = USBC_UESTA0CLR_RAMACERIC;
318 		LOG_ERR("ISR: EP%d RAM Access Error", ep_idx);
319 	}
320 }
321 
usb_dc_ctrl_init(void)322 static void usb_dc_ctrl_init(void)
323 {
324 	LOG_INF("STP - INIT");
325 
326 	/* In case of abort of IN Data Phase:
327 	 * No need to abort IN transfer (rise TXINI),
328 	 * because it is automatically done by hardware when a Setup packet is
329 	 * received. But the interrupt must be disabled to don't generate
330 	 * interrupt TXINI after SETUP reception.
331 	 */
332 	regs->UECONCLR[0] = USBC_UECON0CLR_TXINEC;
333 
334 	/* In case of OUT ZLP event is no processed before Setup event occurs */
335 	regs->UESTACLR[0] = USBC_UESTA0CLR_RXOUTIC;
336 	regs->UECONCLR[0] = USBC_UECON0CLR_RXOUTEC
337 			  | USBC_UECON0CLR_NAKOUTEC
338 			  | USBC_UECON0CLR_NAKINEC;
339 
340 	epctrl_fsm = USB_EPCTRL_SETUP;
341 }
342 
usb_dc_ctrl_stall_data(uint32_t flags)343 static void usb_dc_ctrl_stall_data(uint32_t flags)
344 {
345 	LOG_INF("STP - STALL");
346 
347 	epctrl_fsm = USB_EPCTRL_STALL_REQ;
348 
349 	regs->UECONSET[0] = USBC_UECON0SET_STALLRQS;
350 	regs->UESTACLR[0] = flags;
351 }
352 
usb_dc_ctrl_send_zlp_in(void)353 static void usb_dc_ctrl_send_zlp_in(void)
354 {
355 	uint32_t key;
356 
357 	LOG_INF("STP - ZLP IN");
358 
359 	epctrl_fsm = USB_EPCTRL_HANDSHAKE_WAIT_IN_ZLP;
360 
361 	/* Validate and send empty IN packet on control endpoint */
362 	dev_desc[0].sizes = 0;
363 
364 	key = irq_lock();
365 
366 	/* Send ZLP on IN endpoint */
367 	regs->UESTACLR[0] = USBC_UESTA0CLR_TXINIC;
368 	regs->UECONSET[0] = USBC_UECON0SET_TXINES;
369 
370 	/* To detect a protocol error, enable nak interrupt on data OUT phase */
371 	regs->UESTACLR[0] = USBC_UESTA0CLR_NAKOUTIC;
372 	regs->UECONSET[0] = USBC_UECON0SET_NAKOUTES;
373 	irq_unlock(key);
374 }
375 
usb_dc_ctrl_send_zlp_out(void)376 static void usb_dc_ctrl_send_zlp_out(void)
377 {
378 	uint32_t key;
379 
380 	LOG_INF("STP - ZLP OUT");
381 
382 	epctrl_fsm = USB_EPCTRL_HANDSHAKE_WAIT_OUT_ZLP;
383 
384 	/* To detect a protocol error, enable nak interrupt on data IN phase */
385 	key = irq_lock();
386 	regs->UESTACLR[0] = USBC_UESTA0CLR_NAKINIC;
387 	regs->UECONSET[0] = USBC_UECON0SET_NAKINES;
388 	irq_unlock(key);
389 }
390 
usb_dc_ep0_isr(void)391 static void usb_dc_ep0_isr(void)
392 {
393 	uint32_t sr = regs->UESTA[0];
394 	uint32_t dev_ctrl = regs->UDCON;
395 
396 	usb_dc_ep_isr_sta(0);
397 
398 	regs->UECONCLR[0] = USBC_UECON0CLR_NAKINEC;
399 	regs->UECONCLR[0] = USBC_UECON0CLR_NAKOUTEC;
400 
401 	if (sr & USBC_UESTA0_RXSTPI) {
402 		/* May be a hidden DATA or ZLP phase or protocol abort */
403 		if (epctrl_fsm != USB_EPCTRL_SETUP) {
404 			/* Reinitializes control endpoint management */
405 			usb_dc_ctrl_init();
406 		}
407 
408 		/* SETUP data received */
409 		dev_data.ep_data[0].cb_out(USB_EP_DIR_OUT, USB_DC_EP_SETUP);
410 		return;
411 	}
412 
413 	if (sr & USBC_UESTA0_RXOUTI) {
414 		LOG_DBG("RXOUT= fsm: %s",
415 			usb_dc_epctrl_state_string[epctrl_fsm]);
416 
417 		if (epctrl_fsm != USB_EPCTRL_DATA_OUT) {
418 			if ((epctrl_fsm == USB_EPCTRL_DATA_IN)
419 			||  (epctrl_fsm == USB_EPCTRL_HANDSHAKE_WAIT_OUT_ZLP)) {
420 				/* End of SETUP request:
421 				 * - Data IN Phase aborted,
422 				 * - or last Data IN Phase hidden by ZLP OUT
423 				 *   sending quickly,
424 				 * - or ZLP OUT received normally.
425 				 *
426 				 * Nothing to do
427 				 */
428 			} else {
429 				/* Protocol error during SETUP request */
430 				usb_dc_ctrl_stall_data(0);
431 			}
432 
433 			usb_dc_ctrl_init();
434 			return;
435 		}
436 
437 		/* OUT (to device) data received */
438 		dev_data.ep_data[0].cb_out(USB_EP_DIR_OUT, USB_DC_EP_DATA_OUT);
439 		return;
440 	}
441 
442 	if ((sr & USBC_UESTA0_TXINI) &&
443 	    (regs->UECON[0] & USBC_UECON0_TXINE)) {
444 		LOG_DBG("TXINI= fsm: %s",
445 			usb_dc_epctrl_state_string[epctrl_fsm]);
446 
447 		regs->UECONCLR[0] = USBC_UECON0CLR_TXINEC;
448 
449 		if (epctrl_fsm == USB_EPCTRL_HANDSHAKE_WAIT_IN_ZLP) {
450 			if (!(dev_ctrl & USBC_UDCON_ADDEN)
451 			&&   (dev_ctrl & USBC_UDCON_UADD_Msk) != 0U) {
452 				/* Commit the pending address update.  This
453 				 * must be done after the ack to the host
454 				 * completes else the ack will get dropped.
455 				 */
456 				regs->UDCON |= USBC_UDCON_ADDEN;
457 			}
458 
459 			/* ZLP on IN is sent */
460 			usb_dc_ctrl_init();
461 			return;
462 		}
463 
464 		/* IN (to host) transmit complete */
465 		dev_data.ep_data[0].cb_in(USB_EP_DIR_IN, USB_DC_EP_DATA_IN);
466 		return;
467 	}
468 
469 	if (sr & USBC_UESTA0_NAKOUTI) {
470 		LOG_DBG("NAKOUT= fsm: %s",
471 			usb_dc_epctrl_state_string[epctrl_fsm]);
472 
473 		regs->UESTACLR[0] = USBC_UESTA0CLR_NAKOUTIC;
474 
475 		if (regs->UESTA[0] & USBC_UESTA0_TXINI) {
476 			/** overflow ignored if IN data is received */
477 			return;
478 		}
479 
480 		if (epctrl_fsm == USB_EPCTRL_HANDSHAKE_WAIT_IN_ZLP) {
481 			/* A IN handshake is waiting by device, but host want
482 			 * extra OUT data then stall extra OUT data
483 			 */
484 			regs->UECONSET[0] = USBC_UECON0SET_STALLRQS;
485 		}
486 		return;
487 	}
488 
489 	if (sr & USBC_UESTA0_NAKINI) {
490 		LOG_DBG("NAKIN= fsm: %s",
491 			usb_dc_epctrl_state_string[epctrl_fsm]);
492 
493 		regs->UESTACLR[0] = USBC_UESTA0CLR_NAKINIC;
494 
495 		if (regs->UESTA[0] & USBC_UESTA0_RXOUTI) {
496 			/** underflow ignored if OUT data is received */
497 			return;
498 		}
499 
500 		if (epctrl_fsm == USB_EPCTRL_DATA_OUT) {
501 			/* Host want to stop OUT transaction then stop to
502 			 * wait OUT data phase and wait IN ZLP handshake.
503 			 */
504 			usb_dc_ctrl_send_zlp_in();
505 		} else if (epctrl_fsm == USB_EPCTRL_HANDSHAKE_WAIT_OUT_ZLP) {
506 			/* A OUT handshake is waiting by device, but host want
507 			 * extra IN data then stall extra IN data.
508 			 */
509 			regs->UECONSET[0] = USBC_UECON0SET_STALLRQS;
510 		} else {
511 			/** Nothing to do */
512 		}
513 		return;
514 	}
515 }
516 
usb_dc_ep_isr(uint8_t ep_idx)517 static void usb_dc_ep_isr(uint8_t ep_idx)
518 {
519 	uint32_t sr = regs->UESTA[ep_idx];
520 
521 	usb_dc_ep_isr_sta(ep_idx);
522 
523 	if (sr & USBC_UESTA0_RXOUTI) {
524 		uint8_t ep = ep_idx | USB_EP_DIR_OUT;
525 
526 		regs->UESTACLR[ep_idx] = USBC_UESTA0CLR_RXOUTIC;
527 
528 		/* OUT (to device) data received */
529 		dev_data.ep_data[ep_idx].cb_out(ep, USB_DC_EP_DATA_OUT);
530 	}
531 	if (sr & USBC_UESTA0_TXINI) {
532 		uint8_t ep = ep_idx | USB_EP_DIR_IN;
533 
534 		regs->UESTACLR[ep_idx] = USBC_UESTA0CLR_TXINIC;
535 
536 		/* IN (to host) transmit complete */
537 		dev_data.ep_data[ep_idx].cb_in(ep, USB_DC_EP_DATA_IN);
538 	}
539 }
540 
usb_dc_sam_usbc_isr(void)541 static void usb_dc_sam_usbc_isr(void)
542 {
543 	uint32_t sr = regs->UDINT;
544 
545 	if (IS_ENABLED(CONFIG_USB_DEVICE_SOF)) {
546 		/* SOF interrupt */
547 		if (sr & USBC_UDINT_SOF) {
548 			/* Acknowledge the interrupt */
549 			regs->UDINTCLR = USBC_UDINTCLR_SOFC;
550 
551 			dev_data.status_cb(USB_DC_SOF, NULL);
552 
553 			goto usb_dc_sam_usbc_isr_barrier;
554 		}
555 	}
556 
557 	/* EP0 endpoint interrupt */
558 	if (sr & USBC_UDINT_EP0INT) {
559 		usb_dc_ep0_isr();
560 
561 		goto usb_dc_sam_usbc_isr_barrier;
562 	}
563 
564 	/* Other endpoints interrupt */
565 	if (sr & EP_UDINT_MASK) {
566 		for (int ep_idx = 1; ep_idx < NUM_OF_EP_MAX; ep_idx++) {
567 			if (sr & (USBC_UDINT_EP0INT << ep_idx)) {
568 				usb_dc_ep_isr(ep_idx);
569 			}
570 		}
571 
572 		goto usb_dc_sam_usbc_isr_barrier;
573 	}
574 
575 	/* End of resume interrupt */
576 	if (sr & USBC_UDINT_EORSM) {
577 		LOG_DBG("ISR: End Of Resume");
578 
579 		regs->UDINTCLR = USBC_UDINTCLR_EORSMC;
580 
581 		dev_data.status_cb(USB_DC_RESUME, NULL);
582 
583 		goto usb_dc_sam_usbc_isr_barrier;
584 	}
585 
586 	/* End of reset interrupt */
587 	if (sr & USBC_UDINT_EORST) {
588 		LOG_DBG("ISR: End Of Reset");
589 
590 		regs->UDINTCLR = USBC_UDINTCLR_EORSTC;
591 
592 		if (usb_dc_ep_is_enabled(0)) {
593 			/* The device clears some of the configuration of EP0
594 			 * when it receives the EORST. Re-enable interrupts.
595 			 */
596 			usb_dc_ep_enable_interrupts(0);
597 			usb_dc_ctrl_init();
598 		}
599 
600 		dev_data.status_cb(USB_DC_RESET, NULL);
601 
602 		usb_dc_sam_usbc_clean_sta_dbg();
603 
604 		goto usb_dc_sam_usbc_isr_barrier;
605 	}
606 
607 	/* Suspend interrupt */
608 	if (sr & USBC_UDINT_SUSP && regs->UDINTE & USBC_UDINTE_SUSPE) {
609 		LOG_DBG("ISR: Suspend");
610 
611 		regs->UDINTCLR = USBC_UDINTCLR_SUSPC;
612 
613 		usb_dc_sam_usbc_unfreeze_clk();
614 
615 		/**
616 		 * Sync Generic Clock
617 		 * Check USB clock ready after suspend and
618 		 * eventually sleep USB clock
619 		 */
620 		while ((regs->USBSTA & USBC_USBSTA_CLKUSABLE) == 0) {
621 			;
622 		};
623 
624 		regs->UDINTECLR = USBC_UDINTECLR_SUSPEC;
625 		regs->UDINTCLR = USBC_UDINTCLR_WAKEUPC;
626 		regs->UDINTESET = USBC_UDINTESET_WAKEUPES;
627 
628 		usb_dc_sam_usbc_freeze_clk();
629 
630 		dev_data.status_cb(USB_DC_SUSPEND, NULL);
631 
632 		goto usb_dc_sam_usbc_isr_barrier;
633 	}
634 
635 	/* Wakeup interrupt */
636 	if (sr & USBC_UDINT_WAKEUP && regs->UDINTE & USBC_UDINTE_WAKEUPE) {
637 		LOG_DBG("ISR: Wake Up");
638 
639 		regs->UDINTCLR = USBC_UDINTCLR_WAKEUPC;
640 
641 		usb_dc_sam_usbc_unfreeze_clk();
642 
643 		/**
644 		 * Sync Generic Clock
645 		 * Check USB clock ready after suspend and
646 		 * eventually sleep USB clock
647 		 */
648 		while ((regs->USBSTA & USBC_USBSTA_CLKUSABLE) == 0) {
649 			;
650 		};
651 
652 		regs->UDINTECLR = USBC_UDINTECLR_WAKEUPEC;
653 		regs->UDINTCLR = USBC_UDINTCLR_SUSPC;
654 		regs->UDINTESET = USBC_UDINTESET_SUSPES;
655 	}
656 
657 usb_dc_sam_usbc_isr_barrier:
658 	barrier_dmem_fence_full();
659 }
660 
usb_dc_attach(void)661 int usb_dc_attach(void)
662 {
663 	uint32_t pmcon;
664 	uint32_t regval;
665 	uint32_t key = irq_lock();
666 	int retval;
667 
668 	/* Enable USBC asynchronous wake-up source */
669 	PM->AWEN |= BIT(PM_AWEN_USBC);
670 
671 	/* Always authorize asynchronous USB interrupts to exit of sleep mode
672 	 * For SAM USB wake up device except BACKUP mode
673 	 */
674 	pmcon = BPM->PMCON | BPM_PMCON_FASTWKUP;
675 	BPM->UNLOCK = BPM_UNLOCK_KEY(0xAAu)
676 		    | BPM_UNLOCK_ADDR((uint32_t)&BPM->PMCON - (uint32_t)BPM);
677 	BPM->PMCON = pmcon;
678 
679 	/* Start the peripheral clock PBB & DATA */
680 	soc_pmc_peripheral_enable(
681 		PM_CLOCK_MASK(PM_CLK_GRP_PBB, SYSCLK_USBC_REGS));
682 	soc_pmc_peripheral_enable(
683 		PM_CLOCK_MASK(PM_CLK_GRP_HSB, SYSCLK_USBC_DATA));
684 
685 	/* Enable USB Generic clock */
686 	SCIF->GCCTRL[GEN_CLK_USBC] = 0;
687 	SCIF->GCCTRL[GEN_CLK_USBC] = SCIF_GCCTRL_OSCSEL(SCIF_GC_USES_CLK_HSB)
688 				   | SCIF_GCCTRL_CEN;
689 
690 	/* Sync Generic Clock */
691 	while ((regs->USBSTA & USBC_USBSTA_CLKUSABLE) == 0) {
692 		;
693 	};
694 
695 	retval = pinctrl_apply_state(pcfg, PINCTRL_STATE_DEFAULT);
696 	if (retval < 0) {
697 		return retval;
698 	}
699 
700 	/* Enable the USB controller in device mode with the clock unfrozen */
701 	regs->USBCON = USBC_USBCON_UIMOD | USBC_USBCON_USBE;
702 
703 	usb_dc_sam_usbc_unfreeze_clk();
704 
705 	regs->UDESC = USBC_UDESC_UDESCA((int) &dev_desc);
706 
707 	/* Select the speed with pads detached */
708 	regval = USBC_UDCON_DETACH;
709 
710 	switch (DT_INST_ENUM_IDX(0, maximum_speed)) {
711 	case 1:
712 		WRITE_BIT(regval, USBC_UDCON_LS_Pos, 0);
713 		break;
714 	case 0:
715 		WRITE_BIT(regval, USBC_UDCON_LS_Pos, 1);
716 		break;
717 	default:
718 		WRITE_BIT(regval, USBC_UDCON_LS_Pos, 0);
719 		LOG_WRN("Unsupported maximum speed defined in device tree. "
720 			"USB controller will default to its maximum HW "
721 			"capability");
722 	}
723 
724 	regs->UDCON = regval;
725 
726 	/* Enable device interrupts
727 	 *  EORSM	End of Resume Interrupt
728 	 *  SOF		Start of Frame Interrupt
729 	 *  EORST	End of Reset Interrupt
730 	 *  SUSP	Suspend Interrupt
731 	 *  WAKEUP	Wake-Up Interrupt
732 	 */
733 	regs->UDINTCLR = USBC_UDINTCLR_EORSMC
734 		       | USBC_UDINTCLR_EORSTC
735 		       | USBC_UDINTCLR_SOFC
736 		       | USBC_UDINTCLR_SUSPC
737 		       | USBC_UDINTCLR_WAKEUPC;
738 
739 	regs->UDINTESET = USBC_UDINTESET_EORSMES
740 			| USBC_UDINTESET_EORSTES
741 			| USBC_UDINTESET_SUSPES
742 			| USBC_UDINTESET_WAKEUPES;
743 
744 	if (IS_ENABLED(CONFIG_USB_DEVICE_SOF)) {
745 		regs->UDINTESET |= USBC_UDINTESET_SOFES;
746 	}
747 
748 	IRQ_CONNECT(DT_INST_IRQN(0),
749 		    DT_INST_IRQ(0, priority),
750 		    usb_dc_sam_usbc_isr, 0, 0);
751 	irq_enable(DT_INST_IRQN(0));
752 
753 	/* Attach the device */
754 	regs->UDCON &= ~USBC_UDCON_DETACH;
755 
756 	/* Put USB on low power state (wait Susp/Wake int) */
757 	usb_dc_sam_usbc_freeze_clk();
758 
759 	/* Force Susp 2 Wake transition */
760 	regs->UDINTSET = USBC_UDINTSET_SUSPS;
761 
762 	irq_unlock(key);
763 
764 	LOG_DBG("USB DC attach");
765 	return 0;
766 }
767 
usb_dc_detach(void)768 int usb_dc_detach(void)
769 {
770 	uint32_t key = irq_lock();
771 
772 	regs->UDCON |= USBC_UDCON_DETACH;
773 
774 	/* Disable the USB controller and freeze the clock */
775 	regs->USBCON = USBC_USBCON_UIMOD | USBC_USBCON_FRZCLK;
776 
777 	/* Disable USB Generic clock */
778 	SCIF->GCCTRL[GEN_CLK_USBC] = 0;
779 
780 	/* Disable USBC asynchronous wake-up source */
781 	PM->AWEN &= ~(BIT(PM_AWEN_USBC));
782 
783 	/* Disable the peripheral clock HSB & PBB */
784 	soc_pmc_peripheral_enable(
785 		PM_CLOCK_MASK(PM_CLK_GRP_HSB, SYSCLK_USBC_DATA));
786 	soc_pmc_peripheral_enable(
787 		PM_CLOCK_MASK(PM_CLK_GRP_PBB, SYSCLK_USBC_REGS));
788 
789 	irq_disable(DT_INST_IRQN(0));
790 	irq_unlock(key);
791 
792 	LOG_DBG("USB DC detach");
793 	return 0;
794 }
795 
usb_dc_reset(void)796 int usb_dc_reset(void)
797 {
798 	uint32_t key = irq_lock();
799 
800 	/* Reset the controller */
801 	regs->USBCON = USBC_USBCON_UIMOD | USBC_USBCON_FRZCLK;
802 
803 	/* Clear private data */
804 	(void)memset(&dev_data, 0, sizeof(dev_data));
805 	(void)memset(&dev_desc, 0, sizeof(dev_desc));
806 
807 	irq_unlock(key);
808 
809 	LOG_DBG("USB DC reset");
810 	return 0;
811 }
812 
usb_dc_set_address(uint8_t addr)813 int usb_dc_set_address(uint8_t addr)
814 {
815 	/*
816 	 * Set the address but keep it disabled for now. It should be enabled
817 	 * only after the ack to the host completes.
818 	 */
819 	regs->UDCON &= ~USBC_UDCON_ADDEN;
820 	regs->UDCON |= USBC_UDCON_UADD(addr);
821 
822 	LOG_DBG("USB DC set address 0x%02x", addr);
823 	return 0;
824 }
825 
usb_dc_set_status_callback(const usb_dc_status_callback cb)826 void usb_dc_set_status_callback(const usb_dc_status_callback cb)
827 {
828 	regs->UDINTECLR = USBC_UDINTECLR_MASK;
829 	regs->UDINTCLR = USBC_UDINTCLR_MASK;
830 
831 	usb_dc_detach();
832 	usb_dc_reset();
833 
834 	dev_data.status_cb = cb;
835 
836 	LOG_DBG("USB DC set callback");
837 }
838 
usb_dc_ep_check_cap(const struct usb_dc_ep_cfg_data * const cfg)839 int usb_dc_ep_check_cap(const struct usb_dc_ep_cfg_data * const cfg)
840 {
841 	uint8_t ep_idx = USB_EP_GET_IDX(cfg->ep_addr);
842 
843 	if (ep_idx >= NUM_OF_EP_MAX) {
844 		LOG_ERR("endpoint index/address out of range");
845 		return -EINVAL;
846 	}
847 
848 	if (ep_idx == 0U) {
849 		if (cfg->ep_type != USB_DC_EP_CONTROL) {
850 			LOG_ERR("pre-selected as control endpoint");
851 			return -EINVAL;
852 		}
853 	} else if (ep_idx & BIT(0)) {
854 		if (USB_EP_DIR_IS_OUT(cfg->ep_addr)) {
855 			LOG_INF("pre-selected as IN endpoint");
856 			return -EINVAL;
857 		}
858 	} else {
859 		if (USB_EP_DIR_IS_IN(cfg->ep_addr)) {
860 			LOG_INF("pre-selected as OUT endpoint");
861 			return -EINVAL;
862 		}
863 	}
864 
865 	if (cfg->ep_mps < 1 || cfg->ep_mps > 1024 ||
866 	    (cfg->ep_type == USB_DC_EP_CONTROL && cfg->ep_mps > 64)) {
867 		LOG_ERR("invalid endpoint size");
868 		return -EINVAL;
869 	}
870 	return 0;
871 }
872 
usb_dc_ep_configure(const struct usb_dc_ep_cfg_data * const cfg)873 int usb_dc_ep_configure(const struct usb_dc_ep_cfg_data *const cfg)
874 {
875 	uint8_t ep_idx = USB_EP_GET_IDX(cfg->ep_addr);
876 	uint32_t regval = 0U;
877 	int log2ceil_mps;
878 
879 	if (usb_dc_ep_check_cap(cfg) != 0) {
880 		return -EINVAL;
881 	}
882 
883 	if (!usb_dc_is_attached()) {
884 		LOG_ERR("device not attached");
885 		return -ENODEV;
886 	}
887 
888 	/* Allow re-configure any endpoint */
889 	if (usb_dc_ep_is_enabled(ep_idx)) {
890 		usb_dc_ep_disable(ep_idx);
891 	}
892 
893 	LOG_DBG("Configure ep 0x%02x, mps %d, type %d",
894 		cfg->ep_addr, cfg->ep_mps, cfg->ep_type);
895 
896 	switch (cfg->ep_type) {
897 	case USB_DC_EP_CONTROL:
898 		regval |= USBC_UECFG0_EPTYPE_CONTROL;
899 		break;
900 	case USB_DC_EP_ISOCHRONOUS:
901 		regval |= USBC_UECFG0_EPTYPE_ISOCHRONOUS;
902 		break;
903 	case USB_DC_EP_BULK:
904 		regval |= USBC_UECFG0_EPTYPE_BULK;
905 		break;
906 	case USB_DC_EP_INTERRUPT:
907 		regval |= USBC_UECFG0_EPTYPE_INTERRUPT;
908 		break;
909 	default:
910 		return -EINVAL;
911 	}
912 
913 	if (USB_EP_DIR_IS_OUT(cfg->ep_addr) ||
914 	    cfg->ep_type == USB_DC_EP_CONTROL) {
915 		regval |= USBC_UECFG0_EPDIR_OUT;
916 	} else {
917 		regval |= USBC_UECFG0_EPDIR_IN;
918 	}
919 
920 	/*
921 	 * Map the endpoint size to the buffer size. Only power of 2 buffer
922 	 * sizes between 8 and 1024 are possible, get the next power of 2.
923 	 */
924 	log2ceil_mps = 32 - __builtin_clz((MAX(cfg->ep_mps, 8) << 1) - 1) - 1;
925 	regval |= USBC_UECFG0_EPSIZE(log2ceil_mps - 3);
926 	dev_data.ep_data[ep_idx].mps = cfg->ep_mps;
927 
928 	/* Use double bank buffering for: ISOCHRONOUS, BULK and INTERRUPT */
929 	if (cfg->ep_type != USB_DC_EP_CONTROL) {
930 		regval |= USBC_UECFG0_EPBK_DOUBLE;
931 		dev_data.ep_data[ep_idx].mps_x2 = true;
932 	} else {
933 		regval |= USBC_UECFG0_EPBK_SINGLE;
934 		dev_data.ep_data[ep_idx].mps_x2 = false;
935 	}
936 
937 	/** Enable Global NAK */
938 	regs->UDCON |= USBC_UDCON_GNAK;
939 	if (usb_dc_sam_usbc_ep_alloc_buf(ep_idx) < 0) {
940 		dev_data.ep_data[ep_idx].is_configured = false;
941 		regs->UDCON &= ~USBC_UDCON_GNAK;
942 		return -ENOMEM;
943 	}
944 	regs->UDCON &= ~USBC_UDCON_GNAK;
945 
946 	/* Configure the endpoint */
947 	dev_data.ep_data[ep_idx].is_configured = true;
948 	regs->UECFG[ep_idx] = regval;
949 
950 	LOG_DBG("ep 0x%02x configured", cfg->ep_addr);
951 	return 0;
952 }
953 
usb_dc_ep_set_stall(uint8_t ep)954 int usb_dc_ep_set_stall(uint8_t ep)
955 {
956 	uint8_t ep_idx = USB_EP_GET_IDX(ep);
957 
958 	if (ep_idx >= NUM_OF_EP_MAX) {
959 		LOG_ERR("wrong endpoint index/address");
960 		return -EINVAL;
961 	}
962 
963 	if (ep_idx == 0) {
964 		if (epctrl_fsm == USB_EPCTRL_SETUP) {
965 			usb_dc_ctrl_stall_data(USBC_UESTA0CLR_RXSTPIC);
966 		} else if (epctrl_fsm == USB_EPCTRL_DATA_OUT) {
967 			usb_dc_ctrl_stall_data(USBC_UESTA0CLR_RXOUTIC);
968 		} else {
969 			/** Stall without commit any status */
970 			usb_dc_ctrl_stall_data(0);
971 		}
972 	} else {
973 		regs->UECONSET[ep_idx] = USBC_UECON0SET_STALLRQS;
974 	}
975 
976 	LOG_WRN("USB DC stall set ep 0x%02x", ep);
977 	return 0;
978 }
979 
usb_dc_ep_clear_stall(uint8_t ep)980 int usb_dc_ep_clear_stall(uint8_t ep)
981 {
982 	uint8_t ep_idx = USB_EP_GET_IDX(ep);
983 	uint32_t key;
984 
985 	if (ep_idx >= NUM_OF_EP_MAX) {
986 		LOG_ERR("wrong endpoint index/address");
987 		return -EINVAL;
988 	}
989 
990 	if (regs->UECON[ep_idx] & USBC_UECON0_STALLRQ) {
991 		key = irq_lock();
992 
993 		dev_data.ep_data[ep_idx].out_at = 0U;
994 
995 		regs->UECONCLR[ep_idx] = USBC_UECON0CLR_STALLRQC;
996 		if (regs->UESTA[ep_idx] & USBC_UESTA0_STALLEDI) {
997 			regs->UESTACLR[ep_idx] = USBC_UESTA0CLR_STALLEDIC;
998 			regs->UECONSET[ep_idx] = USBC_UECON0SET_RSTDTS;
999 		}
1000 
1001 		irq_unlock(key);
1002 	}
1003 
1004 	LOG_DBG("USB DC stall clear ep 0x%02x", ep);
1005 	return 0;
1006 }
1007 
usb_dc_ep_is_stalled(uint8_t ep,uint8_t * stalled)1008 int usb_dc_ep_is_stalled(uint8_t ep, uint8_t *stalled)
1009 {
1010 	uint8_t ep_idx = USB_EP_GET_IDX(ep);
1011 
1012 	if (ep_idx >= NUM_OF_EP_MAX) {
1013 		LOG_ERR("wrong endpoint index/address");
1014 		return -EINVAL;
1015 	}
1016 
1017 	if (!stalled) {
1018 		return -EINVAL;
1019 	}
1020 
1021 	*stalled = ((regs->UECON[ep_idx] & USBC_UECON0_STALLRQ) != 0);
1022 
1023 	LOG_DBG("USB DC stall check ep 0x%02x stalled: %d", ep, *stalled);
1024 	return 0;
1025 }
1026 
usb_dc_ep_halt(uint8_t ep)1027 int usb_dc_ep_halt(uint8_t ep)
1028 {
1029 	return usb_dc_ep_set_stall(ep);
1030 }
1031 
usb_dc_ep_enable(uint8_t ep)1032 int usb_dc_ep_enable(uint8_t ep)
1033 {
1034 	uint8_t ep_idx = USB_EP_GET_IDX(ep);
1035 	uint32_t key;
1036 
1037 	if (ep_idx >= NUM_OF_EP_MAX) {
1038 		LOG_ERR("wrong endpoint index/address");
1039 		return -EINVAL;
1040 	}
1041 
1042 	if (!dev_data.ep_data[ep_idx].is_configured) {
1043 		LOG_ERR("endpoint not configured");
1044 		return -ENODEV;
1045 	}
1046 
1047 	key = irq_lock();
1048 	dev_data.ep_data[ep_idx].out_at = 0U;
1049 
1050 	/* Enable endpoint */
1051 	regs->UERST |= BIT(USBC_UERST_EPEN0_Pos + ep_idx);
1052 	/* Enable global endpoint interrupts */
1053 	regs->UDINTESET = (USBC_UDINTESET_EP0INTES << ep_idx);
1054 
1055 	usb_dc_ep_enable_interrupts(ep_idx);
1056 	irq_unlock(key);
1057 
1058 	LOG_DBG("Enable ep 0x%02x", ep);
1059 	return 0;
1060 }
1061 
usb_dc_ep_disable(uint8_t ep)1062 int usb_dc_ep_disable(uint8_t ep)
1063 {
1064 	uint8_t ep_idx = USB_EP_GET_IDX(ep);
1065 	uint32_t key;
1066 
1067 	if (ep_idx >= NUM_OF_EP_MAX) {
1068 		LOG_ERR("wrong endpoint index/address");
1069 		return -EINVAL;
1070 	}
1071 
1072 	key = irq_lock();
1073 
1074 	/* Disable global endpoint interrupt */
1075 	regs->UDINTECLR = BIT(USBC_UDINTESET_EP0INTES_Pos + ep_idx);
1076 
1077 	/* Disable endpoint and reset */
1078 	regs->UERST &= ~BIT(USBC_UERST_EPEN0_Pos + ep_idx);
1079 
1080 	irq_unlock(key);
1081 
1082 	LOG_DBG("Disable ep 0x%02x", ep);
1083 	return 0;
1084 }
1085 
usb_dc_ep_flush(uint8_t ep)1086 int usb_dc_ep_flush(uint8_t ep)
1087 {
1088 	uint8_t ep_idx = USB_EP_GET_IDX(ep);
1089 	uint32_t key;
1090 
1091 	if (ep_idx >= NUM_OF_EP_MAX) {
1092 		LOG_ERR("wrong endpoint index/address");
1093 		return -EINVAL;
1094 	}
1095 
1096 	if (!usb_dc_ep_is_enabled(ep_idx)) {
1097 		LOG_ERR("endpoint not enabled");
1098 		return -ENODEV;
1099 	}
1100 
1101 	key = irq_lock();
1102 
1103 	/* Disable the IN interrupt */
1104 	regs->UECONCLR[ep_idx] = USBC_UECON0CLR_TXINEC;
1105 
1106 	/* Reset the endpoint */
1107 	regs->UERST &= ~(BIT(ep_idx));
1108 	regs->UERST |= BIT(ep_idx);
1109 
1110 	dev_data.ep_data[ep_idx].out_at = 0U;
1111 
1112 	/* Re-enable interrupts */
1113 	usb_dc_ep_enable_interrupts(ep_idx);
1114 
1115 	irq_unlock(key);
1116 
1117 	LOG_DBG("ep 0x%02x flushed", ep);
1118 	return 0;
1119 }
1120 
usb_dc_ep_set_callback(uint8_t ep,const usb_dc_ep_callback cb)1121 int usb_dc_ep_set_callback(uint8_t ep, const usb_dc_ep_callback cb)
1122 {
1123 	uint8_t ep_idx = USB_EP_GET_IDX(ep);
1124 
1125 	if (ep_idx >= NUM_OF_EP_MAX) {
1126 		LOG_ERR("wrong endpoint index/address");
1127 		return -EINVAL;
1128 	}
1129 
1130 	if (USB_EP_DIR_IS_IN(ep)) {
1131 		dev_data.ep_data[ep_idx].cb_in = cb;
1132 	} else {
1133 		dev_data.ep_data[ep_idx].cb_out = cb;
1134 	}
1135 
1136 	LOG_DBG("set ep 0x%02x %s callback", ep,
1137 		USB_EP_DIR_IS_IN(ep) ? "IN" : "OUT");
1138 	return 0;
1139 }
1140 
usb_dc_ep_write_stp(uint8_t ep_bank,const uint8_t * data,uint32_t packet_len)1141 static int usb_dc_ep_write_stp(uint8_t ep_bank, const uint8_t *data,
1142 			       uint32_t packet_len)
1143 {
1144 	uint32_t key;
1145 
1146 	if (epctrl_fsm == USB_EPCTRL_SETUP) {
1147 		regs->UESTACLR[0] = USBC_UESTA0CLR_RXSTPIC;
1148 
1149 		epctrl_fsm = USB_EPCTRL_DATA_IN;
1150 
1151 		key = irq_lock();
1152 		regs->UECONCLR[0] = USBC_UECON0CLR_TXINEC;
1153 		irq_unlock(key);
1154 	}
1155 
1156 	if (epctrl_fsm == USB_EPCTRL_DATA_IN) {
1157 		/* All data requested are transferred or a short packet has
1158 		 * been sent then it is the end of data phase.
1159 		 *
1160 		 * Generate an OUT ZLP for handshake phase.
1161 		 */
1162 		if (packet_len == 0) {
1163 			usb_dc_ctrl_send_zlp_out();
1164 			return 0;
1165 		}
1166 
1167 		/** Critical section
1168 		 * Only in case of DATA IN phase abort without USB Reset
1169 		 * signal after.  The IN data don't must be written in
1170 		 * endpoint 0 DPRAM during a next setup reception in same
1171 		 * endpoint 0 DPRAM.  Thereby, an OUT ZLP reception must
1172 		 * check before IN data write and if no OUT ZLP is received
1173 		 * the data must be written quickly (800us) before an
1174 		 * eventually ZLP OUT and SETUP reception.
1175 		 */
1176 		key = irq_lock();
1177 
1178 		if (regs->UESTA[0] & USBC_UESTA0_RXOUTI) {
1179 
1180 			/* IN DATA phase aborted by OUT ZLP */
1181 			irq_unlock(key);
1182 
1183 			epctrl_fsm = USB_EPCTRL_HANDSHAKE_WAIT_OUT_ZLP;
1184 			return 0;
1185 		}
1186 
1187 		if (data) {
1188 			memcpy(dev_desc[ep_bank].ep_pipe_addr,
1189 			       data, packet_len);
1190 			barrier_dsync_fence_full();
1191 		}
1192 		dev_desc[ep_bank].sizes = packet_len;
1193 
1194 		/*
1195 		 * Control endpoint: clear the interrupt flag to send
1196 		 * the data, and re-enable the interrupts to trigger
1197 		 * an interrupt at the end of the transfer.
1198 		 */
1199 		regs->UESTACLR[0] = USBC_UESTA0CLR_TXINIC;
1200 		regs->UECONSET[0] = USBC_UECON0SET_TXINES;
1201 
1202 		/* In case of abort of DATA IN phase, no need to enable
1203 		 * nak OUT interrupt because OUT endpoint is already
1204 		 * free and ZLP OUT accepted.
1205 		 */
1206 		irq_unlock(key);
1207 	} else if (epctrl_fsm == USB_EPCTRL_DATA_OUT ||
1208 		   epctrl_fsm == USB_EPCTRL_HANDSHAKE_WAIT_IN_ZLP) {
1209 		/* ZLP on IN is sent, then valid end of setup request
1210 		 * or
1211 		 * No data phase requested.
1212 		 *
1213 		 * Send IN ZLP to ACK setup request
1214 		 */
1215 		usb_dc_ctrl_send_zlp_in();
1216 	} else {
1217 		LOG_ERR("Invalid STP state %d on IN phase", epctrl_fsm);
1218 		return -EPERM;
1219 	}
1220 	return 0;
1221 }
1222 
usb_dc_ep_write(uint8_t ep,const uint8_t * data,uint32_t data_len,uint32_t * ret_bytes)1223 int usb_dc_ep_write(uint8_t ep, const uint8_t *data,
1224 		    uint32_t data_len, uint32_t *ret_bytes)
1225 {
1226 	uint8_t ep_idx = USB_EP_GET_IDX(ep);
1227 	uint8_t ep_bank;
1228 	uint32_t packet_len;
1229 
1230 	if (ep_idx >= NUM_OF_EP_MAX) {
1231 		LOG_ERR("wrong endpoint index/address");
1232 		return -EINVAL;
1233 	}
1234 
1235 	if (!usb_dc_ep_is_enabled(ep_idx)) {
1236 		LOG_ERR("endpoint not enabled");
1237 		return -ENODEV;
1238 	}
1239 
1240 	if (USB_EP_DIR_IS_OUT(ep)) {
1241 		LOG_ERR("wrong endpoint direction");
1242 		return -EINVAL;
1243 	}
1244 
1245 	if ((regs->UECON[ep_idx] & USBC_UECON0_STALLRQ) != 0) {
1246 		LOG_WRN("endpoint is stalled");
1247 		return -EBUSY;
1248 	}
1249 
1250 	/* Check if there is bank available */
1251 	if (ep_idx > 0) {
1252 		if ((regs->UECON[ep_idx] & USBC_UECON0_FIFOCON) == 0) {
1253 			return -EAGAIN;
1254 		}
1255 	}
1256 
1257 	ep_bank = usb_dc_sam_usbc_ep_curr_bank(ep_idx);
1258 
1259 	packet_len = MIN(data_len, dev_data.ep_data[ep_idx].mps);
1260 
1261 	if (ret_bytes) {
1262 		*ret_bytes = packet_len;
1263 	}
1264 
1265 	if (ep_idx == 0U) {
1266 		if (usb_dc_ep_write_stp(ep_bank, data, packet_len)) {
1267 			return -EPERM;
1268 		}
1269 	} else {
1270 		if (data && packet_len > 0) {
1271 			memcpy(dev_desc[ep_bank].ep_pipe_addr, data, packet_len);
1272 			barrier_dsync_fence_full();
1273 		}
1274 		dev_desc[ep_bank].sizes = packet_len;
1275 
1276 		/*
1277 		 * Other endpoint types: clear the FIFO control flag to send
1278 		 * the data.
1279 		 */
1280 		regs->UECONCLR[ep_idx] = USBC_UECON0CLR_FIFOCONC;
1281 	}
1282 
1283 	LOG_INF("ep 0x%02x write %d bytes from %d to bank %d%s",
1284 		ep, packet_len, data_len, ep_bank % 2,
1285 		packet_len == 0 ? " (ZLP)" : "");
1286 	return 0;
1287 }
1288 
usb_dc_ep_read_ex_stp(uint32_t take,uint32_t wLength)1289 static int usb_dc_ep_read_ex_stp(uint32_t take, uint32_t wLength)
1290 {
1291 	uint32_t key;
1292 
1293 	if (epctrl_fsm == USB_EPCTRL_SETUP) {
1294 		if (regs->UESTA[0] & USBC_UESTA0_CTRLDIR) {
1295 			/** Do Nothing */
1296 		} else {
1297 			regs->UESTACLR[0] = USBC_UESTA0CLR_RXSTPIC;
1298 
1299 			epctrl_fsm = USB_EPCTRL_DATA_OUT;
1300 
1301 			if (wLength == 0) {
1302 				/* No data phase requested.
1303 				 * Send IN ZLP to ACK setup request
1304 				 *
1305 				 * This is send at usb_dc_ep_write()
1306 				 */
1307 				return 0;
1308 			}
1309 
1310 			regs->UECONSET[0] = USBC_UECON0SET_RXOUTES;
1311 
1312 			/* To detect a protocol error, enable nak
1313 			 * interrupt on data IN phase
1314 			 */
1315 			regs->UESTACLR[0] = USBC_UESTA0CLR_NAKINIC;
1316 			key = irq_lock();
1317 			regs->UECONSET[0] = USBC_UECON0SET_NAKINES;
1318 			irq_unlock(key);
1319 		}
1320 	} else if (epctrl_fsm == USB_EPCTRL_DATA_OUT) {
1321 		regs->UESTACLR[0] = USBC_UESTA0CLR_RXOUTIC;
1322 
1323 		if (take == 0) {
1324 			usb_dc_ctrl_send_zlp_in();
1325 		} else {
1326 			regs->UESTACLR[0] = USBC_UESTA0CLR_NAKINIC;
1327 			key = irq_lock();
1328 			regs->UECONSET[0] = USBC_UECON0SET_NAKINES;
1329 			irq_unlock(key);
1330 		}
1331 	} else {
1332 		LOG_ERR("Invalid STP state %d on OUT phase", epctrl_fsm);
1333 		return -EPERM;
1334 	}
1335 	return 0;
1336 }
1337 
usb_dc_ep_read_ex(uint8_t ep,uint8_t * data,uint32_t max_data_len,uint32_t * read_bytes,bool wait)1338 int usb_dc_ep_read_ex(uint8_t ep, uint8_t *data, uint32_t max_data_len,
1339 		      uint32_t *read_bytes, bool wait)
1340 {
1341 	uint8_t ep_idx = USB_EP_GET_IDX(ep);
1342 	struct usb_setup_packet *setup;
1343 	uint8_t ep_bank;
1344 	uint32_t data_len;
1345 	uint32_t remaining;
1346 	uint32_t take;
1347 	int rc = 0;
1348 
1349 	if (ep_idx >= NUM_OF_EP_MAX) {
1350 		LOG_ERR("wrong endpoint index/address");
1351 		return -EINVAL;
1352 	}
1353 
1354 	if (!usb_dc_ep_is_enabled(ep_idx)) {
1355 		LOG_ERR("endpoint not enabled");
1356 		return -ENODEV;
1357 	}
1358 
1359 	if (USB_EP_DIR_IS_IN(ep)) {
1360 		LOG_ERR("wrong endpoint direction");
1361 		return -EINVAL;
1362 	}
1363 
1364 	if ((regs->UECON[ep_idx] & USBC_UECON0_STALLRQ) != 0) {
1365 		LOG_WRN("endpoint is stalled");
1366 		return -EBUSY;
1367 	}
1368 
1369 	ep_bank = usb_dc_sam_usbc_ep_curr_bank(ep_idx);
1370 	data_len = dev_desc[ep_bank].udesc_sizes.byte_count;
1371 
1372 	if (data == NULL) {
1373 		dev_data.ep_data[ep_idx].out_at = 0U;
1374 
1375 		if (read_bytes) {
1376 			*read_bytes = data_len;
1377 		}
1378 		return 0;
1379 	}
1380 
1381 	remaining = data_len - dev_data.ep_data[ep_idx].out_at;
1382 	take = MIN(max_data_len, remaining);
1383 	if (take) {
1384 		memcpy(data,
1385 		       (uint8_t *) dev_desc[ep_bank].ep_pipe_addr +
1386 		       dev_data.ep_data[ep_idx].out_at,
1387 		       take);
1388 		barrier_dsync_fence_full();
1389 	}
1390 
1391 	if (read_bytes) {
1392 		*read_bytes = take;
1393 	}
1394 
1395 	if (take == remaining || take == 0) {
1396 		if (!wait) {
1397 			dev_data.ep_data[ep_idx].out_at = 0U;
1398 
1399 			if (ep_idx == 0) {
1400 				setup = (struct usb_setup_packet *) data;
1401 				rc = usb_dc_ep_read_ex_stp(take,
1402 							   setup->wLength);
1403 			} else {
1404 				rc = usb_dc_ep_read_continue(ep);
1405 			}
1406 		}
1407 	} else {
1408 		dev_data.ep_data[ep_idx].out_at += take;
1409 	}
1410 
1411 	LOG_INF("ep 0x%02x read %d bytes from bank %d and %s",
1412 		ep, take, ep_bank % 2, wait ? "wait" : "NO wait");
1413 	return rc;
1414 }
1415 
usb_dc_ep_read_continue(uint8_t ep)1416 int usb_dc_ep_read_continue(uint8_t ep)
1417 {
1418 	uint8_t ep_idx = USB_EP_GET_IDX(ep);
1419 
1420 	if (ep_idx == 0 || ep_idx >= NUM_OF_EP_MAX) {
1421 		LOG_ERR("wrong endpoint index/address");
1422 		return -EINVAL;
1423 	}
1424 
1425 	if (!usb_dc_ep_is_enabled(ep_idx)) {
1426 		LOG_ERR("endpoint not enabled");
1427 		return -ENODEV;
1428 	}
1429 
1430 	if (USB_EP_DIR_IS_IN(ep)) {
1431 		LOG_ERR("wrong endpoint direction");
1432 		return -EINVAL;
1433 	}
1434 
1435 	regs->UECONCLR[ep_idx] = USBC_UECON0CLR_FIFOCONC;
1436 	return 0;
1437 }
1438 
usb_dc_ep_read(uint8_t ep,uint8_t * data,uint32_t max_data_len,uint32_t * read_bytes)1439 int usb_dc_ep_read(uint8_t ep, uint8_t *data, uint32_t max_data_len,
1440 		   uint32_t *read_bytes)
1441 {
1442 	return usb_dc_ep_read_ex(ep, data, max_data_len, read_bytes, false);
1443 }
1444 
usb_dc_ep_read_wait(uint8_t ep,uint8_t * data,uint32_t max_data_len,uint32_t * read_bytes)1445 int usb_dc_ep_read_wait(uint8_t ep, uint8_t *data, uint32_t max_data_len,
1446 			uint32_t *read_bytes)
1447 {
1448 	return usb_dc_ep_read_ex(ep, data, max_data_len, read_bytes, true);
1449 }
1450 
usb_dc_ep_mps(uint8_t ep)1451 int usb_dc_ep_mps(uint8_t ep)
1452 {
1453 	uint8_t ep_idx = USB_EP_GET_IDX(ep);
1454 
1455 	if (ep_idx >= NUM_OF_EP_MAX) {
1456 		LOG_ERR("wrong endpoint index/address");
1457 		return -EINVAL;
1458 	}
1459 
1460 	return dev_data.ep_data[ep_idx].mps;
1461 }
1462 
usb_dc_wakeup_request(void)1463 int usb_dc_wakeup_request(void)
1464 {
1465 	bool is_clk_frozen = usb_dc_sam_usbc_is_frozen_clk();
1466 
1467 	if (is_clk_frozen) {
1468 		usb_dc_sam_usbc_unfreeze_clk();
1469 	}
1470 
1471 	regs->UDCON |= USBC_UDCON_RMWKUP;
1472 
1473 	if (is_clk_frozen) {
1474 		usb_dc_sam_usbc_freeze_clk();
1475 	}
1476 	return 0;
1477 }
1478