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