ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / usb / host / hc_sl811.c
1 /*-------------------------------------------------------------------------*/
2 /*-------------------------------------------------------------------------*
3  * SL811HS USB HCD for Linux Version 0.1 (10/28/2001)
4  * 
5  * requires (includes) hc_simple.[hc] simple generic HCD frontend
6  *  
7  * COPYRIGHT(C) 2001 by CYPRESS SEMICONDUCTOR INC.
8  *
9  *-------------------------------------------------------------------------*
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23  *
24  *-------------------------------------------------------------------------*/
25
26 #include <linux/config.h>
27 #include <linux/module.h>
28 #include <linux/kernel.h>
29 #include <linux/delay.h>
30 #include <linux/sched.h>
31 #include <linux/slab.h>
32 #include <linux/errno.h>
33 #include <linux/init.h>
34 #include <linux/smp_lock.h>
35 #include <linux/list.h>
36 #include <linux/ioport.h>
37 #include <asm/io.h>
38 #include <asm/irq.h>
39
40 #include <linux/usb.h>
41 #include "../core/hcd.h"
42
43 #undef HC_URB_TIMEOUT
44 #undef HC_SWITCH_INT
45 #undef HC_ENABLE_ISOC
46
47 #define SL811_DEBUG_ERR
48
49 #ifdef SL811_DEBUG_ERR
50 #define DBGERR(fmt, args...) printk(fmt,## args)
51 #else
52 #define DBGERR(fmt, args...)
53 #endif
54
55 #ifdef SL811_DEBUG
56 #define DBG(fmt, args...) printk(fmt,## args)
57 #else
58 #define DBG(fmt, args...)
59 #endif
60
61 #ifdef SL811_DEBUG_FUNC
62 #define DBGFUNC(fmt, args...) printk(fmt,## args)
63 #else
64 #define DBGFUNC(fmt, args...)
65 #endif
66
67 #ifdef SL811_DEBUG_DATA
68 #define DBGDATAR(fmt, args...) printk(fmt,## args)
69 #define DBGDATAW(fmt, args...) printk(fmt,## args)
70 #else
71 #define DBGDATAR(fmt, args...)
72 #define DBGDATAW(fmt, args...)
73 #endif
74
75 #ifdef SL811_DEBUG_VERBOSE
76 #define DBGVERBOSE(fmt, args...) printk(fmt,## args)
77 #else
78 #define DBGVERBOSE(fmt, args...)
79 #endif
80
81 #define TRUE 1
82 #define FALSE 0
83
84 #define HC_SWITCH_INT
85 #include "hc_sl811.h"
86 #include "hc_simple.h"
87
88 static int urb_debug = 0;
89
90 #include "hc_simple.c"
91 #include "hc_sl811_rh.c"
92
93 /* The base_addr, data_reg_addr, and irq number are board specific.
94  * The current values are design to run on the Accelent SA1110 IDP
95  * NOTE: values need to modify for different development boards 
96  */
97
98 static int base_addr = 0xd3800000;
99 static int data_reg_addr = 0xd3810000;
100 static int irq = 34;
101
102 /* forware declaration */
103
104 int SL11StartXaction (hci_t * hci, __u8 addr, __u8 epaddr, int pid, int len,
105                       int toggle, int slow, int urb_state);
106
107 static int sofWaitCnt = 0;
108
109 MODULE_PARM (urb_debug, "i");
110 MODULE_PARM_DESC (urb_debug, "debug urb messages, default is 0 (no)");
111
112 MODULE_PARM (base_addr, "i");
113 MODULE_PARM_DESC (base_addr, "sl811 base address 0xd3800000");
114 MODULE_PARM (data_reg_addr, "i");
115 MODULE_PARM_DESC (data_reg_addr, "sl811 data register address 0xd3810000");
116 MODULE_PARM (irq, "i");
117 MODULE_PARM_DESC (irq, "IRQ 34 (default)");
118
119 static int hc_reset (hci_t * hci);
120
121 /***************************************************************************
122  * Function Name : SL811Read
123  *
124  * Read a byte of data from the SL811H/SL11H
125  *
126  * Input:  hci = data structure for the host controller
127  *         offset = address of SL811/SL11H register or memory
128  *
129  * Return: data 
130  **************************************************************************/
131 char SL811Read (hci_t * hci, char offset)
132 {
133         hcipriv_t *hp = &hci->hp;
134         char data;
135         writeb (offset, hp->hcport);
136         wmb ();
137         data = readb (hp->hcport2);
138         rmb ();
139         return (data);
140 }
141
142 /***************************************************************************
143  * Function Name : SL811Write
144  *
145  * Write a byte of data to the SL811H/SL11H
146  *
147  * Input:  hci = data structure for the host controller
148  *         offset = address of SL811/SL11H register or memory
149  *         data  = the data going to write to SL811H
150  *
151  * Return: none 
152  **************************************************************************/
153 void SL811Write (hci_t * hci, char offset, char data)
154 {
155         hcipriv_t *hp = &hci->hp;
156         writeb (offset, hp->hcport);
157         writeb (data, hp->hcport2);
158         wmb ();
159 }
160
161 /***************************************************************************
162  * Function Name : SL811BufRead
163  *
164  * Read consecutive bytes of data from the SL811H/SL11H buffer
165  *
166  * Input:  hci = data structure for the host controller
167  *         offset = SL811/SL11H register offset
168  *         buf = the buffer where the data will store
169  *         size = number of bytes to read
170  *
171  * Return: none 
172  **************************************************************************/
173 void SL811BufRead (hci_t * hci, short offset, char *buf, short size)
174 {
175         hcipriv_t *hp = &hci->hp;
176         if (size <= 0)
177                 return;
178         writeb ((char) offset, hp->hcport);
179         wmb ();
180         DBGDATAR ("SL811BufRead: offset = 0x%x, data = ", offset);
181         while (size--) {
182                 *buf++ = (char) readb (hp->hcport2);
183                 DBGDATAR ("0x%x ", *(buf - 1));
184                 rmb ();
185         }
186         DBGDATAR ("\n");
187 }
188
189 /***************************************************************************
190  * Function Name : SL811BufWrite
191  *
192  * Write consecutive bytes of data to the SL811H/SL11H buffer
193  *
194  * Input:  hci = data structure for the host controller
195  *         offset = SL811/SL11H register offset
196  *         buf = the data buffer 
197  *         size = number of bytes to write
198  *
199  * Return: none 
200  **************************************************************************/
201 void SL811BufWrite (hci_t * hci, short offset, char *buf, short size)
202 {
203         hcipriv_t *hp = &hci->hp;
204         if (size <= 0)
205                 return;
206         writeb ((char) offset, hp->hcport);
207         wmb ();
208         DBGDATAW ("SL811BufWrite: offset = 0x%x, data = ", offset);
209         while (size--) {
210                 DBGDATAW ("0x%x ", *buf);
211                 writeb (*buf, hp->hcport2);
212                 wmb ();
213                 buf++;
214         }
215         DBGDATAW ("\n");
216 }
217
218 /***************************************************************************
219  * Function Name : regTest
220  *
221  * This routine test the Read/Write functionality of SL811HS registers  
222  *
223  * 1) Store original register value into a buffer
224  * 2) Write to registers with a RAMP pattern. (10, 11, 12, ..., 255)
225  * 3) Read from register
226  * 4) Compare the written value with the read value and make sure they are 
227  *    equivalent
228  * 5) Restore the original register value 
229  *
230  * Input:  hci = data structure for the host controller
231  *   
232  *
233  * Return: TRUE = passed; FALSE = failed 
234  **************************************************************************/
235 int regTest (hci_t * hci)
236 {
237         int i, data, result = TRUE;
238         char buf[256];
239
240         DBGFUNC ("Enter regTest\n");
241         for (i = 0x10; i < 256; i++) {
242                 /* save the original buffer */
243                 buf[i] = (char) SL811Read (hci, i);
244
245                 /* Write the new data to the buffer */
246                 SL811Write (hci, i, i);
247         }
248
249         /* compare the written data */
250         for (i = 0x10; i < 256; i++) {
251                 data = SL811Read (hci, i);
252                 if (data != i) {
253                         DBGERR ("Pattern test failed!! value = 0x%x, s/b 0x%x\n",
254                                 data, i);
255                         result = FALSE;
256                 }
257         }
258
259         /* restore the data */
260         for (i = 0x10; i < 256; i++) {
261                 SL811Write (hci, i, buf[i]);
262         }
263
264         return (result);
265 }
266
267 /***************************************************************************
268  * Function Name : regShow
269  *
270  * Display all SL811HS register values
271  *
272  * Input:  hci = data structure for the host controller
273  *
274  * Return: none 
275  **************************************************************************/
276 void regShow (hci_t * hci)
277 {
278         int i;
279         for (i = 0; i < 256; i++) {
280                 printk ("offset %d: 0x%x\n", i, SL811Read (hci, i));
281         }
282 }
283
284 /************************************************************************
285  * Function Name : USBReset
286  *  
287  * This function resets SL811HS controller and detects the speed of
288  * the connecting device                                  
289  *
290  * Input:  hci = data structure for the host controller
291  *                
292  * Return: 0 = no device attached; 1 = USB device attached
293  *                
294  ***********************************************************************/
295 static int USBReset (hci_t * hci)
296 {
297         int status;
298         hcipriv_t *hp = &hci->hp;
299
300         DBGFUNC ("enter USBReset\n");
301
302         SL811Write (hci, SL11H_CTLREG2, 0xae);
303
304         // setup master and full speed
305
306         SL811Write (hci, SL11H_CTLREG1, 0x08);  // reset USB
307         mdelay (20);            // 20ms                             
308         SL811Write (hci, SL11H_CTLREG1, 0);     // remove SE0        
309
310         for (status = 0; status < 100; status++)
311                 SL811Write (hci, SL11H_INTSTATREG, 0xff);       // clear all interrupt bits
312
313         status = SL811Read (hci, SL11H_INTSTATREG);
314
315         if (status & 0x40)      // Check if device is removed
316         {
317                 DBG ("USBReset: Device removed\n");
318                 SL811Write (hci, SL11H_INTENBLREG,
319                             SL11H_INTMASK_XFERDONE | SL11H_INTMASK_SOFINTR |
320                             SL11H_INTMASK_INSRMV);
321                 hp->RHportStatus->portStatus &=
322                     ~(PORT_CONNECT_STAT | PORT_ENABLE_STAT);
323
324                 return 0;
325         }
326
327         SL811Write (hci, SL11H_BUFLNTHREG_B, 0);        //zero lenth
328         SL811Write (hci, SL11H_PIDEPREG_B, 0x50);       //send SOF to EP0       
329         SL811Write (hci, SL11H_DEVADDRREG_B, 0x01);     //address0
330         SL811Write (hci, SL11H_SOFLOWREG, 0xe0);
331
332         if (!(status & 0x80)) {
333                 /* slow speed device connect directly to root-hub */
334
335                 DBG ("USBReset: low speed Device attached\n");
336                 SL811Write (hci, SL11H_CTLREG1, 0x8);
337                 mdelay (20);
338                 SL811Write (hci, SL11H_SOFTMRREG, 0xee);
339                 SL811Write (hci, SL11H_CTLREG1, 0x21);
340
341                 /* start the SOF or EOP */
342
343                 SL811Write (hci, SL11H_HOSTCTLREG_B, 0x01);
344                 hp->RHportStatus->portStatus |=
345                     (PORT_CONNECT_STAT | PORT_LOW_SPEED_DEV_ATTACH_STAT);
346
347                 /* clear all interrupt bits */
348
349                 for (status = 0; status < 20; status++)
350                         SL811Write (hci, SL11H_INTSTATREG, 0xff);
351         } else {
352                 /* full speed device connect directly to root hub */
353
354                 DBG ("USBReset: full speed Device attached\n");
355                 SL811Write (hci, SL11H_CTLREG1, 0x8);
356                 mdelay (20);
357                 SL811Write (hci, SL11H_SOFTMRREG, 0xae);
358                 SL811Write (hci, SL11H_CTLREG1, 0x01);
359
360                 /* start the SOF or EOP */
361
362                 SL811Write (hci, SL11H_HOSTCTLREG_B, 0x01);
363                 hp->RHportStatus->portStatus |= (PORT_CONNECT_STAT);
364                 hp->RHportStatus->portStatus &= ~PORT_LOW_SPEED_DEV_ATTACH_STAT;
365
366                 /* clear all interrupt bits */
367
368                 SL811Write (hci, SL11H_INTSTATREG, 0xff);
369
370         }
371
372         /* enable all interrupts */
373         SL811Write (hci, SL11H_INTENBLREG,
374                     SL11H_INTMASK_XFERDONE | SL11H_INTMASK_SOFINTR |
375                     SL11H_INTMASK_INSRMV);
376
377         return 1;
378 }
379
380 /*-------------------------------------------------------------------------*/
381 /* tl functions */
382 static inline void hc_mark_last_trans (hci_t * hci)
383 {
384         hcipriv_t *hp = &hci->hp;
385         __u8 *ptd = hp->tl;
386
387         dbg ("enter hc_mark_last_trans\n");
388         if (ptd == NULL) {
389                 printk ("hc_mark_last_trans: ptd = null\n");
390                 return;
391         }
392         if (hp->xferPktLen > 0)
393                 *(ptd + hp->tl_last) |= (1 << 3);
394 }
395
396 static inline void hc_flush_data_cache (hci_t * hci, void *data, int len)
397 {
398 }
399
400 /************************************************************************
401  * Function Name : hc_add_trans
402  *  
403  * This function sets up the SL811HS register and transmit the USB packets.
404  * 
405  * 1) Determine if enough time within the current frame to send the packet
406  * 2) Load the data into the SL811HS register
407  * 3) Set the appropriate command to the register and trigger the transmit
408  *
409  * Input:  hci = data structure for the host controller
410  *         len = data length
411  *         data = transmitting data
412  *         toggle = USB toggle bit, either 0 or 1
413  *         maxps = maximum packet size for this endpoint
414  *         slow = speed of the device
415  *         endpoint = endpoint number
416  *         address = USB address of the device
417  *         pid = packet ID
418  *         format = 
419  *         urb_state = the current stage of USB transaction
420  *       
421  * Return: 0 = no time left to schedule the transfer
422  *         1 = success 
423  *                
424  ***********************************************************************/
425 static inline int hc_add_trans (hci_t * hci, int len, void *data, int toggle,
426                                 int maxps, int slow, int endpoint, int address,
427                                 int pid, int format, int urb_state)
428 {
429         hcipriv_t *hp = &hci->hp;
430         __u16 speed;
431         int ii, jj, kk;
432
433         DBGFUNC ("enter hc_addr_trans: len =0x%x, toggle:0x%x, endpoing:0x%x,"
434                  " addr:0x%x, pid:0x%x,format:0x%x\n", len, toggle, endpoint,
435                  i address, pid, format);
436
437         if (len > maxps) {
438                 len = maxps;
439         }
440
441         speed = hp->RHportStatus->portStatus;
442         if (speed & PORT_LOW_SPEED_DEV_ATTACH_STAT) {
443 //      ii = (8*7*8 + 6*3) * len + 800; 
444                 ii = 8 * 8 * len + 1024;
445         } else {
446                 if (slow) {
447 //          ii = (8*7*8 + 6*3) * len + 800; 
448                         ii = 8 * 8 * len + 2048;
449                 } else
450 //          ii = (8*7 + 6*3)*len + 110;
451                         ii = 8 * len + 256;
452         }
453
454         ii += 2 * 10 * len;
455
456         jj = SL811Read (hci, SL11H_SOFTMRREG);
457         kk = (jj & 0xFF) * 64 - ii;
458
459         if (kk < 0) {
460                 DBGVERBOSE
461                     ("hc_add_trans: no bandwidth for schedule, ii = 0x%x,"
462                      "jj = 0x%x, len =0x%x, active_trans = 0x%x\n", ii, jj, len,
463                      hci->active_trans);
464                 return (-1);
465         }
466
467         if (pid != PID_IN) {
468                 /* Load data into hc */
469
470                 SL811BufWrite (hci, SL11H_DATA_START, (__u8 *) data, len);
471         }
472
473         /* transmit */
474
475         SL11StartXaction (hci, (__u8) address, (__u8) endpoint, (__u8) pid, len,
476                           toggle, slow, urb_state);
477
478         return len;
479 }
480
481 /************************************************************************
482  * Function Name : hc_parse_trans
483  *  
484  * This function checks the status of the transmitted or received packet
485  * and copy the data from the SL811HS register into a buffer.
486  *
487  * 1) Check the status of the packet 
488  * 2) If successful, and IN packet then copy the data from the SL811HS register
489  *    into a buffer
490  *
491  * Input:  hci = data structure for the host controller
492  *         actbytes = pointer to actual number of bytes
493  *         data = data buffer
494  *         cc = packet status
495  *         length = the urb transmit length
496  *         pid = packet ID
497  *         urb_state = the current stage of USB transaction
498  *       
499  * Return: 0 
500  ***********************************************************************/
501 static inline int hc_parse_trans (hci_t * hci, int *actbytes, __u8 * data,
502                                   int *cc, int *toggle, int length, int pid,
503                                   int urb_state)
504 {
505         __u8 addr;
506         __u8 len;
507
508         DBGFUNC ("enter hc_parse_trans\n");
509
510         /* get packet status; convert ack rcvd to ack-not-rcvd */
511
512         *cc = (int) SL811Read (hci, SL11H_PKTSTATREG);
513
514         if (*cc &
515             (SL11H_STATMASK_ERROR | SL11H_STATMASK_TMOUT | SL11H_STATMASK_OVF |
516              SL11H_STATMASK_NAK | SL11H_STATMASK_STALL)) {
517                 if (*cc & SL11H_STATMASK_OVF)
518                         DBGERR ("parse trans: error recv ack, cc = 0x%x, TX_BASE_Len = "
519                                 "0x%x, TX_count=0x%x\n", *cc,
520                                 SL811Read (hci, SL11H_BUFLNTHREG),
521                                 SL811Read (hci, SL11H_XFERCNTREG));
522
523         } else {
524                 DBGVERBOSE ("parse trans: recv ack, cc = 0x%x, len = 0x%x, \n",
525                             *cc, length);
526
527                 /* Successful data */
528                 if ((pid == PID_IN) && (urb_state != US_CTRL_SETUP)) {
529
530                         /* Find the base address */
531                         addr = SL811Read (hci, SL11H_BUFADDRREG);
532
533                         /* Find the Transmit Length */
534                         len = SL811Read (hci, SL11H_BUFLNTHREG);
535
536                         /* The actual data length = xmit length reg - xfer count reg */
537                         *actbytes = len - SL811Read (hci, SL11H_XFERCNTREG);
538
539                         if ((data != NULL) && (*actbytes > 0)) {
540                                 SL811BufRead (hci, addr, data, *actbytes);
541
542                         } else if ((data == NULL) && (*actbytes <= 0)) {
543                                 DBGERR ("hc_parse_trans: data = NULL or actbyte = 0x%x\n",
544                                         *actbytes);
545                                 return 0;
546                         }
547                 } else if (pid == PID_OUT) {
548                         *actbytes = length;
549                 } else {
550                         // printk ("ERR:parse_trans, pid != IN or OUT, pid = 0x%x\n", pid);
551                 }
552                 *toggle = !*toggle;
553         }
554
555         return 0;
556 }
557
558 /************************************************************************
559  * Function Name : hc_start_int
560  *  
561  * This function enables SL811HS interrupts
562  *
563  * Input:  hci = data structure for the host controller
564  *       
565  * Return: none 
566  ***********************************************************************/
567 static void hc_start_int (hci_t * hci)
568 {
569 #ifdef HC_SWITCH_INT
570         int mask =
571             SL11H_INTMASK_XFERDONE | SL11H_INTMASK_SOFINTR |
572             SL11H_INTMASK_INSRMV | SL11H_INTMASK_USBRESET;
573         SL811Write (hci, IntEna, mask);
574 #endif
575 }
576
577 /************************************************************************
578  * Function Name : hc_stop_int
579  *  
580  * This function disables SL811HS interrupts
581  *
582  * Input:  hci = data structure for the host controller
583  *       
584  * Return: none 
585  ***********************************************************************/
586 static void hc_stop_int (hci_t * hci)
587 {
588 #ifdef HC_SWITCH_INT
589         SL811Write (hci, SL11H_INTSTATREG, 0xff);
590 //  SL811Write(hci, SL11H_INTENBLREG, SL11H_INTMASK_INSRMV);
591
592 #endif
593 }
594
595 /************************************************************************
596  * Function Name : handleInsRmvIntr
597  *  
598  * This function handles the insertion or removal of device on  SL811HS. 
599  * It resets the controller and updates the port status
600  *
601  * Input:  hci = data structure for the host controller
602  *       
603  * Return: none 
604  ***********************************************************************/
605 void handleInsRmvIntr (hci_t * hci)
606 {
607         hcipriv_t *hp = &hci->hp;
608
609         USBReset (hci);
610
611         /* Changes in connection status */
612
613         hp->RHportStatus->portChange |= PORT_CONNECT_CHANGE;
614
615         /* Port Enable or Disable */
616
617         if (hp->RHportStatus->portStatus & PORT_CONNECT_STAT) {
618                 /* device is connected to the port:
619                  *    1) Enable port 
620                  *    2) Resume ?? 
621                  */
622 //               hp->RHportStatus->portChange |= PORT_ENABLE_CHANGE;
623
624                 /* Over Current is not supported by the SL811 HW ?? */
625
626                 /* How about the Port Power ?? */
627
628         } else {
629                 /* Device has disconnect:
630                  *    1) Disable port
631                  */
632
633                 hp->RHportStatus->portStatus &= ~(PORT_ENABLE_STAT);
634                 hp->RHportStatus->portChange |= PORT_ENABLE_CHANGE;
635
636         }
637 }
638
639 /*****************************************************************
640  *
641  * Function Name: SL11StartXaction
642  *  
643  * This functions load the registers with appropriate value and 
644  * transmit the packet.                           
645  *
646  * Input:  hci = data structure for the host controller
647  *         addr = USB address of the device
648  *         epaddr = endpoint number
649  *         pid = packet ID
650  *         len = data length
651  *         toggle = USB toggle bit, either 0 or 1
652  *         slow = speed of the device
653  *         urb_state = the current stage of USB transaction
654  *
655  * Return: 0 = error; 1 = successful
656  *                
657  *****************************************************************/
658 int SL11StartXaction (hci_t * hci, __u8 addr, __u8 epaddr, int pid, int len,
659                       int toggle, int slow, int urb_state)
660 {
661
662         hcipriv_t *hp = &hci->hp;
663         __u8 cmd = 0;
664         __u8 setup_data[4];
665         __u16 speed;
666
667         speed = hp->RHportStatus->portStatus;
668         if (!(speed & PORT_LOW_SPEED_DEV_ATTACH_STAT) && slow) {
669                 cmd |= SL11H_HCTLMASK_PREAMBLE;
670         }
671         switch (pid) {
672         case PID_SETUP:
673                 cmd &= SL11H_HCTLMASK_PREAMBLE;
674                 cmd |=
675                     (SL11H_HCTLMASK_ARM | SL11H_HCTLMASK_ENBLEP |
676                      SL11H_HCTLMASK_WRITE);
677                 break;
678
679         case PID_OUT:
680                 cmd &= (SL11H_HCTLMASK_SEQ | SL11H_HCTLMASK_PREAMBLE);
681                 cmd |=
682                     (SL11H_HCTLMASK_ARM | SL11H_HCTLMASK_ENBLEP |
683                      SL11H_HCTLMASK_WRITE);
684                 if (toggle) {
685                         cmd |= SL11H_HCTLMASK_SEQ;
686                 }
687                 break;
688
689         case PID_IN:
690                 cmd &= (SL11H_HCTLMASK_SEQ | SL11H_HCTLMASK_PREAMBLE);
691                 cmd |= (SL11H_HCTLMASK_ARM | SL11H_HCTLMASK_ENBLEP);
692                 break;
693
694         default:
695                 DBGERR ("ERR: SL11StartXaction: unknow pid = 0x%x\n", pid);
696                 return 0;
697         }
698         setup_data[0] = SL11H_DATA_START;
699         setup_data[1] = len;
700         setup_data[2] = (((pid & 0x0F) << 4) | (epaddr & 0xF));
701         setup_data[3] = addr & 0x7F;
702
703         SL811BufWrite (hci, SL11H_BUFADDRREG, (__u8 *) & setup_data[0], 4);
704
705         SL811Write (hci, SL11H_HOSTCTLREG, cmd);
706
707 #if 0
708         /* The SL811 has a hardware flaw when hub devices sends out
709          * SE0 between packets. It has been found in a TI chipset and
710          * cypress hub chipset. It causes the SL811 to hang
711          * The workaround is to re-issue the preample again.
712          */
713
714         if ((cmd & SL11H_HCTLMASK_PREAMBLE)) {
715                 SL811Write (hci, SL11H_PIDEPREG_B, 0xc0);
716                 SL811Write (hci, SL11H_HOSTCTLREG_B, 0x1);      // send the premable
717         }
718 #endif
719         return 1;
720 }
721
722 /*****************************************************************
723  *
724  * Function Name: hc_interrupt
725  *
726  * Interrupt service routine. 
727  *
728  * 1) determine the causes of interrupt
729  * 2) clears all interrupts
730  * 3) calls appropriate function to service the interrupt
731  *
732  * Input:  irq = interrupt line associated with the controller 
733  *         hci = data structure for the host controller
734  *         r = holds the snapshot of the processor's context before 
735  *             the processor entered interrupt code. (not used here) 
736  *
737  * Return value  : None.
738  *                
739  *****************************************************************/
740 static void hc_interrupt (int irq, void *__hci, struct pt_regs *r)
741 {
742         char ii;
743         hci_t *hci = __hci;
744         int isExcessNak = 0;
745         int urb_state = 0;
746         char tmpIrq = 0;
747
748         /* Get value from interrupt status register */
749
750         ii = SL811Read (hci, SL11H_INTSTATREG);
751
752         if (ii & SL11H_INTMASK_INSRMV) {
753                 /* Device insertion or removal detected for the USB port */
754
755                 SL811Write (hci, SL11H_INTENBLREG, 0);
756                 SL811Write (hci, SL11H_CTLREG1, 0);
757                 mdelay (100);   // wait for device stable 
758                 handleInsRmvIntr (hci);
759                 return;
760         }
761
762         /* Clear all interrupts */
763
764         SL811Write (hci, SL11H_INTSTATREG, 0xff);
765
766         if (ii & SL11H_INTMASK_XFERDONE) {
767                 /* USB Done interrupt occurred */
768
769                 urb_state = sh_done_list (hci, &isExcessNak);
770 #ifdef WARNING
771                 if (hci->td_array->len > 0)
772                         printk ("WARNING: IRQ, td_array->len = 0x%x, s/b:0\n",
773                                 hci->td_array->len);
774 #endif
775                 if (hci->td_array->len == 0 && !isExcessNak
776                     && !(ii & SL11H_INTMASK_SOFINTR) && (urb_state == 0)) {
777                         if (urb_state == 0) {
778                                 /* All urb_state has not been finished yet! 
779                                  * continue with the current urb transaction 
780                                  */
781
782                                 if (hci->last_packet_nak == 0) {
783                                         if (!usb_pipecontrol
784                                             (hci->td_array->td[0].urb->pipe))
785                                                 sh_add_packet (hci, hci->td_array-> td[0].urb);
786                                 }
787                         } else {
788                                 /* The last transaction has completed:
789                                  * schedule the next transaction 
790                                  */
791
792                                 sh_schedule_trans (hci, 0);
793                         }
794                 }
795                 SL811Write (hci, SL11H_INTSTATREG, 0xff);
796                 return;
797         }
798
799         if (ii & SL11H_INTMASK_SOFINTR) {
800                 hci->frame_number = (hci->frame_number + 1) % 2048;
801                 if (hci->td_array->len == 0)
802                         sh_schedule_trans (hci, 1);
803                 else {
804                         if (sofWaitCnt++ > 100) {
805                                 /* The last transaction has not completed.
806                                  * Need to retire the current td, and let
807                                  * it transmit again later on.
808                                  * (THIS NEEDS TO BE WORK ON MORE, IT SHOULD NEVER 
809                                  *  GET TO THIS POINT)
810                                  */
811
812                                 DBGERR ("SOF interrupt: td_array->len = 0x%x, s/b: 0\n",
813                                         hci->td_array->len);
814                                 urb_print (hci->td_array->td[hci->td_array->len - 1].urb,
815                                            "INTERRUPT", 0);
816                                 sh_done_list (hci, &isExcessNak);
817                                 SL811Write (hci, SL11H_INTSTATREG, 0xff);
818                                 hci->td_array->len = 0;
819                                 sofWaitCnt = 0;
820                         }
821                 }
822                 tmpIrq = SL811Read (hci, SL11H_INTSTATREG) & SL811Read (hci, SL11H_INTENBLREG);
823                 if (tmpIrq) {
824                         DBG ("IRQ occurred while service SOF: irq = 0x%x\n",
825                              tmpIrq);
826
827                         /* If we receive a DONE IRQ after schedule, need to 
828                          * handle DONE IRQ again 
829                          */
830
831                         if (tmpIrq & SL11H_INTMASK_XFERDONE) {
832                                 DBGERR ("IRQ occurred while service SOF: irq = 0x%x\n",
833                                         tmpIrq);
834                                 urb_state = sh_done_list (hci, &isExcessNak);
835                         }
836                         SL811Write (hci, SL11H_INTSTATREG, 0xff);
837                 }
838         } else {
839                 DBG ("SL811 ISR: unknown, int = 0x%x \n", ii);
840         }
841
842         SL811Write (hci, SL11H_INTSTATREG, 0xff);
843         return;
844 }
845
846 /*****************************************************************
847  *
848  * Function Name: hc_reset
849  *
850  * This function does register test and resets the SL811HS 
851  * controller.
852  *
853  * Input:  hci = data structure for the host controller
854  *
855  * Return value  : 0
856  *                
857  *****************************************************************/
858 static int hc_reset (hci_t * hci)
859 {
860         int attachFlag = 0;
861
862         DBGFUNC ("Enter hc_reset\n");
863         regTest (hci);
864         attachFlag = USBReset (hci);
865         if (attachFlag) {
866                 setPortChange (hci, PORT_CONNECT_CHANGE);
867         }
868         return (0);
869 }
870
871 /*****************************************************************
872  *
873  * Function Name: hc_alloc_trans_buffer
874  *
875  * This function allocates all transfer buffer  
876  *
877  * Input:  hci = data structure for the host controller
878  *
879  * Return value  : 0
880  *                
881  *****************************************************************/
882 static int hc_alloc_trans_buffer (hci_t * hci)
883 {
884         hcipriv_t *hp = &hci->hp;
885         int maxlen;
886
887         hp->itl0_len = 0;
888         hp->itl1_len = 0;
889         hp->atl_len = 0;
890
891         hp->itl_buffer_len = 1024;
892         hp->atl_buffer_len = 4096 - 2 * hp->itl_buffer_len;     /* 2048 */
893
894         maxlen = (hp->itl_buffer_len > hp->atl_buffer_len) ? hp->itl_buffer_len : hp->atl_buffer_len;
895
896         hp->tl = kmalloc (maxlen, GFP_KERNEL);
897
898         if (!hp->tl)
899                 return -ENOMEM;
900
901         memset (hp->tl, 0, maxlen);
902         return 0;
903 }
904
905 /*****************************************************************
906  *
907  * Function Name: getPortStatusAndChange
908  *
909  * This function gets the ports status from SL811 and format it 
910  * to a USB request format
911  *
912  * Input:  hci = data structure for the host controller
913  *
914  * Return value  : port status and change
915  *                
916  *****************************************************************/
917 static __u32 getPortStatusAndChange (hci_t * hci)
918 {
919         hcipriv_t *hp = &hci->hp;
920         __u32 portstatus;
921
922         DBGFUNC ("enter getPorStatusAndChange\n");
923
924         portstatus = hp->RHportStatus->portChange << 16 | hp->RHportStatus->portStatus;
925
926         return (portstatus);
927 }
928
929 /*****************************************************************
930  *
931  * Function Name: setPortChange
932  *
933  * This function set the bit position of portChange.
934  *
935  * Input:  hci = data structure for the host controller
936  *         bitPos = the bit position
937  *
938  * Return value  : none 
939  *                
940  *****************************************************************/
941 static void setPortChange (hci_t * hci, __u16 bitPos)
942 {
943         hcipriv_t *hp = &hci->hp;
944
945         switch (bitPos) {
946         case PORT_CONNECT_STAT:
947                 hp->RHportStatus->portChange |= bitPos;
948                 break;
949
950         case PORT_ENABLE_STAT:
951                 hp->RHportStatus->portChange |= bitPos;
952                 break;
953
954         case PORT_RESET_STAT:
955                 hp->RHportStatus->portChange |= bitPos;
956                 break;
957
958         case PORT_POWER_STAT:
959                 hp->RHportStatus->portChange |= bitPos;
960                 break;
961
962         case PORT_SUSPEND_STAT:
963                 hp->RHportStatus->portChange |= bitPos;
964                 break;
965
966         case PORT_OVER_CURRENT_STAT:
967                 hp->RHportStatus->portChange |= bitPos;
968                 break;
969         }
970 }
971
972 /*****************************************************************
973  *
974  * Function Name: clrPortChange
975  *
976  * This function clear the bit position of portChange.
977  *
978  * Input:  hci = data structure for the host controller
979  *         bitPos = the bit position
980  *
981  * Return value  : none 
982  *                
983  *****************************************************************/
984 static void clrPortChange (hci_t * hci, __u16 bitPos)
985 {
986         hcipriv_t *hp = &hci->hp;
987         switch (bitPos) {
988         case PORT_CONNECT_CHANGE:
989                 hp->RHportStatus->portChange &= ~bitPos;
990                 break;
991
992         case PORT_ENABLE_CHANGE:
993                 hp->RHportStatus->portChange &= ~bitPos;
994                 break;
995
996         case PORT_RESET_CHANGE:
997                 hp->RHportStatus->portChange &= ~bitPos;
998                 break;
999
1000         case PORT_SUSPEND_CHANGE:
1001                 hp->RHportStatus->portChange &= ~bitPos;
1002                 break;
1003
1004         case PORT_OVER_CURRENT_CHANGE:
1005                 hp->RHportStatus->portChange &= ~bitPos;
1006                 break;
1007         }
1008 }
1009
1010 /*****************************************************************
1011  *
1012  * Function Name: clrPortStatus
1013  *
1014  * This function clear the bit position of portStatus.
1015  *
1016  * Input:  hci = data structure for the host controller
1017  *         bitPos = the bit position
1018  *
1019  * Return value  : none 
1020  *                
1021  *****************************************************************/
1022 static void clrPortStatus (hci_t * hci, __u16 bitPos)
1023 {
1024         hcipriv_t *hp = &hci->hp;
1025         switch (bitPos) {
1026         case PORT_ENABLE_STAT:
1027                 hp->RHportStatus->portStatus &= ~bitPos;
1028                 break;
1029
1030         case PORT_RESET_STAT:
1031                 hp->RHportStatus->portStatus &= ~bitPos;
1032                 break;
1033
1034         case PORT_POWER_STAT:
1035                 hp->RHportStatus->portStatus &= ~bitPos;
1036                 break;
1037
1038         case PORT_SUSPEND_STAT:
1039                 hp->RHportStatus->portStatus &= ~bitPos;
1040                 break;
1041         }
1042 }
1043
1044 /*****************************************************************
1045  *
1046  * Function Name: setPortStatus
1047  *
1048  * This function set the bit position of portStatus.
1049  *
1050  * Input:  hci = data structure for the host controller
1051  *         bitPos = the bit position
1052  *
1053  * Return value  : none 
1054  *                
1055  *****************************************************************/
1056 static void setPortStatus (hci_t * hci, __u16 bitPos)
1057 {
1058         hcipriv_t *hp = &hci->hp;
1059         switch (bitPos) {
1060         case PORT_ENABLE_STAT:
1061                 hp->RHportStatus->portStatus |= bitPos;
1062                 break;
1063
1064         case PORT_RESET_STAT:
1065                 hp->RHportStatus->portStatus |= bitPos;
1066                 break;
1067
1068         case PORT_POWER_STAT:
1069                 hp->RHportStatus->portStatus |= bitPos;
1070                 break;
1071
1072         case PORT_SUSPEND_STAT:
1073                 hp->RHportStatus->portStatus |= bitPos;
1074                 break;
1075         }
1076 }
1077
1078 /*****************************************************************
1079  *
1080  * Function Name: hc_start
1081  *
1082  * This function starts the root hub functionality. 
1083  *
1084  * Input:  hci = data structure for the host controller
1085  *
1086  * Return value  : 0 
1087  *                
1088  *****************************************************************/
1089 static int hc_start (hci_t * hci)
1090 {
1091         DBGFUNC ("Enter hc_start\n");
1092
1093         rh_connect_rh (hci);
1094
1095         return 0;
1096 }
1097
1098 /*****************************************************************
1099  *
1100  * Function Name: hc_alloc_hci
1101  *
1102  * This function allocates all data structure and store in the 
1103  * private data structure. 
1104  *
1105  * Input:  hci = data structure for the host controller
1106  *
1107  * Return value  : 0 
1108  *                
1109  *****************************************************************/
1110 static hci_t *__devinit hc_alloc_hci (void)
1111 {
1112         hci_t *hci;
1113         hcipriv_t *hp;
1114         portstat_t *ps;
1115         struct usb_bus *bus;
1116
1117         DBGFUNC ("Enter hc_alloc_hci\n");
1118         hci = (hci_t *) kmalloc (sizeof (hci_t), GFP_KERNEL);
1119         if (!hci)
1120                 return NULL;
1121
1122         memset (hci, 0, sizeof (hci_t));
1123
1124         hp = &hci->hp;
1125
1126         hp->irq = -1;
1127         hp->hcport = -1;
1128
1129         /* setup root hub port status */
1130
1131         ps = (portstat_t *) kmalloc (sizeof (portstat_t), GFP_KERNEL);
1132
1133         if (!ps)
1134                 return NULL;
1135         ps->portStatus = PORT_STAT_DEFAULT;
1136         ps->portChange = PORT_CHANGE_DEFAULT;
1137         hp->RHportStatus = ps;
1138
1139         hci->nakCnt = 0;
1140         hci->last_packet_nak = 0;
1141
1142         hci->a_td_array.len = 0;
1143         hci->i_td_array[0].len = 0;
1144         hci->i_td_array[1].len = 0;
1145         hci->td_array = &hci->a_td_array;
1146         hci->active_urbs = 0;
1147         hci->active_trans = 0;
1148         INIT_LIST_HEAD (&hci->hci_hcd_list);
1149         list_add (&hci->hci_hcd_list, &hci_hcd_list);
1150         init_waitqueue_head (&hci->waitq);
1151
1152         INIT_LIST_HEAD (&hci->ctrl_list);
1153         INIT_LIST_HEAD (&hci->bulk_list);
1154         INIT_LIST_HEAD (&hci->iso_list);
1155         INIT_LIST_HEAD (&hci->intr_list);
1156         INIT_LIST_HEAD (&hci->del_list);
1157
1158         bus = usb_alloc_bus (&hci_device_operations);
1159         if (!bus) {
1160                 kfree (hci);
1161                 kfree (ps);
1162                 return NULL;
1163         }
1164
1165         hci->bus = bus;
1166         bus->hcpriv = (void *) hci;
1167
1168         return hci;
1169 }
1170
1171 /*****************************************************************
1172  *
1173  * Function Name: hc_release_hci
1174  *
1175  * This function De-allocate all resources  
1176  *
1177  * Input:  hci = data structure for the host controller
1178  *
1179  * Return value  : 0 
1180  *                
1181  *****************************************************************/
1182 static void hc_release_hci (hci_t * hci)
1183 {
1184         hcipriv_t *hp = &hci->hp;
1185
1186         DBGFUNC ("Enter hc_release_hci\n");
1187
1188         /* disconnect all devices */
1189         if (hci->bus->root_hub)
1190                 usb_disconnect (&hci->bus->root_hub);
1191
1192         hc_reset (hci);
1193
1194         if (hp->tl)
1195                 kfree (hp->tl);
1196
1197         if (hp->hcport > 0) {
1198                 release_region (hp->hcport, 2);
1199                 hp->hcport = 0;
1200         }
1201
1202         if (hp->irq >= 0) {
1203                 free_irq (hp->irq, hci);
1204                 hp->irq = -1;
1205         }
1206
1207         usb_deregister_bus (hci->bus);
1208         usb_put_bus (hci->bus);
1209
1210         list_del_init (&hci->hci_hcd_list);
1211
1212         kfree (hci);
1213 }
1214
1215 /*****************************************************************
1216  *
1217  * Function Name: init_irq
1218  *
1219  * This function is board specific.  It sets up the interrupt to 
1220  * be an edge trigger and trigger on the rising edge  
1221  *
1222  * Input: none 
1223  *
1224  * Return value  : none 
1225  *                
1226  *****************************************************************/
1227 void init_irq (void)
1228 {
1229         GPDR &= ~(1 << 13);
1230         set_GPIO_IRQ_edge (1 << 13, GPIO_RISING_EDGE);
1231 }
1232
1233 /*****************************************************************
1234  *
1235  * Function Name: hc_found_hci
1236  *
1237  * This function request IO memory regions, request IRQ, and
1238  * allocate all other resources. 
1239  *
1240  * Input: addr = first IO address
1241  *        addr2 = second IO address
1242  *        irq = interrupt number 
1243  *
1244  * Return: 0 = success or error condition 
1245  *                
1246  *****************************************************************/
1247 static int __devinit hc_found_hci (int addr, int addr2, int irq)
1248 {
1249         hci_t *hci;
1250         hcipriv_t *hp;
1251
1252         DBGFUNC ("Enter hc_found_hci\n");
1253         hci = hc_alloc_hci ();
1254         if (!hci) {
1255                 return -ENOMEM;
1256         }
1257
1258         init_irq ();
1259         hp = &hci->hp;
1260
1261         if (!request_region (addr, 256, "SL811 USB HOST")) {
1262                 DBGERR ("request address %d failed", addr);
1263                 hc_release_hci (hci);
1264                 return -EBUSY;
1265         }
1266         hp->hcport = addr;
1267         if (!hp->hcport) {
1268                 DBGERR ("Error mapping SL811 Memory 0x%x", hp->hcport);
1269         }
1270
1271         if (!request_region (addr2, 256, "SL811 USB HOST")) {
1272                 DBGERR ("request address %d failed", addr2);
1273                 hc_release_hci (hci);
1274                 return -EBUSY;
1275         }
1276         hp->hcport2 = addr2;
1277         if (!hp->hcport2) {
1278                 DBGERR ("Error mapping SL811 Memory 0x%x", hp->hcport2);
1279         }
1280
1281         if (hc_alloc_trans_buffer (hci)) {
1282                 hc_release_hci (hci);
1283                 return -ENOMEM;
1284         }
1285
1286         usb_register_bus (hci->bus);
1287
1288         if (request_irq (irq, hc_interrupt, 0, "SL811", hci) != 0) {
1289                 DBGERR ("request interrupt %d failed", irq);
1290                 hc_release_hci (hci);
1291                 return -EBUSY;
1292         }
1293         hp->irq = irq;
1294
1295         printk (KERN_INFO __FILE__ ": USB SL811 at %x, addr2 = %x, IRQ %d\n",
1296                 addr, addr2, irq);
1297         hc_reset (hci);
1298
1299         if (hc_start (hci) < 0) {
1300                 DBGERR ("can't start usb-%x", addr);
1301                 hc_release_hci (hci);
1302                 return -EBUSY;
1303         }
1304
1305         return 0;
1306 }
1307
1308 /*****************************************************************
1309  *
1310  * Function Name: hci_hcd_init
1311  *
1312  * This is an init function, and it is the first function being called
1313  *
1314  * Input: none 
1315  *
1316  * Return: 0 = success or error condition 
1317  *                
1318  *****************************************************************/
1319 static int __init hci_hcd_init (void)
1320 {
1321         int ret;
1322
1323         DBGFUNC ("Enter hci_hcd_init\n");
1324         if (usb_disabled())
1325                 return -ENODEV;
1326
1327         ret = hc_found_hci (base_addr, data_reg_addr, irq);
1328
1329         return ret;
1330 }
1331
1332 /*****************************************************************
1333  *
1334  * Function Name: hci_hcd_cleanup
1335  *
1336  * This is a cleanup function, and it is called when module is 
1337  * unloaded. 
1338  *
1339  * Input: none 
1340  *
1341  * Return: none 
1342  *                
1343  *****************************************************************/
1344 static void __exit hci_hcd_cleanup (void)
1345 {
1346         struct list_head *hci_l;
1347         hci_t *hci;
1348
1349         DBGFUNC ("Enter hci_hcd_cleanup\n");
1350         for (hci_l = hci_hcd_list.next; hci_l != &hci_hcd_list;) {
1351                 hci = list_entry (hci_l, hci_t, hci_hcd_list);
1352                 hci_l = hci_l->next;
1353                 hc_release_hci (hci);
1354         }
1355 }
1356
1357 module_init (hci_hcd_init);
1358 module_exit (hci_hcd_cleanup);
1359
1360 MODULE_AUTHOR ("Pei Liu <pbl@cypress.com>");
1361 MODULE_DESCRIPTION ("USB SL811HS Host Controller Driver");