Lines Matching +full:iso +full:- +full:out +full:- +full:mps

4  * SPDX-License-Identifier: Apache-2.0
40 /* Reserve DMA buffer for Setup/CTRL OUT/CTRL IN, required to be 8-byte aligned */
48 /* OUT transaction for specific EP completed */
52 /* Re-activate queued transfer for specific EP */
69 } out; member
93 /* NOTE: On USBD, Setup and CTRL OUT are not completely separated. CTRL OUT MXPLD
95 * OUT MXPLD immediately on its interrupt.
103 /* EP MPS */
105 uint16_t mps; member
132 * Allocate-only, and de-allocate all on re-initialize in udc_numaker_init().
138 * Allocate-only, and de-allocate all on re-initialize in udc_numaker_init().
156 /* Track end of CTRL DATA OUT/STATUS OUT stage
158 * net_buf can over-allocate for UDC_BUF_GRANULARITY requirement
167 const struct udc_numaker_config *config = dev->config; in numaker_usbd_sw_connect()
168 USBD_T *const base = config->base; in numaker_usbd_sw_connect()
171 base->INTSTS = base->INTSTS; in numaker_usbd_sw_connect()
174 base->INTEN = USBD_INT_BUS | USBD_INT_USB | USBD_INT_FLDET | USBD_INT_WAKEUP | USBD_INT_SOF; in numaker_usbd_sw_connect()
177 base->SE0 &= ~USBD_DRVSE0; in numaker_usbd_sw_connect()
182 const struct udc_numaker_config *config = dev->config; in numaker_usbd_sw_disconnect()
183 USBD_T *const base = config->base; in numaker_usbd_sw_disconnect()
186 base->SE0 |= USBD_DRVSE0; in numaker_usbd_sw_disconnect()
199 const struct udc_numaker_config *config = dev->config; in numaker_usbd_reset_addr()
201 USBD_T *const base = config->base; in numaker_usbd_reset_addr()
203 base->FADDR = 0; in numaker_usbd_reset_addr()
204 priv->addr = 0; in numaker_usbd_reset_addr()
209 const struct udc_numaker_config *config = dev->config; in numaker_usbd_set_addr()
211 USBD_T *const base = config->base; in numaker_usbd_set_addr()
213 if (base->FADDR != priv->addr) { in numaker_usbd_set_addr()
214 base->FADDR = priv->addr; in numaker_usbd_set_addr()
221 const struct udc_numaker_config *config = dev->config; in numaker_usbd_ep_base()
222 USBD_T *const base = config->base; in numaker_usbd_ep_base()
224 return base->EP + ep_hw_idx; in numaker_usbd_ep_base()
229 const struct device *dev = ep_cur->dev; in numaker_usbd_ep_sync_udc_halt()
232 __ASSERT_NO_MSG(ep_cur->addr_valid); in numaker_usbd_ep_sync_udc_halt()
233 ep_cfg = udc_get_ep_cfg(dev, ep_cur->addr); in numaker_usbd_ep_sync_udc_halt()
234 ep_cfg->stat.halted = stalled; in numaker_usbd_ep_sync_udc_halt()
239 const struct device *dev = ep_cur->dev; in numaker_usbd_ep_set_stall()
240 USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); in numaker_usbd_ep_set_stall()
243 ep_base->CFGP |= USBD_CFGP_SSTALL_Msk; in numaker_usbd_ep_set_stall()
250 const struct device *dev = ep_cur->dev; in numaker_usbd_ep_clear_stall_n_data_toggle()
251 USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); in numaker_usbd_ep_clear_stall_n_data_toggle()
254 ep_base->CFGP &= ~USBD_CFGP_SSTALL_Msk; in numaker_usbd_ep_clear_stall_n_data_toggle()
258 ep_base->CFG &= ~USBD_CFG_DSQSYNC_Msk; in numaker_usbd_ep_clear_stall_n_data_toggle()
266 err = k_msgq_put(priv->msgq, msg, K_NO_WAIT); in numaker_usbd_send_msg()
276 k_msgq_purge(priv->msgq); in numaker_usbd_send_msg()
278 err = k_msgq_put(priv->msgq, &msg_reconn, K_NO_WAIT); in numaker_usbd_send_msg()
289 const struct udc_numaker_config *config = dev->config; in numaker_usbd_hw_setup()
290 USBD_T *const base = config->base; in numaker_usbd_hw_setup()
295 if (!device_is_ready(config->reset.dev)) { in numaker_usbd_hw_setup()
297 return -ENODEV; in numaker_usbd_hw_setup()
303 SYS->USBPHY = (SYS->USBPHY & ~SYS_USBPHY_USBROLE_Msk) | in numaker_usbd_hw_setup()
309 scc_subsys.pcc.clk_modidx = config->clk_modidx; in numaker_usbd_hw_setup()
310 scc_subsys.pcc.clk_src = config->clk_src; in numaker_usbd_hw_setup()
311 scc_subsys.pcc.clk_div = config->clk_div; in numaker_usbd_hw_setup()
314 err = clock_control_on(config->clkctrl_dev, (clock_control_subsys_t)&scc_subsys); in numaker_usbd_hw_setup()
319 err = clock_control_configure(config->clkctrl_dev, (clock_control_subsys_t)&scc_subsys, in numaker_usbd_hw_setup()
326 err = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); in numaker_usbd_hw_setup()
334 reset_line_toggle_dt(&config->reset); in numaker_usbd_hw_setup()
338 base->ATTR = USBD_ATTR_BYTEM_Msk | BIT(9) | USBD_ATTR_DPPUEN_Msk | USBD_ATTR_USBEN_Msk | in numaker_usbd_hw_setup()
344 /* NOTE: Ignore DT maximum-speed with USBD fixed to full-speed */ in numaker_usbd_hw_setup()
347 config->irq_config_func(dev); in numaker_usbd_hw_setup()
358 const struct udc_numaker_config *config = dev->config; in numaker_usbd_hw_shutdown()
359 USBD_T *const base = config->base; in numaker_usbd_hw_shutdown()
365 config->irq_unconfig_func(dev); in numaker_usbd_hw_shutdown()
371 base->ATTR &= ~USBD_PHY_EN; in numaker_usbd_hw_shutdown()
376 scc_subsys.pcc.clk_modidx = config->clk_modidx; in numaker_usbd_hw_shutdown()
379 clock_control_off(config->clkctrl_dev, (clock_control_subsys_t)&scc_subsys); in numaker_usbd_hw_shutdown()
383 reset_line_toggle_dt(&config->reset); in numaker_usbd_hw_shutdown()
394 for (uint32_t i = 0ul; i < priv->ep_pool_size; i++) { in numaker_usbd_bus_reset_th()
397 /* Cancel EP on-going transaction */ in numaker_usbd_bus_reset_th()
398 ep_base->CFGP |= USBD_CFGP_CLRRDY_Msk; in numaker_usbd_bus_reset_th()
401 ep_base->CFGP &= ~USBD_CFGP_SSTALL_Msk; in numaker_usbd_bus_reset_th()
404 ep_base->CFG &= ~USBD_CFG_DSQSYNC_Msk; in numaker_usbd_bus_reset_th()
406 /* Except EP0/EP1 kept resident for CTRL OUT/IN, disable all other EPs */ in numaker_usbd_bus_reset_th()
408 ep_base->CFG = 0; in numaker_usbd_bus_reset_th()
418 const struct udc_numaker_config *config = dev->config; in numaker_usbd_buf_base()
419 USBD_T *const base = config->base; in numaker_usbd_buf_base()
427 const struct udc_numaker_config *config = dev->config; in numaker_usbd_setup_copy_to_user()
428 USBD_T *const base = config->base; in numaker_usbd_setup_copy_to_user()
431 dmabuf_addr = numaker_usbd_buf_base(dev) + (base->STBUFSEG & USBD_STBUFSEG_STBUFSEG_Msk); in numaker_usbd_setup_copy_to_user()
443 const struct device *dev = ep_cur->dev; in numaker_usbd_ep_copy_to_user()
444 USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); in numaker_usbd_ep_copy_to_user()
449 __ASSERT_NO_MSG(ep_cur->dmabuf_valid); in numaker_usbd_ep_copy_to_user()
451 dmabuf_addr = numaker_usbd_buf_base(dev) + ep_base->BUFSEG; in numaker_usbd_ep_copy_to_user()
453 /* NOTE: See comment on mxpld_ctrlout for why make one copy of CTRL OUT's MXPLD */ in numaker_usbd_ep_copy_to_user()
454 if (ep_cur->addr == USB_CONTROL_EP_OUT) { in numaker_usbd_ep_copy_to_user()
455 data_rmn = ep_cur->mxpld_ctrlout; in numaker_usbd_ep_copy_to_user()
457 data_rmn = ep_base->MXPLD; in numaker_usbd_ep_copy_to_user()
463 data_rmn -= *size_p; in numaker_usbd_ep_copy_to_user()
477 const struct device *dev = ep_cur->dev; in numaker_usbd_ep_copy_from_user()
478 USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); in numaker_usbd_ep_copy_from_user()
482 __ASSERT_NO_MSG(ep_cur->dmabuf_valid); in numaker_usbd_ep_copy_from_user()
483 __ASSERT_NO_MSG(ep_cur->mps_valid); in numaker_usbd_ep_copy_from_user()
484 __ASSERT_NO_MSG(ep_cur->mps <= ep_cur->dmabuf_size); in numaker_usbd_ep_copy_from_user()
486 dmabuf_addr = numaker_usbd_buf_base(dev) + ep_base->BUFSEG; in numaker_usbd_ep_copy_from_user()
488 *size_p = MIN(*size_p, ep_cur->mps); in numaker_usbd_ep_copy_from_user()
496 const struct device *dev = ep_cur->dev; in numaker_usbd_ep_config_dmabuf()
497 USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); in numaker_usbd_ep_config_dmabuf()
499 ep_base->BUFSEG = dmabuf_base; in numaker_usbd_ep_config_dmabuf()
501 ep_cur->dmabuf_valid = true; in numaker_usbd_ep_config_dmabuf()
502 ep_cur->dmabuf_base = dmabuf_base; in numaker_usbd_ep_config_dmabuf()
503 ep_cur->dmabuf_size = dmabuf_size; in numaker_usbd_ep_config_dmabuf()
508 const struct device *dev = ep_cur->dev; in numaker_usbd_ep_abort()
509 USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); in numaker_usbd_ep_abort()
511 /* Abort EP on-going transaction */ in numaker_usbd_ep_abort()
512 ep_base->CFGP |= USBD_CFGP_CLRRDY_Msk; in numaker_usbd_ep_abort()
514 if (ep_cur->addr_valid) { in numaker_usbd_ep_abort()
515 udc_ep_set_busy(dev, ep_cur->addr, false); in numaker_usbd_ep_abort()
523 const struct device *dev = ep_cur->dev; in numaker_usbd_ep_config_major()
524 USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); in numaker_usbd_ep_config_major()
526 ep_cur->mps_valid = true; in numaker_usbd_ep_config_major()
527 ep_cur->mps = ep_cfg->mps; in numaker_usbd_ep_config_major()
530 ep_cur->ep_hw_cfg = 0; in numaker_usbd_ep_config_major()
533 if ((ep_cfg->attributes & USB_EP_TRANSFER_TYPE_MASK) == USB_EP_TYPE_CONTROL) { in numaker_usbd_ep_config_major()
534 ep_cur->ep_hw_cfg |= USBD_CFG_CSTALL; in numaker_usbd_ep_config_major()
538 ep_cur->ep_hw_cfg &= ~USBD_CFG_DSQSYNC_Msk; in numaker_usbd_ep_config_major()
540 /* Endpoint IN/OUT, though, default to disabled */ in numaker_usbd_ep_config_major()
541 ep_cur->ep_hw_cfg |= USBD_CFG_EPMODE_DISABLE; in numaker_usbd_ep_config_major()
544 if ((ep_cfg->attributes & USB_EP_TRANSFER_TYPE_MASK) == USB_EP_TYPE_ISO) { in numaker_usbd_ep_config_major()
545 ep_cur->ep_hw_cfg |= USBD_CFG_TYPE_ISO; in numaker_usbd_ep_config_major()
549 ep_cur->ep_hw_cfg |= in numaker_usbd_ep_config_major()
550 (USB_EP_GET_IDX(ep_cfg->addr) << USBD_CFG_EPNUM_Pos) & USBD_CFG_EPNUM_Msk; in numaker_usbd_ep_config_major()
552 ep_base->CFG = ep_cur->ep_hw_cfg; in numaker_usbd_ep_config_major()
557 const struct device *dev = ep_cur->dev; in numaker_usbd_ep_enable()
558 USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); in numaker_usbd_ep_enable()
560 /* For safe, EP (re-)enable from clean state */ in numaker_usbd_ep_enable()
564 /* Enable EP to IN/OUT */ in numaker_usbd_ep_enable()
565 ep_cur->ep_hw_cfg &= ~USBD_CFG_STATE_Msk; in numaker_usbd_ep_enable()
566 if (USB_EP_DIR_IS_IN(ep_cur->addr)) { in numaker_usbd_ep_enable()
567 ep_cur->ep_hw_cfg |= USBD_CFG_EPMODE_IN; in numaker_usbd_ep_enable()
569 ep_cur->ep_hw_cfg |= USBD_CFG_EPMODE_OUT; in numaker_usbd_ep_enable()
572 ep_base->CFG = ep_cur->ep_hw_cfg; in numaker_usbd_ep_enable()
579 const struct device *dev = ep_cur->dev; in numaker_usbd_ep_disable()
580 USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); in numaker_usbd_ep_disable()
585 ep_cur->ep_hw_cfg = (ep_cur->ep_hw_cfg & ~USBD_CFG_STATE_Msk) | USBD_CFG_EPMODE_DISABLE; in numaker_usbd_ep_disable()
586 ep_base->CFG = ep_cur->ep_hw_cfg; in numaker_usbd_ep_disable()
592 const struct device *dev = ep_cur->dev; in udc_numaker_ep_trigger()
593 USBD_EP_T *ep_base = numaker_usbd_ep_base(dev, ep_cur->ep_hw_idx); in udc_numaker_ep_trigger()
595 if (ep_cur->addr_valid) { in udc_numaker_ep_trigger()
596 udc_ep_set_busy(dev, ep_cur->addr, true); in udc_numaker_ep_trigger()
599 ep_base->MXPLD = len; in udc_numaker_ep_trigger()
605 struct numaker_usbd_ep_mgmt *ep_mgmt = &priv->ep_mgmt; in numaker_usbd_ep_mgmt_alloc_ep()
608 if (ep_mgmt->ep_idx < priv->ep_pool_size) { in numaker_usbd_ep_mgmt_alloc_ep()
609 ep_cur = priv->ep_pool + ep_mgmt->ep_idx; in numaker_usbd_ep_mgmt_alloc_ep()
610 ep_mgmt->ep_idx++; in numaker_usbd_ep_mgmt_alloc_ep()
612 __ASSERT_NO_MSG(!ep_cur->valid); in numaker_usbd_ep_mgmt_alloc_ep()
615 ep_cur->valid = true; in numaker_usbd_ep_mgmt_alloc_ep()
623 * Return -ENOMEM on OOM error, or 0 on success with DMA buffer base/size (rounded up) allocated
628 const struct udc_numaker_config *config = dev->config; in numaker_usbd_ep_mgmt_alloc_dmabuf()
630 struct numaker_usbd_ep_mgmt *ep_mgmt = &priv->ep_mgmt; in numaker_usbd_ep_mgmt_alloc_dmabuf()
635 /* Required to be 8-byte aligned */ in numaker_usbd_ep_mgmt_alloc_dmabuf()
638 ep_mgmt->dmabuf_pos += size; in numaker_usbd_ep_mgmt_alloc_dmabuf()
639 if (ep_mgmt->dmabuf_pos > config->dmabuf_size) { in numaker_usbd_ep_mgmt_alloc_dmabuf()
640 ep_mgmt->dmabuf_pos -= size; in numaker_usbd_ep_mgmt_alloc_dmabuf()
641 return -ENOMEM; in numaker_usbd_ep_mgmt_alloc_dmabuf()
644 *dmabuf_base_p = ep_mgmt->dmabuf_pos - size; in numaker_usbd_ep_mgmt_alloc_dmabuf()
652 const struct udc_numaker_config *config = dev->config; in numaker_usbd_ep_mgmt_init()
654 USBD_T *const base = config->base; in numaker_usbd_ep_mgmt_init()
655 struct numaker_usbd_ep_mgmt *ep_mgmt = &priv->ep_mgmt; in numaker_usbd_ep_mgmt_init()
663 ep_cur = priv->ep_pool; in numaker_usbd_ep_mgmt_init()
664 ep_end = priv->ep_pool + priv->ep_pool_size; in numaker_usbd_ep_mgmt_init()
668 /* Zero-initialize */ in numaker_usbd_ep_mgmt_init()
672 ep_cur->dev = dev; in numaker_usbd_ep_mgmt_init()
675 ep_cur->ep_hw_idx = EP0 + (ep_cur - priv->ep_pool); in numaker_usbd_ep_mgmt_init()
678 /* Reserve 1st/2nd EP H/W contexts (BSP USBD driver EP0/EP1) for CTRL OUT/IN */ in numaker_usbd_ep_mgmt_init()
679 ep_mgmt->ep_idx = 2; in numaker_usbd_ep_mgmt_init()
681 /* Reserve DMA buffer for Setup/CTRL OUT/CTRL IN, starting from 0 */ in numaker_usbd_ep_mgmt_init()
682 ep_mgmt->dmabuf_pos = 0; in numaker_usbd_ep_mgmt_init()
685 base->STBUFSEG = ep_mgmt->dmabuf_pos; in numaker_usbd_ep_mgmt_init()
686 ep_mgmt->dmabuf_pos += NUMAKER_USBD_DMABUF_SIZE_SETUP; in numaker_usbd_ep_mgmt_init()
688 /* Reserve 1st EP H/W context (BSP USBD driver EP0) for CTRL OUT */ in numaker_usbd_ep_mgmt_init()
689 ep_cur = priv->ep_pool + 0; in numaker_usbd_ep_mgmt_init()
690 ep_cur->valid = true; in numaker_usbd_ep_mgmt_init()
691 ep_cur->addr_valid = true; in numaker_usbd_ep_mgmt_init()
692 ep_cur->addr = USB_EP_GET_ADDR(0, USB_EP_DIR_OUT); in numaker_usbd_ep_mgmt_init()
693 numaker_usbd_ep_config_dmabuf(ep_cur, ep_mgmt->dmabuf_pos, in numaker_usbd_ep_mgmt_init()
695 ep_mgmt->dmabuf_pos += NUMAKER_USBD_DMABUF_SIZE_CTRLOUT; in numaker_usbd_ep_mgmt_init()
696 ep_cur->mps_valid = true; in numaker_usbd_ep_mgmt_init()
697 ep_cur->mps = NUMAKER_USBD_DMABUF_SIZE_CTRLOUT; in numaker_usbd_ep_mgmt_init()
700 ep_cur = priv->ep_pool + 1; in numaker_usbd_ep_mgmt_init()
701 ep_cur->valid = true; in numaker_usbd_ep_mgmt_init()
702 ep_cur->addr_valid = true; in numaker_usbd_ep_mgmt_init()
703 ep_cur->addr = USB_EP_GET_ADDR(0, USB_EP_DIR_IN); in numaker_usbd_ep_mgmt_init()
704 numaker_usbd_ep_config_dmabuf(ep_cur, ep_mgmt->dmabuf_pos, NUMAKER_USBD_DMABUF_SIZE_CTRLIN); in numaker_usbd_ep_mgmt_init()
705 ep_mgmt->dmabuf_pos += NUMAKER_USBD_DMABUF_SIZE_CTRLIN; in numaker_usbd_ep_mgmt_init()
706 ep_cur->mps_valid = true; in numaker_usbd_ep_mgmt_init()
707 ep_cur->mps = NUMAKER_USBD_DMABUF_SIZE_CTRLIN; in numaker_usbd_ep_mgmt_init()
715 struct numaker_usbd_ep *ep_cur = priv->ep_pool; in numaker_usbd_ep_mgmt_find_ep()
716 struct numaker_usbd_ep *ep_end = priv->ep_pool + priv->ep_pool_size; in numaker_usbd_ep_mgmt_find_ep()
719 if (!ep_cur->valid) { in numaker_usbd_ep_mgmt_find_ep()
723 if (!ep_cur->addr_valid) { in numaker_usbd_ep_mgmt_find_ep()
727 if (ep == ep_cur->addr) { in numaker_usbd_ep_mgmt_find_ep()
749 ep_cur->addr = ep; in numaker_usbd_ep_mgmt_bind_ep()
750 ep_cur->addr_valid = true; in numaker_usbd_ep_mgmt_bind_ep()
754 __ASSERT_NO_MSG(ep_cur->valid); in numaker_usbd_ep_mgmt_bind_ep()
755 __ASSERT_NO_MSG(ep_cur->addr_valid); in numaker_usbd_ep_mgmt_bind_ep()
756 __ASSERT_NO_MSG(ep_cur->addr == ep); in numaker_usbd_ep_mgmt_bind_ep()
767 LOG_ERR("Invalid EP address 0x%02x for data out", ep); in numaker_usbd_xfer_out()
768 return -EINVAL; in numaker_usbd_xfer_out()
774 return -EAGAIN; in numaker_usbd_xfer_out()
784 return -ENODATA; in numaker_usbd_xfer_out()
794 return -ENODEV; in numaker_usbd_xfer_out()
797 udc_numaker_ep_trigger(ep_cur, ep_cur->mps); in numaker_usbd_xfer_out()
810 return -EINVAL; in numaker_usbd_xfer_in()
816 return -EAGAIN; in numaker_usbd_xfer_in()
826 return -ENODATA; in numaker_usbd_xfer_in()
836 return -ENODEV; in numaker_usbd_xfer_in()
839 data_len = buf->len; in numaker_usbd_xfer_in()
841 numaker_usbd_ep_copy_from_user(ep_cur, buf->data, &data_len); in numaker_usbd_xfer_in()
864 return -ENODEV; in numaker_usbd_ctrl_feed_dout()
870 return -ENOMEM; in numaker_usbd_ctrl_feed_dout()
872 priv->ctrlout_tailroom = length; in numaker_usbd_ctrl_feed_dout()
874 k_fifo_put(&ep_cfg->fifo, buf); in numaker_usbd_ctrl_feed_dout()
876 return numaker_usbd_xfer_out(dev, ep_cfg->addr, true); in numaker_usbd_ctrl_feed_dout()
888 __ASSERT_NO_MSG(msg->type == NUMAKER_USBD_MSG_TYPE_SETUP); in numaker_usbd_msg_handle_setup()
896 return -ENODEV; in numaker_usbd_msg_handle_setup()
899 /* We should have reserved 1st/2nd EP H/W contexts for CTRL OUT/IN */ in numaker_usbd_msg_handle_setup()
900 __ASSERT_NO_MSG(ep_cur->addr == USB_CONTROL_EP_OUT); in numaker_usbd_msg_handle_setup()
901 __ASSERT_NO_MSG((ep_cur + 1)->addr == USB_CONTROL_EP_IN); in numaker_usbd_msg_handle_setup()
903 /* Abort previous CTRL OUT/IN */ in numaker_usbd_msg_handle_setup()
907 /* CTRL OUT/IN reset to unstalled by H/W on receive of Setup packet */ in numaker_usbd_msg_handle_setup()
914 return -ENOMEM; in numaker_usbd_msg_handle_setup()
926 /* Allocate and feed buffer for DATA OUT stage */ in numaker_usbd_msg_handle_setup()
928 if (err == -ENOMEM) { in numaker_usbd_msg_handle_setup()
940 /* Message handler for DATA OUT transaction completed */
952 __ASSERT_NO_MSG(msg->type == NUMAKER_USBD_MSG_TYPE_OUT); in numaker_usbd_msg_handle_out()
954 ep = msg->out.ep; in numaker_usbd_msg_handle_out()
962 return -ENODEV; in numaker_usbd_msg_handle_out()
968 return -ENODATA; in numaker_usbd_msg_handle_out()
972 __ASSERT_NO_MSG(net_buf_tailroom(buf) >= priv->ctrlout_tailroom); in numaker_usbd_msg_handle_out()
973 data_len = priv->ctrlout_tailroom; in numaker_usbd_msg_handle_out()
981 __ASSERT_NO_MSG(priv->ctrlout_tailroom >= data_len); in numaker_usbd_msg_handle_out()
982 priv->ctrlout_tailroom -= data_len; in numaker_usbd_msg_handle_out()
987 return -ENOBUFS; in numaker_usbd_msg_handle_out()
990 /* CTRL DATA OUT/STATUS OUT stage completed */ in numaker_usbd_msg_handle_out()
991 if (ep == USB_CONTROL_EP_OUT && priv->ctrlout_tailroom != 0) { in numaker_usbd_msg_handle_out()
1000 /* s-in-status finished */ in numaker_usbd_msg_handle_out()
1003 LOG_ERR("udc_ctrl_submit_status failed for s-in-status: %d", err); in numaker_usbd_msg_handle_out()
1014 LOG_ERR("udc_ctrl_submit_s_out_status failed for s-out-status: %d", in numaker_usbd_msg_handle_out()
1028 /* Continue with next DATA OUT transaction on request */ in numaker_usbd_msg_handle_out()
1042 __ASSERT_NO_MSG(msg->type == NUMAKER_USBD_MSG_TYPE_IN); in numaker_usbd_msg_handle_in()
1044 ep = msg->in.ep; in numaker_usbd_msg_handle_in()
1052 return -ENODEV; in numaker_usbd_msg_handle_in()
1061 if (buf->len || udc_ep_buf_has_zlp(buf)) { in numaker_usbd_msg_handle_in()
1070 /* s-out-status/s-status finished */ in numaker_usbd_msg_handle_in()
1073 LOG_ERR("udc_ctrl_submit_status failed for s-out-status/s-status: " in numaker_usbd_msg_handle_in()
1087 /* Allocate and feed buffer for STATUS OUT stage */ in numaker_usbd_msg_handle_in()
1090 LOG_ERR("ctrl_feed_dout failed for status out: %d", err); in numaker_usbd_msg_handle_in()
1109 /* Message handler for queued transfer re-activated */
1114 __ASSERT_NO_MSG(msg->type == NUMAKER_USBD_MSG_TYPE_XFER); in numaker_usbd_msg_handle_xfer()
1116 ep = msg->xfer.ep; in numaker_usbd_msg_handle_xfer()
1130 __ASSERT_NO_MSG(msg->type == NUMAKER_USBD_MSG_TYPE_SW_RECONN); in numaker_usbd_msg_handle_sw_reconn()
1145 if (k_msgq_get(priv->msgq, &msg, K_FOREVER)) { in numaker_usbd_msg_handler()
1188 const struct udc_numaker_config *config = dev->config; in numaker_udbd_isr()
1190 USBD_T *const base = config->base; in numaker_udbd_isr()
1194 uint32_t volatile usbd_intsts = base->INTSTS; in numaker_udbd_isr()
1195 uint32_t volatile usbd_bus_state = base->ATTR; in numaker_udbd_isr()
1197 /* USB plug-in/unplug */ in numaker_udbd_isr()
1200 base->INTSTS = USBD_INTSTS_FLDET; in numaker_udbd_isr()
1202 if (base->VBUSDET & USBD_VBUSDET_VBUSDET_Msk) { in numaker_udbd_isr()
1203 /* USB plug-in */ in numaker_udbd_isr()
1206 base->ATTR |= USBD_ATTR_USBEN_Msk | USBD_ATTR_PHYEN_Msk; in numaker_udbd_isr()
1208 /* UDC stack would handle bottom-half processing */ in numaker_udbd_isr()
1211 LOG_DBG("USB plug-in"); in numaker_udbd_isr()
1216 base->ATTR &= ~USBD_USB_EN; in numaker_udbd_isr()
1218 /* UDC stack would handle bottom-half processing */ in numaker_udbd_isr()
1225 /* USB wake-up */ in numaker_udbd_isr()
1228 base->INTSTS = USBD_INTSTS_WAKEUP; in numaker_udbd_isr()
1230 LOG_DBG("USB wake-up"); in numaker_udbd_isr()
1236 base->INTSTS = USBD_INTSTS_BUS; in numaker_udbd_isr()
1242 base->ATTR |= USBD_ATTR_USBEN_Msk | USBD_ATTR_PHYEN_Msk; in numaker_udbd_isr()
1247 /* UDC stack would handle bottom-half processing, in numaker_udbd_isr()
1249 * un-configure device (udc_ep_disable), etc. in numaker_udbd_isr()
1257 base->ATTR &= ~USBD_PHY_EN; in numaker_udbd_isr()
1259 /* UDC stack would handle bottom-half processing */ in numaker_udbd_isr()
1266 base->ATTR |= USBD_ATTR_USBEN_Msk | USBD_ATTR_PHYEN_Msk; in numaker_udbd_isr()
1268 /* UDC stack would handle bottom-half processing */ in numaker_udbd_isr()
1278 base->INTSTS = USBD_INTSTS_SOFIF_Msk; in numaker_udbd_isr()
1280 /* UDC stack would handle bottom-half processing */ in numaker_udbd_isr()
1294 base->INTSTS = USBD_INTSTS_SETUP; in numaker_udbd_isr()
1296 /* Clear the data IN/OUT ready flag of control endpoints */ in numaker_udbd_isr()
1297 ep0_base->CFGP |= USBD_CFGP_CLRRDY_Msk; in numaker_udbd_isr()
1298 ep1_base->CFGP |= USBD_CFGP_CLRRDY_Msk; in numaker_udbd_isr()
1303 ep0_base->CFG |= USBD_CFG_DSQSYNC_Msk; in numaker_udbd_isr()
1304 ep1_base->CFG |= USBD_CFG_DSQSYNC_Msk; in numaker_udbd_isr()
1306 /* Message for bottom-half processing */ in numaker_udbd_isr()
1308 * CTRL OUT EP in numaker_udbd_isr()
1316 epintsts = base->EPINTSTS; in numaker_udbd_isr()
1318 base->EPINTSTS = epintsts; in numaker_udbd_isr()
1329 * CTRL/BULK/INT or no-ACK for Iso), that is, no need to check EPSTS0, in numaker_udbd_isr()
1334 ep_dir = ((ep_base->CFG & USBD_CFG_STATE_Msk) == USBD_CFG_EPMODE_IN) in numaker_udbd_isr()
1337 ep_idx = (ep_base->CFG & USBD_CFG_EPNUM_Msk) >> USBD_CFG_EPNUM_Pos; in numaker_udbd_isr()
1348 * CTRL OUT's MXPLD in numaker_udbd_isr()
1351 struct numaker_usbd_ep *ep_ctrlout = priv->ep_pool + 0; in numaker_udbd_isr()
1353 numaker_usbd_ep_base(dev, ep_ctrlout->ep_hw_idx); in numaker_udbd_isr()
1355 ep_ctrlout->mxpld_ctrlout = ep_ctrlout_base->MXPLD; in numaker_udbd_isr()
1358 /* Message for bottom-half processing */ in numaker_udbd_isr()
1361 msg.out.ep = ep; in numaker_udbd_isr()
1388 if (!ep_cfg->stat.halted) { in udc_numaker_ep_enqueue()
1390 msg.xfer.ep = ep_cfg->addr; in udc_numaker_ep_enqueue()
1403 ep_cur = numaker_usbd_ep_mgmt_bind_ep(dev, ep_cfg->addr); in udc_numaker_ep_dequeue()
1405 LOG_ERR("Bind EP H/W context: ep=0x%02x", ep_cfg->addr); in udc_numaker_ep_dequeue()
1406 return -ENODEV; in udc_numaker_ep_dequeue()
1411 buf = udc_buf_get_all(dev, ep_cfg->addr); in udc_numaker_ep_dequeue()
1413 udc_submit_ep_event(dev, buf, -ECONNABORTED); in udc_numaker_ep_dequeue()
1423 LOG_DBG("Set halt ep 0x%02x", ep_cfg->addr); in udc_numaker_ep_set_halt()
1426 ep_cur = numaker_usbd_ep_mgmt_bind_ep(dev, ep_cfg->addr); in udc_numaker_ep_set_halt()
1428 LOG_ERR("Bind EP H/W context: ep=0x%02x", ep_cfg->addr); in udc_numaker_ep_set_halt()
1429 return -ENODEV; in udc_numaker_ep_set_halt()
1443 LOG_DBG("Clear halt ep 0x%02x", ep_cfg->addr); in udc_numaker_ep_clear_halt()
1446 ep_cur = numaker_usbd_ep_mgmt_bind_ep(dev, ep_cfg->addr); in udc_numaker_ep_clear_halt()
1448 LOG_ERR("Bind EP H/W context: ep=0x%02x", ep_cfg->addr); in udc_numaker_ep_clear_halt()
1449 return -ENODEV; in udc_numaker_ep_clear_halt()
1457 msg.xfer.ep = ep_cfg->addr; in udc_numaker_ep_clear_halt()
1470 LOG_DBG("Enable ep 0x%02x", ep_cfg->addr); in udc_numaker_ep_enable()
1473 ep_cur = numaker_usbd_ep_mgmt_bind_ep(dev, ep_cfg->addr); in udc_numaker_ep_enable()
1475 LOG_ERR("Bind EP H/W context: ep=0x%02x", ep_cfg->addr); in udc_numaker_ep_enable()
1476 return -ENODEV; in udc_numaker_ep_enable()
1480 if (!ep_cur->dmabuf_valid || ep_cur->dmabuf_size < ep_cfg->mps) { in udc_numaker_ep_enable()
1482 err = numaker_usbd_ep_mgmt_alloc_dmabuf(dev, ep_cfg->mps, &dmabuf_base, in udc_numaker_ep_enable()
1506 LOG_DBG("Disable ep 0x%02x", ep_cfg->addr); in udc_numaker_ep_disable()
1509 ep_cur = numaker_usbd_ep_mgmt_bind_ep(dev, ep_cfg->addr); in udc_numaker_ep_disable()
1511 LOG_ERR("Bind EP H/W context: ep=0x%02x", ep_cfg->addr); in udc_numaker_ep_disable()
1512 return -ENODEV; in udc_numaker_ep_disable()
1523 const struct udc_numaker_config *config = dev->config; in udc_numaker_host_wakeup()
1524 USBD_T *const base = config->base; in udc_numaker_host_wakeup()
1527 base->ATTR |= USBD_ATTR_USBEN_Msk | USBD_ATTR_PHYEN_Msk; in udc_numaker_host_wakeup()
1530 base->ATTR |= USBD_ATTR_RWAKEUP_Msk; in udc_numaker_host_wakeup()
1532 base->ATTR ^= USBD_ATTR_RWAKEUP_Msk; in udc_numaker_host_wakeup()
1544 * in-between SET_ADDRESS control transfer and next transfer. For this, it is done in in udc_numaker_set_address()
1547 priv->addr = addr; in udc_numaker_set_address()
1591 return -EIO; in udc_numaker_init()
1596 return -EIO; in udc_numaker_init()
1608 return -EIO; in udc_numaker_shutdown()
1613 return -EIO; in udc_numaker_shutdown()
1620 k_msgq_purge(priv->msgq); in udc_numaker_shutdown()
1637 const struct udc_numaker_config *config = dev->config; in udc_numaker_driver_preinit()
1638 struct udc_data *data = dev->data; in udc_numaker_driver_preinit()
1641 data->caps.rwup = true; in udc_numaker_driver_preinit()
1642 data->caps.addr_before_status = true; in udc_numaker_driver_preinit()
1643 data->caps.mps0 = UDC_MPS0_64; in udc_numaker_driver_preinit()
1645 /* Some soc series don't allow ISO IN/OUT to be assigned the same EP number. in udc_numaker_driver_preinit()
1646 * This is addressed by limiting all OUT/IN EP addresses in top/bottom halves, in udc_numaker_driver_preinit()
1647 * except CTRL OUT/IN. in udc_numaker_driver_preinit()
1650 for (int i = 0; i < config->ep_cfg_out_size; i++) { in udc_numaker_driver_preinit()
1651 /* Limit all OUT EP numbers to 0, 1~7 */ in udc_numaker_driver_preinit()
1652 if (config->disallow_iso_inout_same && i != 0 && i >= 8) { in udc_numaker_driver_preinit()
1656 config->ep_cfg_out[i].caps.out = 1; in udc_numaker_driver_preinit()
1658 config->ep_cfg_out[i].caps.control = 1; in udc_numaker_driver_preinit()
1659 config->ep_cfg_out[i].caps.mps = 64; in udc_numaker_driver_preinit()
1661 config->ep_cfg_out[i].caps.bulk = 1; in udc_numaker_driver_preinit()
1662 config->ep_cfg_out[i].caps.interrupt = 1; in udc_numaker_driver_preinit()
1663 config->ep_cfg_out[i].caps.iso = 1; in udc_numaker_driver_preinit()
1664 config->ep_cfg_out[i].caps.mps = 1023; in udc_numaker_driver_preinit()
1667 config->ep_cfg_out[i].addr = USB_EP_DIR_OUT | i; in udc_numaker_driver_preinit()
1668 err = udc_register_ep(dev, &config->ep_cfg_out[i]); in udc_numaker_driver_preinit()
1675 for (int i = 0; i < config->ep_cfg_in_size; i++) { in udc_numaker_driver_preinit()
1677 if (config->disallow_iso_inout_same && i != 0 && i < 8) { in udc_numaker_driver_preinit()
1681 config->ep_cfg_in[i].caps.in = 1; in udc_numaker_driver_preinit()
1683 config->ep_cfg_in[i].caps.control = 1; in udc_numaker_driver_preinit()
1684 config->ep_cfg_in[i].caps.mps = 64; in udc_numaker_driver_preinit()
1686 config->ep_cfg_in[i].caps.bulk = 1; in udc_numaker_driver_preinit()
1687 config->ep_cfg_in[i].caps.interrupt = 1; in udc_numaker_driver_preinit()
1688 config->ep_cfg_in[i].caps.iso = 1; in udc_numaker_driver_preinit()
1689 config->ep_cfg_in[i].caps.mps = 1023; in udc_numaker_driver_preinit()
1692 config->ep_cfg_in[i].addr = USB_EP_DIR_IN | i; in udc_numaker_driver_preinit()
1693 err = udc_register_ep(dev, &config->ep_cfg_in[i]); in udc_numaker_driver_preinit()
1700 config->make_thread(dev); in udc_numaker_driver_preinit()
1752 k_thread_create(&priv->thread_data, udc_numaker_stack_##inst, \
1757 k_thread_name_set(&priv->thread_data, dev->name); \