1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44#include <common.h>
45#include <asm/io.h>
46#include <usb.h>
47#include <malloc.h>
48#include <linux/list.h>
49
50
51
52
53
54
55
56
57
58
59#ifdef ISP116X_HCD_USE_UDELAY
60#define UDELAY 1
61#endif
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82#ifdef ISP116X_HCD_USE_EXTRA_DELAY
83#define EXTRA_DELAY 2
84#endif
85
86
87
88
89#undef DEBUG
90#undef TRACE
91#undef VERBOSE
92
93#include "isp116x.h"
94
95#define DRIVER_VERSION "08 Jan 2007"
96static const char hcd_name[] = "isp116x-hcd";
97
98struct isp116x isp116x_dev;
99struct isp116x_platform_data isp116x_board;
100static int got_rhsc;
101struct usb_device *devgone;
102static int rh_devnum;
103
104
105
106static int isp116x_reset(struct isp116x *isp116x);
107
108
109
110#define isp116x_show_reg(d, r) { \
111 if ((r) < 0x20) { \
112 DBG("%-12s[%02x]: %08x", #r, \
113 r, isp116x_read_reg32(d, r)); \
114 } else { \
115 DBG("%-12s[%02x]: %04x", #r, \
116 r, isp116x_read_reg16(d, r)); \
117 } \
118}
119
120#define isp116x_show_regs(d) { \
121 isp116x_show_reg(d, HCREVISION); \
122 isp116x_show_reg(d, HCCONTROL); \
123 isp116x_show_reg(d, HCCMDSTAT); \
124 isp116x_show_reg(d, HCINTSTAT); \
125 isp116x_show_reg(d, HCINTENB); \
126 isp116x_show_reg(d, HCFMINTVL); \
127 isp116x_show_reg(d, HCFMREM); \
128 isp116x_show_reg(d, HCFMNUM); \
129 isp116x_show_reg(d, HCLSTHRESH); \
130 isp116x_show_reg(d, HCRHDESCA); \
131 isp116x_show_reg(d, HCRHDESCB); \
132 isp116x_show_reg(d, HCRHSTATUS); \
133 isp116x_show_reg(d, HCRHPORT1); \
134 isp116x_show_reg(d, HCRHPORT2); \
135 isp116x_show_reg(d, HCHWCFG); \
136 isp116x_show_reg(d, HCDMACFG); \
137 isp116x_show_reg(d, HCXFERCTR); \
138 isp116x_show_reg(d, HCuPINT); \
139 isp116x_show_reg(d, HCuPINTENB); \
140 isp116x_show_reg(d, HCCHIPID); \
141 isp116x_show_reg(d, HCSCRATCH); \
142 isp116x_show_reg(d, HCITLBUFLEN); \
143 isp116x_show_reg(d, HCATLBUFLEN); \
144 isp116x_show_reg(d, HCBUFSTAT); \
145 isp116x_show_reg(d, HCRDITL0LEN); \
146 isp116x_show_reg(d, HCRDITL1LEN); \
147}
148
149#if defined(TRACE)
150
151static int isp116x_get_current_frame_number(struct usb_device *usb_dev)
152{
153 struct isp116x *isp116x = &isp116x_dev;
154
155 return isp116x_read_reg32(isp116x, HCFMNUM);
156}
157
158static void dump_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
159 int len, char *str)
160{
161#if defined(VERBOSE)
162 int i;
163#endif
164
165 DBG("%s URB:[%4x] dev:%2d,ep:%2d-%c,type:%s,len:%d stat:%#lx",
166 str,
167 isp116x_get_current_frame_number(dev),
168 usb_pipedevice(pipe),
169 usb_pipeendpoint(pipe),
170 usb_pipeout(pipe) ? 'O' : 'I',
171 usb_pipetype(pipe) < 2 ?
172 (usb_pipeint(pipe) ?
173 "INTR" : "ISOC") :
174 (usb_pipecontrol(pipe) ? "CTRL" : "BULK"), len, dev->status);
175#if defined(VERBOSE)
176 if (len > 0 && buffer) {
177 printf(__FILE__ ": data(%d):", len);
178 for (i = 0; i < 16 && i < len; i++)
179 printf(" %02x", ((__u8 *) buffer)[i]);
180 printf("%s\n", i < len ? "..." : "");
181 }
182#endif
183}
184
185#define PTD_DIR_STR(ptd) ({char __c; \
186 switch(PTD_GET_DIR(ptd)){ \
187 case 0: __c = 's'; break; \
188 case 1: __c = 'o'; break; \
189 default: __c = 'i'; break; \
190 }; __c;})
191
192
193
194
195
196static inline void dump_ptd(struct ptd *ptd)
197{
198#if defined(VERBOSE)
199 int k;
200#endif
201
202 DBG("PTD(ext) : cc:%x %d%c%d %d,%d,%d t:%x %x%x%x",
203 PTD_GET_CC(ptd),
204 PTD_GET_FA(ptd), PTD_DIR_STR(ptd), PTD_GET_EP(ptd),
205 PTD_GET_COUNT(ptd), PTD_GET_LEN(ptd), PTD_GET_MPS(ptd),
206 PTD_GET_TOGGLE(ptd),
207 PTD_GET_ACTIVE(ptd), PTD_GET_SPD(ptd), PTD_GET_LAST(ptd));
208#if defined(VERBOSE)
209 printf("isp116x: %s: PTD(byte): ", __FUNCTION__);
210 for (k = 0; k < sizeof(struct ptd); ++k)
211 printf("%02x ", ((u8 *) ptd)[k]);
212 printf("\n");
213#endif
214}
215
216static inline void dump_ptd_data(struct ptd *ptd, u8 * buf, int type)
217{
218#if defined(VERBOSE)
219 int k;
220
221 if (type == 0 ) {
222 printf("isp116x: %s: out data: ", __FUNCTION__);
223 for (k = 0; k < PTD_GET_LEN(ptd); ++k)
224 printf("%02x ", ((u8 *) buf)[k]);
225 printf("\n");
226 }
227 if (type == 1 ) {
228 printf("isp116x: %s: in data: ", __FUNCTION__);
229 for (k = 0; k < PTD_GET_COUNT(ptd); ++k)
230 printf("%02x ", ((u8 *) buf)[k]);
231 printf("\n");
232 }
233
234 if (PTD_GET_LAST(ptd))
235 DBG("--- last PTD ---");
236#endif
237}
238
239#else
240
241#define dump_msg(dev, pipe, buffer, len, str) do { } while (0)
242#define dump_pkt(dev, pipe, buffer, len, setup, str, small) do {} while (0)
243
244#define dump_ptd(ptd) do {} while (0)
245#define dump_ptd_data(ptd, buf, type) do {} while (0)
246
247#endif
248
249
250
251#include <usbroothubdes.h>
252
253
254
255
256
257
258
259static int rh_check_port_status(struct isp116x *isp116x)
260{
261 u32 temp, ndp, i;
262 int res;
263
264 res = -1;
265 temp = isp116x_read_reg32(isp116x, HCRHSTATUS);
266 ndp = (temp & RH_A_NDP);
267 for (i = 0; i < ndp; i++) {
268 temp = isp116x_read_reg32(isp116x, HCRHPORT1 + i);
269
270 if (((temp & (RH_PS_PESC | RH_PS_CSC)) ==
271 (RH_PS_PESC | RH_PS_CSC)) && ((temp & RH_PS_CCS) == 0)) {
272 res = i;
273 break;
274 }
275 }
276 return res;
277}
278
279
280
281
282
283static void write_ptddata_to_fifo(struct isp116x *isp116x, void *buf, int len)
284{
285 u8 *dp = (u8 *) buf;
286 u16 *dp2 = (u16 *) buf;
287 u16 w;
288 int quot = len % 4;
289
290 if ((unsigned long)dp2 & 1) {
291
292 for (; len > 1; len -= 2) {
293 w = *dp++;
294 w |= *dp++ << 8;
295 isp116x_raw_write_data16(isp116x, w);
296 }
297 if (len)
298 isp116x_write_data16(isp116x, (u16) * dp);
299 } else {
300
301 for (; len > 1; len -= 2)
302 isp116x_raw_write_data16(isp116x, *dp2++);
303 if (len)
304 isp116x_write_data16(isp116x, 0xff & *((u8 *) dp2));
305 }
306 if (quot == 1 || quot == 2)
307 isp116x_raw_write_data16(isp116x, 0);
308}
309
310
311
312static void read_ptddata_from_fifo(struct isp116x *isp116x, void *buf, int len)
313{
314 u8 *dp = (u8 *) buf;
315 u16 *dp2 = (u16 *) buf;
316 u16 w;
317 int quot = len % 4;
318
319 if ((unsigned long)dp2 & 1) {
320
321 for (; len > 1; len -= 2) {
322 w = isp116x_raw_read_data16(isp116x);
323 *dp++ = w & 0xff;
324 *dp++ = (w >> 8) & 0xff;
325 }
326 if (len)
327 *dp = 0xff & isp116x_read_data16(isp116x);
328 } else {
329
330 for (; len > 1; len -= 2)
331 *dp2++ = isp116x_raw_read_data16(isp116x);
332 if (len)
333 *(u8 *) dp2 = 0xff & isp116x_read_data16(isp116x);
334 }
335 if (quot == 1 || quot == 2)
336 isp116x_raw_read_data16(isp116x);
337}
338
339
340
341static void pack_fifo(struct isp116x *isp116x, struct usb_device *dev,
342 unsigned long pipe, struct ptd *ptd, int n, void *data,
343 int len)
344{
345 int buflen = n * sizeof(struct ptd) + len;
346 int i, done;
347
348 DBG("--- pack buffer %p - %d bytes (fifo %d) ---", data, len, buflen);
349
350 isp116x_write_reg16(isp116x, HCuPINT, HCuPINT_AIIEOT);
351 isp116x_write_reg16(isp116x, HCXFERCTR, buflen);
352 isp116x_write_addr(isp116x, HCATLPORT | ISP116x_WRITE_OFFSET);
353
354 done = 0;
355 for (i = 0; i < n; i++) {
356 DBG("i=%d - done=%d - len=%d", i, done, PTD_GET_LEN(&ptd[i]));
357
358 dump_ptd(&ptd[i]);
359 isp116x_write_data16(isp116x, ptd[i].count);
360 isp116x_write_data16(isp116x, ptd[i].mps);
361 isp116x_write_data16(isp116x, ptd[i].len);
362 isp116x_write_data16(isp116x, ptd[i].faddr);
363
364 dump_ptd_data(&ptd[i], (__u8 *) data + done, 0);
365 write_ptddata_to_fifo(isp116x,
366 (__u8 *) data + done,
367 PTD_GET_LEN(&ptd[i]));
368
369 done += PTD_GET_LEN(&ptd[i]);
370 }
371}
372
373
374
375static int unpack_fifo(struct isp116x *isp116x, struct usb_device *dev,
376 unsigned long pipe, struct ptd *ptd, int n, void *data,
377 int len)
378{
379 int buflen = n * sizeof(struct ptd) + len;
380 int i, done, cc, ret;
381
382 isp116x_write_reg16(isp116x, HCuPINT, HCuPINT_AIIEOT);
383 isp116x_write_reg16(isp116x, HCXFERCTR, buflen);
384 isp116x_write_addr(isp116x, HCATLPORT);
385
386 ret = TD_CC_NOERROR;
387 done = 0;
388 for (i = 0; i < n; i++) {
389 DBG("i=%d - done=%d - len=%d", i, done, PTD_GET_LEN(&ptd[i]));
390
391 ptd[i].count = isp116x_read_data16(isp116x);
392 ptd[i].mps = isp116x_read_data16(isp116x);
393 ptd[i].len = isp116x_read_data16(isp116x);
394 ptd[i].faddr = isp116x_read_data16(isp116x);
395 dump_ptd(&ptd[i]);
396
397 read_ptddata_from_fifo(isp116x,
398 (__u8 *) data + done,
399 PTD_GET_LEN(&ptd[i]));
400 dump_ptd_data(&ptd[i], (__u8 *) data + done, 1);
401
402 done += PTD_GET_LEN(&ptd[i]);
403
404 cc = PTD_GET_CC(&ptd[i]);
405
406
407
408
409
410 if (cc == TD_NOTACCESSED ||
411 (cc != TD_CC_NOERROR && (ret == TD_CC_NOERROR || ret == TD_DATAUNDERRUN)))
412 ret = cc;
413 }
414
415 DBG("--- unpack buffer %p - %d bytes (fifo %d) ---", data, len, buflen);
416
417 return ret;
418}
419
420
421
422static int isp116x_interrupt(struct isp116x *isp116x)
423{
424 u16 irqstat;
425 u32 intstat;
426 int ret = 0;
427
428 isp116x_write_reg16(isp116x, HCuPINTENB, 0);
429 irqstat = isp116x_read_reg16(isp116x, HCuPINT);
430 isp116x_write_reg16(isp116x, HCuPINT, irqstat);
431 DBG("------ irqstat %x ------", irqstat);
432
433 if (irqstat & HCuPINT_ATL) {
434 DBG("------ HCuPINT_ATL ------");
435 udelay(500);
436 ret = 1;
437 }
438
439 if (irqstat & HCuPINT_OPR) {
440 intstat = isp116x_read_reg32(isp116x, HCINTSTAT);
441 isp116x_write_reg32(isp116x, HCINTSTAT, intstat);
442 DBG("------ HCuPINT_OPR %x ------", intstat);
443
444 if (intstat & HCINT_UE) {
445 ERR("unrecoverable error, controller disabled");
446
447
448
449
450
451
452 isp116x_reset(isp116x);
453 ret = -1;
454 return -1;
455 }
456
457 if (intstat & HCINT_RHSC) {
458 got_rhsc = 1;
459 ret = 1;
460
461
462
463 mdelay(20);
464 }
465
466 if (intstat & HCINT_SO) {
467 ERR("schedule overrun");
468 ret = -1;
469 }
470
471 irqstat &= ~HCuPINT_OPR;
472 }
473
474 return ret;
475}
476
477
478
479
480struct ptd ptd[1];
481
482static inline int max_transfer_len(struct usb_device *dev, unsigned long pipe)
483{
484 unsigned mpck = usb_maxpacket(dev, pipe);
485
486
487
488
489 return 1023 / mpck * mpck;
490}
491
492
493
494static int isp116x_submit_job(struct usb_device *dev, unsigned long pipe,
495 int dir, void *buffer, int len)
496{
497 struct isp116x *isp116x = &isp116x_dev;
498 int type = usb_pipetype(pipe);
499 int epnum = usb_pipeendpoint(pipe);
500 int max = usb_maxpacket(dev, pipe);
501 int dir_out = usb_pipeout(pipe);
502 int speed_low = (dev->speed == USB_SPEED_LOW);
503 int i, done = 0, stat, timeout, cc;
504
505
506 int retries = 500;
507
508 DBG("------------------------------------------------");
509 dump_msg(dev, pipe, buffer, len, "SUBMIT");
510 DBG("------------------------------------------------");
511
512 if (len >= 1024) {
513 ERR("Too big job");
514 dev->status = USB_ST_CRC_ERR;
515 return -1;
516 }
517
518 if (isp116x->disabled) {
519 ERR("EPIPE");
520 dev->status = USB_ST_CRC_ERR;
521 return -1;
522 }
523
524
525 if (devgone == dev) {
526 ERR("ENODEV");
527 dev->status = USB_ST_CRC_ERR;
528 return USB_ST_CRC_ERR;
529 }
530
531 if (!max) {
532 ERR("pipesize for pipe %lx is zero", pipe);
533 dev->status = USB_ST_CRC_ERR;
534 return -1;
535 }
536
537 if (type == PIPE_ISOCHRONOUS) {
538 ERR("isochronous transfers not supported");
539 dev->status = USB_ST_CRC_ERR;
540 return -1;
541 }
542
543
544 if (isp116x_read_reg16(isp116x, HCBUFSTAT) & HCBUFSTAT_ATL_FULL) {
545 ERR("****** FIFO not empty! ******");
546 dev->status = USB_ST_BUF_ERR;
547 return -1;
548 }
549
550 retry:
551 isp116x_write_reg32(isp116x, HCINTSTAT, 0xff);
552
553
554 ptd->count = PTD_CC_MSK | PTD_ACTIVE_MSK |
555 PTD_TOGGLE(usb_gettoggle(dev, epnum, dir_out));
556 ptd->mps = PTD_MPS(max) | PTD_SPD(speed_low) | PTD_EP(epnum) | PTD_LAST_MSK;
557 ptd->len = PTD_LEN(len) | PTD_DIR(dir);
558 ptd->faddr = PTD_FA(usb_pipedevice(pipe));
559
560retry_same:
561
562 pack_fifo(isp116x, dev, pipe, ptd, 1, buffer, len);
563#ifdef EXTRA_DELAY
564 mdelay(EXTRA_DELAY);
565#endif
566
567
568
569
570 if (usb_pipebulk(pipe))
571 timeout = 5000;
572 else
573 timeout = 100;
574
575
576 for (;;) {
577
578 stat = isp116x_interrupt(isp116x);
579
580 if (stat < 0) {
581 dev->status = USB_ST_CRC_ERR;
582 break;
583 }
584 if (stat > 0)
585 break;
586
587
588 if (--timeout)
589 udelay(1);
590 else {
591 ERR("CTL:TIMEOUT ");
592 stat = USB_ST_CRC_ERR;
593 break;
594 }
595 }
596
597
598 if (got_rhsc) {
599 isp116x_show_regs(isp116x);
600
601 got_rhsc = 0;
602
603
604 timeout = rh_check_port_status(isp116x);
605 if (timeout >= 0) {
606
607
608
609
610
611 devgone = dev;
612 }
613 }
614
615
616
617
618 if (!(isp116x_read_reg16(isp116x, HCBUFSTAT) & HCBUFSTAT_ATL_DONE)) {
619 ERR("****** FIFO not ready! ******");
620 dev->status = USB_ST_BUF_ERR;
621 return -1;
622 }
623
624
625 cc = unpack_fifo(isp116x, dev, pipe, ptd, 1, buffer, len);
626
627 i = PTD_GET_COUNT(ptd);
628 done += i;
629 buffer += i;
630 len -= i;
631
632
633
634
635 if (cc && cc != TD_NOTACCESSED && cc != TD_DATAUNDERRUN) {
636 if (retries >= 100) {
637 retries -= 100;
638
639
640
641 usb_settoggle(dev, epnum, dir_out, !PTD_GET_TOGGLE(ptd));
642 goto retry;
643 }
644 }
645
646
647
648
649
650
651 else if (cc == TD_NOTACCESSED || PTD_GET_ACTIVE(ptd) || (cc != TD_DATAUNDERRUN && PTD_GET_COUNT(ptd) < PTD_GET_LEN(ptd))) {
652 if (retries) {
653 --retries;
654 if (cc == TD_NOTACCESSED && PTD_GET_ACTIVE(ptd) && !PTD_GET_COUNT(ptd)) goto retry_same;
655 usb_settoggle(dev, epnum, dir_out, PTD_GET_TOGGLE(ptd));
656 goto retry;
657 }
658 }
659
660 if (cc != TD_CC_NOERROR && cc != TD_DATAUNDERRUN) {
661 DBG("****** completition code error %x ******", cc);
662 switch (cc) {
663 case TD_CC_BITSTUFFING:
664 dev->status = USB_ST_BIT_ERR;
665 break;
666 case TD_CC_STALL:
667 dev->status = USB_ST_STALLED;
668 break;
669 case TD_BUFFEROVERRUN:
670 case TD_BUFFERUNDERRUN:
671 dev->status = USB_ST_BUF_ERR;
672 break;
673 default:
674 dev->status = USB_ST_CRC_ERR;
675 }
676 return -cc;
677 }
678 else usb_settoggle(dev, epnum, dir_out, PTD_GET_TOGGLE(ptd));
679
680 dump_msg(dev, pipe, buffer, len, "SUBMIT(ret)");
681
682 dev->status = 0;
683 return done;
684}
685
686
687
688static int isp116x_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
689 void *buffer, int transfer_len,
690 struct devrequest *cmd)
691{
692 struct isp116x *isp116x = &isp116x_dev;
693 u32 tmp = 0;
694
695 int leni = transfer_len;
696 int len = 0;
697 int stat = 0;
698 u32 datab[4];
699 u8 *data_buf = (u8 *) datab;
700 u16 bmRType_bReq;
701 u16 wValue;
702 u16 wIndex;
703 u16 wLength;
704
705 if (usb_pipeint(pipe)) {
706 INFO("Root-Hub submit IRQ: NOT implemented");
707 return 0;
708 }
709
710 bmRType_bReq = cmd->requesttype | (cmd->request << 8);
711 wValue = swap_16(cmd->value);
712 wIndex = swap_16(cmd->index);
713 wLength = swap_16(cmd->length);
714
715 DBG("--- HUB ----------------------------------------");
716 DBG("submit rh urb, req=%x val=%#x index=%#x len=%d",
717 bmRType_bReq, wValue, wIndex, wLength);
718 dump_msg(dev, pipe, buffer, transfer_len, "RH");
719 DBG("------------------------------------------------");
720
721 switch (bmRType_bReq) {
722 case RH_GET_STATUS:
723 DBG("RH_GET_STATUS");
724
725 *(__u16 *) data_buf = swap_16(1);
726 len = 2;
727 break;
728
729 case RH_GET_STATUS | RH_INTERFACE:
730 DBG("RH_GET_STATUS | RH_INTERFACE");
731
732 *(__u16 *) data_buf = swap_16(0);
733 len = 2;
734 break;
735
736 case RH_GET_STATUS | RH_ENDPOINT:
737 DBG("RH_GET_STATUS | RH_ENDPOINT");
738
739 *(__u16 *) data_buf = swap_16(0);
740 len = 2;
741 break;
742
743 case RH_GET_STATUS | RH_CLASS:
744 DBG("RH_GET_STATUS | RH_CLASS");
745
746 tmp = isp116x_read_reg32(isp116x, HCRHSTATUS);
747
748 *(__u32 *) data_buf = swap_32(tmp & ~(RH_HS_CRWE | RH_HS_DRWE));
749 len = 4;
750 break;
751
752 case RH_GET_STATUS | RH_OTHER | RH_CLASS:
753 DBG("RH_GET_STATUS | RH_OTHER | RH_CLASS");
754
755 tmp = isp116x_read_reg32(isp116x, HCRHPORT1 + wIndex - 1);
756 *(__u32 *) data_buf = swap_32(tmp);
757 isp116x_show_regs(isp116x);
758 len = 4;
759 break;
760
761 case RH_CLEAR_FEATURE | RH_ENDPOINT:
762 DBG("RH_CLEAR_FEATURE | RH_ENDPOINT");
763
764 switch (wValue) {
765 case RH_ENDPOINT_STALL:
766 DBG("C_HUB_ENDPOINT_STALL");
767 len = 0;
768 break;
769 }
770 break;
771
772 case RH_CLEAR_FEATURE | RH_CLASS:
773 DBG("RH_CLEAR_FEATURE | RH_CLASS");
774
775 switch (wValue) {
776 case RH_C_HUB_LOCAL_POWER:
777 DBG("C_HUB_LOCAL_POWER");
778 len = 0;
779 break;
780
781 case RH_C_HUB_OVER_CURRENT:
782 DBG("C_HUB_OVER_CURRENT");
783 isp116x_write_reg32(isp116x, HCRHSTATUS, RH_HS_OCIC);
784 len = 0;
785 break;
786 }
787 break;
788
789 case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
790 DBG("RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS");
791
792 switch (wValue) {
793 case RH_PORT_ENABLE:
794 isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
795 RH_PS_CCS);
796 len = 0;
797 break;
798
799 case RH_PORT_SUSPEND:
800 isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
801 RH_PS_POCI);
802 len = 0;
803 break;
804
805 case RH_PORT_POWER:
806 isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
807 RH_PS_LSDA);
808 len = 0;
809 break;
810
811 case RH_C_PORT_CONNECTION:
812 isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
813 RH_PS_CSC);
814 len = 0;
815 break;
816
817 case RH_C_PORT_ENABLE:
818 isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
819 RH_PS_PESC);
820 len = 0;
821 break;
822
823 case RH_C_PORT_SUSPEND:
824 isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
825 RH_PS_PSSC);
826 len = 0;
827 break;
828
829 case RH_C_PORT_OVER_CURRENT:
830 isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
831 RH_PS_POCI);
832 len = 0;
833 break;
834
835 case RH_C_PORT_RESET:
836 isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
837 RH_PS_PRSC);
838 len = 0;
839 break;
840
841 default:
842 ERR("invalid wValue");
843 stat = USB_ST_STALLED;
844 }
845
846 isp116x_show_regs(isp116x);
847
848 break;
849
850 case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
851 DBG("RH_SET_FEATURE | RH_OTHER | RH_CLASS");
852
853 switch (wValue) {
854 case RH_PORT_SUSPEND:
855 isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
856 RH_PS_PSS);
857 len = 0;
858 break;
859
860 case RH_PORT_RESET:
861
862 while (1) {
863 tmp =
864 isp116x_read_reg32(isp116x,
865 HCRHPORT1 + wIndex - 1);
866 if (!(tmp & RH_PS_PRS))
867 break;
868 mdelay(1);
869 }
870 isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
871 RH_PS_PRS);
872 mdelay(10);
873
874 len = 0;
875 break;
876
877 case RH_PORT_POWER:
878 isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
879 RH_PS_PPS);
880 len = 0;
881 break;
882
883 case RH_PORT_ENABLE:
884 isp116x_write_reg32(isp116x, HCRHPORT1 + wIndex - 1,
885 RH_PS_PES);
886 len = 0;
887 break;
888
889 default:
890 ERR("invalid wValue");
891 stat = USB_ST_STALLED;
892 }
893
894 isp116x_show_regs(isp116x);
895
896 break;
897
898 case RH_SET_ADDRESS:
899 DBG("RH_SET_ADDRESS");
900
901 rh_devnum = wValue;
902 len = 0;
903 break;
904
905 case RH_GET_DESCRIPTOR:
906 DBG("RH_GET_DESCRIPTOR: %x, %d", wValue, wLength);
907
908 switch (wValue) {
909 case (USB_DT_DEVICE << 8):
910 len = min_t(unsigned int,
911 leni, min_t(unsigned int,
912 sizeof(root_hub_dev_des),
913 wLength));
914 data_buf = root_hub_dev_des;
915 break;
916
917 case (USB_DT_CONFIG << 8):
918 len = min_t(unsigned int,
919 leni, min_t(unsigned int,
920 sizeof(root_hub_config_des),
921 wLength));
922 data_buf = root_hub_config_des;
923 break;
924
925 case ((USB_DT_STRING << 8) | 0x00):
926 len = min_t(unsigned int,
927 leni, min_t(unsigned int,
928 sizeof(root_hub_str_index0),
929 wLength));
930 data_buf = root_hub_str_index0;
931 break;
932
933 case ((USB_DT_STRING << 8) | 0x01):
934 len = min_t(unsigned int,
935 leni, min_t(unsigned int,
936 sizeof(root_hub_str_index1),
937 wLength));
938 data_buf = root_hub_str_index1;
939 break;
940
941 default:
942 ERR("invalid wValue");
943 stat = USB_ST_STALLED;
944 }
945
946 break;
947
948 case RH_GET_DESCRIPTOR | RH_CLASS:
949 DBG("RH_GET_DESCRIPTOR | RH_CLASS");
950
951 tmp = isp116x_read_reg32(isp116x, HCRHDESCA);
952
953 data_buf[0] = 0x09;
954 data_buf[1] = 0x29;
955 data_buf[2] = tmp & RH_A_NDP;
956 data_buf[3] = 0;
957 if (tmp & RH_A_PSM)
958 data_buf[3] |= 0x01;
959 if (tmp & RH_A_NOCP)
960 data_buf[3] |= 0x10;
961 else if (tmp & RH_A_OCPM)
962 data_buf[3] |= 0x08;
963
964
965 datab[1] = 0;
966 data_buf[5] = (tmp & RH_A_POTPGT) >> 24;
967
968 tmp = isp116x_read_reg32(isp116x, HCRHDESCB);
969
970 data_buf[7] = tmp & RH_B_DR;
971 if (data_buf[2] < 7)
972 data_buf[8] = 0xff;
973 else {
974 data_buf[0] += 2;
975 data_buf[8] = (tmp & RH_B_DR) >> 8;
976 data_buf[10] = data_buf[9] = 0xff;
977 }
978
979 len = min_t(unsigned int, leni,
980 min_t(unsigned int, data_buf[0], wLength));
981 break;
982
983 case RH_GET_CONFIGURATION:
984 DBG("RH_GET_CONFIGURATION");
985
986 *(__u8 *) data_buf = 0x01;
987 len = 1;
988 break;
989
990 case RH_SET_CONFIGURATION:
991 DBG("RH_SET_CONFIGURATION");
992
993 isp116x_write_reg32(isp116x, HCRHSTATUS, RH_HS_LPSC);
994 len = 0;
995 break;
996
997 default:
998 ERR("*** *** *** unsupported root hub command *** *** ***");
999 stat = USB_ST_STALLED;
1000 }
1001
1002 len = min_t(int, len, leni);
1003 if (buffer != data_buf)
1004 memcpy(buffer, data_buf, len);
1005
1006 dev->act_len = len;
1007 dev->status = stat;
1008 DBG("dev act_len %d, status %d", dev->act_len, dev->status);
1009
1010 dump_msg(dev, pipe, buffer, transfer_len, "RH(ret)");
1011
1012 return stat;
1013}
1014
1015
1016
1017int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
1018 int len, int interval)
1019{
1020 DBG("dev=%p pipe=%#lx buf=%p size=%d int=%d",
1021 dev, pipe, buffer, len, interval);
1022
1023 return -1;
1024}
1025
1026int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
1027 int len, struct devrequest *setup)
1028{
1029 int devnum = usb_pipedevice(pipe);
1030 int epnum = usb_pipeendpoint(pipe);
1031 int max = max_transfer_len(dev, pipe);
1032 int dir_in = usb_pipein(pipe);
1033 int done, ret;
1034
1035
1036 if (devnum == rh_devnum)
1037 return isp116x_submit_rh_msg(dev, pipe, buffer, len, setup);
1038
1039
1040
1041
1042 DBG("--- SETUP PHASE --------------------------------");
1043 usb_settoggle(dev, epnum, 1, 0);
1044 ret = isp116x_submit_job(dev, pipe,
1045 PTD_DIR_SETUP,
1046 setup, sizeof(struct devrequest));
1047 if (ret < 0) {
1048 DBG("control setup phase error (ret = %d", ret);
1049 return -1;
1050 }
1051
1052
1053 DBG("--- DATA PHASE ---------------------------------");
1054 done = 0;
1055 usb_settoggle(dev, epnum, !dir_in, 1);
1056 while (done < len) {
1057 ret = isp116x_submit_job(dev, pipe,
1058 dir_in ? PTD_DIR_IN : PTD_DIR_OUT,
1059 (__u8 *) buffer + done,
1060 max > len - done ? len - done : max);
1061 if (ret < 0) {
1062 DBG("control data phase error (ret = %d)", ret);
1063 return -1;
1064 }
1065 done += ret;
1066
1067 if (dir_in && ret < max)
1068 break;
1069 }
1070
1071
1072 DBG("--- STATUS PHASE -------------------------------");
1073 usb_settoggle(dev, epnum, !dir_in, 1);
1074 ret = isp116x_submit_job(dev, pipe,
1075 !dir_in ? PTD_DIR_IN : PTD_DIR_OUT, NULL, 0);
1076 if (ret < 0) {
1077 DBG("control status phase error (ret = %d", ret);
1078 return -1;
1079 }
1080
1081 dev->act_len = done;
1082
1083 dump_msg(dev, pipe, buffer, len, "DEV(ret)");
1084
1085 return done;
1086}
1087
1088int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
1089 int len)
1090{
1091 int dir_out = usb_pipeout(pipe);
1092 int max = max_transfer_len(dev, pipe);
1093 int done, ret;
1094
1095 DBG("--- BULK ---------------------------------------");
1096 DBG("dev=%ld pipe=%ld buf=%p size=%d dir_out=%d",
1097 usb_pipedevice(pipe), usb_pipeendpoint(pipe), buffer, len, dir_out);
1098
1099 done = 0;
1100 while (done < len) {
1101 ret = isp116x_submit_job(dev, pipe,
1102 !dir_out ? PTD_DIR_IN : PTD_DIR_OUT,
1103 (__u8 *) buffer + done,
1104 max > len - done ? len - done : max);
1105 if (ret < 0) {
1106 DBG("error on bulk message (ret = %d)", ret);
1107 return -1;
1108 }
1109
1110 done += ret;
1111
1112 if (!dir_out && ret < max)
1113 break;
1114 }
1115
1116 dev->act_len = done;
1117
1118 return 0;
1119}
1120
1121
1122
1123static int isp116x_sw_reset(struct isp116x *isp116x)
1124{
1125 int retries = 15;
1126 int ret = 0;
1127
1128 DBG("");
1129
1130 isp116x->disabled = 1;
1131
1132 isp116x_write_reg16(isp116x, HCSWRES, HCSWRES_MAGIC);
1133 isp116x_write_reg32(isp116x, HCCMDSTAT, HCCMDSTAT_HCR);
1134 while (--retries) {
1135
1136 mdelay(1);
1137 if (!(isp116x_read_reg32(isp116x, HCCMDSTAT) & HCCMDSTAT_HCR))
1138 break;
1139 }
1140 if (!retries) {
1141 ERR("software reset timeout");
1142 ret = -1;
1143 }
1144 return ret;
1145}
1146
1147static int isp116x_reset(struct isp116x *isp116x)
1148{
1149 unsigned long t;
1150 u16 clkrdy = 0;
1151 int ret, timeout = 15 ;
1152
1153 DBG("");
1154
1155 ret = isp116x_sw_reset(isp116x);
1156 if (ret)
1157 return ret;
1158
1159 for (t = 0; t < timeout; t++) {
1160 clkrdy = isp116x_read_reg16(isp116x, HCuPINT) & HCuPINT_CLKRDY;
1161 if (clkrdy)
1162 break;
1163 mdelay(1);
1164 }
1165 if (!clkrdy) {
1166 ERR("clock not ready after %dms", timeout);
1167
1168
1169 ERR("please make sure that the H_WAKEUP pin is pulled low!");
1170 ret = -1;
1171 }
1172 return ret;
1173}
1174
1175static void isp116x_stop(struct isp116x *isp116x)
1176{
1177 u32 val;
1178
1179 DBG("");
1180
1181 isp116x_write_reg16(isp116x, HCuPINTENB, 0);
1182
1183
1184
1185 val = isp116x_read_reg32(isp116x, HCRHDESCA);
1186 val &= ~(RH_A_NPS | RH_A_PSM);
1187 isp116x_write_reg32(isp116x, HCRHDESCA, val);
1188 isp116x_write_reg32(isp116x, HCRHSTATUS, RH_HS_LPS);
1189
1190 isp116x_sw_reset(isp116x);
1191}
1192
1193
1194
1195
1196static int isp116x_start(struct isp116x *isp116x)
1197{
1198 struct isp116x_platform_data *board = isp116x->board;
1199 u32 val;
1200
1201 DBG("");
1202
1203
1204 isp116x_write_reg16(isp116x, HCuPINT, 0xff);
1205 isp116x_write_reg16(isp116x, HCuPINTENB, 0);
1206
1207 isp116x_write_reg16(isp116x, HCITLBUFLEN, ISP116x_ITL_BUFSIZE);
1208 isp116x_write_reg16(isp116x, HCATLBUFLEN, ISP116x_ATL_BUFSIZE);
1209
1210
1211 val = HCHWCFG_DBWIDTH(1);
1212 if (board->sel15Kres)
1213 val |= HCHWCFG_15KRSEL;
1214
1215 if (board->remote_wakeup_enable)
1216 val |= HCHWCFG_CLKNOTSTOP;
1217 if (board->oc_enable)
1218 val |= HCHWCFG_ANALOG_OC;
1219 isp116x_write_reg16(isp116x, HCHWCFG, val);
1220
1221
1222 val = (25 << 24) & RH_A_POTPGT;
1223
1224
1225
1226 val |= RH_A_PSM;
1227
1228 val |= RH_A_OCPM;
1229 isp116x_write_reg32(isp116x, HCRHDESCA, val);
1230 isp116x->rhdesca = isp116x_read_reg32(isp116x, HCRHDESCA);
1231
1232 val = RH_B_PPCM;
1233 isp116x_write_reg32(isp116x, HCRHDESCB, val);
1234 isp116x->rhdescb = isp116x_read_reg32(isp116x, HCRHDESCB);
1235
1236 val = 0;
1237 if (board->remote_wakeup_enable)
1238 val |= RH_HS_DRWE;
1239 isp116x_write_reg32(isp116x, HCRHSTATUS, val);
1240 isp116x->rhstatus = isp116x_read_reg32(isp116x, HCRHSTATUS);
1241
1242 isp116x_write_reg32(isp116x, HCFMINTVL, 0x27782edf);
1243
1244
1245 val = HCCONTROL_USB_OPER;
1246 if (board->remote_wakeup_enable)
1247 val |= HCCONTROL_RWE;
1248 isp116x_write_reg32(isp116x, HCCONTROL, val);
1249
1250
1251 isp116x_write_reg32(isp116x, HCRHPORT1, RH_PS_CCS);
1252 isp116x_write_reg32(isp116x, HCRHPORT2, RH_PS_CCS);
1253
1254 isp116x_show_regs(isp116x);
1255
1256 isp116x->disabled = 0;
1257
1258 return 0;
1259}
1260
1261
1262
1263int isp116x_check_id(struct isp116x *isp116x)
1264{
1265 int val;
1266
1267 val = isp116x_read_reg16(isp116x, HCCHIPID);
1268 if ((val & HCCHIPID_MASK) != HCCHIPID_MAGIC) {
1269 ERR("invalid chip ID %04x", val);
1270 return -1;
1271 }
1272
1273 return 0;
1274}
1275
1276int usb_lowlevel_init(int index, enum usb_init_type init, void **controller))
1277{
1278 struct isp116x *isp116x = &isp116x_dev;
1279
1280 DBG("");
1281
1282 got_rhsc = rh_devnum = 0;
1283
1284
1285 isp116x->addr_reg = (u16 *) ISP116X_HCD_ADDR;
1286 isp116x->data_reg = (u16 *) ISP116X_HCD_DATA;
1287
1288
1289#ifdef ISP116X_HCD_SEL15kRES
1290 isp116x_board.sel15Kres = 1;
1291#endif
1292#ifdef ISP116X_HCD_OC_ENABLE
1293 isp116x_board.oc_enable = 1;
1294#endif
1295#ifdef ISP116X_HCD_REMOTE_WAKEUP_ENABLE
1296 isp116x_board.remote_wakeup_enable = 1;
1297#endif
1298 isp116x->board = &isp116x_board;
1299
1300
1301 if (isp116x_check_id(isp116x) < 0)
1302 return -1;
1303
1304 isp116x->disabled = 1;
1305 isp116x->sleeping = 0;
1306
1307 isp116x_reset(isp116x);
1308 isp116x_start(isp116x);
1309
1310 return 0;
1311}
1312
1313int usb_lowlevel_stop(int index)
1314{
1315 struct isp116x *isp116x = &isp116x_dev;
1316
1317 DBG("");
1318
1319 if (!isp116x->disabled)
1320 isp116x_stop(isp116x);
1321
1322 return 0;
1323}
1324