blob: 60e03a4bf73a5d755a5d68f05b8198b4600746e8 [file] [log] [blame]
Thomas Abraham38f424f2009-01-04 09:41:03 +05301/*
2 * Mentor USB OTG Core host controller driver.
3 *
4 * Copyright (c) 2008 Texas Instruments
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of
9 * the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19 * MA 02111-1307 USA
20 *
21 * Author: Thomas Abraham t-abraham@ti.com, Texas Instruments
22 */
23
24#include <common.h>
Ilya Yanoka1cf10f2012-11-06 13:48:20 +000025#include <usb.h>
Thomas Abraham38f424f2009-01-04 09:41:03 +053026#include "musb_hcd.h"
27
28/* MSC control transfers */
29#define USB_MSC_BBB_RESET 0xFF
30#define USB_MSC_BBB_GET_MAX_LUN 0xFE
31
32/* Endpoint configuration information */
Mike Frysinger671bc3d2010-10-20 07:15:35 -040033static const struct musb_epinfo epinfo[3] = {
Thomas Abraham38f424f2009-01-04 09:41:03 +053034 {MUSB_BULK_EP, 1, 512}, /* EP1 - Bluk Out - 512 Bytes */
35 {MUSB_BULK_EP, 0, 512}, /* EP1 - Bluk In - 512 Bytes */
36 {MUSB_INTR_EP, 0, 64} /* EP2 - Interrupt IN - 64 Bytes */
37};
38
Bryan Wu73073cc2010-01-09 16:53:54 -050039/* --- Virtual Root Hub ---------------------------------------------------- */
40#ifdef MUSB_NO_MULTIPOINT
41static int rh_devnum;
42static u32 port_status;
43
44/* Device descriptor */
Mike Frysinger671bc3d2010-10-20 07:15:35 -040045static const u8 root_hub_dev_des[] = {
Bryan Wu73073cc2010-01-09 16:53:54 -050046 0x12, /* __u8 bLength; */
47 0x01, /* __u8 bDescriptorType; Device */
48 0x00, /* __u16 bcdUSB; v1.1 */
49 0x02,
50 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */
51 0x00, /* __u8 bDeviceSubClass; */
52 0x00, /* __u8 bDeviceProtocol; */
53 0x08, /* __u8 bMaxPacketSize0; 8 Bytes */
54 0x00, /* __u16 idVendor; */
55 0x00,
56 0x00, /* __u16 idProduct; */
57 0x00,
58 0x00, /* __u16 bcdDevice; */
59 0x00,
60 0x00, /* __u8 iManufacturer; */
61 0x01, /* __u8 iProduct; */
62 0x00, /* __u8 iSerialNumber; */
63 0x01 /* __u8 bNumConfigurations; */
64};
65
66/* Configuration descriptor */
Mike Frysinger671bc3d2010-10-20 07:15:35 -040067static const u8 root_hub_config_des[] = {
Bryan Wu73073cc2010-01-09 16:53:54 -050068 0x09, /* __u8 bLength; */
69 0x02, /* __u8 bDescriptorType; Configuration */
70 0x19, /* __u16 wTotalLength; */
71 0x00,
72 0x01, /* __u8 bNumInterfaces; */
73 0x01, /* __u8 bConfigurationValue; */
74 0x00, /* __u8 iConfiguration; */
75 0x40, /* __u8 bmAttributes;
76 Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, 4..0: resvd */
77 0x00, /* __u8 MaxPower; */
78
79 /* interface */
80 0x09, /* __u8 if_bLength; */
81 0x04, /* __u8 if_bDescriptorType; Interface */
82 0x00, /* __u8 if_bInterfaceNumber; */
83 0x00, /* __u8 if_bAlternateSetting; */
84 0x01, /* __u8 if_bNumEndpoints; */
85 0x09, /* __u8 if_bInterfaceClass; HUB_CLASSCODE */
86 0x00, /* __u8 if_bInterfaceSubClass; */
87 0x00, /* __u8 if_bInterfaceProtocol; */
88 0x00, /* __u8 if_iInterface; */
89
90 /* endpoint */
91 0x07, /* __u8 ep_bLength; */
92 0x05, /* __u8 ep_bDescriptorType; Endpoint */
93 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */
94 0x03, /* __u8 ep_bmAttributes; Interrupt */
95 0x00, /* __u16 ep_wMaxPacketSize; ((MAX_ROOT_PORTS + 1) / 8 */
96 0x02,
97 0xff /* __u8 ep_bInterval; 255 ms */
98};
99
Mike Frysinger671bc3d2010-10-20 07:15:35 -0400100static const unsigned char root_hub_str_index0[] = {
Bryan Wu73073cc2010-01-09 16:53:54 -0500101 0x04, /* __u8 bLength; */
102 0x03, /* __u8 bDescriptorType; String-descriptor */
103 0x09, /* __u8 lang ID */
104 0x04, /* __u8 lang ID */
105};
106
Mike Frysinger671bc3d2010-10-20 07:15:35 -0400107static const unsigned char root_hub_str_index1[] = {
Bryan Wu73073cc2010-01-09 16:53:54 -0500108 0x1c, /* __u8 bLength; */
109 0x03, /* __u8 bDescriptorType; String-descriptor */
110 'M', /* __u8 Unicode */
111 0, /* __u8 Unicode */
112 'U', /* __u8 Unicode */
113 0, /* __u8 Unicode */
114 'S', /* __u8 Unicode */
115 0, /* __u8 Unicode */
116 'B', /* __u8 Unicode */
117 0, /* __u8 Unicode */
118 ' ', /* __u8 Unicode */
119 0, /* __u8 Unicode */
120 'R', /* __u8 Unicode */
121 0, /* __u8 Unicode */
122 'o', /* __u8 Unicode */
123 0, /* __u8 Unicode */
124 'o', /* __u8 Unicode */
125 0, /* __u8 Unicode */
126 't', /* __u8 Unicode */
127 0, /* __u8 Unicode */
128 ' ', /* __u8 Unicode */
129 0, /* __u8 Unicode */
130 'H', /* __u8 Unicode */
131 0, /* __u8 Unicode */
132 'u', /* __u8 Unicode */
133 0, /* __u8 Unicode */
134 'b', /* __u8 Unicode */
135 0, /* __u8 Unicode */
136};
137#endif
138
Thomas Abraham38f424f2009-01-04 09:41:03 +0530139/*
140 * This function writes the data toggle value.
141 */
142static void write_toggle(struct usb_device *dev, u8 ep, u8 dir_out)
143{
144 u16 toggle = usb_gettoggle(dev, ep, dir_out);
145 u16 csr;
146
147 if (dir_out) {
Bryan Wufe439d22010-08-09 14:58:24 -0400148 csr = readw(&musbr->txcsr);
149 if (!toggle) {
150 if (csr & MUSB_TXCSR_MODE)
151 csr = MUSB_TXCSR_CLRDATATOG;
152 else
153 csr = 0;
154 writew(csr, &musbr->txcsr);
155 } else {
Thomas Abraham38f424f2009-01-04 09:41:03 +0530156 csr |= MUSB_TXCSR_H_WR_DATATOGGLE;
157 writew(csr, &musbr->txcsr);
158 csr |= (toggle << MUSB_TXCSR_H_DATATOGGLE_SHIFT);
159 writew(csr, &musbr->txcsr);
160 }
161 } else {
Bryan Wufe439d22010-08-09 14:58:24 -0400162 if (!toggle) {
163 csr = readw(&musbr->txcsr);
164 if (csr & MUSB_TXCSR_MODE)
165 csr = MUSB_RXCSR_CLRDATATOG;
166 else
167 csr = 0;
168 writew(csr, &musbr->rxcsr);
169 } else {
Thomas Abraham38f424f2009-01-04 09:41:03 +0530170 csr = readw(&musbr->rxcsr);
171 csr |= MUSB_RXCSR_H_WR_DATATOGGLE;
172 writew(csr, &musbr->rxcsr);
173 csr |= (toggle << MUSB_S_RXCSR_H_DATATOGGLE);
174 writew(csr, &musbr->rxcsr);
175 }
176 }
177}
178
179/*
180 * This function checks if RxStall has occured on the endpoint. If a RxStall
181 * has occured, the RxStall is cleared and 1 is returned. If RxStall has
182 * not occured, 0 is returned.
183 */
184static u8 check_stall(u8 ep, u8 dir_out)
185{
186 u16 csr;
187
188 /* For endpoint 0 */
189 if (!ep) {
190 csr = readw(&musbr->txcsr);
191 if (csr & MUSB_CSR0_H_RXSTALL) {
192 csr &= ~MUSB_CSR0_H_RXSTALL;
193 writew(csr, &musbr->txcsr);
194 return 1;
195 }
196 } else { /* For non-ep0 */
197 if (dir_out) { /* is it tx ep */
198 csr = readw(&musbr->txcsr);
199 if (csr & MUSB_TXCSR_H_RXSTALL) {
200 csr &= ~MUSB_TXCSR_H_RXSTALL;
201 writew(csr, &musbr->txcsr);
202 return 1;
203 }
204 } else { /* is it rx ep */
205 csr = readw(&musbr->rxcsr);
206 if (csr & MUSB_RXCSR_H_RXSTALL) {
207 csr &= ~MUSB_RXCSR_H_RXSTALL;
208 writew(csr, &musbr->rxcsr);
209 return 1;
210 }
211 }
212 }
213 return 0;
214}
215
216/*
217 * waits until ep0 is ready. Returns 0 if ep is ready, -1 for timeout
218 * error and -2 for stall.
219 */
220static int wait_until_ep0_ready(struct usb_device *dev, u32 bit_mask)
221{
222 u16 csr;
223 int result = 1;
Bryan Wu3169ce82009-06-16 05:26:27 -0400224 int timeout = CONFIG_MUSB_TIMEOUT;
Thomas Abraham38f424f2009-01-04 09:41:03 +0530225
226 while (result > 0) {
227 csr = readw(&musbr->txcsr);
228 if (csr & MUSB_CSR0_H_ERROR) {
229 csr &= ~MUSB_CSR0_H_ERROR;
230 writew(csr, &musbr->txcsr);
231 dev->status = USB_ST_CRC_ERR;
232 result = -1;
233 break;
234 }
235
236 switch (bit_mask) {
237 case MUSB_CSR0_TXPKTRDY:
238 if (!(csr & MUSB_CSR0_TXPKTRDY)) {
239 if (check_stall(MUSB_CONTROL_EP, 0)) {
240 dev->status = USB_ST_STALLED;
241 result = -2;
242 } else
243 result = 0;
244 }
245 break;
246
247 case MUSB_CSR0_RXPKTRDY:
248 if (check_stall(MUSB_CONTROL_EP, 0)) {
249 dev->status = USB_ST_STALLED;
250 result = -2;
251 } else
252 if (csr & MUSB_CSR0_RXPKTRDY)
253 result = 0;
254 break;
255
256 case MUSB_CSR0_H_REQPKT:
257 if (!(csr & MUSB_CSR0_H_REQPKT)) {
258 if (check_stall(MUSB_CONTROL_EP, 0)) {
259 dev->status = USB_ST_STALLED;
260 result = -2;
261 } else
262 result = 0;
263 }
264 break;
265 }
Bryan Wu3169ce82009-06-16 05:26:27 -0400266
267 /* Check the timeout */
268 if (--timeout)
269 udelay(1);
270 else {
271 dev->status = USB_ST_CRC_ERR;
272 result = -1;
273 break;
274 }
Thomas Abraham38f424f2009-01-04 09:41:03 +0530275 }
Bryan Wu3169ce82009-06-16 05:26:27 -0400276
Thomas Abraham38f424f2009-01-04 09:41:03 +0530277 return result;
278}
279
280/*
281 * waits until tx ep is ready. Returns 1 when ep is ready and 0 on error.
282 */
283static u8 wait_until_txep_ready(struct usb_device *dev, u8 ep)
284{
285 u16 csr;
Bryan Wu3169ce82009-06-16 05:26:27 -0400286 int timeout = CONFIG_MUSB_TIMEOUT;
Thomas Abraham38f424f2009-01-04 09:41:03 +0530287
288 do {
289 if (check_stall(ep, 1)) {
290 dev->status = USB_ST_STALLED;
291 return 0;
292 }
293
294 csr = readw(&musbr->txcsr);
295 if (csr & MUSB_TXCSR_H_ERROR) {
296 dev->status = USB_ST_CRC_ERR;
297 return 0;
298 }
Bryan Wu3169ce82009-06-16 05:26:27 -0400299
300 /* Check the timeout */
301 if (--timeout)
302 udelay(1);
303 else {
304 dev->status = USB_ST_CRC_ERR;
305 return -1;
306 }
307
Thomas Abraham38f424f2009-01-04 09:41:03 +0530308 } while (csr & MUSB_TXCSR_TXPKTRDY);
309 return 1;
310}
311
312/*
313 * waits until rx ep is ready. Returns 1 when ep is ready and 0 on error.
314 */
315static u8 wait_until_rxep_ready(struct usb_device *dev, u8 ep)
316{
317 u16 csr;
Bryan Wu3169ce82009-06-16 05:26:27 -0400318 int timeout = CONFIG_MUSB_TIMEOUT;
Thomas Abraham38f424f2009-01-04 09:41:03 +0530319
320 do {
321 if (check_stall(ep, 0)) {
322 dev->status = USB_ST_STALLED;
323 return 0;
324 }
325
326 csr = readw(&musbr->rxcsr);
327 if (csr & MUSB_RXCSR_H_ERROR) {
328 dev->status = USB_ST_CRC_ERR;
329 return 0;
330 }
Bryan Wu3169ce82009-06-16 05:26:27 -0400331
332 /* Check the timeout */
333 if (--timeout)
334 udelay(1);
335 else {
336 dev->status = USB_ST_CRC_ERR;
337 return -1;
338 }
339
Thomas Abraham38f424f2009-01-04 09:41:03 +0530340 } while (!(csr & MUSB_RXCSR_RXPKTRDY));
341 return 1;
342}
343
344/*
345 * This function performs the setup phase of the control transfer
346 */
347static int ctrlreq_setup_phase(struct usb_device *dev, struct devrequest *setup)
348{
349 int result;
350 u16 csr;
351
352 /* write the control request to ep0 fifo */
353 write_fifo(MUSB_CONTROL_EP, sizeof(struct devrequest), (void *)setup);
354
355 /* enable transfer of setup packet */
356 csr = readw(&musbr->txcsr);
357 csr |= (MUSB_CSR0_TXPKTRDY|MUSB_CSR0_H_SETUPPKT);
358 writew(csr, &musbr->txcsr);
359
360 /* wait until the setup packet is transmitted */
361 result = wait_until_ep0_ready(dev, MUSB_CSR0_TXPKTRDY);
362 dev->act_len = 0;
363 return result;
364}
365
366/*
367 * This function handles the control transfer in data phase
368 */
369static int ctrlreq_in_data_phase(struct usb_device *dev, u32 len, void *buffer)
370{
371 u16 csr;
372 u32 rxlen = 0;
373 u32 nextlen = 0;
374 u8 maxpktsize = (1 << dev->maxpacketsize) * 8;
375 u8 *rxbuff = (u8 *)buffer;
376 u8 rxedlength;
377 int result;
378
379 while (rxlen < len) {
380 /* Determine the next read length */
381 nextlen = ((len-rxlen) > maxpktsize) ? maxpktsize : (len-rxlen);
382
383 /* Set the ReqPkt bit */
384 csr = readw(&musbr->txcsr);
385 writew(csr | MUSB_CSR0_H_REQPKT, &musbr->txcsr);
386 result = wait_until_ep0_ready(dev, MUSB_CSR0_RXPKTRDY);
387 if (result < 0)
388 return result;
389
390 /* Actual number of bytes received by usb */
391 rxedlength = readb(&musbr->rxcount);
392
393 /* Read the data from the RxFIFO */
394 read_fifo(MUSB_CONTROL_EP, rxedlength, &rxbuff[rxlen]);
395
396 /* Clear the RxPktRdy Bit */
397 csr = readw(&musbr->txcsr);
398 csr &= ~MUSB_CSR0_RXPKTRDY;
399 writew(csr, &musbr->txcsr);
400
401 /* short packet? */
402 if (rxedlength != nextlen) {
403 dev->act_len += rxedlength;
404 break;
405 }
406 rxlen += nextlen;
407 dev->act_len = rxlen;
408 }
409 return 0;
410}
411
412/*
413 * This function handles the control transfer out data phase
414 */
415static int ctrlreq_out_data_phase(struct usb_device *dev, u32 len, void *buffer)
416{
417 u16 csr;
418 u32 txlen = 0;
419 u32 nextlen = 0;
420 u8 maxpktsize = (1 << dev->maxpacketsize) * 8;
421 u8 *txbuff = (u8 *)buffer;
422 int result = 0;
423
424 while (txlen < len) {
425 /* Determine the next write length */
426 nextlen = ((len-txlen) > maxpktsize) ? maxpktsize : (len-txlen);
427
428 /* Load the data to send in FIFO */
429 write_fifo(MUSB_CONTROL_EP, txlen, &txbuff[txlen]);
430
431 /* Set TXPKTRDY bit */
432 csr = readw(&musbr->txcsr);
433 writew(csr | MUSB_CSR0_H_DIS_PING | MUSB_CSR0_TXPKTRDY,
434 &musbr->txcsr);
435 result = wait_until_ep0_ready(dev, MUSB_CSR0_TXPKTRDY);
436 if (result < 0)
437 break;
438
439 txlen += nextlen;
440 dev->act_len = txlen;
441 }
442 return result;
443}
444
445/*
446 * This function handles the control transfer out status phase
447 */
448static int ctrlreq_out_status_phase(struct usb_device *dev)
449{
450 u16 csr;
451 int result;
452
453 /* Set the StatusPkt bit */
454 csr = readw(&musbr->txcsr);
455 csr |= (MUSB_CSR0_H_DIS_PING | MUSB_CSR0_TXPKTRDY |
456 MUSB_CSR0_H_STATUSPKT);
457 writew(csr, &musbr->txcsr);
458
459 /* Wait until TXPKTRDY bit is cleared */
460 result = wait_until_ep0_ready(dev, MUSB_CSR0_TXPKTRDY);
461 return result;
462}
463
464/*
465 * This function handles the control transfer in status phase
466 */
467static int ctrlreq_in_status_phase(struct usb_device *dev)
468{
469 u16 csr;
470 int result;
471
472 /* Set the StatusPkt bit and ReqPkt bit */
473 csr = MUSB_CSR0_H_DIS_PING | MUSB_CSR0_H_REQPKT | MUSB_CSR0_H_STATUSPKT;
474 writew(csr, &musbr->txcsr);
475 result = wait_until_ep0_ready(dev, MUSB_CSR0_H_REQPKT);
476
477 /* clear StatusPkt bit and RxPktRdy bit */
478 csr = readw(&musbr->txcsr);
479 csr &= ~(MUSB_CSR0_RXPKTRDY | MUSB_CSR0_H_STATUSPKT);
480 writew(csr, &musbr->txcsr);
481 return result;
482}
483
484/*
485 * determines the speed of the device (High/Full/Slow)
486 */
487static u8 get_dev_speed(struct usb_device *dev)
488{
Ilya Yanoka1cf10f2012-11-06 13:48:20 +0000489 return (dev->speed == USB_SPEED_HIGH) ? MUSB_TYPE_SPEED_HIGH :
490 ((dev->speed == USB_SPEED_LOW) ? MUSB_TYPE_SPEED_LOW :
Thomas Abraham38f424f2009-01-04 09:41:03 +0530491 MUSB_TYPE_SPEED_FULL);
492}
493
494/*
495 * configure the hub address and the port address.
496 */
497static void config_hub_port(struct usb_device *dev, u8 ep)
498{
499 u8 chid;
500 u8 hub;
501
502 /* Find out the nearest parent which is high speed */
503 while (dev->parent->parent != NULL)
504 if (get_dev_speed(dev->parent) != MUSB_TYPE_SPEED_HIGH)
505 dev = dev->parent;
506 else
507 break;
508
509 /* determine the port address at that hub */
510 hub = dev->parent->devnum;
511 for (chid = 0; chid < USB_MAXCHILDREN; chid++)
512 if (dev->parent->children[chid] == dev)
513 break;
514
Bryan Wu784f1382009-12-16 22:04:00 -0500515#ifndef MUSB_NO_MULTIPOINT
Thomas Abraham38f424f2009-01-04 09:41:03 +0530516 /* configure the hub address and the port address */
517 writeb(hub, &musbr->tar[ep].txhubaddr);
518 writeb((chid + 1), &musbr->tar[ep].txhubport);
519 writeb(hub, &musbr->tar[ep].rxhubaddr);
520 writeb((chid + 1), &musbr->tar[ep].rxhubport);
Bryan Wu784f1382009-12-16 22:04:00 -0500521#endif
Thomas Abraham38f424f2009-01-04 09:41:03 +0530522}
523
Bryan Wu73073cc2010-01-09 16:53:54 -0500524#ifdef MUSB_NO_MULTIPOINT
525
526static void musb_port_reset(int do_reset)
527{
528 u8 power = readb(&musbr->power);
529
530 if (do_reset) {
531 power &= 0xf0;
532 writeb(power | MUSB_POWER_RESET, &musbr->power);
533 port_status |= USB_PORT_STAT_RESET;
534 port_status &= ~USB_PORT_STAT_ENABLE;
535 udelay(30000);
536 } else {
537 writeb(power & ~MUSB_POWER_RESET, &musbr->power);
538
539 power = readb(&musbr->power);
540 if (power & MUSB_POWER_HSMODE)
541 port_status |= USB_PORT_STAT_HIGH_SPEED;
542
543 port_status &= ~(USB_PORT_STAT_RESET | (USB_PORT_STAT_C_CONNECTION << 16));
544 port_status |= USB_PORT_STAT_ENABLE
545 | (USB_PORT_STAT_C_RESET << 16)
546 | (USB_PORT_STAT_C_ENABLE << 16);
547 }
548}
549
Thomas Abraham38f424f2009-01-04 09:41:03 +0530550/*
Bryan Wu73073cc2010-01-09 16:53:54 -0500551 * root hub control
552 */
553static int musb_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
554 void *buffer, int transfer_len,
555 struct devrequest *cmd)
556{
557 int leni = transfer_len;
558 int len = 0;
559 int stat = 0;
560 u32 datab[4];
Mike Frysinger671bc3d2010-10-20 07:15:35 -0400561 const u8 *data_buf = (u8 *) datab;
Bryan Wu73073cc2010-01-09 16:53:54 -0500562 u16 bmRType_bReq;
563 u16 wValue;
564 u16 wIndex;
565 u16 wLength;
566 u16 int_usb;
567
568 if ((pipe & PIPE_INTERRUPT) == PIPE_INTERRUPT) {
569 debug("Root-Hub submit IRQ: NOT implemented\n");
570 return 0;
571 }
572
573 bmRType_bReq = cmd->requesttype | (cmd->request << 8);
574 wValue = swap_16(cmd->value);
575 wIndex = swap_16(cmd->index);
576 wLength = swap_16(cmd->length);
577
578 debug("--- HUB ----------------------------------------\n");
579 debug("submit rh urb, req=%x val=%#x index=%#x len=%d\n",
580 bmRType_bReq, wValue, wIndex, wLength);
581 debug("------------------------------------------------\n");
582
583 switch (bmRType_bReq) {
584 case RH_GET_STATUS:
585 debug("RH_GET_STATUS\n");
586
587 *(__u16 *) data_buf = swap_16(1);
588 len = 2;
589 break;
590
591 case RH_GET_STATUS | RH_INTERFACE:
592 debug("RH_GET_STATUS | RH_INTERFACE\n");
593
594 *(__u16 *) data_buf = swap_16(0);
595 len = 2;
596 break;
597
598 case RH_GET_STATUS | RH_ENDPOINT:
599 debug("RH_GET_STATUS | RH_ENDPOINT\n");
600
601 *(__u16 *) data_buf = swap_16(0);
602 len = 2;
603 break;
604
605 case RH_GET_STATUS | RH_CLASS:
606 debug("RH_GET_STATUS | RH_CLASS\n");
607
608 *(__u32 *) data_buf = swap_32(0);
609 len = 4;
610 break;
611
612 case RH_GET_STATUS | RH_OTHER | RH_CLASS:
613 debug("RH_GET_STATUS | RH_OTHER | RH_CLASS\n");
614
615 int_usb = readw(&musbr->intrusb);
616 if (int_usb & MUSB_INTR_CONNECT) {
617 port_status |= USB_PORT_STAT_CONNECTION
618 | (USB_PORT_STAT_C_CONNECTION << 16);
619 port_status |= USB_PORT_STAT_HIGH_SPEED
620 | USB_PORT_STAT_ENABLE;
621 }
622
623 if (port_status & USB_PORT_STAT_RESET)
624 musb_port_reset(0);
625
626 *(__u32 *) data_buf = swap_32(port_status);
627 len = 4;
628 break;
629
630 case RH_CLEAR_FEATURE | RH_ENDPOINT:
631 debug("RH_CLEAR_FEATURE | RH_ENDPOINT\n");
632
633 switch (wValue) {
634 case RH_ENDPOINT_STALL:
635 debug("C_HUB_ENDPOINT_STALL\n");
636 len = 0;
637 break;
638 }
639 port_status &= ~(1 << wValue);
640 break;
641
642 case RH_CLEAR_FEATURE | RH_CLASS:
643 debug("RH_CLEAR_FEATURE | RH_CLASS\n");
644
645 switch (wValue) {
646 case RH_C_HUB_LOCAL_POWER:
647 debug("C_HUB_LOCAL_POWER\n");
648 len = 0;
649 break;
650
651 case RH_C_HUB_OVER_CURRENT:
652 debug("C_HUB_OVER_CURRENT\n");
653 len = 0;
654 break;
655 }
656 port_status &= ~(1 << wValue);
657 break;
658
659 case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
660 debug("RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS\n");
661
662 switch (wValue) {
663 case RH_PORT_ENABLE:
664 len = 0;
665 break;
666
667 case RH_PORT_SUSPEND:
668 len = 0;
669 break;
670
671 case RH_PORT_POWER:
672 len = 0;
673 break;
674
675 case RH_C_PORT_CONNECTION:
676 len = 0;
677 break;
678
679 case RH_C_PORT_ENABLE:
680 len = 0;
681 break;
682
683 case RH_C_PORT_SUSPEND:
684 len = 0;
685 break;
686
687 case RH_C_PORT_OVER_CURRENT:
688 len = 0;
689 break;
690
691 case RH_C_PORT_RESET:
692 len = 0;
693 break;
694
695 default:
696 debug("invalid wValue\n");
697 stat = USB_ST_STALLED;
698 }
699
700 port_status &= ~(1 << wValue);
701 break;
702
703 case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
704 debug("RH_SET_FEATURE | RH_OTHER | RH_CLASS\n");
705
706 switch (wValue) {
707 case RH_PORT_SUSPEND:
708 len = 0;
709 break;
710
711 case RH_PORT_RESET:
712 musb_port_reset(1);
713 len = 0;
714 break;
715
716 case RH_PORT_POWER:
717 len = 0;
718 break;
719
720 case RH_PORT_ENABLE:
721 len = 0;
722 break;
723
724 default:
725 debug("invalid wValue\n");
726 stat = USB_ST_STALLED;
727 }
728
729 port_status |= 1 << wValue;
730 break;
731
732 case RH_SET_ADDRESS:
733 debug("RH_SET_ADDRESS\n");
734
735 rh_devnum = wValue;
736 len = 0;
737 break;
738
739 case RH_GET_DESCRIPTOR:
740 debug("RH_GET_DESCRIPTOR: %x, %d\n", wValue, wLength);
741
742 switch (wValue) {
743 case (USB_DT_DEVICE << 8): /* device descriptor */
744 len = min_t(unsigned int,
745 leni, min_t(unsigned int,
746 sizeof(root_hub_dev_des),
747 wLength));
748 data_buf = root_hub_dev_des;
749 break;
750
751 case (USB_DT_CONFIG << 8): /* configuration descriptor */
752 len = min_t(unsigned int,
753 leni, min_t(unsigned int,
754 sizeof(root_hub_config_des),
755 wLength));
756 data_buf = root_hub_config_des;
757 break;
758
759 case ((USB_DT_STRING << 8) | 0x00): /* string 0 descriptors */
760 len = min_t(unsigned int,
761 leni, min_t(unsigned int,
762 sizeof(root_hub_str_index0),
763 wLength));
764 data_buf = root_hub_str_index0;
765 break;
766
767 case ((USB_DT_STRING << 8) | 0x01): /* string 1 descriptors */
768 len = min_t(unsigned int,
769 leni, min_t(unsigned int,
770 sizeof(root_hub_str_index1),
771 wLength));
772 data_buf = root_hub_str_index1;
773 break;
774
775 default:
776 debug("invalid wValue\n");
777 stat = USB_ST_STALLED;
778 }
779
780 break;
781
Mike Frysinger671bc3d2010-10-20 07:15:35 -0400782 case RH_GET_DESCRIPTOR | RH_CLASS: {
783 u8 *_data_buf = (u8 *) datab;
Bryan Wu73073cc2010-01-09 16:53:54 -0500784 debug("RH_GET_DESCRIPTOR | RH_CLASS\n");
785
Mike Frysinger671bc3d2010-10-20 07:15:35 -0400786 _data_buf[0] = 0x09; /* min length; */
787 _data_buf[1] = 0x29;
788 _data_buf[2] = 0x1; /* 1 port */
789 _data_buf[3] = 0x01; /* per-port power switching */
790 _data_buf[3] |= 0x10; /* no overcurrent reporting */
Bryan Wu73073cc2010-01-09 16:53:54 -0500791
792 /* Corresponds to data_buf[4-7] */
Mike Frysinger671bc3d2010-10-20 07:15:35 -0400793 _data_buf[4] = 0;
794 _data_buf[5] = 5;
795 _data_buf[6] = 0;
796 _data_buf[7] = 0x02;
797 _data_buf[8] = 0xff;
Bryan Wu73073cc2010-01-09 16:53:54 -0500798
799 len = min_t(unsigned int, leni,
800 min_t(unsigned int, data_buf[0], wLength));
801 break;
Mike Frysinger671bc3d2010-10-20 07:15:35 -0400802 }
Bryan Wu73073cc2010-01-09 16:53:54 -0500803
804 case RH_GET_CONFIGURATION:
805 debug("RH_GET_CONFIGURATION\n");
806
807 *(__u8 *) data_buf = 0x01;
808 len = 1;
809 break;
810
811 case RH_SET_CONFIGURATION:
812 debug("RH_SET_CONFIGURATION\n");
813
814 len = 0;
815 break;
816
817 default:
818 debug("*** *** *** unsupported root hub command *** *** ***\n");
819 stat = USB_ST_STALLED;
820 }
821
822 len = min_t(int, len, leni);
823 if (buffer != data_buf)
824 memcpy(buffer, data_buf, len);
825
826 dev->act_len = len;
827 dev->status = stat;
Mike Frysinger68896282012-02-03 03:03:04 +0000828 debug("dev act_len %d, status %lu\n", dev->act_len, dev->status);
Bryan Wu73073cc2010-01-09 16:53:54 -0500829
830 return stat;
831}
832
833static void musb_rh_init(void)
834{
835 rh_devnum = 0;
836 port_status = 0;
837}
838
839#else
840
841static void musb_rh_init(void) {}
842
843#endif
844
845/*
Thomas Abraham38f424f2009-01-04 09:41:03 +0530846 * do a control transfer
847 */
848int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
849 int len, struct devrequest *setup)
850{
851 int devnum = usb_pipedevice(pipe);
Thomas Abraham38f424f2009-01-04 09:41:03 +0530852 u8 devspeed;
853
Bryan Wu73073cc2010-01-09 16:53:54 -0500854#ifdef MUSB_NO_MULTIPOINT
855 /* Control message is for the HUB? */
Cliff Cai94cfe2a2011-04-21 12:42:10 -0400856 if (devnum == rh_devnum) {
857 int stat = musb_submit_rh_msg(dev, pipe, buffer, len, setup);
858 if (stat)
859 return stat;
860 }
Bryan Wu73073cc2010-01-09 16:53:54 -0500861#endif
862
Thomas Abraham38f424f2009-01-04 09:41:03 +0530863 /* select control endpoint */
864 writeb(MUSB_CONTROL_EP, &musbr->index);
Anatolij Gustschinb2aed5d2011-11-19 13:12:09 +0000865 readw(&musbr->txcsr);
Thomas Abraham38f424f2009-01-04 09:41:03 +0530866
Bryan Wu784f1382009-12-16 22:04:00 -0500867#ifndef MUSB_NO_MULTIPOINT
Thomas Abraham38f424f2009-01-04 09:41:03 +0530868 /* target addr and (for multipoint) hub addr/port */
869 writeb(devnum, &musbr->tar[MUSB_CONTROL_EP].txfuncaddr);
870 writeb(devnum, &musbr->tar[MUSB_CONTROL_EP].rxfuncaddr);
Bryan Wu784f1382009-12-16 22:04:00 -0500871#endif
Thomas Abraham38f424f2009-01-04 09:41:03 +0530872
873 /* configure the hub address and the port number as required */
874 devspeed = get_dev_speed(dev);
875 if ((musb_ishighspeed()) && (dev->parent != NULL) &&
876 (devspeed != MUSB_TYPE_SPEED_HIGH)) {
877 config_hub_port(dev, MUSB_CONTROL_EP);
878 writeb(devspeed << 6, &musbr->txtype);
879 } else {
880 writeb(musb_cfg.musb_speed << 6, &musbr->txtype);
Bryan Wu784f1382009-12-16 22:04:00 -0500881#ifndef MUSB_NO_MULTIPOINT
Thomas Abraham38f424f2009-01-04 09:41:03 +0530882 writeb(0, &musbr->tar[MUSB_CONTROL_EP].txhubaddr);
883 writeb(0, &musbr->tar[MUSB_CONTROL_EP].txhubport);
884 writeb(0, &musbr->tar[MUSB_CONTROL_EP].rxhubaddr);
885 writeb(0, &musbr->tar[MUSB_CONTROL_EP].rxhubport);
Bryan Wu784f1382009-12-16 22:04:00 -0500886#endif
Thomas Abraham38f424f2009-01-04 09:41:03 +0530887 }
888
889 /* Control transfer setup phase */
890 if (ctrlreq_setup_phase(dev, setup) < 0)
891 return 0;
892
893 switch (setup->request) {
894 case USB_REQ_GET_DESCRIPTOR:
895 case USB_REQ_GET_CONFIGURATION:
896 case USB_REQ_GET_INTERFACE:
897 case USB_REQ_GET_STATUS:
898 case USB_MSC_BBB_GET_MAX_LUN:
899 /* control transfer in-data-phase */
900 if (ctrlreq_in_data_phase(dev, len, buffer) < 0)
901 return 0;
902 /* control transfer out-status-phase */
903 if (ctrlreq_out_status_phase(dev) < 0)
904 return 0;
905 break;
906
907 case USB_REQ_SET_ADDRESS:
908 case USB_REQ_SET_CONFIGURATION:
909 case USB_REQ_SET_FEATURE:
910 case USB_REQ_SET_INTERFACE:
911 case USB_REQ_CLEAR_FEATURE:
912 case USB_MSC_BBB_RESET:
913 /* control transfer in status phase */
914 if (ctrlreq_in_status_phase(dev) < 0)
915 return 0;
916 break;
917
918 case USB_REQ_SET_DESCRIPTOR:
919 /* control transfer out data phase */
920 if (ctrlreq_out_data_phase(dev, len, buffer) < 0)
921 return 0;
922 /* control transfer in status phase */
923 if (ctrlreq_in_status_phase(dev) < 0)
924 return 0;
925 break;
926
927 default:
928 /* unhandled control transfer */
929 return -1;
930 }
931
932 dev->status = 0;
933 dev->act_len = len;
Bryan Wu953ee312010-08-09 18:41:12 -0400934
935#ifdef MUSB_NO_MULTIPOINT
936 /* Set device address to USB_FADDR register */
937 if (setup->request == USB_REQ_SET_ADDRESS)
938 writeb(dev->devnum, &musbr->faddr);
939#endif
940
Thomas Abraham38f424f2009-01-04 09:41:03 +0530941 return len;
942}
943
944/*
945 * do a bulk transfer
946 */
947int submit_bulk_msg(struct usb_device *dev, unsigned long pipe,
948 void *buffer, int len)
949{
950 int dir_out = usb_pipeout(pipe);
951 int ep = usb_pipeendpoint(pipe);
Bryan Wu784f1382009-12-16 22:04:00 -0500952#ifndef MUSB_NO_MULTIPOINT
Thomas Abraham38f424f2009-01-04 09:41:03 +0530953 int devnum = usb_pipedevice(pipe);
Bryan Wu784f1382009-12-16 22:04:00 -0500954#endif
Thomas Abraham38f424f2009-01-04 09:41:03 +0530955 u8 type;
956 u16 csr;
957 u32 txlen = 0;
958 u32 nextlen = 0;
959 u8 devspeed;
960
961 /* select bulk endpoint */
962 writeb(MUSB_BULK_EP, &musbr->index);
963
Bryan Wu784f1382009-12-16 22:04:00 -0500964#ifndef MUSB_NO_MULTIPOINT
Thomas Abraham38f424f2009-01-04 09:41:03 +0530965 /* write the address of the device */
966 if (dir_out)
967 writeb(devnum, &musbr->tar[MUSB_BULK_EP].txfuncaddr);
968 else
969 writeb(devnum, &musbr->tar[MUSB_BULK_EP].rxfuncaddr);
Bryan Wu784f1382009-12-16 22:04:00 -0500970#endif
Thomas Abraham38f424f2009-01-04 09:41:03 +0530971
972 /* configure the hub address and the port number as required */
973 devspeed = get_dev_speed(dev);
974 if ((musb_ishighspeed()) && (dev->parent != NULL) &&
975 (devspeed != MUSB_TYPE_SPEED_HIGH)) {
976 /*
977 * MUSB is in high speed and the destination device is full
978 * speed device. So configure the hub address and port
979 * address registers.
980 */
981 config_hub_port(dev, MUSB_BULK_EP);
982 } else {
Bryan Wu784f1382009-12-16 22:04:00 -0500983#ifndef MUSB_NO_MULTIPOINT
Thomas Abraham38f424f2009-01-04 09:41:03 +0530984 if (dir_out) {
985 writeb(0, &musbr->tar[MUSB_BULK_EP].txhubaddr);
986 writeb(0, &musbr->tar[MUSB_BULK_EP].txhubport);
987 } else {
988 writeb(0, &musbr->tar[MUSB_BULK_EP].rxhubaddr);
989 writeb(0, &musbr->tar[MUSB_BULK_EP].rxhubport);
990 }
Bryan Wu784f1382009-12-16 22:04:00 -0500991#endif
Thomas Abraham38f424f2009-01-04 09:41:03 +0530992 devspeed = musb_cfg.musb_speed;
993 }
994
995 /* Write the saved toggle bit value */
996 write_toggle(dev, ep, dir_out);
997
998 if (dir_out) { /* bulk-out transfer */
999 /* Program the TxType register */
1000 type = (devspeed << MUSB_TYPE_SPEED_SHIFT) |
1001 (MUSB_TYPE_PROTO_BULK << MUSB_TYPE_PROTO_SHIFT) |
1002 (ep & MUSB_TYPE_REMOTE_END);
1003 writeb(type, &musbr->txtype);
1004
1005 /* Write maximum packet size to the TxMaxp register */
1006 writew(dev->epmaxpacketout[ep], &musbr->txmaxp);
1007 while (txlen < len) {
1008 nextlen = ((len-txlen) < dev->epmaxpacketout[ep]) ?
1009 (len-txlen) : dev->epmaxpacketout[ep];
1010
Bryan Wu2dc21e32010-08-09 14:57:41 -04001011#ifdef CONFIG_USB_BLACKFIN
1012 /* Set the transfer data size */
1013 writew(nextlen, &musbr->txcount);
1014#endif
1015
Thomas Abraham38f424f2009-01-04 09:41:03 +05301016 /* Write the data to the FIFO */
1017 write_fifo(MUSB_BULK_EP, nextlen,
1018 (void *)(((u8 *)buffer) + txlen));
1019
1020 /* Set the TxPktRdy bit */
1021 csr = readw(&musbr->txcsr);
1022 writew(csr | MUSB_TXCSR_TXPKTRDY, &musbr->txcsr);
1023
1024 /* Wait until the TxPktRdy bit is cleared */
1025 if (!wait_until_txep_ready(dev, MUSB_BULK_EP)) {
1026 readw(&musbr->txcsr);
1027 usb_settoggle(dev, ep, dir_out,
1028 (csr >> MUSB_TXCSR_H_DATATOGGLE_SHIFT) & 1);
1029 dev->act_len = txlen;
1030 return 0;
1031 }
1032 txlen += nextlen;
1033 }
1034
1035 /* Keep a copy of the data toggle bit */
1036 csr = readw(&musbr->txcsr);
1037 usb_settoggle(dev, ep, dir_out,
1038 (csr >> MUSB_TXCSR_H_DATATOGGLE_SHIFT) & 1);
1039 } else { /* bulk-in transfer */
1040 /* Write the saved toggle bit value */
1041 write_toggle(dev, ep, dir_out);
1042
1043 /* Program the RxType register */
1044 type = (devspeed << MUSB_TYPE_SPEED_SHIFT) |
1045 (MUSB_TYPE_PROTO_BULK << MUSB_TYPE_PROTO_SHIFT) |
1046 (ep & MUSB_TYPE_REMOTE_END);
1047 writeb(type, &musbr->rxtype);
1048
1049 /* Write the maximum packet size to the RxMaxp register */
1050 writew(dev->epmaxpacketin[ep], &musbr->rxmaxp);
1051 while (txlen < len) {
1052 nextlen = ((len-txlen) < dev->epmaxpacketin[ep]) ?
1053 (len-txlen) : dev->epmaxpacketin[ep];
1054
1055 /* Set the ReqPkt bit */
Bryan Wu65b99d32009-12-16 22:04:01 -05001056 csr = readw(&musbr->rxcsr);
1057 writew(csr | MUSB_RXCSR_H_REQPKT, &musbr->rxcsr);
Thomas Abraham38f424f2009-01-04 09:41:03 +05301058
1059 /* Wait until the RxPktRdy bit is set */
1060 if (!wait_until_rxep_ready(dev, MUSB_BULK_EP)) {
1061 csr = readw(&musbr->rxcsr);
1062 usb_settoggle(dev, ep, dir_out,
1063 (csr >> MUSB_S_RXCSR_H_DATATOGGLE) & 1);
1064 csr &= ~MUSB_RXCSR_RXPKTRDY;
1065 writew(csr, &musbr->rxcsr);
1066 dev->act_len = txlen;
1067 return 0;
1068 }
1069
1070 /* Read the data from the FIFO */
1071 read_fifo(MUSB_BULK_EP, nextlen,
1072 (void *)(((u8 *)buffer) + txlen));
1073
1074 /* Clear the RxPktRdy bit */
1075 csr = readw(&musbr->rxcsr);
1076 csr &= ~MUSB_RXCSR_RXPKTRDY;
1077 writew(csr, &musbr->rxcsr);
1078 txlen += nextlen;
1079 }
1080
1081 /* Keep a copy of the data toggle bit */
1082 csr = readw(&musbr->rxcsr);
1083 usb_settoggle(dev, ep, dir_out,
1084 (csr >> MUSB_S_RXCSR_H_DATATOGGLE) & 1);
1085 }
1086
1087 /* bulk transfer is complete */
1088 dev->status = 0;
1089 dev->act_len = len;
1090 return 0;
1091}
1092
1093/*
1094 * This function initializes the usb controller module.
1095 */
Lucas Stacha3231282012-09-26 00:14:34 +02001096int usb_lowlevel_init(int index, void **controller)
Thomas Abraham38f424f2009-01-04 09:41:03 +05301097{
1098 u8 power;
1099 u32 timeout;
1100
Bryan Wu73073cc2010-01-09 16:53:54 -05001101 musb_rh_init();
1102
Thomas Abraham38f424f2009-01-04 09:41:03 +05301103 if (musb_platform_init() == -1)
1104 return -1;
1105
1106 /* Configure all the endpoint FIFO's and start usb controller */
1107 musbr = musb_cfg.regs;
1108 musb_configure_ep(&epinfo[0],
1109 sizeof(epinfo) / sizeof(struct musb_epinfo));
1110 musb_start();
1111
1112 /*
1113 * Wait until musb is enabled in host mode with a timeout. There
1114 * should be a usb device connected.
1115 */
1116 timeout = musb_cfg.timeout;
Matej Frančeškin36eccd22012-08-30 09:24:39 +02001117 while (--timeout)
Thomas Abraham38f424f2009-01-04 09:41:03 +05301118 if (readb(&musbr->devctl) & MUSB_DEVCTL_HM)
1119 break;
1120
1121 /* if musb core is not in host mode, then return */
1122 if (!timeout)
1123 return -1;
1124
1125 /* start usb bus reset */
1126 power = readb(&musbr->power);
1127 writeb(power | MUSB_POWER_RESET, &musbr->power);
1128
1129 /* After initiating a usb reset, wait for about 20ms to 30ms */
1130 udelay(30000);
1131
1132 /* stop usb bus reset */
1133 power = readb(&musbr->power);
1134 power &= ~MUSB_POWER_RESET;
1135 writeb(power, &musbr->power);
1136
1137 /* Determine if the connected device is a high/full/low speed device */
1138 musb_cfg.musb_speed = (readb(&musbr->power) & MUSB_POWER_HSMODE) ?
1139 MUSB_TYPE_SPEED_HIGH :
1140 ((readb(&musbr->devctl) & MUSB_DEVCTL_FSDEV) ?
1141 MUSB_TYPE_SPEED_FULL : MUSB_TYPE_SPEED_LOW);
1142 return 0;
1143}
1144
1145/*
1146 * This function stops the operation of the davinci usb module.
1147 */
Lucas Stacha3231282012-09-26 00:14:34 +02001148int usb_lowlevel_stop(int index)
Thomas Abraham38f424f2009-01-04 09:41:03 +05301149{
1150 /* Reset the USB module */
1151 musb_platform_deinit();
1152 writeb(0, &musbr->devctl);
1153 return 0;
1154}
1155
1156/*
1157 * This function supports usb interrupt transfers. Currently, usb interrupt
1158 * transfers are not supported.
1159 */
1160int submit_int_msg(struct usb_device *dev, unsigned long pipe,
1161 void *buffer, int len, int interval)
1162{
1163 int dir_out = usb_pipeout(pipe);
1164 int ep = usb_pipeendpoint(pipe);
Bryan Wu784f1382009-12-16 22:04:00 -05001165#ifndef MUSB_NO_MULTIPOINT
Thomas Abraham38f424f2009-01-04 09:41:03 +05301166 int devnum = usb_pipedevice(pipe);
Bryan Wu784f1382009-12-16 22:04:00 -05001167#endif
Thomas Abraham38f424f2009-01-04 09:41:03 +05301168 u8 type;
1169 u16 csr;
1170 u32 txlen = 0;
1171 u32 nextlen = 0;
1172 u8 devspeed;
1173
1174 /* select interrupt endpoint */
1175 writeb(MUSB_INTR_EP, &musbr->index);
1176
Bryan Wu784f1382009-12-16 22:04:00 -05001177#ifndef MUSB_NO_MULTIPOINT
Thomas Abraham38f424f2009-01-04 09:41:03 +05301178 /* write the address of the device */
1179 if (dir_out)
1180 writeb(devnum, &musbr->tar[MUSB_INTR_EP].txfuncaddr);
1181 else
1182 writeb(devnum, &musbr->tar[MUSB_INTR_EP].rxfuncaddr);
Bryan Wu784f1382009-12-16 22:04:00 -05001183#endif
Thomas Abraham38f424f2009-01-04 09:41:03 +05301184
1185 /* configure the hub address and the port number as required */
1186 devspeed = get_dev_speed(dev);
1187 if ((musb_ishighspeed()) && (dev->parent != NULL) &&
1188 (devspeed != MUSB_TYPE_SPEED_HIGH)) {
1189 /*
1190 * MUSB is in high speed and the destination device is full
1191 * speed device. So configure the hub address and port
1192 * address registers.
1193 */
1194 config_hub_port(dev, MUSB_INTR_EP);
1195 } else {
Bryan Wu784f1382009-12-16 22:04:00 -05001196#ifndef MUSB_NO_MULTIPOINT
Thomas Abraham38f424f2009-01-04 09:41:03 +05301197 if (dir_out) {
1198 writeb(0, &musbr->tar[MUSB_INTR_EP].txhubaddr);
1199 writeb(0, &musbr->tar[MUSB_INTR_EP].txhubport);
1200 } else {
1201 writeb(0, &musbr->tar[MUSB_INTR_EP].rxhubaddr);
1202 writeb(0, &musbr->tar[MUSB_INTR_EP].rxhubport);
1203 }
Bryan Wu784f1382009-12-16 22:04:00 -05001204#endif
Thomas Abraham38f424f2009-01-04 09:41:03 +05301205 devspeed = musb_cfg.musb_speed;
1206 }
1207
1208 /* Write the saved toggle bit value */
1209 write_toggle(dev, ep, dir_out);
1210
1211 if (!dir_out) { /* intrrupt-in transfer */
1212 /* Write the saved toggle bit value */
1213 write_toggle(dev, ep, dir_out);
1214 writeb(interval, &musbr->rxinterval);
1215
1216 /* Program the RxType register */
1217 type = (devspeed << MUSB_TYPE_SPEED_SHIFT) |
1218 (MUSB_TYPE_PROTO_INTR << MUSB_TYPE_PROTO_SHIFT) |
1219 (ep & MUSB_TYPE_REMOTE_END);
1220 writeb(type, &musbr->rxtype);
1221
1222 /* Write the maximum packet size to the RxMaxp register */
1223 writew(dev->epmaxpacketin[ep], &musbr->rxmaxp);
1224
1225 while (txlen < len) {
1226 nextlen = ((len-txlen) < dev->epmaxpacketin[ep]) ?
1227 (len-txlen) : dev->epmaxpacketin[ep];
1228
1229 /* Set the ReqPkt bit */
Bryan Wu65b99d32009-12-16 22:04:01 -05001230 csr = readw(&musbr->rxcsr);
1231 writew(csr | MUSB_RXCSR_H_REQPKT, &musbr->rxcsr);
Thomas Abraham38f424f2009-01-04 09:41:03 +05301232
1233 /* Wait until the RxPktRdy bit is set */
1234 if (!wait_until_rxep_ready(dev, MUSB_INTR_EP)) {
1235 csr = readw(&musbr->rxcsr);
1236 usb_settoggle(dev, ep, dir_out,
1237 (csr >> MUSB_S_RXCSR_H_DATATOGGLE) & 1);
1238 csr &= ~MUSB_RXCSR_RXPKTRDY;
1239 writew(csr, &musbr->rxcsr);
1240 dev->act_len = txlen;
1241 return 0;
1242 }
1243
1244 /* Read the data from the FIFO */
1245 read_fifo(MUSB_INTR_EP, nextlen,
1246 (void *)(((u8 *)buffer) + txlen));
1247
1248 /* Clear the RxPktRdy bit */
1249 csr = readw(&musbr->rxcsr);
1250 csr &= ~MUSB_RXCSR_RXPKTRDY;
1251 writew(csr, &musbr->rxcsr);
1252 txlen += nextlen;
1253 }
1254
1255 /* Keep a copy of the data toggle bit */
1256 csr = readw(&musbr->rxcsr);
1257 usb_settoggle(dev, ep, dir_out,
1258 (csr >> MUSB_S_RXCSR_H_DATATOGGLE) & 1);
1259 }
1260
1261 /* interrupt transfer is complete */
1262 dev->irq_status = 0;
1263 dev->irq_act_len = len;
1264 dev->irq_handle(dev);
1265 dev->status = 0;
1266 dev->act_len = len;
1267 return 0;
1268}