⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 patch-2.4.4-sl811hs

📁 基于Linux的USB芯片SL811主机驱动程序,由芯片厂家提供.
💻 4-SL811HS
📖 第 1 页 / 共 5 页
字号:
++void regShow(hci_t *hci)+{+   int i;+   for (i = 0; i<256; i++)+   {+       printk ("offset %d: 0x%x\n", i, SL811Read(hci, i));+   }+} ++/************************************************************************+ * Function Name : USBReset+ *  + * This function resets SL811HS controller and detects the speed of+ * the connecting device				  + *+ * Input:  hci = data structure for the host controller+ *                + * Return: 0 = no device attached; 1 = USB device attached+ *                + ***********************************************************************/++static int USBReset (hci_t *hci)+{+    int status ;+    hcipriv_t *hp = &hci->hp; ++    DBGFUNC ("enter USBReset\n");	+	++    SL811Write(hci, SL11H_CTLREG2, 0xae);++    // setup master and full speed+ +    SL811Write(hci, SL11H_CTLREG1, 0x08 );	// reset USB+    mdelay(20);                             // 20ms				+    SL811Write(hci, SL11H_CTLREG1, 0);     // remove SE0	++    for (status=0; status < 100; status++)+        SL811Write (hci, SL11H_INTSTATREG, 0xff); // clear all interrupt bits++    status = SL811Read (hci, SL11H_INTSTATREG);++    if (status & 0x40)  // Check if device is removed+    {+        DBG ("USBReset: Device removed\n");+	SL811Write(hci, SL11H_INTENBLREG, SL11H_INTMASK_XFERDONE +                   | SL11H_INTMASK_SOFINTR|SL11H_INTMASK_INSRMV); +        hp->RHportStatus->portStatus &= ~(PORT_CONNECT_STAT | PORT_ENABLE_STAT);+                +		return 0;+    }+	+    SL811Write (hci, SL11H_BUFLNTHREG_B, 0 ) ;	//zero lenth+    SL811Write (hci, SL11H_PIDEPREG_B, 0x50 ) ;	//send SOF to EP0	+    SL811Write (hci, SL11H_DEVADDRREG_B, 0x01 ) ;	//address0+    SL811Write (hci, SL11H_SOFLOWREG, 0xe0 ) ;++    if (!(status & 0x80 ))+    {   +         /* slow speed device connect directly to root-hub */+         +         DBG ("USBReset: low speed Device attached\n");+	 SL811Write (hci, SL11H_CTLREG1, 0x8);+         mdelay(20);+	 SL811Write (hci, SL11H_SOFTMRREG, 0xee );  +	 SL811Write (hci, SL11H_CTLREG1, 0x21 );+         +         /* start the SOF or EOP */+	 +         SL811Write (hci, SL11H_HOSTCTLREG_B, 0x01 ) ;	+         hp->RHportStatus->portStatus |= (PORT_CONNECT_STAT +             | PORT_LOW_SPEED_DEV_ATTACH_STAT);+         +         /* clear all interrupt bits */+         +         for (status=0; status < 20; status++)+             SL811Write (hci, SL11H_INTSTATREG, 0xff);  +    }+    else+    {	+        /* full speed device connect directly to root hub */+ +        DBG ("USBReset: full speed Device attached\n");+	SL811Write (hci, SL11H_CTLREG1, 0x8);+        mdelay(20);+	SL811Write (hci, SL11H_SOFTMRREG, 0xae ) ;+        SL811Write (hci, SL11H_CTLREG1, 0x01 ) ; ++        /* start the SOF or EOP */+        +        SL811Write (hci, SL11H_HOSTCTLREG_B, 0x01 ) ;	+        hp->RHportStatus->portStatus |= (PORT_CONNECT_STAT);+        hp->RHportStatus->portStatus &= ~PORT_LOW_SPEED_DEV_ATTACH_STAT; +        +        /* clear all interrupt bits */++        SL811Write (hci, SL11H_INTSTATREG, 0xff);  ++    }+    +    /* enable all interrupts */	++    SL811Write(hci, SL11H_INTENBLREG, SL11H_INTMASK_XFERDONE +              | SL11H_INTMASK_SOFINTR|SL11H_INTMASK_INSRMV);++    return 1;+}++/*-------------------------------------------------------------------------*/+/* tl functions */+static inline void hc_mark_last_trans (hci_t * hci) +{+	hcipriv_t * hp = &hci->hp; +	__u8 * ptd = hp->tl;+	+        dbg ("enter hc_mark_last_trans\n");+        if (ptd == NULL)+        {+		printk ("hc_mark_last_trans: ptd = null\n");+ 		return;+        }+	if (hp->xferPktLen > 0)+		*(ptd + hp->tl_last) |= (1 << 3);+}++static inline void hc_flush_data_cache (hci_t * hci, void * data, int len) +{}+++/************************************************************************+ * Function Name : hc_add_trans+ *  + * This function sets up the SL811HS register and transmit the USB packets.+ * + * 1) Determine if enough time within the current frame to send the packet+ * 2) Load the data into the SL811HS register+ * 3) Set the appropriate command to the register and trigger the transmit+ *+ * Input:  hci = data structure for the host controller+ *         len = data length+ *         data = transmitting data+ *         toggle = USB toggle bit, either 0 or 1+ *         maxps = maximum packet size for this endpoint+ *         slow = speed of the device+ *         endpoint = endpoint number+ *         address = USB address of the device+ *         pid = packet ID+ *         format = + *         urb_state = the current stage of USB transaction+ *       + * Return: 0 = no time left to schedule the transfer+ *         1 = success + *                + ***********************************************************************/++static inline int hc_add_trans (hci_t * hci, int len, void * data,+		int toggle, int maxps, int slow, int endpoint, int address, int pid, int format, int urb_state)+{+    hcipriv_t * hp = &hci->hp; +    __u16 speed;+    int ii, jj, kk;+	+    DBGFUNC ("enter hc_addr_trans: len =0x%x, toggle:0x%x, endpoing:0x%x," +             " addr:0x%x, pid:0x%x,format:0x%x\n", len, toggle, endpoint, i+             address, pid, format);+	+    if (len > maxps)+    {+        len = maxps;+    }++    speed = hp->RHportStatus->portStatus;+    if (speed & PORT_LOW_SPEED_DEV_ATTACH_STAT)+    {+//	ii = (8*7*8 + 6*3) * len + 800; +        ii = 8*8*len + 1024; +    }+    else+    {+        if (slow)+	{+//	    ii = (8*7*8 + 6*3) * len + 800; +	    ii = 8*8*len + 2048;+	}+	else	+//	    ii = (8*7 + 6*3)*len + 110;+            ii = 8*len + 256;+        }++    ii += 2*10 * len;+++    jj = SL811Read(hci, SL11H_SOFTMRREG);+    kk = (jj & 0xFF) * 64 - ii;++    if (kk < 0)+    {+        DBGVERBOSE ("hc_add_trans: no bandwidth for schedule, ii = 0x%x," +                 "jj = 0x%x, len =0x%x, active_trans = 0x%x\n", ii, jj, +                 len, hci->active_trans);+        return (-1);+    } ++    if (pid != PID_IN) +    {+        /* Load data into hc */++	SL811BufWrite(hci, SL11H_DATA_START, (__u8 *) data, len);+    }		+    +    /* transmit */++    SL11StartXaction(hci, (__u8) address, (__u8) endpoint, +                    (__u8) pid, len, toggle, slow, urb_state);++    return len;+}+++/************************************************************************+ * Function Name : hc_parse_trans+ *  + * This function checks the status of the transmitted or received packet+ * and copy the data from the SL811HS register into a buffer.+ *+ * 1) Check the status of the packet + * 2) If successful, and IN packet then copy the data from the SL811HS register+ *    into a buffer+ *+ * Input:  hci = data structure for the host controller+ *         actbytes = pointer to actual number of bytes+ *         data = data buffer+ *         cc = packet status+ *         length = the urb transmit length+ *         pid = packet ID+ *         urb_state = the current stage of USB transaction+ *       + * Return: 0 + ***********************************************************************/++static inline int hc_parse_trans (hci_t * hci, int * actbytes, __u8 * data, +		int * cc, int * toggle, int length, int pid, int urb_state)+{+    __u8 addr;+    __u8 len;++    DBGFUNC ("enter hc_parse_trans\n");+	+    /* get packet status; convert ack rcvd to ack-not-rcvd */++    *cc = (int) SL811Read(hci, SL11H_PKTSTATREG);+++    if (*cc & (SL11H_STATMASK_ERROR | SL11H_STATMASK_TMOUT | +        SL11H_STATMASK_OVF | SL11H_STATMASK_NAK | SL11H_STATMASK_STALL))+    {+ 	if (*cc & SL11H_STATMASK_OVF)+            DBGERR ("parse trans: error recv ack, cc = 0x%x, TX_BASE_Len = "+                "0x%x, TX_count=0x%x\n", *cc, +                 SL811Read(hci, SL11H_BUFLNTHREG), +                 SL811Read(hci, SL11H_XFERCNTREG));+	+    }+    else +    {+        DBGVERBOSE ("parse trans: recv ack, cc = 0x%x, len = 0x%x, \n", +	 	 *cc, length);+		+	/* Successful data */++	if ((pid == PID_IN) && (urb_state != US_CTRL_SETUP))+	{++	    /* Find the base address */+ +	    addr = SL811Read(hci, SL11H_BUFADDRREG);++	    /* Find the Transmit Length */+ +	    len = SL811Read(hci, SL11H_BUFLNTHREG);++	    /* The actual data length = xmit length reg - xfer count reg */++	    *actbytes = len - SL811Read(hci, SL11H_XFERCNTREG);++	    if ((data != NULL) && (*actbytes > 0))+	    {+		SL811BufRead (hci, addr, data, *actbytes); +			+	    }+	    else if ((data == NULL) && (*actbytes <=0))+	    {	+	        DBGERR ("hc_parse_trans: data = NULL or actbyte = 0x%x\n", +                         *actbytes);+		return 0;+	    }+	}+	else if (pid == PID_OUT)+        {+	    *actbytes = length;+        }+	else+	{+         // printk ("ERR:parse_trans, pid != IN or OUT, pid = 0x%x\n", pid);+        }	+	*toggle = !*toggle;+    }	+	+    return 0;+}++/************************************************************************+ * Function Name : hc_start_int+ *  + * This function enables SL811HS interrupts+ *+ * Input:  hci = data structure for the host controller+ *       + * Return: none + ***********************************************************************/++static void hc_start_int (hci_t *hci)+{+#ifdef HC_SWITCH_INT	+    int mask = SL11H_INTMASK_XFERDONE | SL11H_INTMASK_SOFINTR |+               SL11H_INTMASK_INSRMV | SL11H_INTMASK_USBRESET;+    SL811Write (hci, IntEna, mask); +#endif+}	++/************************************************************************+ * Function Name : hc_stop_int+ *  + * This function disables SL811HS interrupts+ *+ * Input:  hci = data structure for the host controller+ *       + * Return: none + ***********************************************************************/++static void hc_stop_int (hci_t *hci)+{+#ifdef HC_SWITCH_INT+    SL811Write(hci, SL11H_INTSTATREG, 0xff); +//  SL811Write(hci, SL11H_INTENBLREG, SL11H_INTMASK_INSRMV);++#endif+}+++/************************************************************************+ * 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 handleInsRmvIntr (hci_t * hci)+{+    hcipriv_t * hp = &hci->hp; ++    USBReset(hci);+	+    /* Changes in connection status */++    hp->RHportStatus->portChange |=  PORT_CONNECT_CHANGE;++    /* Port Enable or Disable */++    if (hp->RHportStatus->portStatus & PORT_CONNECT_STAT)+    {+    /* device is connected to the port:+     *    1) Enable port +     *    2) Resume ?? +     */+//               hp->RHportStatus->portChange |= PORT_ENABLE_CHANGE;++		/* Over Current is not supported by the SL811 HW ?? */++		/* How about the Port Power ?? */++    }+    else+    {+        /* Device has disconnect:+	 *    1) Disable port+	 */++	 hp->RHportStatus->portStatus &= ~(PORT_ENABLE_STAT);+	 hp->RHportStatus->portChange |= PORT_ENABLE_CHANGE;+		+		+    }+}++/*****************************************************************+ *+ * Function Name: SL11StartXaction+ *  + * This functions load the registers with appropriate value and + * transmit the packet.				  + *+ * Input:  hci = data structure for the host controller+ *         addr = 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+ *         urb_state = the current stage of USB transaction+ *+ * Return: 0 = error; 1 = successful+ *                + *****************************************************************/++int SL11StartXaction(hci_t *hci, __u8 addr, __u8 epaddr, int pid, int len, +                     int toggle, int slow, int urb_state)+{+	+    hcipriv_t * hp = &hci->hp; +    __u8 cmd = 0;+    __u8 setup_data[4];+    __u16 speed;++    speed = hp->RHportStatus->portStatus;+    if (!(speed & PORT_LOW_SPEED_DEV_ATTACH_STAT) && slow)+    {+        cmd |= SL11H_HCTLMASK_PREAMBLE; +    }+    switch (pid)+    {+        case PID_SETUP:+	cmd &= SL11H_HCTLMASK_PREAMBLE;+	cmd |= (SL11H_HCTLMASK_ARM | SL11H_HCTLMASK_ENBLEP +            | SL11H_HCTLMASK_WRITE);+	break;++	case PID_OUT:+	cmd &= (SL11H_HCTLMASK_SEQ | SL11H_HCTLMASK_PREAMBLE);+	cmd |= (SL11H_HCTLMASK_ARM | SL11H_HCTLMASK

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -