1 /*
2 * Copyright (c) 2017 PHYTEC Messtechnik GmbH
3 * Copyright (c) 2022 Nordic Semiconductor ASA
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 /*
9 * Driver for the USBFSOTG device controller which can be found on
10 * devices like Kinetis K64F.
11 */
12 #define DT_DRV_COMPAT nxp_kinetis_usbd
13
14 #include <soc.h>
15 #include <string.h>
16 #include <stdio.h>
17
18 #include <zephyr/device.h>
19 #include <zephyr/kernel.h>
20 #include <zephyr/sys/byteorder.h>
21 #include <zephyr/drivers/usb/udc.h>
22
23 #include "udc_common.h"
24
25 #include <zephyr/logging/log.h>
26 LOG_MODULE_REGISTER(usbfsotg, CONFIG_UDC_DRIVER_LOG_LEVEL);
27
28 #define USBFSOTG_BD_OWN BIT(5)
29 #define USBFSOTG_BD_DATA1 BIT(4)
30 #define USBFSOTG_BD_KEEP BIT(3)
31 #define USBFSOTG_BD_NINC BIT(2)
32 #define USBFSOTG_BD_DTS BIT(1)
33 #define USBFSOTG_BD_STALL BIT(0)
34
35 #define USBFSOTG_SETUP_TOKEN 0x0D
36 #define USBFSOTG_IN_TOKEN 0x09
37 #define USBFSOTG_OUT_TOKEN 0x01
38
39 #define USBFSOTG_PERID 0x04
40 #define USBFSOTG_REV 0x33
41
42 /*
43 * There is no real advantage to change control endpoint size
44 * but we can use it for testing UDC driver API and higher layers.
45 */
46 #define USBFSOTG_MPS0 UDC_MPS0_64
47 #define USBFSOTG_EP0_SIZE 64
48
49 /*
50 * Buffer Descriptor (BD) entry provides endpoint buffer control
51 * information for USBFSOTG controller. Every endpoint direction requires
52 * two BD entries.
53 */
54 struct usbfsotg_bd {
55 union {
56 uint32_t bd_fields;
57
58 struct {
59 uint32_t reserved_1_0 : 2;
60 uint32_t tok_pid : 4;
61 uint32_t data1 : 1;
62 uint32_t own : 1;
63 uint32_t reserved_15_8 : 8;
64 uint32_t bc : 16;
65 } get __packed;
66
67 struct {
68 uint32_t reserved_1_0 : 2;
69 uint32_t bd_ctrl : 6;
70 uint32_t reserved_15_8 : 8;
71 uint32_t bc : 16;
72 } set __packed;
73
74 } __packed;
75 uint32_t buf_addr;
76 } __packed;
77
78 struct usbfsotg_config {
79 USB_Type *base;
80 /*
81 * Pointer to Buffer Descriptor Table for the endpoints
82 * buffer management. The driver configuration with 16 fully
83 * bidirectional endpoints would require four BD entries
84 * per endpoint and 512 bytes of memory.
85 */
86 struct usbfsotg_bd *bdt;
87 void (*irq_enable_func)(const struct device *dev);
88 void (*irq_disable_func)(const struct device *dev);
89 size_t num_of_eps;
90 struct udc_ep_config *ep_cfg_in;
91 struct udc_ep_config *ep_cfg_out;
92 };
93
94 enum usbfsotg_event_type {
95 /* Trigger next transfer, must not be used for control OUT */
96 USBFSOTG_EVT_XFER,
97 /* Setup packet received */
98 USBFSOTG_EVT_SETUP,
99 /* OUT transaction for specific endpoint is finished */
100 USBFSOTG_EVT_DOUT,
101 /* IN transaction for specific endpoint is finished */
102 USBFSOTG_EVT_DIN,
103 /* Workaround for clear halt in ISR */
104 USBFSOTG_EVT_CLEAR_HALT,
105 };
106
107 /* Structure for driver's endpoint events */
108 struct usbfsotg_ep_event {
109 sys_snode_t node;
110 const struct device *dev;
111 enum usbfsotg_event_type event;
112 uint8_t ep;
113 };
114
115 K_MEM_SLAB_DEFINE(usbfsotg_ee_slab, sizeof(struct usbfsotg_ep_event),
116 CONFIG_UDC_KINETIS_EVENT_COUNT, sizeof(void *));
117
118 struct usbfsotg_data {
119 struct k_work work;
120 struct k_fifo fifo;
121 /*
122 * Buffer pointers and busy flags used only for control OUT
123 * to map the buffers to BDs when both are occupied
124 */
125 struct net_buf *out_buf[2];
126 bool busy[2];
127 };
128
129 static int usbfsotg_ep_clear_halt(const struct device *dev,
130 struct udc_ep_config *const cfg);
131
132 /* Get buffer descriptor (BD) based on endpoint address */
usbfsotg_get_ebd(const struct device * const dev,struct udc_ep_config * const cfg,const bool opposite)133 static struct usbfsotg_bd *usbfsotg_get_ebd(const struct device *const dev,
134 struct udc_ep_config *const cfg,
135 const bool opposite)
136 {
137 const struct usbfsotg_config *config = dev->config;
138 uint8_t bd_idx;
139
140 bd_idx = USB_EP_GET_IDX(cfg->addr) * 4U + (cfg->stat.odd ^ opposite);
141 if (USB_EP_DIR_IS_IN(cfg->addr)) {
142 bd_idx += 2U;
143 }
144
145 return &config->bdt[bd_idx];
146 }
147
usbfsotg_bd_is_busy(const struct usbfsotg_bd * const bd)148 static bool usbfsotg_bd_is_busy(const struct usbfsotg_bd *const bd)
149 {
150 /* Do not use it for control OUT endpoint */
151 return bd->get.own;
152 }
153
usbfsotg_bd_set_ctrl(struct usbfsotg_bd * const bd,const size_t bc,uint8_t * const data,const bool data1)154 static void usbfsotg_bd_set_ctrl(struct usbfsotg_bd *const bd,
155 const size_t bc,
156 uint8_t *const data,
157 const bool data1)
158 {
159 bd->set.bc = bc;
160 bd->buf_addr = POINTER_TO_UINT(data);
161
162 if (data1) {
163 bd->set.bd_ctrl = USBFSOTG_BD_OWN | USBFSOTG_BD_DATA1 |
164 USBFSOTG_BD_DTS;
165 } else {
166 bd->set.bd_ctrl = USBFSOTG_BD_OWN | USBFSOTG_BD_DTS;
167 }
168
169 }
170
171 /* Resume TX token processing, see USBx_CTL field descriptions */
usbfsotg_resume_tx(const struct device * dev)172 static ALWAYS_INLINE void usbfsotg_resume_tx(const struct device *dev)
173 {
174 const struct usbfsotg_config *config = dev->config;
175 USB_Type *base = config->base;
176
177 base->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;
178 }
179
usbfsotg_xfer_continue(const struct device * dev,struct udc_ep_config * const cfg,struct net_buf * const buf)180 static int usbfsotg_xfer_continue(const struct device *dev,
181 struct udc_ep_config *const cfg,
182 struct net_buf *const buf)
183 {
184 const struct usbfsotg_config *config = dev->config;
185 USB_Type *base = config->base;
186 struct usbfsotg_bd *bd;
187 uint8_t *data_ptr;
188 size_t len;
189
190 bd = usbfsotg_get_ebd(dev, cfg, false);
191 if (unlikely(usbfsotg_bd_is_busy(bd))) {
192 LOG_ERR("ep 0x%02x buf busy", cfg->addr);
193 __ASSERT_NO_MSG(false);
194 return -EBUSY;
195 }
196
197 if (USB_EP_DIR_IS_OUT(cfg->addr)) {
198 len = MIN(net_buf_tailroom(buf), cfg->mps);
199 data_ptr = net_buf_tail(buf);
200 } else {
201 len = MIN(buf->len, cfg->mps);
202 data_ptr = buf->data;
203 }
204
205 usbfsotg_bd_set_ctrl(bd, len, data_ptr, cfg->stat.data1);
206
207 if (USB_EP_GET_IDX(cfg->addr) == 0U) {
208 usbfsotg_resume_tx(dev);
209 }
210
211 LOG_DBG("xfer %p, bd %p, ENDPT 0x%x, bd field 0x%02x",
212 buf, bd, base->ENDPOINT[USB_EP_GET_IDX(cfg->addr)].ENDPT,
213 bd->bd_fields);
214
215 return 0;
216 }
217
218 /* Initiate a new transfer, must not be used for control endpoint OUT */
usbfsotg_xfer_next(const struct device * dev,struct udc_ep_config * const cfg)219 static int usbfsotg_xfer_next(const struct device *dev,
220 struct udc_ep_config *const cfg)
221 {
222 struct net_buf *buf;
223
224 buf = udc_buf_peek(dev, cfg->addr);
225 if (buf == NULL) {
226 return -ENODATA;
227 }
228
229 return usbfsotg_xfer_continue(dev, cfg, buf);
230 }
231
usbfsotg_ctrl_feed_start(const struct device * dev,struct net_buf * const buf)232 static inline int usbfsotg_ctrl_feed_start(const struct device *dev,
233 struct net_buf *const buf)
234 {
235 struct usbfsotg_data *priv = udc_get_private(dev);
236 struct udc_ep_config *cfg;
237 struct usbfsotg_bd *bd;
238 size_t length;
239
240 cfg = udc_get_ep_cfg(dev, USB_CONTROL_EP_OUT);
241 if (priv->busy[cfg->stat.odd]) {
242 return -EBUSY;
243 }
244
245 bd = usbfsotg_get_ebd(dev, cfg, false);
246 length = MIN(net_buf_tailroom(buf), cfg->mps);
247
248 priv->out_buf[cfg->stat.odd] = buf;
249 priv->busy[cfg->stat.odd] = true;
250 usbfsotg_bd_set_ctrl(bd, length, net_buf_tail(buf), cfg->stat.data1);
251 LOG_DBG("ep0 %p|odd: %u|d: %u", buf, cfg->stat.odd, cfg->stat.data1);
252
253 return 0;
254 }
255
usbfsotg_ctrl_feed_start_next(const struct device * dev,struct net_buf * const buf)256 static inline int usbfsotg_ctrl_feed_start_next(const struct device *dev,
257 struct net_buf *const buf)
258 {
259 struct usbfsotg_data *priv = udc_get_private(dev);
260 struct udc_ep_config *cfg;
261 struct usbfsotg_bd *bd;
262 size_t length;
263
264 cfg = udc_get_ep_cfg(dev, USB_CONTROL_EP_OUT);
265 if (priv->busy[!cfg->stat.odd]) {
266 return -EBUSY;
267 }
268
269 bd = usbfsotg_get_ebd(dev, cfg, true);
270 length = MIN(net_buf_tailroom(buf), cfg->mps);
271
272 priv->out_buf[!cfg->stat.odd] = buf;
273 priv->busy[!cfg->stat.odd] = true;
274 usbfsotg_bd_set_ctrl(bd, length, net_buf_tail(buf), cfg->stat.data1);
275 LOG_DBG("ep0 %p|odd: %u|d: %u (n)", buf, cfg->stat.odd, cfg->stat.data1);
276
277 return 0;
278 }
279
280 /*
281 * Allocate buffer and initiate a new control OUT transfer,
282 * use successive buffer descriptor when next is true.
283 */
usbfsotg_ctrl_feed_dout(const struct device * dev,const size_t length,const bool next,const bool resume_tx)284 static int usbfsotg_ctrl_feed_dout(const struct device *dev,
285 const size_t length,
286 const bool next,
287 const bool resume_tx)
288 {
289 struct net_buf *buf;
290 int ret;
291
292 buf = udc_ctrl_alloc(dev, USB_CONTROL_EP_OUT, length);
293 if (buf == NULL) {
294 return -ENOMEM;
295 }
296
297 if (next) {
298 ret = usbfsotg_ctrl_feed_start_next(dev, buf);
299 } else {
300 ret = usbfsotg_ctrl_feed_start(dev, buf);
301 }
302
303 if (ret) {
304 net_buf_unref(buf);
305 return ret;
306 }
307
308 if (resume_tx) {
309 usbfsotg_resume_tx(dev);
310 }
311
312 return 0;
313 }
314
work_handler_setup(const struct device * dev)315 static inline int work_handler_setup(const struct device *dev)
316 {
317 struct net_buf *buf;
318 int err;
319
320 buf = udc_buf_get(dev, USB_CONTROL_EP_OUT);
321 if (buf == NULL) {
322 return -ENODATA;
323 }
324
325 /* Update to next stage of control transfer */
326 udc_ctrl_update_stage(dev, buf);
327
328 if (udc_ctrl_stage_is_data_out(dev)) {
329 /* Allocate and feed buffer for data OUT stage */
330 LOG_DBG("s:%p|feed for -out-", buf);
331 err = usbfsotg_ctrl_feed_dout(dev, udc_data_stage_length(buf),
332 false, true);
333 if (err == -ENOMEM) {
334 err = udc_submit_ep_event(dev, buf, err);
335 }
336 } else if (udc_ctrl_stage_is_data_in(dev)) {
337 /*
338 * Here we have to feed both descriptor tables so that
339 * no setup packets are lost in case of successive
340 * status OUT stage and next setup.
341 */
342 LOG_DBG("s:%p|feed for -in-status >setup", buf);
343 err = usbfsotg_ctrl_feed_dout(dev, 8U, false, false);
344 if (err == 0) {
345 err = usbfsotg_ctrl_feed_dout(dev, 8U, true, true);
346 }
347
348 /* Finally alloc buffer for IN and submit to upper layer */
349 if (err == 0) {
350 err = udc_ctrl_submit_s_in_status(dev);
351 }
352 } else {
353 LOG_DBG("s:%p|feed >setup", buf);
354 /*
355 * For all other cases we feed with a buffer
356 * large enough for setup packet.
357 */
358 err = usbfsotg_ctrl_feed_dout(dev, 8U, false, true);
359 if (err == 0) {
360 err = udc_ctrl_submit_s_status(dev);
361 }
362 }
363
364 return err;
365 }
366
work_handler_out(const struct device * dev,const uint8_t ep)367 static inline int work_handler_out(const struct device *dev,
368 const uint8_t ep)
369 {
370 struct net_buf *buf;
371 int err = 0;
372
373 buf = udc_buf_get(dev, ep);
374 if (buf == NULL) {
375 return -ENODATA;
376 }
377
378 if (ep == USB_CONTROL_EP_OUT) {
379 if (udc_ctrl_stage_is_status_out(dev)) {
380 /* s-in-status finished, next bd is already fed */
381 LOG_DBG("dout:%p|no feed", buf);
382 /* Status stage finished, notify upper layer */
383 udc_ctrl_submit_status(dev, buf);
384 } else {
385 /*
386 * For all other cases we feed with a buffer
387 * large enough for setup packet.
388 */
389 LOG_DBG("dout:%p|feed >setup", buf);
390 err = usbfsotg_ctrl_feed_dout(dev, 8U, false, false);
391 }
392
393 /* Update to next stage of control transfer */
394 udc_ctrl_update_stage(dev, buf);
395
396 if (udc_ctrl_stage_is_status_in(dev)) {
397 err = udc_ctrl_submit_s_out_status(dev, buf);
398 }
399 } else {
400 err = udc_submit_ep_event(dev, buf, 0);
401 }
402
403 return err;
404 }
405
work_handler_in(const struct device * dev,const uint8_t ep)406 static inline int work_handler_in(const struct device *dev,
407 const uint8_t ep)
408 {
409 struct net_buf *buf;
410
411 buf = udc_buf_get(dev, ep);
412 if (buf == NULL) {
413 return -ENODATA;
414 }
415
416 if (ep == USB_CONTROL_EP_IN) {
417 if (udc_ctrl_stage_is_status_in(dev) ||
418 udc_ctrl_stage_is_no_data(dev)) {
419 /* Status stage finished, notify upper layer */
420 udc_ctrl_submit_status(dev, buf);
421 }
422
423 /* Update to next stage of control transfer */
424 udc_ctrl_update_stage(dev, buf);
425
426 if (udc_ctrl_stage_is_status_out(dev)) {
427 /*
428 * IN transfer finished, release buffer,
429 * control OUT buffer should be already fed.
430 */
431 net_buf_unref(buf);
432 }
433
434 return 0;
435 }
436
437 return udc_submit_ep_event(dev, buf, 0);
438 }
439
usbfsotg_event_submit(const struct device * dev,const uint8_t ep,const enum usbfsotg_event_type event)440 static void usbfsotg_event_submit(const struct device *dev,
441 const uint8_t ep,
442 const enum usbfsotg_event_type event)
443 {
444 struct usbfsotg_data *priv = udc_get_private(dev);
445 struct usbfsotg_ep_event *ev;
446 int ret;
447
448 ret = k_mem_slab_alloc(&usbfsotg_ee_slab, (void **)&ev, K_NO_WAIT);
449 if (ret) {
450 udc_submit_event(dev, UDC_EVT_ERROR, ret);
451 }
452
453 ev->dev = dev;
454 ev->ep = ep;
455 ev->event = event;
456 k_fifo_put(&priv->fifo, ev);
457 k_work_submit_to_queue(udc_get_work_q(), &priv->work);
458 }
459
xfer_work_handler(struct k_work * item)460 static void xfer_work_handler(struct k_work *item)
461 {
462 struct usbfsotg_ep_event *ev;
463 struct usbfsotg_data *priv;
464
465 priv = CONTAINER_OF(item, struct usbfsotg_data, work);
466 while ((ev = k_fifo_get(&priv->fifo, K_NO_WAIT)) != NULL) {
467 struct udc_ep_config *ep_cfg;
468 int err = 0;
469
470 LOG_DBG("dev %p, ep 0x%02x, event %u",
471 ev->dev, ev->ep, ev->event);
472 ep_cfg = udc_get_ep_cfg(ev->dev, ev->ep);
473 if (unlikely(ep_cfg == NULL)) {
474 udc_submit_event(ev->dev, UDC_EVT_ERROR, -ENODATA);
475 goto xfer_work_error;
476 }
477
478 switch (ev->event) {
479 case USBFSOTG_EVT_SETUP:
480 err = work_handler_setup(ev->dev);
481 break;
482 case USBFSOTG_EVT_DOUT:
483 err = work_handler_out(ev->dev, ev->ep);
484 udc_ep_set_busy(ev->dev, ev->ep, false);
485 break;
486 case USBFSOTG_EVT_DIN:
487 err = work_handler_in(ev->dev, ev->ep);
488 udc_ep_set_busy(ev->dev, ev->ep, false);
489 break;
490 case USBFSOTG_EVT_CLEAR_HALT:
491 err = usbfsotg_ep_clear_halt(ev->dev, ep_cfg);
492 case USBFSOTG_EVT_XFER:
493 default:
494 break;
495 }
496
497 if (unlikely(err)) {
498 udc_submit_event(ev->dev, UDC_EVT_ERROR, err);
499 }
500
501 /* Peek next transfer */
502 if (ev->ep != USB_CONTROL_EP_OUT && !udc_ep_is_busy(ev->dev, ev->ep)) {
503 if (usbfsotg_xfer_next(ev->dev, ep_cfg) == 0) {
504 udc_ep_set_busy(ev->dev, ev->ep, true);
505 }
506 }
507
508 xfer_work_error:
509 k_mem_slab_free(&usbfsotg_ee_slab, (void *)ev);
510 }
511 }
512
stat_reg_get_ep(const uint8_t status)513 static ALWAYS_INLINE uint8_t stat_reg_get_ep(const uint8_t status)
514 {
515 uint8_t ep_idx = status >> USB_STAT_ENDP_SHIFT;
516
517 return (status & USB_STAT_TX_MASK) ? (USB_EP_DIR_IN | ep_idx) : ep_idx;
518 }
519
stat_reg_is_odd(const uint8_t status)520 static ALWAYS_INLINE bool stat_reg_is_odd(const uint8_t status)
521 {
522 return (status & USB_STAT_ODD_MASK) >> USB_STAT_ODD_SHIFT;
523 }
524
set_control_in_pid_data1(const struct device * dev)525 static ALWAYS_INLINE void set_control_in_pid_data1(const struct device *dev)
526 {
527 struct udc_ep_config *ep_cfg = udc_get_ep_cfg(dev, USB_CONTROL_EP_IN);
528
529 /* Set DATA1 PID for data or status stage */
530 ep_cfg->stat.data1 = true;
531 }
532
isr_handle_xfer_done(const struct device * dev,const uint8_t istatus,const uint8_t status)533 static ALWAYS_INLINE void isr_handle_xfer_done(const struct device *dev,
534 const uint8_t istatus,
535 const uint8_t status)
536 {
537 struct usbfsotg_data *priv = udc_get_private(dev);
538 uint8_t ep = stat_reg_get_ep(status);
539 bool odd = stat_reg_is_odd(status);
540 struct usbfsotg_bd *bd, *bd_op;
541 struct udc_ep_config *ep_cfg;
542 struct net_buf *buf;
543 uint8_t token_pid;
544 bool data1;
545 size_t len;
546
547 ep_cfg = udc_get_ep_cfg(dev, ep);
548 bd = usbfsotg_get_ebd(dev, ep_cfg, false);
549 bd_op = usbfsotg_get_ebd(dev, ep_cfg, true);
550 token_pid = bd->get.tok_pid;
551 len = bd->get.bc;
552 data1 = bd->get.data1 ? true : false;
553
554 LOG_DBG("TOKDNE, ep 0x%02x len %u odd %u data1 %u",
555 ep, len, odd, data1);
556
557 switch (token_pid) {
558 case USBFSOTG_SETUP_TOKEN:
559 ep_cfg->stat.odd = !odd;
560 ep_cfg->stat.data1 = true;
561 set_control_in_pid_data1(dev);
562
563 if (priv->out_buf[odd] != NULL) {
564 net_buf_add(priv->out_buf[odd], len);
565 udc_ep_buf_set_setup(priv->out_buf[odd]);
566 udc_buf_put(ep_cfg, priv->out_buf[odd]);
567 priv->busy[odd] = false;
568 priv->out_buf[odd] = NULL;
569 usbfsotg_event_submit(dev, ep, USBFSOTG_EVT_SETUP);
570 } else {
571 LOG_ERR("No buffer for ep 0x00");
572 udc_submit_event(dev, UDC_EVT_ERROR, -ENOBUFS);
573 }
574
575 break;
576 case USBFSOTG_OUT_TOKEN:
577 ep_cfg->stat.odd = !odd;
578 ep_cfg->stat.data1 = !data1;
579
580 if (ep == USB_CONTROL_EP_OUT) {
581 buf = priv->out_buf[odd];
582 priv->busy[odd] = false;
583 priv->out_buf[odd] = NULL;
584 } else {
585 buf = udc_buf_peek(dev, ep_cfg->addr);
586 }
587
588 if (buf == NULL) {
589 LOG_ERR("No buffer for ep 0x%02x", ep);
590 udc_submit_event(dev, UDC_EVT_ERROR, -ENOBUFS);
591 break;
592 }
593
594 net_buf_add(buf, len);
595 if (net_buf_tailroom(buf) >= ep_cfg->mps && len == ep_cfg->mps) {
596 if (ep == USB_CONTROL_EP_OUT) {
597 usbfsotg_ctrl_feed_start(dev, buf);
598 } else {
599 usbfsotg_xfer_continue(dev, ep_cfg, buf);
600 }
601 } else {
602 if (ep == USB_CONTROL_EP_OUT) {
603 udc_buf_put(ep_cfg, buf);
604 }
605
606 usbfsotg_event_submit(dev, ep, USBFSOTG_EVT_DOUT);
607 }
608
609 break;
610 case USBFSOTG_IN_TOKEN:
611 ep_cfg->stat.odd = !odd;
612 ep_cfg->stat.data1 = !data1;
613
614 buf = udc_buf_peek(dev, ep_cfg->addr);
615 if (buf == NULL) {
616 LOG_ERR("No buffer for ep 0x%02x", ep);
617 udc_submit_event(dev, UDC_EVT_ERROR, -ENOBUFS);
618 break;
619 }
620
621 net_buf_pull(buf, len);
622 if (buf->len) {
623 usbfsotg_xfer_continue(dev, ep_cfg, buf);
624 } else {
625 if (udc_ep_buf_has_zlp(buf)) {
626 usbfsotg_xfer_continue(dev, ep_cfg, buf);
627 udc_ep_buf_clear_zlp(buf);
628 break;
629 }
630
631 usbfsotg_event_submit(dev, ep, USBFSOTG_EVT_DIN);
632 }
633
634 break;
635 default:
636 break;
637 }
638 }
639
usbfsotg_isr_handler(const struct device * dev)640 static void usbfsotg_isr_handler(const struct device *dev)
641 {
642 const struct usbfsotg_config *config = dev->config;
643 USB_Type *base = config->base;
644 const uint8_t istatus = base->ISTAT;
645 const uint8_t status = base->STAT;
646
647 if (istatus & USB_ISTAT_USBRST_MASK) {
648 base->ADDR = 0U;
649 udc_submit_event(dev, UDC_EVT_RESET, 0);
650 }
651
652 if (istatus == USB_ISTAT_ERROR_MASK) {
653 LOG_DBG("ERROR IRQ 0x%02x", base->ERRSTAT);
654 udc_submit_event(dev, UDC_EVT_ERROR, base->ERRSTAT);
655 base->ERRSTAT = 0xFF;
656 }
657
658 if (istatus & USB_ISTAT_STALL_MASK) {
659 struct udc_ep_config *ep_cfg;
660
661 LOG_DBG("STALL sent");
662
663 ep_cfg = udc_get_ep_cfg(dev, USB_CONTROL_EP_OUT);
664 if (ep_cfg->stat.halted) {
665 /*
666 * usbfsotg_ep_clear_halt(dev, ep_cfg); cannot
667 * be called in ISR context
668 */
669 usbfsotg_event_submit(dev, USB_CONTROL_EP_OUT,
670 USBFSOTG_EVT_CLEAR_HALT);
671 }
672
673 ep_cfg = udc_get_ep_cfg(dev, USB_CONTROL_EP_IN);
674 if (ep_cfg->stat.halted) {
675 usbfsotg_event_submit(dev, USB_CONTROL_EP_IN,
676 USBFSOTG_EVT_CLEAR_HALT);
677 }
678 }
679
680 if (istatus & USB_ISTAT_TOKDNE_MASK) {
681 isr_handle_xfer_done(dev, istatus, status);
682 }
683
684 if (istatus & USB_ISTAT_SLEEP_MASK) {
685 LOG_DBG("SLEEP IRQ");
686 /* Enable resume interrupt */
687 base->INTEN |= USB_INTEN_RESUMEEN_MASK;
688
689 udc_set_suspended(dev, true);
690 udc_submit_event(dev, UDC_EVT_SUSPEND, 0);
691 }
692
693 if (istatus & USB_ISTAT_RESUME_MASK) {
694 LOG_DBG("RESUME IRQ");
695 /* Disable resume interrupt */
696 base->INTEN &= ~USB_INTEN_RESUMEEN_MASK;
697
698 udc_set_suspended(dev, false);
699 udc_submit_event(dev, UDC_EVT_RESUME, 0);
700 }
701
702 /* Clear interrupt status bits */
703 base->ISTAT = istatus;
704 }
705
usbfsotg_ep_enqueue(const struct device * dev,struct udc_ep_config * const cfg,struct net_buf * const buf)706 static int usbfsotg_ep_enqueue(const struct device *dev,
707 struct udc_ep_config *const cfg,
708 struct net_buf *const buf)
709 {
710
711 udc_buf_put(cfg, buf);
712 if (cfg->stat.halted) {
713 LOG_DBG("ep 0x%02x halted", cfg->addr);
714 return 0;
715 }
716
717 usbfsotg_event_submit(dev, cfg->addr, USBFSOTG_EVT_XFER);
718
719 return 0;
720 }
721
usbfsotg_ep_dequeue(const struct device * dev,struct udc_ep_config * const cfg)722 static int usbfsotg_ep_dequeue(const struct device *dev,
723 struct udc_ep_config *const cfg)
724 {
725 struct usbfsotg_bd *bd;
726 unsigned int lock_key;
727 struct net_buf *buf;
728
729 bd = usbfsotg_get_ebd(dev, cfg, false);
730
731 lock_key = irq_lock();
732 bd->set.bd_ctrl = USBFSOTG_BD_DTS;
733 irq_unlock(lock_key);
734
735 cfg->stat.halted = false;
736 buf = udc_buf_get_all(dev, cfg->addr);
737 if (buf) {
738 udc_submit_ep_event(dev, buf, -ECONNABORTED);
739 }
740
741 udc_ep_set_busy(dev, cfg->addr, false);
742
743 return 0;
744 }
745
ctrl_drop_out_successor(const struct device * dev)746 static void ctrl_drop_out_successor(const struct device *dev)
747 {
748 struct usbfsotg_data *priv = udc_get_private(dev);
749 struct udc_ep_config *cfg;
750 struct usbfsotg_bd *bd;
751 struct net_buf *buf;
752
753 cfg = udc_get_ep_cfg(dev, USB_CONTROL_EP_OUT);
754
755 if (priv->busy[!cfg->stat.odd]) {
756 bd = usbfsotg_get_ebd(dev, cfg, true);
757 buf = priv->out_buf[!cfg->stat.odd];
758
759 bd->bd_fields = 0U;
760 priv->busy[!cfg->stat.odd] = false;
761 if (buf) {
762 net_buf_unref(buf);
763 }
764 }
765 }
766
usbfsotg_ep_set_halt(const struct device * dev,struct udc_ep_config * const cfg)767 static int usbfsotg_ep_set_halt(const struct device *dev,
768 struct udc_ep_config *const cfg)
769 {
770 struct usbfsotg_bd *bd;
771
772 bd = usbfsotg_get_ebd(dev, cfg, false);
773 bd->set.bd_ctrl = USBFSOTG_BD_STALL | USBFSOTG_BD_DTS | USBFSOTG_BD_OWN;
774 cfg->stat.halted = true;
775 LOG_DBG("Halt ep 0x%02x bd %p", cfg->addr, bd);
776
777 if (cfg->addr == USB_CONTROL_EP_IN) {
778 /* Drop subsequent out transfer, current can be re-used */
779 ctrl_drop_out_successor(dev);
780 }
781
782 if (USB_EP_GET_IDX(cfg->addr) == 0U) {
783 usbfsotg_resume_tx(dev);
784 }
785
786 return 0;
787 }
788
usbfsotg_ep_clear_halt(const struct device * dev,struct udc_ep_config * const cfg)789 static int usbfsotg_ep_clear_halt(const struct device *dev,
790 struct udc_ep_config *const cfg)
791 {
792 const struct usbfsotg_config *config = dev->config;
793 struct usbfsotg_data *priv = udc_get_private(dev);
794 USB_Type *base = config->base;
795 uint8_t ep_idx = USB_EP_GET_IDX(cfg->addr);
796 struct usbfsotg_bd *bd;
797
798 LOG_DBG("Clear halt ep 0x%02x", cfg->addr);
799 bd = usbfsotg_get_ebd(dev, cfg, false);
800
801 if (bd->set.bd_ctrl & USBFSOTG_BD_STALL) {
802 LOG_DBG("bd %p: %x", bd, bd->set.bd_ctrl);
803 bd->set.bd_ctrl = USBFSOTG_BD_DTS;
804 } else {
805 LOG_WRN("bd %p is not halted", bd);
806 }
807
808 cfg->stat.data1 = false;
809 cfg->stat.halted = false;
810 base->ENDPOINT[ep_idx].ENDPT &= ~USB_ENDPT_EPSTALL_MASK;
811
812 if (cfg->addr == USB_CONTROL_EP_OUT) {
813 if (priv->busy[cfg->stat.odd]) {
814 LOG_DBG("bd %p restarted", bd);
815 bd->set.bd_ctrl = USBFSOTG_BD_DTS | USBFSOTG_BD_OWN;
816 } else {
817 usbfsotg_ctrl_feed_dout(dev, 8U, false, false);
818 }
819 }
820
821 if (USB_EP_GET_IDX(cfg->addr) == 0U) {
822 usbfsotg_resume_tx(dev);
823 } else {
824 /* TODO: trigger queued transfers? */
825 }
826
827 return 0;
828 }
829
usbfsotg_ep_enable(const struct device * dev,struct udc_ep_config * const cfg)830 static int usbfsotg_ep_enable(const struct device *dev,
831 struct udc_ep_config *const cfg)
832 {
833 const struct usbfsotg_config *config = dev->config;
834 struct usbfsotg_data *priv = udc_get_private(dev);
835 USB_Type *base = config->base;
836 const uint8_t ep_idx = USB_EP_GET_IDX(cfg->addr);
837 struct usbfsotg_bd *bd_even, *bd_odd;
838
839 LOG_DBG("Enable ep 0x%02x", cfg->addr);
840 bd_even = usbfsotg_get_ebd(dev, cfg, false);
841 bd_odd = usbfsotg_get_ebd(dev, cfg, true);
842
843 bd_even->bd_fields = 0U;
844 bd_even->buf_addr = 0U;
845 bd_odd->bd_fields = 0U;
846 bd_odd->buf_addr = 0U;
847
848 switch (cfg->attributes & USB_EP_TRANSFER_TYPE_MASK) {
849 case USB_EP_TYPE_CONTROL:
850 base->ENDPOINT[ep_idx].ENDPT = (USB_ENDPT_EPHSHK_MASK |
851 USB_ENDPT_EPRXEN_MASK |
852 USB_ENDPT_EPTXEN_MASK);
853 break;
854 case USB_EP_TYPE_BULK:
855 case USB_EP_TYPE_INTERRUPT:
856 base->ENDPOINT[ep_idx].ENDPT |= USB_ENDPT_EPHSHK_MASK;
857 if (USB_EP_DIR_IS_OUT(cfg->addr)) {
858 base->ENDPOINT[ep_idx].ENDPT |= USB_ENDPT_EPRXEN_MASK;
859 } else {
860 base->ENDPOINT[ep_idx].ENDPT |= USB_ENDPT_EPTXEN_MASK;
861 }
862 break;
863 case USB_EP_TYPE_ISO:
864 if (USB_EP_DIR_IS_OUT(cfg->addr)) {
865 base->ENDPOINT[ep_idx].ENDPT |= USB_ENDPT_EPRXEN_MASK;
866 } else {
867 base->ENDPOINT[ep_idx].ENDPT |= USB_ENDPT_EPTXEN_MASK;
868 }
869 break;
870 default:
871 return -EINVAL;
872 }
873
874 if (cfg->addr == USB_CONTROL_EP_OUT) {
875 struct net_buf *buf;
876
877 buf = udc_ctrl_alloc(dev, USB_CONTROL_EP_OUT, USBFSOTG_EP0_SIZE);
878 usbfsotg_bd_set_ctrl(bd_even, buf->size, buf->data, false);
879 priv->out_buf[0] = buf;
880 }
881
882 return 0;
883 }
884
usbfsotg_ep_disable(const struct device * dev,struct udc_ep_config * const cfg)885 static int usbfsotg_ep_disable(const struct device *dev,
886 struct udc_ep_config *const cfg)
887 {
888 const struct usbfsotg_config *config = dev->config;
889 USB_Type *base = config->base;
890 uint8_t ep_idx = USB_EP_GET_IDX(cfg->addr);
891 struct usbfsotg_bd *bd_even, *bd_odd;
892
893 bd_even = usbfsotg_get_ebd(dev, cfg, false);
894 bd_odd = usbfsotg_get_ebd(dev, cfg, true);
895
896 if (USB_EP_DIR_IS_OUT(cfg->addr)) {
897 base->ENDPOINT[ep_idx].ENDPT &= ~USB_ENDPT_EPRXEN_MASK;
898 } else {
899 base->ENDPOINT[ep_idx].ENDPT &= ~USB_ENDPT_EPTXEN_MASK;
900 }
901
902 if (usbfsotg_bd_is_busy(bd_even) || usbfsotg_bd_is_busy(bd_odd)) {
903 LOG_DBG("Endpoint buffer is busy");
904 }
905
906 bd_even->bd_fields = 0U;
907 bd_even->buf_addr = 0U;
908 bd_odd->bd_fields = 0U;
909 bd_odd->buf_addr = 0U;
910
911 LOG_DBG("Disable ep 0x%02x", cfg->addr);
912
913 return 0;
914 }
915
usbfsotg_host_wakeup(const struct device * dev)916 static int usbfsotg_host_wakeup(const struct device *dev)
917 {
918 return -ENOTSUP;
919 }
920
usbfsotg_set_address(const struct device * dev,const uint8_t addr)921 static int usbfsotg_set_address(const struct device *dev, const uint8_t addr)
922 {
923 const struct usbfsotg_config *config = dev->config;
924 USB_Type *base = config->base;
925
926 base->ADDR = addr;
927
928 return 0;
929 }
930
usbfsotg_enable(const struct device * dev)931 static int usbfsotg_enable(const struct device *dev)
932 {
933 const struct usbfsotg_config *config = dev->config;
934 USB_Type *base = config->base;
935
936 /* non-OTG device mode, enable DP Pullup */
937 base->CONTROL = USB_CONTROL_DPPULLUPNONOTG_MASK;
938
939 return 0;
940 }
941
usbfsotg_disable(const struct device * dev)942 static int usbfsotg_disable(const struct device *dev)
943 {
944 const struct usbfsotg_config *config = dev->config;
945 USB_Type *base = config->base;
946
947 /* disable USB and DP Pullup */
948 base->CTL &= ~USB_CTL_USBENSOFEN_MASK;
949 base->CONTROL &= ~USB_CONTROL_DPPULLUPNONOTG_MASK;
950
951 return 0;
952 }
953
usbfsotg_is_supported(const struct device * dev)954 static bool usbfsotg_is_supported(const struct device *dev)
955 {
956 const struct usbfsotg_config *config = dev->config;
957 USB_Type *base = config->base;
958
959 if ((base->PERID != USBFSOTG_PERID) || (base->REV != USBFSOTG_REV)) {
960 return false;
961 }
962
963 return true;
964 }
965
usbfsotg_init(const struct device * dev)966 static int usbfsotg_init(const struct device *dev)
967 {
968 const struct usbfsotg_config *config = dev->config;
969 USB_Type *base = config->base;
970
971 /* (FIXME) Enable USB voltage regulator */
972 SIM->SOPT1 |= SIM_SOPT1_USBREGEN_MASK;
973
974 /* Reset USB module */
975 base->USBTRC0 |= USB_USBTRC0_USBRESET_MASK;
976 k_busy_wait(2000);
977
978 /* enable USB module, AKA USBEN bit in CTL1 register */
979 base->CTL = USB_CTL_USBENSOFEN_MASK;
980
981 if (!usbfsotg_is_supported(dev)) {
982 return -ENOTSUP;
983 }
984
985 for (uint8_t i = 0; i < 16U; i++) {
986 base->ENDPOINT[i].ENDPT = 0;
987 }
988
989 base->BDTPAGE1 = (uint8_t)(POINTER_TO_UINT(config->bdt) >> 8);
990 base->BDTPAGE2 = (uint8_t)(POINTER_TO_UINT(config->bdt) >> 16);
991 base->BDTPAGE3 = (uint8_t)(POINTER_TO_UINT(config->bdt) >> 24);
992
993 /* (FIXME) Enables the weak pulldowns on the USB transceiver */
994 base->USBCTRL = USB_USBCTRL_PDE_MASK;
995
996 /* Clear interrupt flags */
997 base->ISTAT = 0xFF;
998 /* Clear error flags */
999 base->ERRSTAT = 0xFF;
1000
1001 /* Enable all error interrupt sources */
1002 base->ERREN = 0xFF;
1003 /* Enable reset interrupt */
1004 base->INTEN = (USB_INTEN_SLEEPEN_MASK |
1005 USB_INTEN_STALLEN_MASK |
1006 USB_INTEN_TOKDNEEN_MASK |
1007 USB_INTEN_SOFTOKEN_MASK |
1008 USB_INTEN_ERROREN_MASK |
1009 USB_INTEN_USBRSTEN_MASK);
1010
1011 if (udc_ep_enable_internal(dev, USB_CONTROL_EP_OUT,
1012 USB_EP_TYPE_CONTROL,
1013 USBFSOTG_EP0_SIZE, 0)) {
1014 LOG_ERR("Failed to enable control endpoint");
1015 return -EIO;
1016 }
1017
1018 if (udc_ep_enable_internal(dev, USB_CONTROL_EP_IN,
1019 USB_EP_TYPE_CONTROL,
1020 USBFSOTG_EP0_SIZE, 0)) {
1021 LOG_ERR("Failed to enable control endpoint");
1022 return -EIO;
1023 }
1024
1025 /* Connect and enable USB interrupt */
1026 config->irq_enable_func(dev);
1027
1028 LOG_DBG("Initialized USB controller %p", base);
1029
1030 return 0;
1031 }
1032
usbfsotg_shutdown(const struct device * dev)1033 static int usbfsotg_shutdown(const struct device *dev)
1034 {
1035 const struct usbfsotg_config *config = dev->config;
1036
1037 config->irq_disable_func(dev);
1038
1039 if (udc_ep_disable_internal(dev, USB_CONTROL_EP_OUT)) {
1040 LOG_ERR("Failed to disable control endpoint");
1041 return -EIO;
1042 }
1043
1044 if (udc_ep_disable_internal(dev, USB_CONTROL_EP_IN)) {
1045 LOG_ERR("Failed to disable control endpoint");
1046 return -EIO;
1047 }
1048
1049 /* Disable USB module */
1050 config->base->CTL = 0;
1051
1052 /* Disable USB voltage regulator */
1053 SIM->SOPT1 &= ~SIM_SOPT1_USBREGEN_MASK;
1054
1055 return 0;
1056 }
1057
usbfsotg_lock(const struct device * dev)1058 static int usbfsotg_lock(const struct device *dev)
1059 {
1060 return udc_lock_internal(dev, K_FOREVER);
1061 }
1062
usbfsotg_unlock(const struct device * dev)1063 static int usbfsotg_unlock(const struct device *dev)
1064 {
1065 return udc_unlock_internal(dev);
1066 }
1067
usbfsotg_driver_preinit(const struct device * dev)1068 static int usbfsotg_driver_preinit(const struct device *dev)
1069 {
1070 const struct usbfsotg_config *config = dev->config;
1071 struct udc_data *data = dev->data;
1072 struct usbfsotg_data *priv = data->priv;
1073 int err;
1074
1075 k_mutex_init(&data->mutex);
1076 k_fifo_init(&priv->fifo);
1077 k_work_init(&priv->work, xfer_work_handler);
1078
1079 for (int i = 0; i < config->num_of_eps; i++) {
1080 config->ep_cfg_out[i].caps.out = 1;
1081 if (i == 0) {
1082 config->ep_cfg_out[i].caps.control = 1;
1083 config->ep_cfg_out[i].caps.mps = 64;
1084 } else {
1085 config->ep_cfg_out[i].caps.bulk = 1;
1086 config->ep_cfg_out[i].caps.interrupt = 1;
1087 config->ep_cfg_out[i].caps.iso = 1;
1088 config->ep_cfg_out[i].caps.mps = 1023;
1089 }
1090
1091 config->ep_cfg_out[i].addr = USB_EP_DIR_OUT | i;
1092 err = udc_register_ep(dev, &config->ep_cfg_out[i]);
1093 if (err != 0) {
1094 LOG_ERR("Failed to register endpoint");
1095 return err;
1096 }
1097 }
1098
1099 for (int i = 0; i < config->num_of_eps; i++) {
1100 config->ep_cfg_in[i].caps.in = 1;
1101 if (i == 0) {
1102 config->ep_cfg_in[i].caps.control = 1;
1103 config->ep_cfg_in[i].caps.mps = 64;
1104 } else {
1105 config->ep_cfg_in[i].caps.bulk = 1;
1106 config->ep_cfg_in[i].caps.interrupt = 1;
1107 config->ep_cfg_in[i].caps.iso = 1;
1108 config->ep_cfg_in[i].caps.mps = 1023;
1109 }
1110
1111 config->ep_cfg_in[i].addr = USB_EP_DIR_IN | i;
1112 err = udc_register_ep(dev, &config->ep_cfg_in[i]);
1113 if (err != 0) {
1114 LOG_ERR("Failed to register endpoint");
1115 return err;
1116 }
1117 }
1118
1119 data->caps.rwup = false;
1120 data->caps.mps0 = USBFSOTG_MPS0;
1121
1122 return 0;
1123 }
1124
1125 static const struct udc_api usbfsotg_api = {
1126 .ep_enqueue = usbfsotg_ep_enqueue,
1127 .ep_dequeue = usbfsotg_ep_dequeue,
1128 .ep_set_halt = usbfsotg_ep_set_halt,
1129 .ep_clear_halt = usbfsotg_ep_clear_halt,
1130 .ep_try_config = NULL,
1131 .ep_enable = usbfsotg_ep_enable,
1132 .ep_disable = usbfsotg_ep_disable,
1133 .host_wakeup = usbfsotg_host_wakeup,
1134 .set_address = usbfsotg_set_address,
1135 .enable = usbfsotg_enable,
1136 .disable = usbfsotg_disable,
1137 .init = usbfsotg_init,
1138 .shutdown = usbfsotg_shutdown,
1139 .lock = usbfsotg_lock,
1140 .unlock = usbfsotg_unlock,
1141 };
1142
1143 #define USBFSOTG_DEVICE_DEFINE(n) \
1144 static void udc_irq_enable_func##n(const struct device *dev) \
1145 { \
1146 IRQ_CONNECT(DT_INST_IRQN(n), \
1147 DT_INST_IRQ(n, priority), \
1148 usbfsotg_isr_handler, \
1149 DEVICE_DT_INST_GET(n), 0); \
1150 \
1151 irq_enable(DT_INST_IRQN(n)); \
1152 } \
1153 \
1154 static void udc_irq_disable_func##n(const struct device *dev) \
1155 { \
1156 irq_disable(DT_INST_IRQN(n)); \
1157 } \
1158 \
1159 static struct usbfsotg_bd __aligned(512) \
1160 bdt_##n[DT_INST_PROP(n, num_bidir_endpoints) * 2 * 2]; \
1161 \
1162 static struct udc_ep_config \
1163 ep_cfg_out[DT_INST_PROP(n, num_bidir_endpoints)]; \
1164 static struct udc_ep_config \
1165 ep_cfg_in[DT_INST_PROP(n, num_bidir_endpoints)]; \
1166 \
1167 static struct usbfsotg_config priv_config_##n = { \
1168 .base = (USB_Type *)DT_INST_REG_ADDR(n), \
1169 .bdt = bdt_##n, \
1170 .irq_enable_func = udc_irq_enable_func##n, \
1171 .irq_disable_func = udc_irq_disable_func##n, \
1172 .num_of_eps = DT_INST_PROP(n, num_bidir_endpoints), \
1173 .ep_cfg_in = ep_cfg_out, \
1174 .ep_cfg_out = ep_cfg_in, \
1175 }; \
1176 \
1177 static struct usbfsotg_data priv_data_##n = { \
1178 }; \
1179 \
1180 static struct udc_data udc_data_##n = { \
1181 .mutex = Z_MUTEX_INITIALIZER(udc_data_##n.mutex), \
1182 .priv = &priv_data_##n, \
1183 }; \
1184 \
1185 DEVICE_DT_INST_DEFINE(n, usbfsotg_driver_preinit, NULL, \
1186 &udc_data_##n, &priv_config_##n, \
1187 POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \
1188 &usbfsotg_api);
1189
1190 DT_INST_FOREACH_STATUS_OKAY(USBFSOTG_DEVICE_DEFINE)
1191