cy7c67200_300_hcd.c
来自「linux嵌入式课程实践中的一个关于声卡驱动程序 。」· C语言 代码 · 共 2,356 行 · 第 1/4 页
C
2,356 行
HWTrace(0x80); /* read the TD from cy7c67200/300 */ lcd_read_memory(td_addr, CY_TD_SIZE, (char *) td, cy_priv); retryCnt = td->retry_cnt & TD_RETRYCNTMASK_RTY_CNT; residue = td->residue; *activeFlag = td->retry_cnt & TD_RETRYCNTMASK_ACT_FLG; *cc = td->status; /* Check the Active Flag */ if ((*activeFlag == 0) || (pipetype == PIPE_ISOCHRONOUS) || (pipetype == PIPE_INTERRUPT)) { HWTrace(0x81); /* check the status */ transfer_status = td->status; if ((transfer_status == 0) || ((transfer_status & TD_STATUSMASK_OVF) && (pid == TD_PID_IN) && ((residue & 0x80) == 0)) || (((transfer_status & TD_STATUSMASK_ACK) == 0x1) && ((pipetype == PIPE_ISOCHRONOUS)||(pipetype == PIPE_INTERRUPT))) ) { HWTrace(0x82); /* transfer successful */ *toggle = !*toggle; if (pid == TD_PID_OUT) { /* USB OUT */ *actbytes = len; } else { /* USB IN */ /* NOTE: Residue = expected byte count - actual byte count, * therefore: actual byte count = expected byte count - Residue */ HWTrace(0x83); *actbytes = len - residue; } } else { HWTrace(0x84); /* transfer failed */ if (transfer_status & TD_STATUSMASK_OVF) { HWTrace(0x85); /* overflow or underflow ?? */ if (residue & 0x80) { HWTrace(0x86); cy_err("hc_parse_td: overflow error = 0x%x\n", residue); } else { HWTrace(0x87); cy_err("hc_parse_td: underflow error = 0x%x\n", residue); } } if (transfer_status & TD_STATUSMASK_STALL) { HWTrace(0x89); } return td->status; } } else /* Active flag is set */ { HWTrace(0x88); *actbytes = 0; /* don't do anything, it will take care of it in the next frame */ } HWTrace(0x8F); return 0;}/***********************************************************************/int hc_otg_debug(struct usb_device * dev){ otg_print_state(); return 0 ;}int hc_otg_offer_hnp(struct usb_device * dev){ return(otg_offer_hnp());}int hc_otg_end_hnp (struct usb_device * dev){ return(otg_end_hnp());}int hc_otg_start_session (struct usb_device * dev){ return(otg_start_session());}int hc_otg_end_session (struct usb_device * dev){ return(otg_end_session());}int usb_otg_id (struct usb_device * dev, int * id){ return (otg_id(id));}int usb_otg_state (struct usb_device * dev, int * state){ return otg_state(state);}void hc_disable_port (cy_priv_t * cy_priv, int port_num){ hci_t * hci = cy_priv->hci; hcipriv_t * hp = &hci->port[port_num]; HWTrace(0x6003); hp->RHportStatus->portStatus &= ~(PORT_CONNECT_STAT | PORT_ENABLE_STAT); hp->RHportStatus->portChange |= PORT_CONNECT_CHANGE | PORT_ENABLE_CHANGE; }void hc_enable_port (cy_priv_t * cy_priv, int port_num){ hci_t * hci = cy_priv->hci; hcipriv_t * hp = &hci->port[port_num]; if (cy_priv->otg == NULL) { hc_host_usb_reset(cy_priv, port_num); //hp->RHportStatus->portChange |= PORT_CONNECT_CHANGE; }}void hcd_switch_role(int new_role, cy_priv_t * cy_priv){ unsigned short intStat = 0; switch (new_role) { case PERIPHERAL_ROLE: /* Check for valid hci */ if (cy_priv->hci != NULL) { /* Disable host port */ hc_disable_port(cy_priv, PORT0); } break; case HOST_ROLE: /* Check for valid hci */ if (cy_priv->hci != NULL) { /* Initialize the SIE */ hc_host_usb_init (cy_priv, SIE0); /* Enable host port(s) */ hc_enable_port(cy_priv, PORT0); } break; case HOST_INACTIVE_ROLE: /* Check for valid hci */ if (cy_priv->hci != NULL) { /* Disable host port(s) */ hc_disable_port(cy_priv, PORT0); /* Initialize the SIE */ hc_host_usb_init (cy_priv, SIE0); } break; }}/************************************************************************ * Function Name : handleInsRmvIntr * * This function handles the insertion or removal of device on SL811HS. * It resets the controller and updates the port status * * Input: hci = data structure for the host controller * * Return: none ***********************************************************************/void handle_device_insertion (cy_priv_t * cy_priv, int port_num){ hci_t * hci = (hci_t *) cy_priv->hci; hc_host_usb_reset(cy_priv, port_num);}void handle_device_removal (cy_priv_t * cy_priv, int port_num){ hci_t * hci = (hci_t *) cy_priv->hci; hc_host_usb_reset (cy_priv, port_num);}void handle_remote_wakeup (cy_priv_t * cy_priv, int port_num){ /* Not handled at this time */}/***************************************************************** * * Function Name: fillTd * * This functions fills the TD structure * * Input: td = data structure for the host controller * ly_base_addr = Lyberty base address * devaddr = USB address of the device * epaddr = endpoint number * pid = packet ID * len = data length * toggle = USB toggle bit, either 0 or 1 * slow = speed of the device * transferType = the current stage of USB transaction * * Return: 0 = error; 1 = successful * *****************************************************************/int fillTd(hci_t * hci, td_t *td, __u16 * td_addr, __u16 * buf_addr, __u8 devaddr, __u8 epaddr, int pid, int len, int toggle, int slow, int tt, int port_num){ __u8 cmd = 0; __u16 speed; __u8 activeFlag = 1; __u8 retryCnt = 3; speed = get_port_stat(hci, port_num); /* If the directly connected device is a full-speed hub * the low-speed preamble must be turned on to communicate * to a low-speed device connected to the hub */ if (!(speed & PORT_LOW_SPEED_DEV_ATTACH_STAT) && slow) { cmd |= bmHOST_HCTL_PREAMBLE; } /* Check for isochronous pipe */ if (tt == TT_ISOCHRONOUS) { cmd |= bmHOST_HCTL_ISOCH; } if (toggle) { cmd |= bmHOST_HCTL_DT; } cmd |= bmHOST_HCTL_ARM; /* make sure the buffer address is word align */ *buf_addr = (*buf_addr + 1) & 0xFFFE; *td_addr = (*td_addr + 1) & 0xFFFE; td->ly_base_addr = *buf_addr; td->port_length = (port_num << 14) + (len & 0x3FF); /* Port Length + port Number */ td->pid_ep = ((pid & 0xF) << 4) | (epaddr & 0xF); td->dev_addr = devaddr & 0x7F; td->ctrl_reg = cmd; td->status = 0; td->retry_cnt = (tt << 2) | (activeFlag << 4) | retryCnt; td->residue = 0; td->next_td_addr = *td_addr + CY_TD_SIZE; td->last_td_flag = 0; return 1;}/******************************************************************/int is_host_enable(hci_t * hci, int port_num){ hcipriv_t * hp = &hci->port[port_num]; return (!hp->host_disabled); }/***************************************************************** * * Function Name: get_port_stat_change * * This function gets the ports status from SL811 and format it * to a USB request format * * Input: hci = data structure for the host controller * * Return value : port status and change * *****************************************************************/__u32 get_port_stat_change(hci_t * hci, int port_num){ hcipriv_t * hp = &hci->port[port_num]; __u32 portstatus; cy_dbg("enter getPorStatusAndChange"); HWTrace(0x6004); portstatus = hp->RHportStatus->portChange << 16 | hp->RHportStatus->portStatus; return (portstatus); }static unsigned short get_port_stat(hci_t *hci, int port_num){ hcipriv_t * hp = &hci->port[port_num]; __u32 portstatus; cy_dbg("enter getPorStatusAndChange"); HWTrace(0x6005); portstatus = hp->RHportStatus->portStatus; return (portstatus); }/***************************************************************** * * Function Name: setPortChange * * This function set the bit position of portChange. * * Input: hci = data structure for the host controller * bitPos = the bit position * * Return value : none * *****************************************************************/void set_port_change(hci_t * hci, __u16 bitPos, int port_num){ hcipriv_t * hp = &hci->port[port_num]; switch (bitPos) { case PORT_CONNECT_CHANGE: HWTrace(0x6006); hp->RHportStatus->portChange |= bitPos; break; case PORT_ENABLE_CHANGE: HWTrace(0x6007); hp->RHportStatus->portChange |= bitPos; break; case PORT_RESET_CHANGE: HWTrace(0x6008); hp->RHportStatus->portChange |= bitPos; break; case PORT_SUSPEND_CHANGE: HWTrace(0x6009); hp->RHportStatus->portChange |= bitPos; break; case PORT_OVER_CURRENT_CHANGE: HWTrace(0x600A); hp->RHportStatus->portChange |= bitPos; break; }}/***************************************************************** * * Function Name: clrPortChange * * This function clear the bit position of portChange. * * Input: hci = data structure for the host controller * bitPos = the bit position * * Return value : none * *****************************************************************/void clr_port_change(hci_t * hci, __u16 bitPos, int port_num){ hcipriv_t * hp = &hci->port[port_num]; switch (bitPos) { case PORT_CONNECT_CHANGE: HWTrace(0x600B); hp->RHportStatus->portChange &= ~bitPos; break; case PORT_ENABLE_CHANGE: HWTrace(0x600C); hp->RHportStatus->portChange &= ~bitPos; break; case PORT_RESET_CHANGE: HWTrace(0x600D); hp->RHportStatus->portChange &= ~bitPos; break; case PORT_SUSPEND_CHANGE: HWTrace(0x600E); hp->RHportStatus->portChange &= ~bitPos; break; case PORT_OVER_CURRENT_CHANGE: HWTrace(0x600F); hp->RHportStatus->portChange &= ~bitPos; break; }}/***************************************************************** * * Function Name: clrPortStatus * * This function clear the bit position of portStatus. * * Input: hci = data structure for the host controller * bitPos = the bit position * * Return value : none * *****************************************************************/void clr_port_stat(hci_t * hci, __u16 bitPos, int port_num){ hcipriv_t * hp = &hci->port[port_num]; switch (bitPos) { case PORT_ENABLE_STAT: HWTrace(0x6010); hp->RHportStatus->portStatus &= ~bitPos; break; case PORT_RESET_STAT: HWTrace(0x6011); hp->RHportStatus->portStatus &= ~bitPos; break; case PORT_POWER_STAT: HWTrace(0x6012); hp->RHportStatus->portStatus &= ~bitPos; break; case PORT_SUSPEND_STAT: HWTrace(0x6013); hp->RHportStatus->portStatus &= ~bitPos; break; }}/***************************************************************** * * Function Name: setPortStatus * * This function set the bit position of portStatus. * * Input: hci = data structure for the host controller * bitPos = the bit position * * Return value : none * *****************************************************************/void set_port_stat(hci_t * hci, __u16 bitPos, int port_num){ hcipriv_t * hp = &hci->port[port_num]; switch (bitPos) { case PORT_ENABLE_STAT: HWTrace(0x6014); hp->RHportStatus->portStatus |= bitPos; break; case PORT_RESET_STAT: HWTrace(0x6015); hp->RHportStatus->portStatus |= bitPos; break; case PORT_POWER_STAT: HWTrace(0x6016); hp->RHportStatus->portStatus |= bitPos; break; case PORT_SUSPEND_STAT: HWTrace(0x6017); hp->RHportStatus->portStatus |= bitPos; break; }} /***************************************************************** * * Function Name: hc_start * * This function starts the root hub functionality. * * Input: hci = data structure for the host controller * * Return value : 0 * *****************************************************************/static int hcd_start (cy_priv_t * cy_priv, int port_num){ cy_dbg("Enter hc_start"); rh_connect_rh (cy_priv, port_num); return 0;}/***************************************************************** * * Function Name: hc_alloc_hci * * This function allocates all data structure and store in the * private data structure. * * Input: hci = data structure for the host controller * * Return value : 0 * *****************************************************************/static hci_t * __devinit hc_alloc_hci (cy_priv_t * cy_priv, int port_num){ hci_t * hci; int i = 0; cy_dbg("Enter hc_alloc_hci"); /* alloc the hci structure */ HWTrace(0xBEF6); hci = (hci_t *) kmalloc (sizeof (hci_t), GFP_KERNEL); if (!hci) { cy_err("can't alloc hci"); return NULL; } memset (hci, 0, sizeof (hci_t)); INIT_LIST_HEAD (&hci->hci_hcd_list); list_add (&hci->hci_hcd_list, &hci_hcd_list); init_waitqueue_head (&hci->waitq); /* set all host port to be invalid at first */ for (i = 0; i< MAX_NUM_PORT; i++) { hci->valid_host_port[i] = -1; hci->port[i].host_disabled = 1; } return hci;} /***************************************************************** * * Function Name: hc_init_port * * This function initializes the port specify by port_num. *
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?