📄 dwc_otg_hcd.c
字号:
haint.d32 = dwc_read_reg32(&hc_global_regs->haint); //fprintf(stderr, "HAINT: %08x\n", haint.d32); /* Read HCINT */ hcint.d32 = dwc_read_reg32(&hc_regs->hcint); //fprintf(stderr, "HCINT: %08x\n", hcint.d32); /* Read HCCHAR */ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32); /* Clear HCINT */ dwc_write_reg32(&hc_regs->hcint, hcint.d32); /* Clear HAINT */ dwc_write_reg32(&hc_global_regs->haint, haint.d32); /* Clear GINTSTS */ dwc_write_reg32(&global_regs->gintsts, gintsts.d32); hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); //if (hcchar.b.chen) { // fprintf(stderr, "** Channel _still_ enabled 2, HCCHAR = %08x **\n", hcchar.d32); //} } /* Set HCTSIZ */ hctsiz.d32 = 0; hctsiz.b.xfersize = 8; hctsiz.b.pktcnt = 1; hctsiz.b.pid = DWC_OTG_HC_PID_DATA1; dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32); /* Set HCCHAR */ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL; hcchar.b.epdir = 1; hcchar.b.epnum = 0; hcchar.b.mps = 8; hcchar.b.chen = 1; dwc_write_reg32(&hc_regs->hcchar, hcchar.d32); gintsts.d32 = dwc_read_reg32(&global_regs->gintsts); //fprintf(stderr, "Waiting for RXSTSQLVL intr 1, GINTSTS = %08x\n", gintsts.d32); /* Wait for receive status queue interrupt */ do { gintsts.d32 = dwc_read_reg32(&global_regs->gintsts); } while (gintsts.b.rxstsqlvl == 0); //fprintf(stderr, "Got RXSTSQLVL intr 1, GINTSTS = %08x\n", gintsts.d32); /* Read RXSTS */ grxsts.d32 = dwc_read_reg32(&global_regs->grxstsp); //fprintf(stderr, "GRXSTS: %08x\n", grxsts.d32); /* Clear RXSTSQLVL in GINTSTS */ gintsts.d32 = 0; gintsts.b.rxstsqlvl = 1; dwc_write_reg32(&global_regs->gintsts, gintsts.d32); switch (grxsts.b.pktsts) { case DWC_GRXSTS_PKTSTS_IN: /* Read the data into the host buffer */ if (grxsts.b.bcnt > 0) { int i; int word_count = (grxsts.b.bcnt + 3) / 4; data_fifo = (uint32_t *) ((char *) global_regs + 0x1000); for (i = 0; i < word_count; i++) { (void) dwc_read_reg32(data_fifo++); } } //fprintf(stderr, "Received %u bytes\n", (unsigned)grxsts.b.bcnt); break; default: //fprintf(stderr, "** Unexpected GRXSTS packet status 1 **\n"); break; } gintsts.d32 = dwc_read_reg32(&global_regs->gintsts); //fprintf(stderr, "Waiting for RXSTSQLVL intr 2, GINTSTS = %08x\n", gintsts.d32); /* Wait for receive status queue interrupt */ do { gintsts.d32 = dwc_read_reg32(&global_regs->gintsts); } while (gintsts.b.rxstsqlvl == 0); //fprintf(stderr, "Got RXSTSQLVL intr 2, GINTSTS = %08x\n", gintsts.d32); /* Read RXSTS */ grxsts.d32 = dwc_read_reg32(&global_regs->grxstsp); //fprintf(stderr, "GRXSTS: %08x\n", grxsts.d32); /* Clear RXSTSQLVL in GINTSTS */ gintsts.d32 = 0; gintsts.b.rxstsqlvl = 1; dwc_write_reg32(&global_regs->gintsts, gintsts.d32); switch (grxsts.b.pktsts) { case DWC_GRXSTS_PKTSTS_IN_XFER_COMP: break; default: //fprintf(stderr, "** Unexpected GRXSTS packet status 2 **\n"); break; } gintsts.d32 = dwc_read_reg32(&global_regs->gintsts); //fprintf(stderr, "Waiting for HCINTR intr 2, GINTSTS = %08x\n", gintsts.d32); /* Wait for host channel interrupt */ do { gintsts.d32 = dwc_read_reg32(&global_regs->gintsts); } while (gintsts.b.hcintr == 0); //fprintf(stderr, "Got HCINTR intr 2, GINTSTS = %08x\n", gintsts.d32); /* Read HAINT */ haint.d32 = dwc_read_reg32(&hc_global_regs->haint); //fprintf(stderr, "HAINT: %08x\n", haint.d32); /* Read HCINT */ hcint.d32 = dwc_read_reg32(&hc_regs->hcint); //fprintf(stderr, "HCINT: %08x\n", hcint.d32); /* Read HCCHAR */ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32); /* Clear HCINT */ dwc_write_reg32(&hc_regs->hcint, hcint.d32); /* Clear HAINT */ dwc_write_reg32(&hc_global_regs->haint, haint.d32); /* Clear GINTSTS */ dwc_write_reg32(&global_regs->gintsts, gintsts.d32); /* Read GINTSTS */ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts); //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);// usleep(100000);// mdelay(100); mdelay(1); /* * Send handshake packet */ /* Read HAINT */ haint.d32 = dwc_read_reg32(&hc_global_regs->haint); //fprintf(stderr, "HAINT: %08x\n", haint.d32); /* Read HCINT */ hcint.d32 = dwc_read_reg32(&hc_regs->hcint); //fprintf(stderr, "HCINT: %08x\n", hcint.d32); /* Read HCCHAR */ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32); /* Clear HCINT */ dwc_write_reg32(&hc_regs->hcint, hcint.d32); /* Clear HAINT */ dwc_write_reg32(&hc_global_regs->haint, haint.d32); /* Clear GINTSTS */ dwc_write_reg32(&global_regs->gintsts, gintsts.d32); /* Read GINTSTS */ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts); //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32); /* Make sure channel is disabled */ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); if (hcchar.b.chen) { //fprintf(stderr, "Channel already enabled 3, HCCHAR = %08x\n", hcchar.d32); hcchar.b.chdis = 1; hcchar.b.chen = 1; dwc_write_reg32(&hc_regs->hcchar, hcchar.d32); //sleep(1); mdelay(1000); /* Read GINTSTS */ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts); //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32); /* Read HAINT */ haint.d32 = dwc_read_reg32(&hc_global_regs->haint); //fprintf(stderr, "HAINT: %08x\n", haint.d32); /* Read HCINT */ hcint.d32 = dwc_read_reg32(&hc_regs->hcint); //fprintf(stderr, "HCINT: %08x\n", hcint.d32); /* Read HCCHAR */ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32); /* Clear HCINT */ dwc_write_reg32(&hc_regs->hcint, hcint.d32); /* Clear HAINT */ dwc_write_reg32(&hc_global_regs->haint, haint.d32); /* Clear GINTSTS */ dwc_write_reg32(&global_regs->gintsts, gintsts.d32); hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); //if (hcchar.b.chen) { // fprintf(stderr, "** Channel _still_ enabled 3, HCCHAR = %08x **\n", hcchar.d32); //} } /* Set HCTSIZ */ hctsiz.d32 = 0; hctsiz.b.xfersize = 0; hctsiz.b.pktcnt = 1; hctsiz.b.pid = DWC_OTG_HC_PID_DATA1; dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32); /* Set HCCHAR */ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); hcchar.b.eptype = DWC_OTG_EP_TYPE_CONTROL; hcchar.b.epdir = 0; hcchar.b.epnum = 0; hcchar.b.mps = 8; hcchar.b.chen = 1; dwc_write_reg32(&hc_regs->hcchar, hcchar.d32); gintsts.d32 = dwc_read_reg32(&global_regs->gintsts); //fprintf(stderr, "Waiting for HCINTR intr 3, GINTSTS = %08x\n", gintsts.d32); /* Wait for host channel interrupt */ do { gintsts.d32 = dwc_read_reg32(&global_regs->gintsts); } while (gintsts.b.hcintr == 0); //fprintf(stderr, "Got HCINTR intr 3, GINTSTS = %08x\n", gintsts.d32); /* Disable HCINTs */ dwc_write_reg32(&hc_regs->hcintmsk, 0x0000); /* Disable HAINTs */ dwc_write_reg32(&hc_global_regs->haintmsk, 0x0000); /* Read HAINT */ haint.d32 = dwc_read_reg32(&hc_global_regs->haint); //fprintf(stderr, "HAINT: %08x\n", haint.d32); /* Read HCINT */ hcint.d32 = dwc_read_reg32(&hc_regs->hcint); //fprintf(stderr, "HCINT: %08x\n", hcint.d32); /* Read HCCHAR */ hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar); //fprintf(stderr, "HCCHAR: %08x\n", hcchar.d32); /* Clear HCINT */ dwc_write_reg32(&hc_regs->hcint, hcint.d32); /* Clear HAINT */ dwc_write_reg32(&hc_global_regs->haint, haint.d32); /* Clear GINTSTS */ dwc_write_reg32(&global_regs->gintsts, gintsts.d32); /* Read GINTSTS */ gintsts.d32 = dwc_read_reg32(&global_regs->gintsts); //fprintf(stderr, "GINTSTS: %08x\n", gintsts.d32);}#endif /* DWC_HS_ELECT_TST *//** Handles hub class-specific requests.*/int dwc_otg_hcd_hub_control(struct usb_hcd *_hcd, u16 _typeReq, u16 _wValue, u16 _wIndex, char *_buf, u16 _wLength){ int retval = 0; dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(_hcd); dwc_otg_core_if_t *core_if = hcd_to_dwc_otg_hcd(_hcd)->core_if; struct usb_hub_descriptor *desc; hprt0_data_t hprt0 = {.d32 = 0 }; uint32_t port_status; switch (_typeReq) { case ClearHubFeature: DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " "ClearHubFeature 0x%x\n", _wValue); switch (_wValue) { case C_HUB_LOCAL_POWER: case C_HUB_OVER_CURRENT: /* Nothing required here */ break; default: retval = -EINVAL; DWC_ERROR("DWC OTG HCD - " "ClearHubFeature request %xh unknown\n", _wValue); } break; case ClearPortFeature: if (!_wIndex || _wIndex > 1) goto error; switch (_wValue) { case USB_PORT_FEAT_ENABLE: DWC_DEBUGPL(DBG_ANY, "DWC OTG HCD HUB CONTROL - " "ClearPortFeature USB_PORT_FEAT_ENABLE\n"); hprt0.d32 = dwc_otg_read_hprt0(core_if); hprt0.b.prtena = 1; dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32); break; case USB_PORT_FEAT_SUSPEND: printk("DWC OTG HCD HUB CONTROL - " "ClearPortFeature USB_PORT_FEAT_SUSPEND\n"); hprt0.d32 = dwc_otg_read_hprt0(core_if); hprt0.b.prtres = 1; dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32); /* Clear Resume bit */ mdelay(100); hprt0.b.prtres = 0; dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32); break; case USB_PORT_FEAT_POWER: DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " "ClearPortFeature USB_PORT_FEAT_POWER\n"); hprt0.d32 = dwc_otg_read_hprt0(core_if); hprt0.b.prtpwr = 0; dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32); break; case USB_PORT_FEAT_INDICATOR: DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " "ClearPortFeature USB_PORT_FEAT_INDICATOR\n"); /* Port inidicator not supported */ break; case USB_PORT_FEAT_C_CONNECTION: /* Clears drivers internal connect status change * flag */ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " "ClearPortFeature USB_PORT_FEAT_C_CONNECTION\n"); dwc_otg_hcd->flags.b.port_connect_status_change = 0; break; case USB_PORT_FEAT_C_RESET: /* Clears the driver's internal Port Reset Change * flag */ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " "ClearPortFeature USB_PORT_FEAT_C_RESET\n"); dwc_otg_hcd->flags.b.port_reset_change = 0; break; case USB_PORT_FEAT_C_ENABLE: /* Clears the driver's internal Port * Enable/Disable Change flag */ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " "ClearPortFeature USB_PORT_FEAT_C_ENABLE\n"); dwc_otg_hcd->flags.b.port_enable_change = 0; break; case USB_PORT_FEAT_C_SUSPEND: /* Clears the driver's internal Port Suspend * Change flag, which is set when resume signaling on * the host port is complete */ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " "ClearPortFeature USB_PORT_FEAT_C_SUSPEND\n"); dwc_otg_hcd->flags.b.port_suspend_change = 0; break; case USB_PORT_FEAT_C_OVER_CURRENT: DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " "ClearPortFeature USB_PORT_FEAT_C_OVER_CURRENT\n"); dwc_otg_hcd->flags.b.port_over_current_change = 0; break; default: retval = -EINVAL; DWC_ERROR("DWC OTG HCD - " "ClearPortFeature request %xh " "unknown or unsupported\n", _wValue); } break; case GetHubDescriptor: DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " "GetHubDescriptor\n"); desc = (struct usb_hub_descriptor *) _buf; desc->bDescLength = 9; desc->bDescriptorType = 0x29; desc->bNbrPorts = 1; desc->wHubCharacteristics = 0x08; desc->bPwrOn2PwrGood = 1; desc->bHubContrCurrent = 0; desc->bitmap[0] = 0; desc->bitmap[1] = 0xff; break; case GetHubStatus: DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " "GetHubStatus\n"); memset(_buf, 0, 4); break; case GetPortStatus: DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD HUB CONTROL - " "GetPortStatus\n"); if (!_wIndex || _wIndex > 1) goto error; port_status = 0; if (dwc_otg_hcd->flags.b.port_connect_status_change) port_status |= (1 << USB_PORT_FEAT_C_CONNECTION); if (dwc_otg_hcd->flags.b.port_enable_change) port_status |= (1 << USB_PORT_FEAT_C_ENABLE); if (dwc_otg_hcd->flags.b.port_suspend_change) port_status |= (1 << USB_PORT_FEAT_C_SUSPEND); if (dwc_otg_hcd->flags.b.port_reset_change) port_status |= (1 << USB_PORT_FEAT_C_RESET); if (dwc_otg_hcd->flags.b.port_over_current_change) { DWC_ERROR("Device Not Supported\n"); port_status |= (1 << USB_PORT_FEAT_C_OVER_CURRENT); } if (!dwc_otg_hcd->flags.b.port_connect_status) { /* * The port is disconnected, which means the core is * either in device mode or it soon will be. Just * return 0's for the remainder of the port status * since the port register can't be read if the core * is in device mode. */ *((__le32 *) _buf) = cpu_to_le32(port_status); break; } hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0); DWC_DEBUGPL(DBG_HCDV, " HPRT0: 0x%08x\n", hprt0.d32); if (hprt0.b.prtconnsts) port_status |= (1 << USB_PORT_FEAT_CONNECTION); if (hprt0.b.prtena) port_status |= (1 << USB_PORT_FEAT_ENABLE); if (hprt0.b.prtsusp) port_status |= (1 << USB_PORT_FEAT_SUSPEND);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -