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), udc_mps_ep_size(cfg));
199 		data_ptr = net_buf_tail(buf);
200 	} else {
201 		len = MIN(buf->len, udc_mps_ep_size(cfg));
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), udc_mps_ep_size(cfg));
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), udc_mps_ep_size(cfg));
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 		LOG_ERR("Failed to allocate slab");
452 		return;
453 	}
454 
455 	ev->dev = dev;
456 	ev->ep = ep;
457 	ev->event = event;
458 	k_fifo_put(&priv->fifo, ev);
459 	k_work_submit_to_queue(udc_get_work_q(), &priv->work);
460 }
461 
xfer_work_handler(struct k_work * item)462 static void xfer_work_handler(struct k_work *item)
463 {
464 	struct usbfsotg_ep_event *ev;
465 	struct usbfsotg_data *priv;
466 
467 	priv = CONTAINER_OF(item, struct usbfsotg_data, work);
468 	while ((ev = k_fifo_get(&priv->fifo, K_NO_WAIT)) != NULL) {
469 		struct udc_ep_config *ep_cfg;
470 		int err = 0;
471 
472 		LOG_DBG("dev %p, ep 0x%02x, event %u",
473 			ev->dev, ev->ep, ev->event);
474 		ep_cfg = udc_get_ep_cfg(ev->dev, ev->ep);
475 		if (unlikely(ep_cfg == NULL)) {
476 			udc_submit_event(ev->dev, UDC_EVT_ERROR, -ENODATA);
477 			goto xfer_work_error;
478 		}
479 
480 		switch (ev->event) {
481 		case USBFSOTG_EVT_SETUP:
482 			err = work_handler_setup(ev->dev);
483 			break;
484 		case USBFSOTG_EVT_DOUT:
485 			err = work_handler_out(ev->dev, ev->ep);
486 			udc_ep_set_busy(ev->dev, ev->ep, false);
487 			break;
488 		case USBFSOTG_EVT_DIN:
489 			err = work_handler_in(ev->dev, ev->ep);
490 			udc_ep_set_busy(ev->dev, ev->ep, false);
491 			break;
492 		case USBFSOTG_EVT_CLEAR_HALT:
493 			err = usbfsotg_ep_clear_halt(ev->dev, ep_cfg);
494 		case USBFSOTG_EVT_XFER:
495 		default:
496 			break;
497 		}
498 
499 		if (unlikely(err)) {
500 			udc_submit_event(ev->dev, UDC_EVT_ERROR, err);
501 		}
502 
503 		/* Peek next transfer */
504 		if (ev->ep != USB_CONTROL_EP_OUT && !udc_ep_is_busy(ev->dev, ev->ep)) {
505 			if (usbfsotg_xfer_next(ev->dev, ep_cfg) == 0) {
506 				udc_ep_set_busy(ev->dev, ev->ep, true);
507 			}
508 		}
509 
510 xfer_work_error:
511 		k_mem_slab_free(&usbfsotg_ee_slab, (void *)ev);
512 	}
513 }
514 
stat_reg_get_ep(const uint8_t status)515 static ALWAYS_INLINE uint8_t stat_reg_get_ep(const uint8_t status)
516 {
517 	uint8_t ep_idx = status >> USB_STAT_ENDP_SHIFT;
518 
519 	return (status & USB_STAT_TX_MASK) ? (USB_EP_DIR_IN | ep_idx) : ep_idx;
520 }
521 
stat_reg_is_odd(const uint8_t status)522 static ALWAYS_INLINE bool stat_reg_is_odd(const uint8_t status)
523 {
524 	return (status & USB_STAT_ODD_MASK) >> USB_STAT_ODD_SHIFT;
525 }
526 
set_control_in_pid_data1(const struct device * dev)527 static ALWAYS_INLINE void set_control_in_pid_data1(const struct device *dev)
528 {
529 	struct udc_ep_config *ep_cfg = udc_get_ep_cfg(dev, USB_CONTROL_EP_IN);
530 
531 	/* Set DATA1 PID for data or status stage */
532 	ep_cfg->stat.data1 = true;
533 }
534 
isr_handle_xfer_done(const struct device * dev,const uint8_t istatus,const uint8_t status)535 static ALWAYS_INLINE void isr_handle_xfer_done(const struct device *dev,
536 					       const uint8_t istatus,
537 					       const uint8_t status)
538 {
539 	struct usbfsotg_data *priv = udc_get_private(dev);
540 	uint8_t ep = stat_reg_get_ep(status);
541 	bool odd = stat_reg_is_odd(status);
542 	struct usbfsotg_bd *bd, *bd_op;
543 	struct udc_ep_config *ep_cfg;
544 	struct net_buf *buf;
545 	uint8_t token_pid;
546 	bool data1;
547 	size_t len;
548 
549 	ep_cfg = udc_get_ep_cfg(dev, ep);
550 	bd = usbfsotg_get_ebd(dev, ep_cfg, false);
551 	bd_op = usbfsotg_get_ebd(dev, ep_cfg, true);
552 	token_pid = bd->get.tok_pid;
553 	len  = bd->get.bc;
554 	data1 = bd->get.data1 ? true : false;
555 
556 	LOG_DBG("TOKDNE, ep 0x%02x len %u odd %u data1 %u",
557 		ep, len, odd, data1);
558 
559 	switch (token_pid) {
560 	case USBFSOTG_SETUP_TOKEN:
561 		ep_cfg->stat.odd = !odd;
562 		ep_cfg->stat.data1 = true;
563 		set_control_in_pid_data1(dev);
564 
565 		if (priv->out_buf[odd] != NULL) {
566 			net_buf_add(priv->out_buf[odd], len);
567 			udc_ep_buf_set_setup(priv->out_buf[odd]);
568 			udc_buf_put(ep_cfg, priv->out_buf[odd]);
569 			priv->busy[odd] = false;
570 			priv->out_buf[odd] = NULL;
571 			usbfsotg_event_submit(dev, ep, USBFSOTG_EVT_SETUP);
572 		} else {
573 			LOG_ERR("No buffer for ep 0x00");
574 			udc_submit_event(dev, UDC_EVT_ERROR, -ENOBUFS);
575 		}
576 
577 		break;
578 	case USBFSOTG_OUT_TOKEN:
579 		ep_cfg->stat.odd = !odd;
580 		ep_cfg->stat.data1 = !data1;
581 
582 		if (ep == USB_CONTROL_EP_OUT) {
583 			buf = priv->out_buf[odd];
584 			priv->busy[odd] = false;
585 			priv->out_buf[odd] = NULL;
586 		} else {
587 			buf = udc_buf_peek(dev, ep_cfg->addr);
588 		}
589 
590 		if (buf == NULL) {
591 			LOG_ERR("No buffer for ep 0x%02x", ep);
592 			udc_submit_event(dev, UDC_EVT_ERROR, -ENOBUFS);
593 			break;
594 		}
595 
596 		net_buf_add(buf, len);
597 		if (net_buf_tailroom(buf) >= udc_mps_ep_size(ep_cfg) &&
598 		    len == udc_mps_ep_size(ep_cfg)) {
599 			if (ep == USB_CONTROL_EP_OUT) {
600 				usbfsotg_ctrl_feed_start(dev, buf);
601 			} else {
602 				usbfsotg_xfer_continue(dev, ep_cfg, buf);
603 			}
604 		} else {
605 			if (ep == USB_CONTROL_EP_OUT) {
606 				udc_buf_put(ep_cfg, buf);
607 			}
608 
609 			usbfsotg_event_submit(dev, ep, USBFSOTG_EVT_DOUT);
610 		}
611 
612 		break;
613 	case USBFSOTG_IN_TOKEN:
614 		ep_cfg->stat.odd = !odd;
615 		ep_cfg->stat.data1 = !data1;
616 
617 		buf = udc_buf_peek(dev, ep_cfg->addr);
618 		if (buf == NULL) {
619 			LOG_ERR("No buffer for ep 0x%02x", ep);
620 			udc_submit_event(dev, UDC_EVT_ERROR, -ENOBUFS);
621 			break;
622 		}
623 
624 		net_buf_pull(buf, len);
625 		if (buf->len) {
626 			usbfsotg_xfer_continue(dev, ep_cfg, buf);
627 		} else {
628 			if (udc_ep_buf_has_zlp(buf)) {
629 				usbfsotg_xfer_continue(dev, ep_cfg, buf);
630 				udc_ep_buf_clear_zlp(buf);
631 				break;
632 			}
633 
634 			usbfsotg_event_submit(dev, ep, USBFSOTG_EVT_DIN);
635 		}
636 
637 		break;
638 	default:
639 		break;
640 	}
641 }
642 
usbfsotg_isr_handler(const struct device * dev)643 static void usbfsotg_isr_handler(const struct device *dev)
644 {
645 	const struct usbfsotg_config *config = dev->config;
646 	USB_Type *base = config->base;
647 	const uint8_t istatus  = base->ISTAT;
648 	const uint8_t status  = base->STAT;
649 
650 	if (istatus & USB_ISTAT_USBRST_MASK) {
651 		base->ADDR = 0U;
652 		udc_submit_event(dev, UDC_EVT_RESET, 0);
653 	}
654 
655 	if (istatus == USB_ISTAT_SOFTOK_MASK) {
656 		udc_submit_event(dev, UDC_EVT_SOF, 0);
657 	}
658 
659 	if (istatus == USB_ISTAT_ERROR_MASK) {
660 		LOG_DBG("ERROR IRQ 0x%02x", base->ERRSTAT);
661 		udc_submit_event(dev, UDC_EVT_ERROR, base->ERRSTAT);
662 		base->ERRSTAT = 0xFF;
663 	}
664 
665 	if (istatus & USB_ISTAT_STALL_MASK) {
666 		struct udc_ep_config *ep_cfg;
667 
668 		LOG_DBG("STALL sent");
669 
670 		ep_cfg = udc_get_ep_cfg(dev, USB_CONTROL_EP_OUT);
671 		if (ep_cfg->stat.halted) {
672 			/*
673 			 * usbfsotg_ep_clear_halt(dev, ep_cfg); cannot
674 			 * be called in ISR context
675 			 */
676 			usbfsotg_event_submit(dev, USB_CONTROL_EP_OUT,
677 					      USBFSOTG_EVT_CLEAR_HALT);
678 		}
679 
680 		ep_cfg = udc_get_ep_cfg(dev, USB_CONTROL_EP_IN);
681 		if (ep_cfg->stat.halted) {
682 			usbfsotg_event_submit(dev, USB_CONTROL_EP_IN,
683 					      USBFSOTG_EVT_CLEAR_HALT);
684 		}
685 	}
686 
687 	if (istatus & USB_ISTAT_TOKDNE_MASK) {
688 		isr_handle_xfer_done(dev, istatus, status);
689 	}
690 
691 	if (istatus & USB_ISTAT_SLEEP_MASK) {
692 		LOG_DBG("SLEEP IRQ");
693 		/* Enable resume interrupt */
694 		base->INTEN |= USB_INTEN_RESUMEEN_MASK;
695 
696 		udc_set_suspended(dev, true);
697 		udc_submit_event(dev, UDC_EVT_SUSPEND, 0);
698 	}
699 
700 	if (istatus & USB_ISTAT_RESUME_MASK) {
701 		LOG_DBG("RESUME IRQ");
702 		/* Disable resume interrupt */
703 		base->INTEN &= ~USB_INTEN_RESUMEEN_MASK;
704 
705 		udc_set_suspended(dev, false);
706 		udc_submit_event(dev, UDC_EVT_RESUME, 0);
707 	}
708 
709 	/* Clear interrupt status bits */
710 	base->ISTAT = istatus;
711 }
712 
usbfsotg_ep_enqueue(const struct device * dev,struct udc_ep_config * const cfg,struct net_buf * const buf)713 static int usbfsotg_ep_enqueue(const struct device *dev,
714 			       struct udc_ep_config *const cfg,
715 			       struct net_buf *const buf)
716 {
717 
718 	udc_buf_put(cfg, buf);
719 	if (cfg->stat.halted) {
720 		LOG_DBG("ep 0x%02x halted", cfg->addr);
721 		return 0;
722 	}
723 
724 	usbfsotg_event_submit(dev, cfg->addr, USBFSOTG_EVT_XFER);
725 
726 	return 0;
727 }
728 
usbfsotg_ep_dequeue(const struct device * dev,struct udc_ep_config * const cfg)729 static int usbfsotg_ep_dequeue(const struct device *dev,
730 			       struct udc_ep_config *const cfg)
731 {
732 	struct usbfsotg_bd *bd;
733 	unsigned int lock_key;
734 	struct net_buf *buf;
735 
736 	bd = usbfsotg_get_ebd(dev, cfg, false);
737 
738 	lock_key = irq_lock();
739 	bd->set.bd_ctrl = USBFSOTG_BD_DTS;
740 	irq_unlock(lock_key);
741 
742 	cfg->stat.halted = false;
743 	buf = udc_buf_get_all(dev, cfg->addr);
744 	if (buf) {
745 		udc_submit_ep_event(dev, buf, -ECONNABORTED);
746 	}
747 
748 	udc_ep_set_busy(dev, cfg->addr, false);
749 
750 	return 0;
751 }
752 
ctrl_drop_out_successor(const struct device * dev)753 static void ctrl_drop_out_successor(const struct device *dev)
754 {
755 	struct usbfsotg_data *priv = udc_get_private(dev);
756 	struct udc_ep_config *cfg;
757 	struct usbfsotg_bd *bd;
758 	struct net_buf *buf;
759 
760 	cfg = udc_get_ep_cfg(dev, USB_CONTROL_EP_OUT);
761 
762 	if (priv->busy[!cfg->stat.odd]) {
763 		bd = usbfsotg_get_ebd(dev, cfg, true);
764 		buf = priv->out_buf[!cfg->stat.odd];
765 
766 		bd->bd_fields = 0U;
767 		priv->busy[!cfg->stat.odd] = false;
768 		if (buf) {
769 			net_buf_unref(buf);
770 		}
771 	}
772 }
773 
usbfsotg_ep_set_halt(const struct device * dev,struct udc_ep_config * const cfg)774 static int usbfsotg_ep_set_halt(const struct device *dev,
775 				struct udc_ep_config *const cfg)
776 {
777 	struct usbfsotg_bd *bd;
778 
779 	bd = usbfsotg_get_ebd(dev, cfg, false);
780 	bd->set.bd_ctrl = USBFSOTG_BD_STALL | USBFSOTG_BD_DTS | USBFSOTG_BD_OWN;
781 	cfg->stat.halted = true;
782 	LOG_DBG("Halt ep 0x%02x bd %p", cfg->addr, bd);
783 
784 	if (cfg->addr == USB_CONTROL_EP_IN) {
785 		/* Drop subsequent out transfer, current can be re-used */
786 		ctrl_drop_out_successor(dev);
787 	}
788 
789 	if (USB_EP_GET_IDX(cfg->addr) == 0U) {
790 		usbfsotg_resume_tx(dev);
791 	}
792 
793 	return 0;
794 }
795 
usbfsotg_ep_clear_halt(const struct device * dev,struct udc_ep_config * const cfg)796 static int usbfsotg_ep_clear_halt(const struct device *dev,
797 				  struct udc_ep_config *const cfg)
798 {
799 	const struct usbfsotg_config *config = dev->config;
800 	struct usbfsotg_data *priv = udc_get_private(dev);
801 	USB_Type *base = config->base;
802 	uint8_t ep_idx = USB_EP_GET_IDX(cfg->addr);
803 	struct usbfsotg_bd *bd;
804 
805 	LOG_DBG("Clear halt ep 0x%02x", cfg->addr);
806 	bd = usbfsotg_get_ebd(dev, cfg, false);
807 
808 	if (bd->set.bd_ctrl & USBFSOTG_BD_STALL) {
809 		LOG_DBG("bd %p: %x", bd, bd->set.bd_ctrl);
810 		bd->set.bd_ctrl = USBFSOTG_BD_DTS;
811 	} else {
812 		LOG_WRN("bd %p is not halted", bd);
813 	}
814 
815 	cfg->stat.data1 = false;
816 	cfg->stat.halted = false;
817 	base->ENDPOINT[ep_idx].ENDPT &= ~USB_ENDPT_EPSTALL_MASK;
818 
819 	if (cfg->addr == USB_CONTROL_EP_OUT) {
820 		if (priv->busy[cfg->stat.odd]) {
821 			LOG_DBG("bd %p restarted", bd);
822 			bd->set.bd_ctrl = USBFSOTG_BD_DTS | USBFSOTG_BD_OWN;
823 		} else {
824 			usbfsotg_ctrl_feed_dout(dev, 8U, false, false);
825 		}
826 	}
827 
828 	if (USB_EP_GET_IDX(cfg->addr) == 0U) {
829 		usbfsotg_resume_tx(dev);
830 	} else {
831 		/* trigger queued transfers */
832 		usbfsotg_event_submit(dev, cfg->addr, USBFSOTG_EVT_XFER);
833 	}
834 
835 	return 0;
836 }
837 
usbfsotg_ep_enable(const struct device * dev,struct udc_ep_config * const cfg)838 static int usbfsotg_ep_enable(const struct device *dev,
839 			      struct udc_ep_config *const cfg)
840 {
841 	const struct usbfsotg_config *config = dev->config;
842 	struct usbfsotg_data *priv = udc_get_private(dev);
843 	USB_Type *base = config->base;
844 	const uint8_t ep_idx = USB_EP_GET_IDX(cfg->addr);
845 	struct usbfsotg_bd *bd_even, *bd_odd;
846 
847 	LOG_DBG("Enable ep 0x%02x", cfg->addr);
848 	bd_even = usbfsotg_get_ebd(dev, cfg, false);
849 	bd_odd = usbfsotg_get_ebd(dev, cfg, true);
850 
851 	bd_even->bd_fields = 0U;
852 	bd_even->buf_addr = 0U;
853 	bd_odd->bd_fields = 0U;
854 	bd_odd->buf_addr = 0U;
855 
856 	switch (cfg->attributes & USB_EP_TRANSFER_TYPE_MASK) {
857 	case USB_EP_TYPE_CONTROL:
858 		base->ENDPOINT[ep_idx].ENDPT = (USB_ENDPT_EPHSHK_MASK |
859 						USB_ENDPT_EPRXEN_MASK |
860 						USB_ENDPT_EPTXEN_MASK);
861 		break;
862 	case USB_EP_TYPE_BULK:
863 	case USB_EP_TYPE_INTERRUPT:
864 		base->ENDPOINT[ep_idx].ENDPT |= USB_ENDPT_EPHSHK_MASK;
865 		if (USB_EP_DIR_IS_OUT(cfg->addr)) {
866 			base->ENDPOINT[ep_idx].ENDPT |= USB_ENDPT_EPRXEN_MASK;
867 		} else {
868 			base->ENDPOINT[ep_idx].ENDPT |= USB_ENDPT_EPTXEN_MASK;
869 		}
870 		break;
871 	case USB_EP_TYPE_ISO:
872 		if (USB_EP_DIR_IS_OUT(cfg->addr)) {
873 			base->ENDPOINT[ep_idx].ENDPT |= USB_ENDPT_EPRXEN_MASK;
874 		} else {
875 			base->ENDPOINT[ep_idx].ENDPT |= USB_ENDPT_EPTXEN_MASK;
876 		}
877 		break;
878 	default:
879 		return -EINVAL;
880 	}
881 
882 	if (cfg->addr == USB_CONTROL_EP_OUT) {
883 		struct net_buf *buf;
884 
885 		priv->busy[0] = false;
886 		priv->busy[1] = false;
887 		buf = udc_ctrl_alloc(dev, USB_CONTROL_EP_OUT, USBFSOTG_EP0_SIZE);
888 		usbfsotg_bd_set_ctrl(bd_even, buf->size, buf->data, false);
889 		priv->out_buf[0] = buf;
890 	}
891 
892 	return 0;
893 }
894 
usbfsotg_ep_disable(const struct device * dev,struct udc_ep_config * const cfg)895 static int usbfsotg_ep_disable(const struct device *dev,
896 			       struct udc_ep_config *const cfg)
897 {
898 	const struct usbfsotg_config *config = dev->config;
899 	USB_Type *base = config->base;
900 	uint8_t ep_idx = USB_EP_GET_IDX(cfg->addr);
901 	struct usbfsotg_bd *bd_even, *bd_odd;
902 
903 	bd_even = usbfsotg_get_ebd(dev, cfg, false);
904 	bd_odd = usbfsotg_get_ebd(dev, cfg, true);
905 
906 	if (USB_EP_DIR_IS_OUT(cfg->addr)) {
907 		base->ENDPOINT[ep_idx].ENDPT &= ~USB_ENDPT_EPRXEN_MASK;
908 	} else {
909 		base->ENDPOINT[ep_idx].ENDPT &= ~USB_ENDPT_EPTXEN_MASK;
910 	}
911 
912 	if (usbfsotg_bd_is_busy(bd_even) || usbfsotg_bd_is_busy(bd_odd)) {
913 		LOG_DBG("Endpoint buffer is busy");
914 	}
915 
916 	bd_even->bd_fields = 0U;
917 	bd_even->buf_addr = 0U;
918 	bd_odd->bd_fields = 0U;
919 	bd_odd->buf_addr = 0U;
920 
921 	LOG_DBG("Disable ep 0x%02x", cfg->addr);
922 
923 	return 0;
924 }
925 
usbfsotg_host_wakeup(const struct device * dev)926 static int usbfsotg_host_wakeup(const struct device *dev)
927 {
928 	return -ENOTSUP;
929 }
930 
usbfsotg_set_address(const struct device * dev,const uint8_t addr)931 static int usbfsotg_set_address(const struct device *dev, const uint8_t addr)
932 {
933 	const struct usbfsotg_config *config = dev->config;
934 	USB_Type *base = config->base;
935 
936 	base->ADDR = addr;
937 
938 	return 0;
939 }
940 
usbfsotg_enable(const struct device * dev)941 static int usbfsotg_enable(const struct device *dev)
942 {
943 	const struct usbfsotg_config *config = dev->config;
944 	USB_Type *base = config->base;
945 
946 	/* non-OTG device mode, enable DP Pullup */
947 	base->CONTROL = USB_CONTROL_DPPULLUPNONOTG_MASK;
948 
949 	return 0;
950 }
951 
usbfsotg_disable(const struct device * dev)952 static int usbfsotg_disable(const struct device *dev)
953 {
954 	const struct usbfsotg_config *config = dev->config;
955 	USB_Type *base = config->base;
956 
957 	/* disable USB and DP Pullup */
958 	base->CTL  &= ~USB_CTL_USBENSOFEN_MASK;
959 	base->CONTROL &= ~USB_CONTROL_DPPULLUPNONOTG_MASK;
960 
961 	return 0;
962 }
963 
usbfsotg_is_supported(const struct device * dev)964 static bool usbfsotg_is_supported(const struct device *dev)
965 {
966 	const struct usbfsotg_config *config = dev->config;
967 	USB_Type *base = config->base;
968 
969 	if ((base->PERID != USBFSOTG_PERID) || (base->REV != USBFSOTG_REV)) {
970 		return false;
971 	}
972 
973 	return true;
974 }
975 
usbfsotg_init(const struct device * dev)976 static int usbfsotg_init(const struct device *dev)
977 {
978 	const struct usbfsotg_config *config = dev->config;
979 	USB_Type *base = config->base;
980 
981 #if !DT_ANY_INST_HAS_PROP_STATUS_OKAY(no_voltage_regulator)
982 	/* (FIXME) Enable USB voltage regulator */
983 	SIM->SOPT1 |= SIM_SOPT1_USBREGEN_MASK;
984 #endif
985 
986 	/* Reset USB module */
987 	base->USBTRC0 |= USB_USBTRC0_USBRESET_MASK;
988 	k_busy_wait(2000);
989 
990 	/* enable USB module, AKA USBEN bit in CTL1 register */
991 	base->CTL = USB_CTL_USBENSOFEN_MASK;
992 
993 	if (!usbfsotg_is_supported(dev)) {
994 		return -ENOTSUP;
995 	}
996 
997 	for (uint8_t i = 0; i < 16U; i++) {
998 		base->ENDPOINT[i].ENDPT = 0;
999 	}
1000 
1001 	base->BDTPAGE1 = (uint8_t)(POINTER_TO_UINT(config->bdt) >> 8);
1002 	base->BDTPAGE2 = (uint8_t)(POINTER_TO_UINT(config->bdt) >> 16);
1003 	base->BDTPAGE3 = (uint8_t)(POINTER_TO_UINT(config->bdt) >> 24);
1004 
1005 	/* (FIXME) Enables the weak pulldowns on the USB transceiver */
1006 	base->USBCTRL = USB_USBCTRL_PDE_MASK;
1007 
1008 	/* Clear interrupt flags */
1009 	base->ISTAT = 0xFF;
1010 	/* Clear error flags */
1011 	base->ERRSTAT = 0xFF;
1012 
1013 	/* Enable all error interrupt sources */
1014 	base->ERREN = 0xFF;
1015 	/* Enable reset interrupt */
1016 	base->INTEN = (USB_INTEN_SLEEPEN_MASK  |
1017 		       USB_INTEN_STALLEN_MASK |
1018 		       USB_INTEN_TOKDNEEN_MASK |
1019 		       USB_INTEN_SOFTOKEN_MASK |
1020 		       USB_INTEN_ERROREN_MASK |
1021 		       USB_INTEN_USBRSTEN_MASK);
1022 
1023 	if (udc_ep_enable_internal(dev, USB_CONTROL_EP_OUT,
1024 				   USB_EP_TYPE_CONTROL,
1025 				   USBFSOTG_EP0_SIZE, 0)) {
1026 		LOG_ERR("Failed to enable control endpoint");
1027 		return -EIO;
1028 	}
1029 
1030 	if (udc_ep_enable_internal(dev, USB_CONTROL_EP_IN,
1031 				   USB_EP_TYPE_CONTROL,
1032 				   USBFSOTG_EP0_SIZE, 0)) {
1033 		LOG_ERR("Failed to enable control endpoint");
1034 		return -EIO;
1035 	}
1036 
1037 	/* Connect and enable USB interrupt */
1038 	config->irq_enable_func(dev);
1039 
1040 	LOG_DBG("Initialized USB controller %p", base);
1041 
1042 	return 0;
1043 }
1044 
usbfsotg_shutdown(const struct device * dev)1045 static int usbfsotg_shutdown(const struct device *dev)
1046 {
1047 	const struct usbfsotg_config *config = dev->config;
1048 
1049 	config->irq_disable_func(dev);
1050 
1051 	if (udc_ep_disable_internal(dev, USB_CONTROL_EP_OUT)) {
1052 		LOG_ERR("Failed to disable control endpoint");
1053 		return -EIO;
1054 	}
1055 
1056 	if (udc_ep_disable_internal(dev, USB_CONTROL_EP_IN)) {
1057 		LOG_ERR("Failed to disable control endpoint");
1058 		return -EIO;
1059 	}
1060 
1061 	/* Disable USB module */
1062 	config->base->CTL = 0;
1063 
1064 #if !DT_ANY_INST_HAS_PROP_STATUS_OKAY(no_voltage_regulator)
1065 	/* Disable USB voltage regulator */
1066 	SIM->SOPT1 &= ~SIM_SOPT1_USBREGEN_MASK;
1067 #endif
1068 
1069 	return 0;
1070 }
1071 
usbfsotg_lock(const struct device * dev)1072 static int usbfsotg_lock(const struct device *dev)
1073 {
1074 	return udc_lock_internal(dev, K_FOREVER);
1075 }
1076 
usbfsotg_unlock(const struct device * dev)1077 static int usbfsotg_unlock(const struct device *dev)
1078 {
1079 	return udc_unlock_internal(dev);
1080 }
1081 
usbfsotg_driver_preinit(const struct device * dev)1082 static int usbfsotg_driver_preinit(const struct device *dev)
1083 {
1084 	const struct usbfsotg_config *config = dev->config;
1085 	struct udc_data *data = dev->data;
1086 	struct usbfsotg_data *priv = data->priv;
1087 	int err;
1088 
1089 	k_mutex_init(&data->mutex);
1090 	k_fifo_init(&priv->fifo);
1091 	k_work_init(&priv->work, xfer_work_handler);
1092 
1093 	for (int i = 0; i < config->num_of_eps; i++) {
1094 		config->ep_cfg_out[i].caps.out = 1;
1095 		if (i == 0) {
1096 			config->ep_cfg_out[i].caps.control = 1;
1097 			config->ep_cfg_out[i].caps.mps = 64;
1098 		} else {
1099 			config->ep_cfg_out[i].caps.bulk = 1;
1100 			config->ep_cfg_out[i].caps.interrupt = 1;
1101 			config->ep_cfg_out[i].caps.iso = 1;
1102 			config->ep_cfg_out[i].caps.mps = 1023;
1103 		}
1104 
1105 		config->ep_cfg_out[i].addr = USB_EP_DIR_OUT | i;
1106 		err = udc_register_ep(dev, &config->ep_cfg_out[i]);
1107 		if (err != 0) {
1108 			LOG_ERR("Failed to register endpoint");
1109 			return err;
1110 		}
1111 	}
1112 
1113 	for (int i = 0; i < config->num_of_eps; i++) {
1114 		config->ep_cfg_in[i].caps.in = 1;
1115 		if (i == 0) {
1116 			config->ep_cfg_in[i].caps.control = 1;
1117 			config->ep_cfg_in[i].caps.mps = 64;
1118 		} else {
1119 			config->ep_cfg_in[i].caps.bulk = 1;
1120 			config->ep_cfg_in[i].caps.interrupt = 1;
1121 			config->ep_cfg_in[i].caps.iso = 1;
1122 			config->ep_cfg_in[i].caps.mps = 1023;
1123 		}
1124 
1125 		config->ep_cfg_in[i].addr = USB_EP_DIR_IN | i;
1126 		err = udc_register_ep(dev, &config->ep_cfg_in[i]);
1127 		if (err != 0) {
1128 			LOG_ERR("Failed to register endpoint");
1129 			return err;
1130 		}
1131 	}
1132 
1133 	data->caps.rwup = false;
1134 	data->caps.mps0 = USBFSOTG_MPS0;
1135 
1136 	return 0;
1137 }
1138 
1139 static const struct udc_api usbfsotg_api = {
1140 	.ep_enqueue = usbfsotg_ep_enqueue,
1141 	.ep_dequeue = usbfsotg_ep_dequeue,
1142 	.ep_set_halt = usbfsotg_ep_set_halt,
1143 	.ep_clear_halt = usbfsotg_ep_clear_halt,
1144 	.ep_try_config = NULL,
1145 	.ep_enable = usbfsotg_ep_enable,
1146 	.ep_disable = usbfsotg_ep_disable,
1147 	.host_wakeup = usbfsotg_host_wakeup,
1148 	.set_address = usbfsotg_set_address,
1149 	.enable = usbfsotg_enable,
1150 	.disable = usbfsotg_disable,
1151 	.init = usbfsotg_init,
1152 	.shutdown = usbfsotg_shutdown,
1153 	.lock = usbfsotg_lock,
1154 	.unlock = usbfsotg_unlock,
1155 };
1156 
1157 #define USBFSOTG_DEVICE_DEFINE(n)						\
1158 	static void udc_irq_enable_func##n(const struct device *dev)		\
1159 	{									\
1160 		IRQ_CONNECT(DT_INST_IRQN(n),					\
1161 			    DT_INST_IRQ(n, priority),				\
1162 			    usbfsotg_isr_handler,				\
1163 			    DEVICE_DT_INST_GET(n), 0);				\
1164 										\
1165 		irq_enable(DT_INST_IRQN(n));					\
1166 	}									\
1167 										\
1168 	static void udc_irq_disable_func##n(const struct device *dev)		\
1169 	{									\
1170 		irq_disable(DT_INST_IRQN(n));					\
1171 	}									\
1172 										\
1173 	static struct usbfsotg_bd __aligned(512)				\
1174 		bdt_##n[DT_INST_PROP(n, num_bidir_endpoints) * 2 * 2];		\
1175 										\
1176 	static struct udc_ep_config						\
1177 		ep_cfg_out[DT_INST_PROP(n, num_bidir_endpoints)];		\
1178 	static struct udc_ep_config						\
1179 		ep_cfg_in[DT_INST_PROP(n, num_bidir_endpoints)];		\
1180 										\
1181 	static struct usbfsotg_config priv_config_##n = {			\
1182 		.base = (USB_Type *)DT_INST_REG_ADDR(n),			\
1183 		.bdt = bdt_##n,							\
1184 		.irq_enable_func = udc_irq_enable_func##n,			\
1185 		.irq_disable_func = udc_irq_disable_func##n,			\
1186 		.num_of_eps = DT_INST_PROP(n, num_bidir_endpoints),		\
1187 		.ep_cfg_in = ep_cfg_out,					\
1188 		.ep_cfg_out = ep_cfg_in,					\
1189 	};									\
1190 										\
1191 	static struct usbfsotg_data priv_data_##n = {				\
1192 	};									\
1193 										\
1194 	static struct udc_data udc_data_##n = {					\
1195 		.mutex = Z_MUTEX_INITIALIZER(udc_data_##n.mutex),		\
1196 		.priv = &priv_data_##n,						\
1197 	};									\
1198 										\
1199 	DEVICE_DT_INST_DEFINE(n, usbfsotg_driver_preinit, NULL,			\
1200 			      &udc_data_##n, &priv_config_##n,			\
1201 			      POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,	\
1202 			      &usbfsotg_api);
1203 
1204 DT_INST_FOREACH_STATUS_OKAY(USBFSOTG_DEVICE_DEFINE)
1205