gk7205v200-uboot/drivers/usb/gadget/udc3/usb3_pcd_intr.c
2025-08-07 17:13:54 +08:00

148 lines
3.3 KiB
C
Executable File

#include "usb3_drv.h"
#include "usb3_pcd.h"
static void handle_usb_reset_intr(usb3_pcd_t *pcd)
{
usb3_pcd_ep_t *ep;
/* Clear stall on each EP */
ep = &pcd->in_ep;
if (ep->stopped)
usb3_ep_clear_stall(pcd, ep);
ep = &pcd->out_ep;
if (ep->stopped)
usb3_ep_clear_stall(pcd, ep);
/* Set Device Address to 0 */
usb3_set_address(pcd, 0);
pcd->ltm_enable = 0;
}
static void handle_connect_done_intr(usb3_pcd_t *pcd)
{
usb3_pcd_ep_t *ep0 = &pcd->ep0;
uint32_t diepcfg0, doepcfg0, diepcfg1, doepcfg1;
usb3_dev_ep_regs_t *ep_reg;
int speed;
ep0->stopped = 0;
speed = usb3_get_device_speed(pcd);
pcd->speed = speed;
usb3_pcd_set_speed(pcd, speed);
/*
* Set the MPS of EP0 based on the connection speed
*/
diepcfg0 = USB3_EP_TYPE_CONTROL << USB3_EPCFG0_EPTYPE_SHIFT;
diepcfg0 |= USB3_CFG_ACTION_MODIFY << USB3_EPCFG0_CFG_ACTION_SHIFT;
diepcfg1 = USB3_EPCFG1_XFER_CMPL_BIT | USB3_EPCFG1_XFER_IN_PROG_BIT | USB3_EPCFG1_XFER_NRDY_BIT |
USB3_EPCFG1_EP_DIR_BIT;
doepcfg0 = USB3_EP_TYPE_CONTROL << USB3_EPCFG0_EPTYPE_SHIFT;
doepcfg0 |= USB3_CFG_ACTION_MODIFY << USB3_EPCFG0_CFG_ACTION_SHIFT;
doepcfg1 = USB3_EPCFG1_XFER_CMPL_BIT | USB3_EPCFG1_XFER_IN_PROG_BIT | USB3_EPCFG1_XFER_NRDY_BIT;
switch (speed) {
case USB_SPEED_SUPER:
diepcfg0 |= 512 << USB3_EPCFG0_MPS_SHIFT;
doepcfg0 |= 512 << USB3_EPCFG0_MPS_SHIFT;
break;
case USB_SPEED_HIGH:
case USB_SPEED_FULL:
diepcfg0 |= 64 << USB3_EPCFG0_MPS_SHIFT;
doepcfg0 |= 64 << USB3_EPCFG0_MPS_SHIFT;
break;
case USB_SPEED_LOW:
diepcfg0 |= 8 << USB3_EPCFG0_MPS_SHIFT;
doepcfg0 |= 8 << USB3_EPCFG0_MPS_SHIFT;
break;
}
diepcfg0 |= ep0->tx_fifo_num << USB3_EPCFG0_TXFNUM_SHIFT;
/* Issue "DEPCFG" command to EP0-OUT */
ep_reg = &pcd->out_ep_regs[0];
usb3_dep_cfg(pcd, ep_reg, doepcfg0, doepcfg1, 0);
/* Issue "DEPCFG" command to EP0-IN */
ep_reg = &pcd->in_ep_regs[0];
usb3_dep_cfg(pcd, ep_reg, diepcfg0, diepcfg1, 0);
pcd->state = USB3_STATE_DEFAULT;
}
int usb3_handle_ep_intr(usb3_pcd_t *pcd, uint32_t physep, uint32_t event)
{
usb3_pcd_ep_t *ep;
int epnum, is_in;
int error = USB_NO_ERR;
/* Physical Out EPs are even, physical In EPs are odd */
is_in = physep & 1;
epnum = (physep >> 1) & 0xf;
/* Get EP pointer */
if (is_in) {
ep = usb3_get_in_ep(pcd, epnum);
} else {
ep = usb3_get_out_ep(pcd, epnum);
}
//printf("\n##########%s,%d,event=0x%x\n",__func__,__LINE__,event);
switch (event & USB3_DEPEVT_INTTYPE_BITS) {
case USB3_DEPEVT_XFER_CMPL << USB3_DEPEVT_INTTYPE_SHIFT:
ep->xfer_started = 0;
/* Complete the transfer */
if (0 == epnum) {
usb3_os_handle_ep0(pcd, event);
} else {
//printf("\n##########%s,%d,event=0x%x\n",__func__,__LINE__,event);
error = usb3_ep_complete_request(pcd, ep, event);
}
break;
case USB3_DEPEVT_XFER_NRDY << USB3_DEPEVT_INTTYPE_SHIFT:
if (0 == epnum) {
switch (pcd->ep0state) {
case EP0_IN_WAIT_NRDY:
if (is_in) {
usb3_os_handle_ep0(pcd, event);
}
break;
case EP0_OUT_WAIT_NRDY:
if (!is_in) {
usb3_os_handle_ep0(pcd, event);
}
break;
default:
break;
}
}
break;
}
return error;
}
void usb3_handle_dev_intr(usb3_pcd_t *pcd, uint32_t event)
{
uint32_t dint = (event >> USB3_DEVT_SHIFT) &
(USB3_DEVT_BITS >> USB3_DEVT_SHIFT);
switch (dint) {
case USB3_DEVT_USBRESET:
handle_usb_reset_intr(pcd);
break;
case USB3_DEVT_CONNDONE:
handle_connect_done_intr(pcd);
break;
}
}