1 /*
2  * Copyright 2024 NXP
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #define DT_DRV_COMPAT nxp_ehci
7 
8 #include <soc.h>
9 #include <string.h>
10 #include <stdio.h>
11 
12 #include <zephyr/device.h>
13 #include <zephyr/kernel.h>
14 #include <zephyr/sys/byteorder.h>
15 #include <zephyr/drivers/usb/udc.h>
16 #include <zephyr/drivers/pinctrl.h>
17 
18 #include "udc_common.h"
19 #include "usb.h"
20 #include "usb_device_config.h"
21 #include "usb_device_mcux_drv_port.h"
22 #include "usb_device_ehci.h"
23 #include "usb_phy.h"
24 
25 #include <zephyr/logging/log.h>
26 LOG_MODULE_REGISTER(udc_mcux, CONFIG_UDC_DRIVER_LOG_LEVEL);
27 
28 /*
29  * There is no real advantage to change control endpoint size
30  * but we can use it for testing UDC driver API and higher layers.
31  */
32 #define USB_MCUX_MPS0		UDC_MPS0_64
33 #define USB_MCUX_EP0_SIZE	64
34 
35 #define PRV_DATA_HANDLE(_handle) CONTAINER_OF(_handle, struct udc_mcux_data, mcux_device)
36 
37 struct udc_mcux_config {
38 	const usb_device_controller_interface_struct_t *mcux_if;
39 	void (*irq_enable_func)(const struct device *dev);
40 	void (*irq_disable_func)(const struct device *dev);
41 	size_t num_of_eps;
42 	struct udc_ep_config *ep_cfg_in;
43 	struct udc_ep_config *ep_cfg_out;
44 	uintptr_t base;
45 	const struct pinctrl_dev_config *pincfg;
46 	usb_phy_config_struct_t *phy_config;
47 };
48 
49 struct udc_mcux_data {
50 	const struct device *dev;
51 	usb_device_struct_t mcux_device;
52 	struct k_work work;
53 	struct k_fifo fifo;
54 	uint8_t controller_id; /* 0xFF is invalid value */
55 };
56 
57 /* Structure for driver's events */
58 struct udc_mcux_event {
59 	sys_snode_t node;
60 	const struct device *dev;
61 	usb_device_callback_message_struct_t mcux_msg;
62 };
63 
64 K_MEM_SLAB_DEFINE(udc_event_slab, sizeof(struct udc_mcux_event),
65 		  CONFIG_UDC_NXP_EVENT_COUNT, sizeof(void *));
66 
udc_mcux_lock(const struct device * dev)67 static void udc_mcux_lock(const struct device *dev)
68 {
69 	udc_lock_internal(dev, K_FOREVER);
70 }
71 
udc_mcux_unlock(const struct device * dev)72 static void udc_mcux_unlock(const struct device *dev)
73 {
74 	udc_unlock_internal(dev);
75 }
76 
udc_mcux_control(const struct device * dev,usb_device_control_type_t command,void * param)77 static int udc_mcux_control(const struct device *dev, usb_device_control_type_t command,
78 				void *param)
79 {
80 	const struct udc_mcux_config *config = dev->config;
81 	const usb_device_controller_interface_struct_t *mcux_if = config->mcux_if;
82 	struct udc_mcux_data *priv = udc_get_private(dev);
83 	usb_status_t status;
84 
85 	status = mcux_if->deviceControl(priv->mcux_device.controllerHandle,
86 			command, param);
87 
88 	if (status != kStatus_USB_Success) {
89 		return -ENOMEM;
90 	}
91 
92 	return 0;
93 }
94 
95 /* If ep is busy, return busy. Otherwise feed the buf to controller */
udc_mcux_ep_feed(const struct device * dev,struct udc_ep_config * const cfg,struct net_buf * const buf)96 static int udc_mcux_ep_feed(const struct device *dev,
97 			struct udc_ep_config *const cfg,
98 			struct net_buf *const buf)
99 {
100 	const struct udc_mcux_config *config = dev->config;
101 	const usb_device_controller_interface_struct_t *mcux_if = config->mcux_if;
102 	struct udc_mcux_data *priv = udc_get_private(dev);
103 	usb_status_t status = kStatus_USB_Success;
104 	uint8_t *data;
105 	uint32_t len;
106 	usb_device_endpoint_status_struct_t ep_status;
107 
108 	ep_status.endpointAddress = cfg->addr;
109 	udc_mcux_control(dev, kUSB_DeviceControlGetEndpointStatus, &ep_status);
110 	if (ep_status.endpointStatus == kUSB_DeviceEndpointStateStalled) {
111 		return -EACCES; /* stalled */
112 	}
113 
114 	udc_mcux_lock(dev);
115 	if (!udc_ep_is_busy(dev, cfg->addr)) {
116 		udc_ep_set_busy(dev, cfg->addr, true);
117 		udc_mcux_unlock(dev);
118 
119 		if (USB_EP_DIR_IS_OUT(cfg->addr)) {
120 			len = net_buf_tailroom(buf);
121 			data = net_buf_tail(buf);
122 			status = mcux_if->deviceRecv(priv->mcux_device.controllerHandle,
123 					cfg->addr, data, len);
124 		} else {
125 			len = buf->len;
126 			data = buf->data;
127 			status = mcux_if->deviceSend(priv->mcux_device.controllerHandle,
128 					cfg->addr, data, len);
129 		}
130 
131 		udc_mcux_lock(dev);
132 		if (status != kStatus_USB_Success) {
133 			udc_ep_set_busy(dev, cfg->addr, false);
134 		}
135 		udc_mcux_unlock(dev);
136 	} else {
137 		udc_mcux_unlock(dev);
138 		return -EBUSY;
139 	}
140 
141 	return (status == kStatus_USB_Success ? 0 : -EIO);
142 }
143 
144 /* return success if the ep is busy or stalled. */
udc_mcux_ep_try_feed(const struct device * dev,struct udc_ep_config * const cfg)145 static int udc_mcux_ep_try_feed(const struct device *dev,
146 			struct udc_ep_config *const cfg)
147 {
148 	struct net_buf *feed_buf;
149 
150 	feed_buf = udc_buf_peek(dev, cfg->addr);
151 	if (feed_buf) {
152 		int ret = udc_mcux_ep_feed(dev, cfg, feed_buf);
153 
154 		return ((ret == -EBUSY || ret == -EACCES || ret == 0) ? 0 : -EIO);
155 	}
156 
157 	return 0;
158 }
159 
160 /*
161  * Allocate buffer and initiate a new control OUT transfer.
162  */
udc_mcux_ctrl_feed_dout(const struct device * dev,const size_t length)163 static int udc_mcux_ctrl_feed_dout(const struct device *dev,
164 				   const size_t length)
165 {
166 	struct net_buf *buf;
167 	struct udc_ep_config *cfg = udc_get_ep_cfg(dev, USB_CONTROL_EP_OUT);
168 	int ret;
169 
170 	buf = udc_ctrl_alloc(dev, USB_CONTROL_EP_OUT, length);
171 	if (buf == NULL) {
172 		return -ENOMEM;
173 	}
174 
175 	k_fifo_put(&cfg->fifo, buf);
176 
177 	ret = udc_mcux_ep_feed(dev, cfg, buf);
178 
179 	if (ret) {
180 		net_buf_unref(buf);
181 		return ret;
182 	}
183 
184 	return 0;
185 }
186 
udc_mcux_handler_setup(const struct device * dev,struct usb_setup_packet * setup)187 static int udc_mcux_handler_setup(const struct device *dev, struct usb_setup_packet *setup)
188 {
189 	int err;
190 	struct net_buf *buf;
191 
192 	LOG_DBG("setup packet");
193 	buf = udc_ctrl_alloc(dev, USB_CONTROL_EP_OUT,
194 			sizeof(struct usb_setup_packet));
195 	if (buf == NULL) {
196 		LOG_ERR("Failed to allocate for setup");
197 		return -EIO;
198 	}
199 
200 	udc_ep_buf_set_setup(buf);
201 	memcpy(buf->data, setup, 8);
202 	net_buf_add(buf, 8);
203 
204 	if (setup->RequestType.type == USB_REQTYPE_TYPE_STANDARD &&
205 	    setup->RequestType.direction == USB_REQTYPE_DIR_TO_DEVICE &&
206 	    setup->bRequest == USB_SREQ_SET_ADDRESS &&
207 	    setup->wLength == 0) {
208 		udc_mcux_control(dev, kUSB_DeviceControlPreSetDeviceAddress,
209 			&setup->wValue);
210 	}
211 
212 	/* Update to next stage of control transfer */
213 	udc_ctrl_update_stage(dev, buf);
214 
215 	if (!buf->len) {
216 		return -EIO;
217 	}
218 
219 	if (udc_ctrl_stage_is_data_out(dev)) {
220 		/*  Allocate and feed buffer for data OUT stage */
221 		LOG_DBG("s:%p|feed for -out-", buf);
222 		err = udc_mcux_ctrl_feed_dout(dev, udc_data_stage_length(buf));
223 		if (err == -ENOMEM) {
224 			err = udc_submit_ep_event(dev, buf, err);
225 		}
226 	} else if (udc_ctrl_stage_is_data_in(dev)) {
227 		err = udc_ctrl_submit_s_in_status(dev);
228 	} else {
229 		err = udc_ctrl_submit_s_status(dev);
230 	}
231 
232 	return err;
233 }
234 
udc_mcux_handler_ctrl_out(const struct device * dev,struct net_buf * buf,uint8_t * mcux_buf,uint16_t mcux_len)235 static int udc_mcux_handler_ctrl_out(const struct device *dev, struct net_buf *buf,
236 				uint8_t *mcux_buf, uint16_t mcux_len)
237 {
238 	int err = 0;
239 	uint32_t len;
240 
241 	len = MIN(net_buf_tailroom(buf), mcux_len);
242 	net_buf_add(buf, len);
243 	if (udc_ctrl_stage_is_status_out(dev)) {
244 		/* Update to next stage of control transfer */
245 		udc_ctrl_update_stage(dev, buf);
246 		/* Status stage finished, notify upper layer */
247 		err = udc_ctrl_submit_status(dev, buf);
248 	} else {
249 		/* Update to next stage of control transfer */
250 		udc_ctrl_update_stage(dev, buf);
251 	}
252 
253 	if (udc_ctrl_stage_is_status_in(dev)) {
254 		err = udc_ctrl_submit_s_out_status(dev, buf);
255 	}
256 
257 	return err;
258 }
259 
udc_mcux_handler_ctrl_in(const struct device * dev,struct net_buf * buf,uint8_t * mcux_buf,uint16_t mcux_len)260 static int udc_mcux_handler_ctrl_in(const struct device *dev, struct net_buf *buf,
261 				uint8_t *mcux_buf, uint16_t mcux_len)
262 {
263 	int err = 0;
264 	uint32_t len;
265 
266 	len = MIN(buf->len, mcux_len);
267 	buf->data += len;
268 	buf->len -= len;
269 
270 	if (udc_ctrl_stage_is_status_in(dev) ||
271 	udc_ctrl_stage_is_no_data(dev)) {
272 		/* Status stage finished, notify upper layer */
273 		err = udc_ctrl_submit_status(dev, buf);
274 	}
275 
276 	/* Update to next stage of control transfer */
277 	udc_ctrl_update_stage(dev, buf);
278 
279 	if (udc_ctrl_stage_is_status_out(dev)) {
280 		/*
281 		 * IN transfer finished, release buffer,
282 		 * control OUT buffer should be already fed.
283 		 */
284 		net_buf_unref(buf);
285 		err = udc_mcux_ctrl_feed_dout(dev, 0u);
286 	}
287 
288 	return err;
289 }
290 
udc_mcux_handler_non_ctrl_in(const struct device * dev,uint8_t ep,struct net_buf * buf,uint8_t * mcux_buf,uint16_t mcux_len)291 static int udc_mcux_handler_non_ctrl_in(const struct device *dev, uint8_t ep,
292 			struct net_buf *buf, uint8_t *mcux_buf, uint16_t mcux_len)
293 {
294 	int err;
295 	uint32_t len;
296 
297 	len = MIN(buf->len, mcux_len);
298 	buf->data += len;
299 	buf->len -= len;
300 
301 	err = udc_submit_ep_event(dev, buf, 0);
302 	udc_mcux_ep_try_feed(dev, udc_get_ep_cfg(dev, ep));
303 
304 	return err;
305 }
306 
udc_mcux_handler_non_ctrl_out(const struct device * dev,uint8_t ep,struct net_buf * buf,uint8_t * mcux_buf,uint16_t mcux_len)307 static int udc_mcux_handler_non_ctrl_out(const struct device *dev, uint8_t ep,
308 			struct net_buf *buf, uint8_t *mcux_buf, uint16_t mcux_len)
309 {
310 	int err;
311 	uint32_t len;
312 
313 	len = MIN(net_buf_tailroom(buf), mcux_len);
314 	net_buf_add(buf, len);
315 
316 	err = udc_submit_ep_event(dev, buf, 0);
317 	udc_mcux_ep_try_feed(dev, udc_get_ep_cfg(dev, ep));
318 
319 	return err;
320 }
321 
udc_mcux_handler_out(const struct device * dev,uint8_t ep,uint8_t * mcux_buf,uint16_t mcux_len)322 static int udc_mcux_handler_out(const struct device *dev, uint8_t ep,
323 				uint8_t *mcux_buf, uint16_t mcux_len)
324 {
325 	int err;
326 	struct net_buf *buf;
327 
328 	buf = udc_buf_get(dev, ep);
329 
330 	udc_mcux_lock(dev);
331 	udc_ep_set_busy(dev, ep, false);
332 	udc_mcux_unlock(dev);
333 
334 	if (buf == NULL) {
335 		udc_submit_event(dev, UDC_EVT_ERROR, -ENOBUFS);
336 		return -ENOBUFS;
337 	}
338 
339 	if (ep == USB_CONTROL_EP_OUT) {
340 		err = udc_mcux_handler_ctrl_out(dev, buf, mcux_buf, mcux_len);
341 	} else {
342 		err = udc_mcux_handler_non_ctrl_out(dev, ep, buf, mcux_buf, mcux_len);
343 	}
344 
345 	return err;
346 }
347 
348 /* return true - zlp is feed; false - no zlp */
udc_mcux_handler_zlt(const struct device * dev,uint8_t ep,struct net_buf * buf,uint16_t mcux_len)349 static bool udc_mcux_handler_zlt(const struct device *dev, uint8_t ep, struct net_buf *buf,
350 				uint16_t mcux_len)
351 {
352 	const struct udc_mcux_config *config = dev->config;
353 	const usb_device_controller_interface_struct_t *mcux_if = config->mcux_if;
354 	struct udc_mcux_data *priv = udc_get_private(dev);
355 
356 	/* The whole transfer is already done by MCUX controller driver. */
357 	if (mcux_len >= buf->len) {
358 		if (udc_ep_buf_has_zlp(buf)) {
359 			usb_status_t status;
360 
361 			udc_ep_buf_clear_zlp(buf);
362 			status = mcux_if->deviceSend(priv->mcux_device.controllerHandle,
363 					ep, NULL, 0);
364 			if (status != kStatus_USB_Success) {
365 				udc_submit_event(dev, UDC_EVT_ERROR, -EIO);
366 				return false;
367 			}
368 			return true;
369 		}
370 	}
371 
372 	return false;
373 }
374 
udc_mcux_handler_in(const struct device * dev,uint8_t ep,uint8_t * mcux_buf,uint16_t mcux_len)375 static int udc_mcux_handler_in(const struct device *dev, uint8_t ep,
376 				uint8_t *mcux_buf, uint16_t mcux_len)
377 {
378 	int err;
379 	struct net_buf *buf;
380 
381 	buf = udc_buf_peek(dev, ep);
382 	if (buf == NULL) {
383 		udc_submit_event(dev, UDC_EVT_ERROR, -ENOBUFS);
384 		return -ENOBUFS;
385 	}
386 
387 	if (udc_mcux_handler_zlt(dev, ep, buf, mcux_len)) {
388 		return 0;
389 	}
390 
391 	buf = udc_buf_get(dev, ep);
392 
393 	udc_mcux_lock(dev);
394 	udc_ep_set_busy(dev, ep, false);
395 	udc_mcux_unlock(dev);
396 
397 	if (buf == NULL) {
398 		udc_submit_event(dev, UDC_EVT_ERROR, -ENOBUFS);
399 		return -ENOBUFS;
400 	}
401 	if (ep == USB_CONTROL_EP_IN) {
402 		err = udc_mcux_handler_ctrl_in(dev, buf, mcux_buf, mcux_len);
403 	} else {
404 		err = udc_mcux_handler_non_ctrl_in(dev, ep, buf, mcux_buf, mcux_len);
405 	}
406 
407 	return err;
408 }
409 
udc_mcux_event_submit(const struct device * dev,const usb_device_callback_message_struct_t * mcux_msg)410 static void udc_mcux_event_submit(const struct device *dev,
411 				  const usb_device_callback_message_struct_t *mcux_msg)
412 {
413 	struct udc_mcux_data *priv = udc_get_private(dev);
414 	struct udc_mcux_event *ev;
415 	int ret;
416 
417 	ret = k_mem_slab_alloc(&udc_event_slab, (void **)&ev, K_NO_WAIT);
418 	if (ret) {
419 		udc_submit_event(dev, UDC_EVT_ERROR, ret);
420 		LOG_ERR("Failed to allocate slab");
421 		return;
422 	}
423 
424 	ev->dev = dev;
425 	ev->mcux_msg = *mcux_msg;
426 	k_fifo_put(&priv->fifo, ev);
427 	k_work_submit_to_queue(udc_get_work_q(), &priv->work);
428 }
429 
udc_mcux_work_handler(struct k_work * item)430 static void udc_mcux_work_handler(struct k_work *item)
431 {
432 	struct udc_mcux_event *ev;
433 	struct udc_mcux_data *priv;
434 	usb_device_callback_message_struct_t *mcux_msg;
435 	int err;
436 	uint8_t ep;
437 
438 	priv = CONTAINER_OF(item, struct udc_mcux_data, work);
439 	while ((ev = k_fifo_get(&priv->fifo, K_NO_WAIT)) != NULL) {
440 		mcux_msg = &ev->mcux_msg;
441 
442 		if (mcux_msg->code == kUSB_DeviceNotifyBusReset) {
443 			struct udc_ep_config *cfg;
444 
445 			udc_mcux_control(ev->dev, kUSB_DeviceControlSetDefaultStatus, NULL);
446 			cfg = udc_get_ep_cfg(ev->dev, USB_CONTROL_EP_OUT);
447 			if (cfg->stat.enabled) {
448 				udc_ep_disable_internal(ev->dev, USB_CONTROL_EP_OUT);
449 			}
450 			cfg = udc_get_ep_cfg(ev->dev, USB_CONTROL_EP_IN);
451 			if (cfg->stat.enabled) {
452 				udc_ep_disable_internal(ev->dev, USB_CONTROL_EP_IN);
453 			}
454 			if (udc_ep_enable_internal(ev->dev, USB_CONTROL_EP_OUT,
455 						USB_EP_TYPE_CONTROL,
456 						USB_MCUX_EP0_SIZE, 0)) {
457 				LOG_ERR("Failed to enable control endpoint");
458 			}
459 
460 			if (udc_ep_enable_internal(ev->dev, USB_CONTROL_EP_IN,
461 						USB_EP_TYPE_CONTROL,
462 						USB_MCUX_EP0_SIZE, 0)) {
463 				LOG_ERR("Failed to enable control endpoint");
464 			}
465 			udc_submit_event(ev->dev, UDC_EVT_RESET, 0);
466 		} else {
467 			ep  = mcux_msg->code;
468 
469 			if (mcux_msg->isSetup) {
470 				struct usb_setup_packet *setup =
471 					(struct usb_setup_packet *)mcux_msg->buffer;
472 
473 				err = udc_mcux_handler_setup(ev->dev, setup);
474 			} else if (USB_EP_DIR_IS_IN(ep)) {
475 				err = udc_mcux_handler_in(ev->dev, ep, mcux_msg->buffer,
476 							  mcux_msg->length);
477 			} else {
478 				err = udc_mcux_handler_out(ev->dev, ep, mcux_msg->buffer,
479 							   mcux_msg->length);
480 			}
481 
482 			if (unlikely(err)) {
483 				udc_submit_event(ev->dev, UDC_EVT_ERROR, err);
484 			}
485 		}
486 
487 		k_mem_slab_free(&udc_event_slab, (void *)ev);
488 	}
489 }
490 
491 /* NXP MCUX controller driver notify transfers/status through this interface */
USB_DeviceNotificationTrigger(void * handle,void * msg)492 usb_status_t USB_DeviceNotificationTrigger(void *handle, void *msg)
493 {
494 	usb_device_callback_message_struct_t *mcux_msg = msg;
495 	usb_device_notification_t mcux_notify;
496 	struct udc_mcux_data *priv;
497 	const struct device *dev;
498 	usb_status_t mcux_status = kStatus_USB_Success;
499 
500 	if ((NULL == msg) || (NULL == handle)) {
501 		return kStatus_USB_InvalidHandle;
502 	}
503 
504 	mcux_notify = (usb_device_notification_t)mcux_msg->code;
505 	priv = (struct udc_mcux_data *)(PRV_DATA_HANDLE(handle));
506 	dev = priv->dev;
507 
508 	switch (mcux_notify) {
509 	case kUSB_DeviceNotifyBusReset:
510 		udc_mcux_event_submit(dev, mcux_msg);
511 		break;
512 	case kUSB_DeviceNotifyError:
513 		udc_submit_event(dev, UDC_EVT_ERROR, -EIO);
514 		break;
515 	case kUSB_DeviceNotifySuspend:
516 		udc_set_suspended(dev, true);
517 		udc_submit_event(dev, UDC_EVT_SUSPEND, 0);
518 		break;
519 	case kUSB_DeviceNotifyResume:
520 		udc_set_suspended(dev, false);
521 		udc_submit_event(dev, UDC_EVT_RESUME, 0);
522 		break;
523 	case kUSB_DeviceNotifyLPMSleep:
524 		break;
525 	case kUSB_DeviceNotifyDetach:
526 		udc_submit_event(dev, UDC_EVT_VBUS_REMOVED, 0);
527 		break;
528 	case kUSB_DeviceNotifyAttach:
529 		udc_submit_event(dev, UDC_EVT_VBUS_READY, 0);
530 		break;
531 	case kUSB_DeviceNotifySOF:
532 		udc_submit_event(dev, UDC_EVT_SOF, 0);
533 		break;
534 	default:
535 		udc_mcux_event_submit(dev, mcux_msg);
536 		break;
537 	}
538 
539 	return mcux_status;
540 }
541 
udc_mcux_isr(const struct device * dev)542 static void udc_mcux_isr(const struct device *dev)
543 {
544 	struct udc_mcux_data *priv = udc_get_private(dev);
545 
546 	USB_DeviceEhciIsrFunction((void *)(&priv->mcux_device));
547 }
548 
549 /* Return actual USB device speed */
udc_mcux_device_speed(const struct device * dev)550 static enum udc_bus_speed udc_mcux_device_speed(const struct device *dev)
551 {
552 	int err;
553 	uint8_t mcux_speed;
554 
555 	err = udc_mcux_control(dev, kUSB_DeviceControlGetSpeed, &mcux_speed);
556 	if (err) {
557 		/*
558 		 * In the current version of all NXP USB device drivers,
559 		 * no error is returned if the parameter is correct.
560 		 */
561 		return UDC_BUS_SPEED_FS;
562 	}
563 
564 	switch (mcux_speed) {
565 	case USB_SPEED_HIGH:
566 		return UDC_BUS_SPEED_HS;
567 	case USB_SPEED_LOW:
568 		__ASSERT(false, "Low speed mode not supported");
569 		__fallthrough;
570 	case USB_SPEED_FULL:
571 		__fallthrough;
572 	default:
573 		return UDC_BUS_SPEED_FS;
574 	}
575 }
576 
udc_mcux_ep_enqueue(const struct device * dev,struct udc_ep_config * const cfg,struct net_buf * const buf)577 static int udc_mcux_ep_enqueue(const struct device *dev,
578 			       struct udc_ep_config *const cfg,
579 			       struct net_buf *const buf)
580 {
581 	udc_buf_put(cfg, buf);
582 	if (cfg->stat.halted) {
583 		LOG_DBG("ep 0x%02x halted", cfg->addr);
584 		return 0;
585 	}
586 
587 	return udc_mcux_ep_try_feed(dev, cfg);
588 }
589 
udc_mcux_ep_dequeue(const struct device * dev,struct udc_ep_config * const cfg)590 static int udc_mcux_ep_dequeue(const struct device *dev,
591 			       struct udc_ep_config *const cfg)
592 {
593 	struct net_buf *buf;
594 
595 	cfg->stat.halted = false;
596 	buf = udc_buf_get_all(dev, cfg->addr);
597 	if (buf) {
598 		udc_submit_ep_event(dev, buf, -ECONNABORTED);
599 	}
600 
601 	udc_mcux_lock(dev);
602 	udc_ep_set_busy(dev, cfg->addr, false);
603 	udc_mcux_unlock(dev);
604 
605 	return 0;
606 }
607 
udc_mcux_ep_set_halt(const struct device * dev,struct udc_ep_config * const cfg)608 static int udc_mcux_ep_set_halt(const struct device *dev,
609 				struct udc_ep_config *const cfg)
610 {
611 	return udc_mcux_control(dev, kUSB_DeviceControlEndpointStall, &cfg->addr);
612 }
613 
udc_mcux_ep_clear_halt(const struct device * dev,struct udc_ep_config * const cfg)614 static int udc_mcux_ep_clear_halt(const struct device *dev,
615 				  struct udc_ep_config *const cfg)
616 {
617 	(void)udc_mcux_control(dev, kUSB_DeviceControlEndpointUnstall, &cfg->addr);
618 	/* transfer is enqueued after stalled */
619 	return udc_mcux_ep_try_feed(dev, cfg);
620 }
621 
udc_mcux_ep_enable(const struct device * dev,struct udc_ep_config * const cfg)622 static int udc_mcux_ep_enable(const struct device *dev,
623 			      struct udc_ep_config *const cfg)
624 {
625 	usb_device_endpoint_init_struct_t ep_init;
626 
627 	LOG_DBG("Enable ep 0x%02x", cfg->addr);
628 
629 	ep_init.zlt             = 0U;
630 	ep_init.interval        = cfg->interval;
631 	ep_init.endpointAddress = cfg->addr;
632 	/* HAL expects wMaxPacketSize value directly in maxPacketSize field */
633 	ep_init.maxPacketSize   = cfg->mps;
634 
635 	switch (cfg->attributes & USB_EP_TRANSFER_TYPE_MASK) {
636 	case USB_EP_TYPE_CONTROL:
637 		ep_init.transferType = USB_ENDPOINT_CONTROL;
638 		break;
639 	case USB_EP_TYPE_BULK:
640 		ep_init.transferType = USB_ENDPOINT_BULK;
641 		break;
642 	case USB_EP_TYPE_INTERRUPT:
643 		ep_init.transferType = USB_ENDPOINT_INTERRUPT;
644 		break;
645 	case USB_EP_TYPE_ISO:
646 		ep_init.transferType = USB_ENDPOINT_ISOCHRONOUS;
647 		break;
648 	default:
649 		return -EINVAL;
650 	}
651 
652 	return udc_mcux_control(dev, kUSB_DeviceControlEndpointInit, &ep_init);
653 }
654 
udc_mcux_ep_disable(const struct device * dev,struct udc_ep_config * const cfg)655 static int udc_mcux_ep_disable(const struct device *dev,
656 			       struct udc_ep_config *const cfg)
657 {
658 	LOG_DBG("Disable ep 0x%02x", cfg->addr);
659 
660 	return udc_mcux_control(dev, kUSB_DeviceControlEndpointDeinit, &cfg->addr);
661 }
662 
udc_mcux_host_wakeup(const struct device * dev)663 static int udc_mcux_host_wakeup(const struct device *dev)
664 {
665 	return -ENOTSUP;
666 }
667 
udc_mcux_set_address(const struct device * dev,const uint8_t addr)668 static int udc_mcux_set_address(const struct device *dev, const uint8_t addr)
669 {
670 	uint8_t temp_addr = addr;
671 
672 	return udc_mcux_control(dev, kUSB_DeviceControlSetDeviceAddress, &temp_addr);
673 }
674 
udc_mcux_enable(const struct device * dev)675 static int udc_mcux_enable(const struct device *dev)
676 {
677 	return udc_mcux_control(dev, kUSB_DeviceControlRun, NULL);
678 }
679 
udc_mcux_disable(const struct device * dev)680 static int udc_mcux_disable(const struct device *dev)
681 {
682 	return udc_mcux_control(dev, kUSB_DeviceControlStop, NULL);
683 }
684 
udc_mcux_init(const struct device * dev)685 static int udc_mcux_init(const struct device *dev)
686 {
687 	const struct udc_mcux_config *config = dev->config;
688 	const usb_device_controller_interface_struct_t *mcux_if = config->mcux_if;
689 	struct udc_mcux_data *priv = udc_get_private(dev);
690 	usb_status_t status;
691 
692 	if (priv->controller_id == 0xFFu) {
693 		return -ENOMEM;
694 	}
695 
696 #ifdef CONFIG_DT_HAS_NXP_USBPHY_ENABLED
697 	if (config->phy_config != NULL) {
698 		USB_EhciPhyInit(priv->controller_id, 0u, config->phy_config);
699 	}
700 #endif
701 
702 	/* Init MCUX USB device driver. */
703 	status = mcux_if->deviceInit(priv->controller_id,
704 		&priv->mcux_device, &(priv->mcux_device.controllerHandle));
705 	if (status != kStatus_USB_Success) {
706 		return -ENOMEM;
707 	}
708 
709 	/* enable USB interrupt */
710 	config->irq_enable_func(dev);
711 
712 	LOG_DBG("Initialized USB controller %x", (uint32_t)config->base);
713 
714 	return 0;
715 }
716 
udc_mcux_shutdown(const struct device * dev)717 static int udc_mcux_shutdown(const struct device *dev)
718 {
719 	const struct udc_mcux_config *config = dev->config;
720 	const usb_device_controller_interface_struct_t *mcux_if = config->mcux_if;
721 	struct udc_mcux_data *priv = udc_get_private(dev);
722 	usb_status_t status;
723 
724 	/* Disable interrupt */
725 	config->irq_disable_func(dev);
726 
727 	/* De-init MCUX USB device driver. */
728 	status = mcux_if->deviceDeinit(priv->mcux_device.controllerHandle);
729 	if (status != kStatus_USB_Success) {
730 		return -ENOMEM;
731 	}
732 
733 	return 0;
734 }
735 
udc_mcux_get_hal_driver_id(struct udc_mcux_data * priv,const struct udc_mcux_config * config)736 static inline void udc_mcux_get_hal_driver_id(struct udc_mcux_data *priv,
737 			const struct udc_mcux_config *config)
738 {
739 	/*
740 	 * MCUX USB controller drivers use an ID to tell the HAL drivers
741 	 * which controller is being used. This part of the code converts
742 	 * the base address to the ID value.
743 	 */
744 #ifdef USBHS_STACK_BASE_ADDRS
745 	uintptr_t usb_base_addrs[] = USBHS_STACK_BASE_ADDRS;
746 #else
747 	uintptr_t usb_base_addrs[] = USBHS_BASE_ADDRS;
748 #endif
749 
750 	/* get the right controller id */
751 	priv->controller_id = 0xFFu; /* invalid value */
752 	for (uint8_t i = 0; i < ARRAY_SIZE(usb_base_addrs); i++) {
753 		if (usb_base_addrs[i] == config->base) {
754 			priv->controller_id = kUSB_ControllerEhci0 + i;
755 			break;
756 		}
757 	}
758 }
759 
udc_mcux_driver_preinit(const struct device * dev)760 static int udc_mcux_driver_preinit(const struct device *dev)
761 {
762 	const struct udc_mcux_config *config = dev->config;
763 	struct udc_data *data = dev->data;
764 	struct udc_mcux_data *priv = data->priv;
765 	int err;
766 
767 	udc_mcux_get_hal_driver_id(priv, config);
768 	if (priv->controller_id == 0xFFu) {
769 		return -ENOMEM;
770 	}
771 
772 	k_mutex_init(&data->mutex);
773 	k_fifo_init(&priv->fifo);
774 	k_work_init(&priv->work, udc_mcux_work_handler);
775 
776 	for (int i = 0; i < config->num_of_eps; i++) {
777 		config->ep_cfg_out[i].caps.out = 1;
778 		if (i == 0) {
779 			config->ep_cfg_out[i].caps.control = 1;
780 			config->ep_cfg_out[i].caps.mps = 64;
781 		} else {
782 			config->ep_cfg_out[i].caps.bulk = 1;
783 			config->ep_cfg_out[i].caps.interrupt = 1;
784 			config->ep_cfg_out[i].caps.iso = 1;
785 			config->ep_cfg_out[i].caps.mps = 1024;
786 			config->ep_cfg_out[i].caps.high_bandwidth = 1;
787 		}
788 
789 		config->ep_cfg_out[i].addr = USB_EP_DIR_OUT | i;
790 		err = udc_register_ep(dev, &config->ep_cfg_out[i]);
791 		if (err != 0) {
792 			LOG_ERR("Failed to register endpoint");
793 			return err;
794 		}
795 	}
796 
797 	for (int i = 0; i < config->num_of_eps; i++) {
798 		config->ep_cfg_in[i].caps.in = 1;
799 		if (i == 0) {
800 			config->ep_cfg_in[i].caps.control = 1;
801 			config->ep_cfg_in[i].caps.mps = 64;
802 		} else {
803 			config->ep_cfg_in[i].caps.bulk = 1;
804 			config->ep_cfg_in[i].caps.interrupt = 1;
805 			config->ep_cfg_in[i].caps.iso = 1;
806 			config->ep_cfg_in[i].caps.mps = 1024;
807 			config->ep_cfg_in[i].caps.high_bandwidth = 1;
808 		}
809 
810 		config->ep_cfg_in[i].addr = USB_EP_DIR_IN | i;
811 		err = udc_register_ep(dev, &config->ep_cfg_in[i]);
812 		if (err != 0) {
813 			LOG_ERR("Failed to register endpoint");
814 			return err;
815 		}
816 	}
817 
818 	/* Requires udc_mcux_host_wakeup() implementation */
819 	data->caps.rwup = false;
820 	data->caps.mps0 = USB_MCUX_MPS0;
821 	data->caps.hs = true;
822 	priv->dev = dev;
823 
824 	pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT);
825 
826 	return 0;
827 }
828 
829 static const struct udc_api udc_mcux_api = {
830 	.device_speed = udc_mcux_device_speed,
831 	.ep_enqueue = udc_mcux_ep_enqueue,
832 	.ep_dequeue = udc_mcux_ep_dequeue,
833 	.ep_set_halt = udc_mcux_ep_set_halt,
834 	.ep_clear_halt = udc_mcux_ep_clear_halt,
835 	.ep_try_config = NULL,
836 	.ep_enable = udc_mcux_ep_enable,
837 	.ep_disable = udc_mcux_ep_disable,
838 	.host_wakeup = udc_mcux_host_wakeup,
839 	.set_address = udc_mcux_set_address,
840 	.enable = udc_mcux_enable,
841 	.disable = udc_mcux_disable,
842 	.init = udc_mcux_init,
843 	.shutdown = udc_mcux_shutdown,
844 	.lock = udc_mcux_lock,
845 	.unlock = udc_mcux_unlock,
846 };
847 
848 /* EHCI device driver interface */
849 static const usb_device_controller_interface_struct_t udc_mcux_if = {
850 	USB_DeviceEhciInit, USB_DeviceEhciDeinit, USB_DeviceEhciSend,
851 	USB_DeviceEhciRecv, USB_DeviceEhciCancel, USB_DeviceEhciControl
852 };
853 
854 #define UDC_MCUX_PHY_DEFINE(n)								\
855 static usb_phy_config_struct_t phy_config_##n = {					\
856 	.D_CAL = DT_PROP_OR(DT_INST_PHANDLE(n, phy_handle), tx_d_cal, 0),		\
857 	.TXCAL45DP = DT_PROP_OR(DT_INST_PHANDLE(n, phy_handle), tx_cal_45_dp_ohms, 0),	\
858 	.TXCAL45DM = DT_PROP_OR(DT_INST_PHANDLE(n, phy_handle), tx_cal_45_dm_ohms, 0),	\
859 }
860 
861 #define UDC_MCUX_PHY_DEFINE_OR(n)							\
862 	COND_CODE_1(DT_NODE_HAS_PROP(DT_DRV_INST(n), phy_handle),			\
863 		    (UDC_MCUX_PHY_DEFINE(n)), ())
864 
865 #define UDC_MCUX_PHY_CFG_PTR_OR_NULL(n)							\
866 	COND_CODE_1(DT_NODE_HAS_PROP(DT_DRV_INST(n), phy_handle),			\
867 		    (&phy_config_##n), (NULL))
868 
869 #define USB_MCUX_EHCI_DEVICE_DEFINE(n)							\
870 	UDC_MCUX_PHY_DEFINE_OR(n);							\
871 											\
872 	static void udc_irq_enable_func##n(const struct device *dev)			\
873 	{										\
874 		IRQ_CONNECT(DT_INST_IRQN(n),						\
875 			    DT_INST_IRQ(n, priority),					\
876 			    udc_mcux_isr,						\
877 			    DEVICE_DT_INST_GET(n), 0);					\
878 											\
879 		irq_enable(DT_INST_IRQN(n));						\
880 	}										\
881 											\
882 	static void udc_irq_disable_func##n(const struct device *dev)			\
883 	{										\
884 		irq_disable(DT_INST_IRQN(n));						\
885 	}										\
886 											\
887 	static struct udc_ep_config							\
888 		ep_cfg_out##n[DT_INST_PROP(n, num_bidir_endpoints)];			\
889 	static struct udc_ep_config							\
890 		ep_cfg_in##n[DT_INST_PROP(n, num_bidir_endpoints)];			\
891 											\
892 	PINCTRL_DT_INST_DEFINE(n);							\
893 											\
894 	static struct udc_mcux_config priv_config_##n = {				\
895 		.base = DT_INST_REG_ADDR(n),						\
896 		.irq_enable_func = udc_irq_enable_func##n,				\
897 		.irq_disable_func = udc_irq_disable_func##n,				\
898 		.num_of_eps = DT_INST_PROP(n, num_bidir_endpoints),			\
899 		.ep_cfg_in = ep_cfg_in##n,						\
900 		.ep_cfg_out = ep_cfg_out##n,						\
901 		.mcux_if = &udc_mcux_if,						\
902 		.pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n),				\
903 		.phy_config = UDC_MCUX_PHY_CFG_PTR_OR_NULL(n),				\
904 	};										\
905 											\
906 	static struct udc_mcux_data priv_data_##n = {					\
907 	};										\
908 											\
909 	static struct udc_data udc_data_##n = {						\
910 		.mutex = Z_MUTEX_INITIALIZER(udc_data_##n.mutex),			\
911 		.priv = &priv_data_##n,							\
912 	};										\
913 											\
914 	DEVICE_DT_INST_DEFINE(n, udc_mcux_driver_preinit, NULL,				\
915 			      &udc_data_##n, &priv_config_##n,				\
916 			      POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,		\
917 			      &udc_mcux_api);
918 
919 DT_INST_FOREACH_STATUS_OKAY(USB_MCUX_EHCI_DEVICE_DEFINE)
920