1 /*
2 * Copyright 2018-2023, NXP
3 * Copyright (c) 2019 PHYTEC Messtechnik GmbH
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #include <soc.h>
9 #include <string.h>
10 #include <zephyr/drivers/usb/usb_dc.h>
11 #include <zephyr/usb/usb_device.h>
12 #include <soc.h>
13 #include <zephyr/init.h>
14 #include <zephyr/kernel.h>
15 #include <zephyr/drivers/pinctrl.h>
16 #include "usb.h"
17 #include "usb_device.h"
18 #include "usb_device_config.h"
19 #include "usb_device_dci.h"
20
21 #ifdef CONFIG_USB_DC_NXP_EHCI
22 #undef DT_DRV_COMPAT
23 #define DT_DRV_COMPAT nxp_ehci
24 #include "usb_device_ehci.h"
25 #endif
26 #ifdef CONFIG_USB_DC_NXP_LPCIP3511
27 #undef DT_DRV_COMPAT
28 #define DT_DRV_COMPAT nxp_lpcip3511
29 #include "usb_device_lpcip3511.h"
30 #endif
31 #ifdef CONFIG_HAS_MCUX_CACHE
32 #include <fsl_cache.h>
33 #endif
34
35
36 #define LOG_LEVEL CONFIG_USB_DRIVER_LOG_LEVEL
37 #include <zephyr/logging/log.h>
38 #include <zephyr/irq.h>
39 LOG_MODULE_REGISTER(usb_dc_mcux);
40
41 static void usb_isr_handler(void);
42
43 /* the setup transfer state */
44 #define SETUP_DATA_STAGE_DONE (0)
45 #define SETUP_DATA_STAGE_IN (1)
46 #define SETUP_DATA_STAGE_OUT (2)
47
48 /*
49 * Endpoint absolute index calculation:
50 *
51 * MCUX EHCI USB device controller supports a specific
52 * number of bidirectional endpoints. Bidirectional means
53 * that an endpoint object is represented to the outside
54 * as an OUT and an IN Endpoint with its own buffers
55 * and control structures.
56 *
57 * EP_ABS_IDX refers to the corresponding control
58 * structure, for example:
59 *
60 * EP addr | ep_idx | ep_abs_idx
61 * -------------------------------
62 * 0x00 | 0x00 | 0x00
63 * 0x80 | 0x00 | 0x01
64 * 0x01 | 0x01 | 0x02
65 * 0x81 | 0x01 | 0x03
66 * .... | .... | ....
67 *
68 * The NUM_OF_EP_MAX (and number of s_ep_ctrl) should be double
69 * of num_bidir_endpoints.
70 */
71 #define EP_ABS_IDX(ep) (USB_EP_GET_IDX(ep) * 2 + \
72 (USB_EP_GET_DIR(ep) >> 7))
73 #define NUM_OF_EP_MAX (DT_INST_PROP(0, num_bidir_endpoints) * 2)
74
75 #define NUM_INSTS DT_NUM_INST_STATUS_OKAY(nxp_ehci) + DT_NUM_INST_STATUS_OKAY(nxp_lpcip3511)
76 BUILD_ASSERT(NUM_INSTS <= 1, "Only one USB device supported");
77
78 /* Controller ID is for HAL usage */
79 #if defined(CONFIG_SOC_SERIES_IMXRT5XX) || \
80 defined(CONFIG_SOC_SERIES_IMXRT6XX) || \
81 defined(CONFIG_SOC_LPC55S26) || defined(CONFIG_SOC_LPC55S28) || \
82 defined(CONFIG_SOC_LPC55S16)
83 #define CONTROLLER_ID kUSB_ControllerLpcIp3511Hs0
84 #elif defined(CONFIG_SOC_LPC55S36)
85 #define CONTROLLER_ID kUSB_ControllerLpcIp3511Fs0
86 #elif defined(CONFIG_SOC_LPC55S69_CPU0) || defined(CONFIG_SOC_LPC55S69_CPU1)
87 #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(usbhs))
88 #define CONTROLLER_ID kUSB_ControllerLpcIp3511Hs0
89 #elif DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(usbfs))
90 #define CONTROLLER_ID kUSB_ControllerLpcIp3511Fs0
91 #endif /* LPC55s69 */
92 #elif defined(CONFIG_SOC_SERIES_IMXRT11XX) || \
93 defined(CONFIG_SOC_SERIES_IMXRT118X) || \
94 defined(CONFIG_SOC_SERIES_IMXRT10XX) || \
95 defined(CONFIG_SOC_SERIES_MCXN)
96 #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(usb1))
97 #define CONTROLLER_ID kUSB_ControllerEhci0
98 #elif DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(usb2))
99 #define CONTROLLER_ID kUSB_ControllerEhci1
100 #endif /* IMX RT */
101 #else
102 #define CONTROLLER_ID kUSB_ControllerEhci0
103 #endif /* CONTROLLER ID */
104
105 /* We do not need a buffer for the write side on platforms that have USB RAM.
106 * The SDK driver will copy the data buffer to be sent to USB RAM.
107 */
108 #ifdef CONFIG_USB_DC_NXP_LPCIP3511
109 #define EP_BUF_NUMOF_BLOCKS (NUM_OF_EP_MAX / 2)
110 #else
111 #define EP_BUF_NUMOF_BLOCKS NUM_OF_EP_MAX
112 #endif
113
114 /* The max MPS is 1023 for FS, 1024 for HS. */
115 #if defined(CONFIG_NOCACHE_MEMORY)
116 #define EP_BUF_NONCACHED
117 K_HEAP_DEFINE_NOCACHE(ep_buf_pool, 1024 * EP_BUF_NUMOF_BLOCKS);
118 #else
119 K_HEAP_DEFINE(ep_buf_pool, 1024 * EP_BUF_NUMOF_BLOCKS);
120 #endif
121
122 struct usb_ep_ctrl_data {
123 usb_device_callback_message_struct_t transfer_message;
124 void *block;
125 usb_dc_ep_callback callback;
126 uint16_t ep_mps;
127 uint8_t ep_enabled : 1;
128 uint8_t ep_occupied : 1;
129 };
130
131 struct usb_dc_state {
132 usb_device_struct_t dev_struct;
133 /* Controller handle */
134 usb_dc_status_callback status_cb;
135 struct usb_ep_ctrl_data *eps;
136 bool attached;
137 uint8_t setup_data_stage;
138 K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_USB_MCUX_THREAD_STACK_SIZE);
139
140 struct k_thread thread;
141 };
142
143 static struct usb_ep_ctrl_data s_ep_ctrl[NUM_OF_EP_MAX];
144 static struct usb_dc_state dev_state;
145
146 /* Message queue for the usb thread */
147 K_MSGQ_DEFINE(usb_dc_msgq, sizeof(usb_device_callback_message_struct_t),
148 CONFIG_USB_DC_MSG_QUEUE_LEN, 4);
149
150 #if defined(CONFIG_USB_DC_NXP_EHCI)
151 /* EHCI device driver interface */
152 static const usb_device_controller_interface_struct_t mcux_usb_iface = {
153 USB_DeviceEhciInit, USB_DeviceEhciDeinit, USB_DeviceEhciSend,
154 USB_DeviceEhciRecv, USB_DeviceEhciCancel, USB_DeviceEhciControl
155 };
156
157 extern void USB_DeviceEhciIsrFunction(void *deviceHandle);
158
159 #elif defined(CONFIG_USB_DC_NXP_LPCIP3511)
160 /* LPCIP3511 device driver interface */
161 static const usb_device_controller_interface_struct_t mcux_usb_iface = {
162 USB_DeviceLpc3511IpInit, USB_DeviceLpc3511IpDeinit, USB_DeviceLpc3511IpSend,
163 USB_DeviceLpc3511IpRecv, USB_DeviceLpc3511IpCancel, USB_DeviceLpc3511IpControl
164 };
165
166 extern void USB_DeviceLpcIp3511IsrFunction(void *deviceHandle);
167
168 #endif
169
usb_dc_reset(void)170 int usb_dc_reset(void)
171 {
172 if (dev_state.dev_struct.controllerHandle != NULL) {
173 dev_state.dev_struct.controllerInterface->deviceControl(
174 dev_state.dev_struct.controllerHandle,
175 kUSB_DeviceControlSetDefaultStatus, NULL);
176 }
177
178 return 0;
179 }
180
usb_dc_attach(void)181 int usb_dc_attach(void)
182 {
183 usb_status_t status;
184
185 dev_state.eps = &s_ep_ctrl[0];
186 if (dev_state.attached) {
187 LOG_WRN("Already attached");
188 return 0;
189 }
190
191 dev_state.dev_struct.controllerInterface = &mcux_usb_iface;
192 status = dev_state.dev_struct.controllerInterface->deviceInit(CONTROLLER_ID,
193 &dev_state.dev_struct,
194 &dev_state.dev_struct.controllerHandle);
195 if (kStatus_USB_Success != status) {
196 return -EIO;
197 }
198
199 IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority),
200 usb_isr_handler, 0, 0);
201 irq_enable(DT_INST_IRQN(0));
202 dev_state.attached = true;
203 status = dev_state.dev_struct.controllerInterface->deviceControl(
204 dev_state.dev_struct.controllerHandle,
205 kUSB_DeviceControlRun, NULL);
206
207 LOG_DBG("Attached");
208
209 return 0;
210 }
211
usb_dc_detach(void)212 int usb_dc_detach(void)
213 {
214 usb_status_t status;
215
216 if (dev_state.dev_struct.controllerHandle == NULL) {
217 LOG_WRN("Device not attached");
218 return 0;
219 }
220
221 status = dev_state.dev_struct.controllerInterface->deviceControl(
222 dev_state.dev_struct.controllerHandle,
223 kUSB_DeviceControlStop,
224 NULL);
225 if (kStatus_USB_Success != status) {
226 return -EIO;
227 }
228
229 status = dev_state.dev_struct.controllerInterface->deviceDeinit(
230 dev_state.dev_struct.controllerHandle);
231 if (kStatus_USB_Success != status) {
232 return -EIO;
233 }
234
235 dev_state.dev_struct.controllerHandle = NULL;
236 dev_state.attached = false;
237 LOG_DBG("Detached");
238
239 return 0;
240 }
241
usb_dc_set_address(const uint8_t addr)242 int usb_dc_set_address(const uint8_t addr)
243 {
244 usb_status_t status;
245
246 dev_state.dev_struct.deviceAddress = addr;
247 status = dev_state.dev_struct.controllerInterface->deviceControl(
248 dev_state.dev_struct.controllerHandle,
249 kUSB_DeviceControlPreSetDeviceAddress,
250 &dev_state.dev_struct.deviceAddress);
251 if (kStatus_USB_Success != status) {
252 LOG_ERR("Failed to set device address");
253 return -EINVAL;
254 }
255 return 0;
256 }
257
usb_dc_ep_check_cap(const struct usb_dc_ep_cfg_data * const cfg)258 int usb_dc_ep_check_cap(const struct usb_dc_ep_cfg_data *const cfg)
259 {
260 uint8_t ep_abs_idx = EP_ABS_IDX(cfg->ep_addr);
261 uint8_t ep_idx = USB_EP_GET_IDX(cfg->ep_addr);
262
263 if ((cfg->ep_type == USB_DC_EP_CONTROL) && ep_idx) {
264 LOG_ERR("invalid endpoint configuration");
265 return -1;
266 }
267
268 if (ep_abs_idx >= NUM_OF_EP_MAX) {
269 LOG_ERR("endpoint index/address out of range");
270 return -1;
271 }
272
273 return 0;
274 }
275
usb_dc_ep_configure(const struct usb_dc_ep_cfg_data * const cfg)276 int usb_dc_ep_configure(const struct usb_dc_ep_cfg_data *const cfg)
277 {
278 uint8_t ep_abs_idx = EP_ABS_IDX(cfg->ep_addr);
279 usb_device_endpoint_init_struct_t ep_init;
280 struct usb_ep_ctrl_data *eps = &dev_state.eps[ep_abs_idx];
281 usb_status_t status;
282 uint8_t ep;
283
284 ep_init.zlt = 0U;
285 ep_init.endpointAddress = cfg->ep_addr;
286 ep_init.maxPacketSize = cfg->ep_mps;
287 ep_init.transferType = cfg->ep_type;
288
289 if (ep_abs_idx >= NUM_OF_EP_MAX) {
290 LOG_ERR("Wrong endpoint index/address");
291 return -EINVAL;
292 }
293
294 if (dev_state.eps[ep_abs_idx].ep_enabled) {
295 LOG_WRN("Endpoint already configured");
296 return 0;
297 }
298
299 ep = cfg->ep_addr;
300 status = dev_state.dev_struct.controllerInterface->deviceControl(
301 dev_state.dev_struct.controllerHandle,
302 kUSB_DeviceControlEndpointDeinit, &ep);
303 if (kStatus_USB_Success != status) {
304 LOG_WRN("Failed to un-initialize endpoint (status=%d)", (int)status);
305 }
306
307 #ifdef CONFIG_USB_DC_NXP_LPCIP3511
308 /* Allocate buffers used during read operation */
309 if (USB_EP_DIR_IS_OUT(cfg->ep_addr)) {
310 #endif
311 void **block;
312
313 block = &(eps->block);
314 if (*block) {
315 k_heap_free(&ep_buf_pool, *block);
316 *block = NULL;
317 }
318
319 *block = k_heap_alloc(&ep_buf_pool, cfg->ep_mps, K_NO_WAIT);
320 if (*block == NULL) {
321 LOG_ERR("Failed to allocate memory");
322 return -ENOMEM;
323 }
324
325 memset(*block, 0, cfg->ep_mps);
326 #ifdef CONFIG_USB_DC_NXP_LPCIP3511
327 }
328 #endif
329
330 dev_state.eps[ep_abs_idx].ep_mps = cfg->ep_mps;
331 status = dev_state.dev_struct.controllerInterface->deviceControl(
332 dev_state.dev_struct.controllerHandle,
333 kUSB_DeviceControlEndpointInit, &ep_init);
334 if (kStatus_USB_Success != status) {
335 LOG_ERR("Failed to initialize endpoint");
336 return -EIO;
337 }
338
339 /*
340 * If it is control endpoint, controller will prime setup
341 * here set the occupied flag.
342 */
343 if ((USB_EP_GET_IDX(cfg->ep_addr) == USB_CONTROL_ENDPOINT) &&
344 (USB_EP_DIR_IS_OUT(cfg->ep_addr))) {
345 dev_state.eps[ep_abs_idx].ep_occupied = true;
346 }
347 dev_state.eps[ep_abs_idx].ep_enabled = true;
348
349 return 0;
350 }
351
usb_dc_ep_set_stall(const uint8_t ep)352 int usb_dc_ep_set_stall(const uint8_t ep)
353 {
354 uint8_t endpoint = ep;
355 uint8_t ep_abs_idx = EP_ABS_IDX(ep);
356 usb_status_t status;
357
358 if (ep_abs_idx >= NUM_OF_EP_MAX) {
359 LOG_ERR("Wrong endpoint index/address");
360 return -EINVAL;
361 }
362
363 status = dev_state.dev_struct.controllerInterface->deviceControl(
364 dev_state.dev_struct.controllerHandle,
365 kUSB_DeviceControlEndpointStall, &endpoint);
366 if (kStatus_USB_Success != status) {
367 LOG_ERR("Failed to stall endpoint");
368 return -EIO;
369 }
370
371 return 0;
372 }
373
usb_dc_ep_clear_stall(const uint8_t ep)374 int usb_dc_ep_clear_stall(const uint8_t ep)
375 {
376 uint8_t endpoint = ep;
377 uint8_t ep_abs_idx = EP_ABS_IDX(ep);
378 usb_status_t status;
379
380 if (ep_abs_idx >= NUM_OF_EP_MAX) {
381 LOG_ERR("Wrong endpoint index/address");
382 return -EINVAL;
383 }
384
385 status = dev_state.dev_struct.controllerInterface->deviceControl(
386 dev_state.dev_struct.controllerHandle,
387 kUSB_DeviceControlEndpointUnstall, &endpoint);
388 if (kStatus_USB_Success != status) {
389 LOG_ERR("Failed to clear stall");
390 return -EIO;
391 }
392
393 if ((USB_EP_GET_IDX(ep) != USB_CONTROL_ENDPOINT) &&
394 (USB_EP_DIR_IS_OUT(ep))) {
395 status = dev_state.dev_struct.controllerInterface->deviceRecv(
396 dev_state.dev_struct.controllerHandle, ep,
397 (uint8_t *)dev_state.eps[ep_abs_idx].block,
398 (uint32_t)dev_state.eps[ep_abs_idx].ep_mps);
399 if (kStatus_USB_Success != status) {
400 LOG_ERR("Failed to enable reception on 0x%02x", ep);
401 return -EIO;
402 }
403
404 dev_state.eps[ep_abs_idx].ep_occupied = true;
405 }
406
407 return 0;
408 }
409
usb_dc_ep_is_stalled(const uint8_t ep,uint8_t * const stalled)410 int usb_dc_ep_is_stalled(const uint8_t ep, uint8_t *const stalled)
411 {
412 uint8_t ep_abs_idx = EP_ABS_IDX(ep);
413 usb_device_endpoint_status_struct_t ep_status;
414 usb_status_t status;
415
416 if (ep_abs_idx >= NUM_OF_EP_MAX) {
417 LOG_ERR("Wrong endpoint index/address");
418 return -EINVAL;
419 }
420
421 if (!stalled) {
422 return -EINVAL;
423 }
424
425 *stalled = 0;
426 ep_status.endpointAddress = ep;
427 ep_status.endpointStatus = kUSB_DeviceEndpointStateIdle;
428 status = dev_state.dev_struct.controllerInterface->deviceControl(
429 dev_state.dev_struct.controllerHandle,
430 kUSB_DeviceControlGetEndpointStatus, &ep_status);
431 if (kStatus_USB_Success != status) {
432 LOG_ERR("Failed to get endpoint status");
433 return -EIO;
434 }
435
436 *stalled = (uint8_t)ep_status.endpointStatus;
437
438 return 0;
439 }
440
usb_dc_ep_halt(const uint8_t ep)441 int usb_dc_ep_halt(const uint8_t ep)
442 {
443 return usb_dc_ep_set_stall(ep);
444 }
445
usb_dc_ep_enable(const uint8_t ep)446 int usb_dc_ep_enable(const uint8_t ep)
447 {
448 uint8_t ep_abs_idx = EP_ABS_IDX(ep);
449 usb_status_t status;
450
451 /*
452 * endpoint 0 OUT is primed by controller driver when configure this
453 * endpoint.
454 */
455 if (!ep_abs_idx) {
456 return 0;
457 }
458
459 if (ep_abs_idx >= NUM_OF_EP_MAX) {
460 LOG_ERR("Wrong endpoint index/address");
461 return -EINVAL;
462 }
463
464 if (dev_state.eps[ep_abs_idx].ep_occupied) {
465 LOG_WRN("endpoint 0x%x already enabled", ep);
466 return -EALREADY;
467 }
468
469 if ((USB_EP_GET_IDX(ep) != USB_CONTROL_ENDPOINT) &&
470 (USB_EP_DIR_IS_OUT(ep))) {
471 status = dev_state.dev_struct.controllerInterface->deviceRecv(
472 dev_state.dev_struct.controllerHandle, ep,
473 (uint8_t *)dev_state.eps[ep_abs_idx].block,
474 (uint32_t)dev_state.eps[ep_abs_idx].ep_mps);
475 if (kStatus_USB_Success != status) {
476 LOG_ERR("Failed to enable reception on 0x%02x", ep);
477 return -EIO;
478 }
479
480 dev_state.eps[ep_abs_idx].ep_occupied = true;
481 } else {
482 /*
483 * control endpoint just be enabled before enumeration,
484 * when running here, setup has been primed.
485 */
486 dev_state.eps[ep_abs_idx].ep_occupied = true;
487 }
488
489 return 0;
490 }
491
usb_dc_ep_disable(const uint8_t ep)492 int usb_dc_ep_disable(const uint8_t ep)
493 {
494 uint8_t ep_abs_idx = EP_ABS_IDX(ep);
495 usb_status_t status;
496
497 if (ep_abs_idx >= NUM_OF_EP_MAX) {
498 LOG_ERR("Wrong endpoint index/address");
499 return -EINVAL;
500 }
501
502 if (dev_state.dev_struct.controllerHandle != NULL) {
503 status = dev_state.dev_struct.controllerInterface->deviceCancel(
504 dev_state.dev_struct.controllerHandle,
505 ep);
506 if (kStatus_USB_Success != status) {
507 LOG_ERR("Failed to disable ep 0x%02x", ep);
508 return -EIO;
509 }
510 }
511
512 dev_state.eps[ep_abs_idx].ep_enabled = false;
513 dev_state.eps[ep_abs_idx].ep_occupied = false;
514
515 return 0;
516 }
517
usb_dc_ep_flush(const uint8_t ep)518 int usb_dc_ep_flush(const uint8_t ep)
519 {
520 uint8_t ep_abs_idx = EP_ABS_IDX(ep);
521
522 if (ep_abs_idx >= NUM_OF_EP_MAX) {
523 LOG_ERR("Wrong endpoint index/address");
524 return -EINVAL;
525 }
526
527 LOG_DBG("Not implemented, idx 0x%02x, ep %u", ep_abs_idx, ep);
528
529 return 0;
530 }
531
usb_dc_ep_write(const uint8_t ep,const uint8_t * const data,const uint32_t data_len,uint32_t * const ret_bytes)532 int usb_dc_ep_write(const uint8_t ep, const uint8_t *const data,
533 const uint32_t data_len, uint32_t *const ret_bytes)
534 {
535 uint8_t ep_abs_idx = EP_ABS_IDX(ep);
536 uint8_t *buffer;
537 uint32_t len_to_send = data_len;
538 usb_status_t status;
539
540 if (ep_abs_idx >= NUM_OF_EP_MAX) {
541 LOG_ERR("Wrong endpoint index/address");
542 return -EINVAL;
543 }
544
545 if (USB_EP_GET_DIR(ep) != USB_EP_DIR_IN) {
546 LOG_ERR("Wrong endpoint direction");
547 return -EINVAL;
548 }
549
550 /* Copy the data for SoC's that do not have a USB RAM
551 * as the SDK driver will copy the data into USB RAM,
552 * if available.
553 */
554 #ifndef CONFIG_USB_DC_NXP_LPCIP3511
555 buffer = (uint8_t *)dev_state.eps[ep_abs_idx].block;
556
557 if (data_len > dev_state.eps[ep_abs_idx].ep_mps) {
558 len_to_send = dev_state.eps[ep_abs_idx].ep_mps;
559 }
560
561 for (uint32_t n = 0; n < len_to_send; n++) {
562 buffer[n] = data[n];
563 }
564 #else
565 buffer = (uint8_t *)data;
566 #endif
567
568 #if defined(CONFIG_HAS_MCUX_CACHE) && !defined(EP_BUF_NONCACHED)
569 DCACHE_CleanByRange((uint32_t)buffer, len_to_send);
570 #endif
571 status = dev_state.dev_struct.controllerInterface->deviceSend(
572 dev_state.dev_struct.controllerHandle,
573 ep, buffer, len_to_send);
574 if (kStatus_USB_Success != status) {
575 LOG_ERR("Failed to fill ep 0x%02x buffer", ep);
576 return -EIO;
577 }
578
579 if (ret_bytes) {
580 *ret_bytes = len_to_send;
581 }
582
583 return 0;
584 }
585
update_control_stage(usb_device_callback_message_struct_t * cb_msg,uint32_t data_len,uint32_t max_data_len)586 static void update_control_stage(usb_device_callback_message_struct_t *cb_msg,
587 uint32_t data_len, uint32_t max_data_len)
588 {
589 struct usb_setup_packet *usbd_setup;
590
591 usbd_setup = (struct usb_setup_packet *)cb_msg->buffer;
592
593 if (cb_msg->isSetup) {
594 if (usbd_setup->wLength == 0) {
595 dev_state.setup_data_stage = SETUP_DATA_STAGE_DONE;
596 } else if (usb_reqtype_is_to_host(usbd_setup)) {
597 dev_state.setup_data_stage = SETUP_DATA_STAGE_IN;
598 } else {
599 dev_state.setup_data_stage = SETUP_DATA_STAGE_OUT;
600 }
601 } else {
602 if (dev_state.setup_data_stage != SETUP_DATA_STAGE_DONE) {
603 if ((data_len >= max_data_len) ||
604 (data_len < dev_state.eps[0].ep_mps)) {
605 dev_state.setup_data_stage = SETUP_DATA_STAGE_DONE;
606 }
607 }
608 }
609 }
610
usb_dc_ep_read_wait(uint8_t ep,uint8_t * data,uint32_t max_data_len,uint32_t * read_bytes)611 int usb_dc_ep_read_wait(uint8_t ep, uint8_t *data, uint32_t max_data_len,
612 uint32_t *read_bytes)
613 {
614 uint8_t ep_abs_idx = EP_ABS_IDX(ep);
615 uint32_t data_len;
616 uint8_t *bufp = NULL;
617
618 if (dev_state.eps[ep_abs_idx].ep_occupied) {
619 LOG_ERR("Endpoint is occupied by the controller");
620 return -EBUSY;
621 }
622
623 if ((ep_abs_idx >= NUM_OF_EP_MAX) ||
624 (USB_EP_GET_DIR(ep) != USB_EP_DIR_OUT)) {
625 LOG_ERR("Wrong endpoint index/address/direction");
626 return -EINVAL;
627 }
628
629 /* Allow to read 0 bytes */
630 if (!data && max_data_len) {
631 LOG_ERR("Wrong arguments");
632 return -EINVAL;
633 }
634
635 /*
636 * It is control setup, we should use message.buffer,
637 * this buffer is from internal setup array.
638 */
639 bufp = dev_state.eps[ep_abs_idx].transfer_message.buffer;
640 data_len = dev_state.eps[ep_abs_idx].transfer_message.length;
641 if (data_len == USB_UNINITIALIZED_VAL_32) {
642 if (read_bytes) {
643 *read_bytes = 0;
644 }
645 return -EINVAL;
646 }
647
648 if (!data && !max_data_len) {
649 /* When both buffer and max data to read are zero return the
650 * available data in buffer.
651 */
652 if (read_bytes) {
653 *read_bytes = data_len;
654 }
655 return 0;
656 }
657
658 if (data_len > max_data_len) {
659 LOG_WRN("Not enough room to copy all the data!");
660 data_len = max_data_len;
661 }
662
663 if (data != NULL) {
664 for (uint32_t i = 0; i < data_len; i++) {
665 data[i] = bufp[i];
666 }
667 }
668
669 if (read_bytes) {
670 *read_bytes = data_len;
671 }
672
673 if (USB_EP_GET_IDX(ep) == USB_ENDPOINT_CONTROL) {
674 update_control_stage(&dev_state.eps[0].transfer_message,
675 data_len, max_data_len);
676 }
677
678 return 0;
679 }
680
usb_dc_ep_read_continue(uint8_t ep)681 int usb_dc_ep_read_continue(uint8_t ep)
682 {
683 uint8_t ep_abs_idx = EP_ABS_IDX(ep);
684 usb_status_t status;
685
686 if (ep_abs_idx >= NUM_OF_EP_MAX ||
687 USB_EP_GET_DIR(ep) != USB_EP_DIR_OUT) {
688 LOG_ERR("Wrong endpoint index/address/direction");
689 return -EINVAL;
690 }
691
692 if (dev_state.eps[ep_abs_idx].ep_occupied) {
693 LOG_WRN("endpoint 0x%x already occupied", ep);
694 return -EBUSY;
695 }
696
697 if (USB_EP_GET_IDX(ep) == USB_ENDPOINT_CONTROL) {
698 if (dev_state.setup_data_stage == SETUP_DATA_STAGE_DONE) {
699 return 0;
700 }
701
702 if (dev_state.setup_data_stage == SETUP_DATA_STAGE_IN) {
703 dev_state.setup_data_stage = SETUP_DATA_STAGE_DONE;
704 }
705 }
706
707 status = dev_state.dev_struct.controllerInterface->deviceRecv(
708 dev_state.dev_struct.controllerHandle, ep,
709 (uint8_t *)dev_state.eps[ep_abs_idx].block,
710 dev_state.eps[ep_abs_idx].ep_mps);
711 if (kStatus_USB_Success != status) {
712 LOG_ERR("Failed to enable reception on ep 0x%02x", ep);
713 return -EIO;
714 }
715
716 dev_state.eps[ep_abs_idx].ep_occupied = true;
717
718 return 0;
719 }
720
usb_dc_ep_read(const uint8_t ep,uint8_t * const data,const uint32_t max_data_len,uint32_t * const read_bytes)721 int usb_dc_ep_read(const uint8_t ep, uint8_t *const data,
722 const uint32_t max_data_len, uint32_t *const read_bytes)
723 {
724 int retval = usb_dc_ep_read_wait(ep, data, max_data_len, read_bytes);
725
726 if (retval) {
727 return retval;
728 }
729
730 if (!data && !max_data_len) {
731 /*
732 * When both buffer and max data to read are zero the above
733 * call would fetch the data len and we simply return.
734 */
735 return 0;
736 }
737
738 return usb_dc_ep_read_continue(ep);
739 }
740
usb_dc_ep_set_callback(const uint8_t ep,const usb_dc_ep_callback cb)741 int usb_dc_ep_set_callback(const uint8_t ep, const usb_dc_ep_callback cb)
742 {
743 uint8_t ep_abs_idx = EP_ABS_IDX(ep);
744
745 if (ep_abs_idx >= NUM_OF_EP_MAX) {
746 LOG_ERR("Wrong endpoint index/address");
747 return -EINVAL;
748 }
749
750 if (!dev_state.attached) {
751 return -EINVAL;
752 }
753 dev_state.eps[ep_abs_idx].callback = cb;
754
755 return 0;
756 }
757
usb_dc_set_status_callback(const usb_dc_status_callback cb)758 void usb_dc_set_status_callback(const usb_dc_status_callback cb)
759 {
760 dev_state.status_cb = cb;
761 }
762
usb_dc_ep_mps(const uint8_t ep)763 int usb_dc_ep_mps(const uint8_t ep)
764 {
765 uint8_t ep_abs_idx = EP_ABS_IDX(ep);
766
767 if (ep_abs_idx >= NUM_OF_EP_MAX) {
768 LOG_ERR("Wrong endpoint index/address");
769 return -EINVAL;
770 }
771
772 return dev_state.eps[ep_abs_idx].ep_mps;
773 }
774
handle_bus_reset(void)775 static void handle_bus_reset(void)
776 {
777 usb_device_endpoint_init_struct_t ep_init;
778 uint8_t ep_abs_idx = 0;
779 usb_status_t status;
780
781 dev_state.dev_struct.deviceAddress = 0;
782 status = dev_state.dev_struct.controllerInterface->deviceControl(
783 dev_state.dev_struct.controllerHandle,
784 kUSB_DeviceControlSetDefaultStatus, NULL);
785 if (kStatus_USB_Success != status) {
786 LOG_ERR("Failed to set default status");
787 }
788
789 for (int i = 0; i < NUM_OF_EP_MAX; i++) {
790 dev_state.eps[i].ep_occupied = false;
791 dev_state.eps[i].ep_enabled = false;
792 }
793
794 ep_init.zlt = 0U;
795 ep_init.transferType = USB_ENDPOINT_CONTROL;
796 ep_init.maxPacketSize = USB_CONTROL_EP_MPS;
797 ep_init.endpointAddress = USB_CONTROL_EP_OUT;
798
799 ep_abs_idx = EP_ABS_IDX(ep_init.endpointAddress);
800 dev_state.eps[ep_abs_idx].ep_mps = USB_CONTROL_EP_MPS;
801
802 status = dev_state.dev_struct.controllerInterface->deviceControl(
803 dev_state.dev_struct.controllerHandle,
804 kUSB_DeviceControlEndpointInit, &ep_init);
805 if (kStatus_USB_Success != status) {
806 LOG_ERR("Failed to initialize control OUT endpoint");
807 }
808
809 dev_state.eps[ep_abs_idx].ep_occupied = false;
810 dev_state.eps[ep_abs_idx].ep_enabled = true;
811
812 ep_init.endpointAddress = USB_CONTROL_EP_IN;
813 ep_abs_idx = EP_ABS_IDX(ep_init.endpointAddress);
814 dev_state.eps[ep_abs_idx].ep_mps = USB_CONTROL_EP_MPS;
815 status = dev_state.dev_struct.controllerInterface->deviceControl(
816 dev_state.dev_struct.controllerHandle,
817 kUSB_DeviceControlEndpointInit, &ep_init);
818 if (kStatus_USB_Success != status) {
819 LOG_ERR("Failed to initialize control IN endpoint");
820 }
821
822 dev_state.eps[ep_abs_idx].ep_occupied = false;
823 dev_state.eps[ep_abs_idx].ep_enabled = true;
824 }
825
handle_transfer_msg(usb_device_callback_message_struct_t * cb_msg)826 static void handle_transfer_msg(usb_device_callback_message_struct_t *cb_msg)
827 {
828 uint8_t ep_status_code = 0;
829 uint8_t ep = cb_msg->code;
830 uint8_t ep_abs_idx = EP_ABS_IDX(ep);
831 usb_status_t status;
832
833 dev_state.eps[ep_abs_idx].ep_occupied = false;
834
835 if (cb_msg->length == UINT32_MAX) {
836 /*
837 * Probably called from USB_DeviceEhciCancel()
838 * LOG_WRN("Drop message for ep 0x%02x", ep);
839 */
840 return;
841 }
842
843 if (cb_msg->isSetup) {
844 ep_status_code = USB_DC_EP_SETUP;
845 } else {
846 /* IN TOKEN */
847 if (USB_EP_DIR_IS_IN(ep)) {
848 if ((dev_state.dev_struct.deviceAddress != 0) && (ep_abs_idx == 1)) {
849 /*
850 * Set Address in the status stage in
851 * the IN transfer.
852 */
853 status = dev_state.dev_struct.controllerInterface->deviceControl(
854 dev_state.dev_struct.controllerHandle,
855 kUSB_DeviceControlSetDeviceAddress,
856 &dev_state.dev_struct.deviceAddress);
857 if (kStatus_USB_Success != status) {
858 LOG_ERR("Failed to set device address");
859 return;
860 }
861 dev_state.dev_struct.deviceAddress = 0;
862 }
863 ep_status_code = USB_DC_EP_DATA_IN;
864 }
865 /* OUT TOKEN */
866 else {
867 ep_status_code = USB_DC_EP_DATA_OUT;
868 }
869 }
870
871 if (dev_state.eps[ep_abs_idx].callback) {
872 #if defined(CONFIG_HAS_MCUX_CACHE) && !defined(EP_BUF_NONCACHED)
873 if (cb_msg->length) {
874 DCACHE_InvalidateByRange((uint32_t)cb_msg->buffer,
875 cb_msg->length);
876 }
877 #endif
878 dev_state.eps[ep_abs_idx].callback(ep, ep_status_code);
879 } else {
880 LOG_ERR("No cb pointer for endpoint 0x%02x", ep);
881 }
882 }
883
884 /**
885 * Similar to the kinetis driver, this thread is used to not run the USB device
886 * stack/endpoint callbacks in the ISR context. This is because callbacks from
887 * the USB stack may use mutexes, or other kernel functions not supported from
888 * an interrupt context.
889 */
usb_mcux_thread_main(void * arg1,void * arg2,void * arg3)890 static void usb_mcux_thread_main(void *arg1, void *arg2, void *arg3)
891 {
892 ARG_UNUSED(arg1);
893 ARG_UNUSED(arg2);
894 ARG_UNUSED(arg3);
895
896 uint8_t ep_abs_idx;
897 usb_device_callback_message_struct_t msg;
898
899 while (1) {
900 k_msgq_get(&usb_dc_msgq, &msg, K_FOREVER);
901 switch (msg.code) {
902 case kUSB_DeviceNotifyBusReset:
903 handle_bus_reset();
904 dev_state.status_cb(USB_DC_RESET, NULL);
905 break;
906 case kUSB_DeviceNotifyError:
907 dev_state.status_cb(USB_DC_ERROR, NULL);
908 break;
909 case kUSB_DeviceNotifySuspend:
910 dev_state.status_cb(USB_DC_SUSPEND, NULL);
911 break;
912 case kUSB_DeviceNotifyResume:
913 dev_state.status_cb(USB_DC_RESUME, NULL);
914 break;
915 default:
916 ep_abs_idx = EP_ABS_IDX(msg.code);
917
918 if (ep_abs_idx >= NUM_OF_EP_MAX) {
919 LOG_ERR("Wrong endpoint index/address");
920 return;
921 }
922
923 memcpy(&dev_state.eps[ep_abs_idx].transfer_message, &msg,
924 sizeof(usb_device_callback_message_struct_t));
925 handle_transfer_msg(&dev_state.eps[ep_abs_idx].transfer_message);
926 }
927 }
928 }
929
930 /* Notify the up layer the KHCI status changed. */
USB_DeviceNotificationTrigger(void * handle,void * msg)931 usb_status_t USB_DeviceNotificationTrigger(void *handle, void *msg)
932 {
933 /* Submit to message queue */
934 k_msgq_put(&usb_dc_msgq,
935 (usb_device_callback_message_struct_t *)msg, K_NO_WAIT);
936 return kStatus_USB_Success;
937 }
938
usb_isr_handler(void)939 static void usb_isr_handler(void)
940 {
941 #if defined(CONFIG_USB_DC_NXP_EHCI)
942 USB_DeviceEhciIsrFunction(&dev_state);
943 #elif defined(CONFIG_USB_DC_NXP_LPCIP3511)
944 USB_DeviceLpcIp3511IsrFunction(&dev_state);
945 #endif
946 }
947
usb_mcux_init(void)948 static int usb_mcux_init(void)
949 {
950 int err;
951
952 k_thread_create(&dev_state.thread, dev_state.thread_stack,
953 CONFIG_USB_MCUX_THREAD_STACK_SIZE,
954 usb_mcux_thread_main, NULL, NULL, NULL,
955 K_PRIO_COOP(2), 0, K_NO_WAIT);
956 k_thread_name_set(&dev_state.thread, "usb_mcux");
957
958 PINCTRL_DT_INST_DEFINE(0);
959
960 /* Apply pinctrl state */
961 err = pinctrl_apply_state(PINCTRL_DT_INST_DEV_CONFIG_GET(0), PINCTRL_STATE_DEFAULT);
962 if (err) {
963 return err;
964 }
965
966 return 0;
967 }
968
969 SYS_INIT(usb_mcux_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);
970