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 + -
显示快捷键?