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

📄 patch-2.4.4-sl811hs

📁 This is cypress sl811 driver. I think it is very useful. Thankyou.
💻 4-SL811HS
📖 第 1 页 / 共 5 页
字号:
+
+/***************************************************************************
+ * Function Name : regTest
+ *
+ * This routine test the Read/Write functionality of SL811HS registers  
+ *
+ * 1) Store original register value into a buffer
+ * 2) Write to registers with a RAMP pattern. (10, 11, 12, ..., 255)
+ * 3) Read from register
+ * 4) Compare the written value with the read value and make sure they are 
+ *    equivalent
+ * 5) Restore the original register value 
+ *
+ * Input:  hci = data structure for the host controller
+ *   
+ *
+ * Return: TRUE = passed; FALSE = failed 
+ **************************************************************************/
+
+int regTest(hci_t *hci)
+{
+   int i, data, result = TRUE;
+   char buf[256];
+
+   DBGFUNC ("Enter regTest\n");
+   for (i=0x10; i < 256; i++)
+   {
+       /* save the original buffer */
+       buf[i] = (char) SL811Read(hci, i);
+ 
+       /* Write the new data to the buffer */
+       SL811Write(hci, i, i);
+   }
+
+   /* compare the written data */
+   for (i=0x10; i < 256; i++)
+   {
+       data = SL811Read(hci, i);
+       if (data != i)
+       {
+	   DBGERR ("Pattern test failed!! value = 0x%x, s/b 0x%x\n", 
+                    data, i);
+           result = FALSE;	
+       }
+   }
+
+   /* restore the data */
+   for (i=0x10; i < 256; i++)
+   {
+       SL811Write(hci, i, buf[i]);
+   }
+   
+   return (result);
+}
+
+/***************************************************************************
+ * Function Name : regShow
+ *
+ * Display all SL811HS register values
+ *
+ * Input:  hci = data structure for the host controller
+ *
+ * Return: none 
+ **************************************************************************/
+
+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_

⌨️ 快捷键说明

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