FS#8961 - Anti-Aliased Fonts.
[kugel-rb.git] / firmware / drivers / m66591.c
blobfca995c154b7f1a87a801d47ae92591c4894d810
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2009 by Karl Kurbjun
11 * Portions Copyright (C) 2007 by Catalin Patulea
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ****************************************************************************/
22 #define LOGF_ENABLE
24 #include "system.h"
25 #include "config.h"
26 #include "string.h"
27 #include "usb_ch9.h"
28 #include "usb_core.h"
29 #include "kernel.h"
30 #include "panic.h"
31 #include "usb_drv.h"
32 #include "logf.h"
34 #include "config.h"
35 #include "cpu.h"
36 #include "ata.h"
37 #include "usb.h"
38 #include "usb-target.h"
39 #include "m66591.h"
41 /*******************************************************************************
42 * These are the driver specific defines.
43 ******************************************************************************/
45 /* This define is primarily intended for testing, using HISPEED all the time
46 * should be acceptable since the defice should down-train if the host does not
47 * support HISPEED.
49 #define HISPEED
51 /* Right now sending blocks till the full transfer has completed, this needs to
52 * be fixed so that it does not require a block. (USB_TRAN_LOCK ideally would
53 * not be set).
55 #define USB_TRAN_BLOCK
57 /*******************************************************************************
58 * The following functions are all helpers which should not be called directly
59 * from the USB stack. They should only be called by eachother, or the USB
60 * stack visible functions.
61 ******************************************************************************/
63 static volatile unsigned short * pipe_ctrl_addr(int pipe);
64 static void pipe_handshake(int pipe, int handshake);
65 static void pipe_c_select (int pipe, bool dir);
66 #if !defined(USB_TRAN_BLOCK)
67 static int pipe_buffer_size (int pipe);
68 #endif
69 static int pipe_maxpack_size (int pipe);
70 static void control_received(void);
71 static void transfer_complete(int endpoint);
72 static int mxx_transmit_receive(int endpoint);
73 static int mxx_queue(int endpoint, void * ptr, int length, bool send);
75 struct M66591_epstat {
76 unsigned char dir; /* endpoint direction */
77 char *buf; /* user buffer to store data */
78 int length; /* how match data will fit */
79 volatile int count; /* actual data count */
80 bool waiting; /* is there data to transfer? */
81 bool busy; /* has the pipe been requested for use? */
82 } ;
84 static struct M66591_epstat M66591_eps[USB_NUM_ENDPOINTS];
86 /* This function is used to return the control address for each pipe */
87 static volatile unsigned short * pipe_ctrl_addr(int pipe) {
88 if(pipe==0) {
89 return &M66591_DCPCTRL;
90 } else {
91 return &M66591_PIPECTRL1 + (pipe-1);
95 /* This function sets the pipe/endpoint handshake */
96 static void pipe_handshake(int pipe, int handshake) {
97 handshake&=0x03;
99 if(handshake == PIPE_SHAKE_STALL) {
100 if( *(pipe_ctrl_addr(pipe)) & 0x03 ) {
101 *(pipe_ctrl_addr(pipe)) = 0x03;
102 } else {
103 *(pipe_ctrl_addr(pipe)) = 0x02;
105 } else {
106 *(pipe_ctrl_addr(pipe)) = handshake;
110 /* This function chooses the pipe desired and waits the required time before
111 * warites/reads are valid */
112 static void pipe_c_select (int pipe, bool dir) {
113 M66591_CPORT_CTRL0 = pipe | (1<<10) | (dir<<5);
115 // Wait for the Pipe to be valid;
116 udelay(2);
119 #if !defined(USB_TRAN_BLOCK)
120 /* This returns the maximum buffer size of each pipe. On this device the size
121 * is fixed.
123 static int pipe_buffer_size (int pipe) {
124 switch(pipe) {
125 case 0:
126 return 256;
127 case 1:
128 case 2:
129 return 1024;
130 case 3:
131 case 4:
132 return 512;
133 case 5:
134 case 6:
135 return 64;
136 default:
137 return 0;
140 #endif
142 /* This function returns the maximum packet size for each endpoint/pipe. The
143 * max packet size is dependent on whether the device is running High or Full
144 * speed.
146 static int pipe_maxpack_size (int pipe) {
147 if( (M66591_HSFS & 0xFF) == 0x03 ) { /* Device is running Highspeed */
148 switch(pipe) {
149 case 0:
150 /* DCP max packet size is configurable */
151 return M66591_DCP_MXPKSZ;
152 case 1:
153 case 2:
154 case 3:
155 case 4:
156 return 512;
157 case 5:
158 case 6:
159 return 64;
160 default:
161 return 0;
163 } else { /* Device is running Full speed */
164 switch(pipe) {
165 case 0:
166 /* DCP max packet size is configurable */
167 return M66591_DCP_MXPKSZ;
168 case 1:
169 case 2:
170 case 3:
171 case 4:
172 return 64;
173 case 5:
174 case 6:
175 return 64;
176 default:
177 return 0;
182 /* This is a helper function that is only called from the interupt handler. It
183 * copies the control packet information from the PHY and notifies the stack.
185 static void control_received(void) {
186 /* copy setup data from packet */
187 static struct usb_ctrlrequest temp;
189 memcpy(&temp, (unsigned char*)&M66591_USB_REQ0, 8);
191 logf("mxx: bReqType=0x%02x bReq=0x%02x wVal=0x%04x"
192 " wIdx=0x%04x wLen=0x%04x",
193 temp.bRequestType, temp.bRequest, temp.wValue,
194 temp.wIndex, temp.wLength);
196 /* acknowledge packet recieved (clear valid) */
197 M66591_INTSTAT_MAIN &= ~(1<<3);
199 usb_core_control_request(&temp);
202 /* This is a helper function, it is used to notife the stack that a transfer is
203 * done.
205 static void transfer_complete(int endpoint) {
206 M66591_INTCFG_EMP &= ~(1 << endpoint);
207 logf("mxx: ep %d transfer complete", endpoint);
208 int temp=M66591_eps[endpoint].dir ? USB_DIR_IN : USB_DIR_OUT;
209 usb_core_transfer_complete(endpoint, temp, 0,
210 M66591_eps[endpoint].length);
213 /* This is the main transmit routine that is typically called from the interrupt
214 * handler (the queue function calls it in some situations)
216 static int mxx_transmit_receive(int endpoint) {
217 logf("mxx: do start");
219 /* Only the lower 15 bits of the endpoint correlate to the pipe number.
220 * For example pipe 2 will corelate to endpoint 0x82, so the upper bits
221 * need to be masked out.
223 endpoint &= 0x7F;
225 int i; /* Used as a loop counter */
226 int length; /* Used in transfers to determine the amount to send/receive */
228 bool send=M66591_eps[endpoint].dir;
230 /* This is used as the internal buffer pointer */
231 unsigned short *ptrs;
233 /* Choose the pipe that data is being transfered on */
234 pipe_c_select(endpoint, send);
236 /* Check to see if the endpoint is ready and give it some time to become
237 * ready. If it runs out of time exit out as an error.
239 i = 0;
240 while (!(M66591_CPORT_CTRL1&(1<<13))) {
241 if (i++ > 100000) {
242 logf("mxx: FIFO %d not ready", endpoint);
243 return -1;
247 /* Write to FIFO */
248 if(send) {
249 int maxpack=pipe_maxpack_size(endpoint);
250 #if defined(USB_TRAN_BLOCK)
251 length = M66591_eps[endpoint].length;
252 #else
253 int bufsize=pipe_buffer_size(endpoint);
254 length=MIN(M66591_eps[endpoint].length, bufsize);
255 #endif
257 /* Calculate the position in the buffer, all transfers should be 2-byte
258 * aligned till the last packet or short packet.
260 ptrs = (unsigned short *)(M66591_eps[endpoint].buf
261 + M66591_eps[endpoint].count);
263 /* Start sending data in 16-bit words */
264 for (i = 0; i < (length>>1); i++) {
265 /* This wait is dangerous in the event that something happens to
266 * the PHY pipe where it never becomes ready again, should probably
267 * add a timeout, and ideally completely remove.
269 while(!(M66591_CPORT_CTRL1&(1<<13))){};
271 M66591_CPORT = *ptrs++;
272 M66591_eps[endpoint].count+=2;
275 /* If the length is odd, send the last byte after setting the byte width
276 * of the FIFO.
278 if(length & 0x01) {
279 /* Unset MBW (8-bit transfer) */
280 M66591_CPORT_CTRL0 &= ~(1<<10);
281 M66591_CPORT = *((unsigned char *)ptrs - 1);
282 M66591_eps[endpoint].count++;
285 /* Set BVAL if length is not a multiple of the maximum packet size */
286 if( (length == 0) || (length % maxpack != 0) ) {
287 logf("mxx: do set BVAL");
288 M66591_CPORT_CTRL1 |= (1<<15);
291 /* If the transfer is complete set up interrupts to notify when FIFO is
292 * EMPTY, disable READY and let the handler know that there is nothing
293 * left to transfer on this pipe.
295 if(M66591_eps[endpoint].count == M66591_eps[endpoint].length) {
296 /* Enable Empty flag */
297 M66591_INTCFG_EMP |= 1 << endpoint;
298 /* Disable ready flag */
299 M66591_INTCFG_RDY &= ~(1 << endpoint);
300 /* Nothing left to transfer */
301 M66591_eps[endpoint].waiting=false;
302 } else {
303 /* There is still data to transfer, make sure READY is enabled */
304 M66591_INTCFG_RDY |= 1 << endpoint;
306 } else {
307 /* Read data from FIFO */
309 /* Read the number of bytes that the PHY received */
310 int receive_length=M66591_CPORT_CTRL1 & 0x03FF;
312 /* The number of bytes to actually read is either what's left of the
313 * amount requested, or the amount that the PHY received. Choose the
314 * smaller of the two.
316 length = MIN(M66591_eps[endpoint].length - M66591_eps[endpoint].count,
317 receive_length);
319 /* If the length is zero, just clear the buffer as specified in the
320 * datasheet. Otherwise read in the data (in 16-bit pieces */
321 if(length==0) {
322 /* Set the BCLR bit */
323 M66591_CPORT_CTRL1 |= 1<<14;
324 } else {
325 /* Set the position in the buffer */
326 ptrs = (unsigned short *)(M66591_eps[endpoint].buf
327 + M66591_eps[endpoint].count);
329 /* Read in the data (buffer size should be even). The PHY cannot
330 * switch from 16-bit mode to 8-bit mode on an OUT buffer.
332 for (i = 0; i < ((length+1)>>1); i++) {
333 *ptrs++ = M66591_CPORT;
334 M66591_eps[endpoint].count+=2;
338 /* If the length was odd subtract 1 from the count */
339 M66591_eps[endpoint].count -= (length&0x01);
341 /* If the requested size of data was received, or the data received was
342 * less than the maximum packet size end the transfer.
344 if( (M66591_eps[endpoint].count == M66591_eps[endpoint].length)
345 || (length % pipe_maxpack_size(endpoint)) ) {
347 /* If the host tries to send anything else the FIFO is not ready/
348 * enabled yet (NAK).
350 pipe_handshake(endpoint, PIPE_SHAKE_NAK);
351 /* Tell the interrupt handler that transfer is complete. */
352 M66591_eps[endpoint].waiting=false;
353 /* Disable ready */
354 M66591_INTCFG_RDY &= ~(1 << endpoint);
356 /* Let the stack know that the transfer is complete */
357 if(endpoint!=0)
358 transfer_complete(endpoint);
362 logf("mxx: do done ep %d %s len: %d cnt: %d", endpoint,
363 send ? "out" : "in", length, M66591_eps[endpoint].count);
365 return 0;
368 /* This function is used to start transfers. It is a helper function for the
369 * usb_drv_send_nonblocking, usb_drv_send, and usb_drv_receive functions.
371 static int mxx_queue(int endpoint, void * ptr, int length, bool send) {
372 /* Disable IRQs */
373 int flags = disable_irq_save();
375 /* Only the lower 15 bits of the endpoint correlate to the pipe number.
376 * For example pipe 2 will corelate to endpoint 0x82, so the upper bits
377 * need to be masked out.
379 endpoint &= 0x7F;
381 /* Initialize the enpoint status registers used for the transfer */
382 M66591_eps[endpoint].buf=ptr;
383 M66591_eps[endpoint].length=length;
384 M66591_eps[endpoint].count=0;
385 M66591_eps[endpoint].dir=send;
386 M66591_eps[endpoint].waiting=true;
388 logf("mxx: queue ep %d %s, len: %d", endpoint, send ? "out" : "in", length);
390 /* Pick the pipe that communications are happening on */
391 pipe_c_select(endpoint, send);
393 /* All transfers start with a BUF handshake */
394 pipe_handshake(endpoint, PIPE_SHAKE_BUF);
396 /* This USB PHY takes care of control completion packets by setting the
397 * CCPL bit in EP0 (endpoint 0, or DCP). If the control state is "write no
398 * data tranfer" then we just need to set the CCPL bit (hopefully)
399 * regardless of what the stack said to send.
401 int control_state = (M66591_INTSTAT_MAIN & 0x07);
402 if(endpoint==0 && control_state==CTRL_WTND) {
403 logf("mxx: queue ep 0 ctls: 5, set ccpl");
405 /* Set CCPL */
406 M66591_DCPCTRL |= 1<<2;
407 } else {
408 /* This is the standard case for transmitting data */
409 if(send) {
410 /* If the pipe is not ready don't try and send right away; instead
411 * just set the READY interrupt so that the handler can initiate
412 * the transfer.
414 if((M66591_CPORT_CTRL1&(1<<13))) {
415 mxx_transmit_receive(endpoint);
416 } else {
417 M66591_INTCFG_RDY |= 1 << endpoint;
420 if(length==0) {
421 transfer_complete(endpoint);
423 } else {
424 /* When receiving data, just enable the ready interrupt, the PHY
425 * will trigger it and then the reads can start.
427 M66591_INTCFG_RDY |= 1 << endpoint;
431 /* Re-enable IRQs */
432 restore_irq(flags);
433 return 0;
436 /*******************************************************************************
437 * This is the interrupt handler for this driver. It should be called from the
438 * target interrupt handler routine (eg. GPIO3 on M:Robe 500).
439 ******************************************************************************/
440 void USB_DEVICE(void) {
441 int pipe_restore=M66591_CPORT_CTRL0;
442 logf("mxx: INT BEGIN tick: %d\n", (int) current_tick);
444 logf("mxx: sMAIN0: 0x%04x, sRDY: 0x%04x",
445 M66591_INTSTAT_MAIN, M66591_INTSTAT_RDY);
446 logf("mxx: sNRDY: 0x%04x, sEMP: 0x%04x",
447 M66591_INTSTAT_NRDY, M66591_INTSTAT_EMP);
449 /* VBUS (connected) interrupt */
450 while ( M66591_INTSTAT_MAIN & (1<<15) ) {
451 M66591_INTSTAT_MAIN &= ~(1<<15);
453 /* If device is not clocked, interrupt flag must be set manually */
454 if ( !(M66591_TRN_CTRL & (1<<10)) ) {
455 M66591_INTSTAT_MAIN |= (1<<15);
459 /* Resume interrupt: This is not used. Extra logic needs to be added similar
460 * to the VBUS interrupt incase the PHY clock is not running.
462 if(M66591_INTSTAT_MAIN & (1<<14)) {
463 M66591_INTSTAT_MAIN &= ~(1<<14);
464 logf("mxx: RESUME");
467 /* Device state transition interrupt: Not used, but useful for debugging */
468 if(M66591_INTSTAT_MAIN & (1<<12)) {
469 M66591_INTSTAT_MAIN &= ~(1<<12);
470 logf("mxx: DEV state CHANGE=%d",
471 ((M66591_INTSTAT_MAIN & (0x07<<4)) >> 4) );
474 /* Control transfer stage interrupt */
475 if(M66591_INTSTAT_MAIN & (1<<11)) {
476 M66591_INTSTAT_MAIN &= ~(1<<11);
477 int control_state = (M66591_INTSTAT_MAIN & 0x07);
479 logf("mxx: CTRT with CTSQ=%d", control_state);
481 switch ( control_state ) {
482 case CTRL_IDLE:
483 transfer_complete(0);
484 break;
485 case CTRL_RTDS:
486 case CTRL_WTDS:
487 case CTRL_WTND:
488 /* If data is not valid stop */
489 if(!(M66591_INTSTAT_MAIN & (1<<3)) ) {
490 logf("mxx: CTRT interrupt but VALID is false");
491 break;
493 control_received();
494 break;
495 case CTRL_RTSS:
496 case CTRL_WTSS:
497 pipe_handshake(0, PIPE_SHAKE_BUF);
498 M66591_DCPCTRL |= 1<<2; /* Set CCPL */
499 break;
500 default:
501 logf("mxx: CTRT with unknown CTSQ");
502 break;
506 /* FIFO EMPTY interrupt: when this happens the transfer should be complete.
507 * When the interrupt occurs notify the stack.
509 if(M66591_INTSTAT_MAIN & (1<<10)) {
510 int i;
511 logf("mxx: INT EMPTY: 0x%04x", M66591_INTSTAT_EMP);
513 for(i=0; i<USB_NUM_ENDPOINTS; i++) {
514 if(M66591_INTSTAT_EMP&(1<<i)) {
515 /* Clear the empty flag */
516 M66591_INTSTAT_EMP=~(1<<i);
517 /* Notify the stack */
518 transfer_complete(i);
523 /* FIFO NOT READY interrupt: This is not used, but included incase the
524 * interrupt is endabled.
526 if(M66591_INTSTAT_MAIN & (1<<9)) {
527 logf("mxx: INT NOT READY: 0x%04x", M66591_INTSTAT_NRDY);
528 M66591_INTSTAT_NRDY = 0;
531 /* FIFO READY interrupt: This just initiates transfers if they are needed */
532 if(M66591_INTSTAT_MAIN & (1<<8)) {
533 int i;
534 logf("mxx: INT READY: 0x%04x", M66591_INTSTAT_RDY);
536 for(i=0; i<USB_NUM_ENDPOINTS; i++) {
537 /* Was this endpoint ready and waiting */
538 if(M66591_INTSTAT_RDY&(1<<i) && M66591_eps[i].waiting) {
539 /* Clear the ready flag */
540 M66591_INTSTAT_RDY=~(1<<i);
541 /* It was ready and waiting so start a transfer */
542 mxx_transmit_receive(i);
547 /* Make sure that the INTStatus register is completely cleared. */
548 M66591_INTSTAT_MAIN = 0;
550 /* Restore the pipe state before the interrupt occured */
551 M66591_CPORT_CTRL0=pipe_restore;
552 logf("\nmxx: INT END");
555 /*******************************************************************************
556 * The following functions are all called by and visible to the USB stack.
557 ******************************************************************************/
559 /* The M55691 handles this automatically, nothing to do */
560 void usb_drv_set_address(int address) {
561 (void) address;
564 /* This function sets the standard test modes, it is not required, but might as
565 * well implement it since the hardware supports it
567 void usb_drv_set_test_mode(int mode) {
568 /* This sets the test bits and assumes that mode is from 0 to 0x04 */
569 M66591_TESTMODE &= 0x0007;
570 M66591_TESTMODE |= mode;
573 /* Request an unused endpoint, support for interrupt endpoints needs addition */
574 int usb_drv_request_endpoint(int type, int dir) {
575 int ep;
576 int pipecfg = 0;
578 if (type == USB_ENDPOINT_XFER_BULK) {
579 /* Enable double buffer mode (only used for ep 1 and 2) */
580 pipecfg |= 1<<9;
582 /* Bulk endpoints must be between 1 and 4 inclusive */
583 ep=1;
585 while(M66591_eps[ep].busy && ep++<5);
587 /* If this reached 5 the endpoints were all busy */
588 if(ep==5) {
589 logf("mxx: ep %d busy", ep);
590 return -1;
592 } else if (type == USB_ENDPOINT_XFER_INT) {
593 ep=5;
595 while(M66591_eps[ep].busy && ep++<7);
597 /* If this reached 7 the endpoints were all busy */
598 if(ep==7) {
599 logf("mxx: ep %d busy", ep);
600 return -1;
602 } else {
603 /* Not a supported type */
604 return -1;
607 if (dir == USB_DIR_IN) {
608 pipecfg |= (1<<4);
611 M66591_eps[ep].busy = true;
612 M66591_eps[ep].dir = dir;
614 M66591_PIPE_CFGSEL=ep;
616 /* Enable pipe (15) and continuous transfer mode (8) */
617 pipecfg |= 1<<15 | 1<<8;
619 pipe_handshake(ep, PIPE_SHAKE_NAK);
621 /* Setup the flags */
622 M66591_PIPE_CFGWND=pipecfg;
624 logf("mxx: ep req ep#: %d config: 0x%04x", ep, M66591_PIPE_CFGWND);
626 return ep | dir;
629 /* Used by stack to tell the helper functions that the pipe is not in use */
630 void usb_drv_release_endpoint(int ep) {
631 int flags;
632 ep &= 0x7f;
634 if (ep < 1 || ep > USB_NUM_ENDPOINTS || M66591_eps[ep].busy == false)
635 return ;
637 flags = disable_irq_save();
639 logf("mxx: ep %d release", ep);
641 M66591_eps[ep].busy = false;
642 M66591_eps[ep].dir = -1;
644 restore_irq(flags);
647 /* Periodically called to check if a cable was plugged into the device */
648 inline int usb_detect(void)
650 if(M66591_INTSTAT_MAIN&(1<<7))
651 return USB_INSERTED;
652 else
653 return USB_EXTRACTED;
656 void usb_enable(bool on) {
657 logf("mxx: %s: %s", __FUNCTION__, on ? "true" : "false");
658 if (on)
659 usb_core_init();
660 else
661 usb_core_exit();
664 /* This is where the driver stuff starts */
665 void usb_drv_init(void) {
666 logf("mxx: Device Init");
668 /* State left behind by m:robe 500i original firmware */
669 M66591_TRN_CTRL = 0x8001; /* External 48 MHz clock */
670 M66591_TRN_LNSTAT = 0x0040; /* "Reserved. Set it to '1'." */
672 M66591_PIN_CFG0 = 0x0000;
673 M66591_PIN_CFG1 = 0x8000; /* Drive Current: 3.3V setting */
674 M66591_PIN_CFG2 = 0x0000;
676 M66591_INTCFG_MAIN = 0x0000; /* All Interrupts Disable for now */
677 M66591_INTCFG_OUT = 0x0000; /* Sense is edge, polarity is low */
678 M66591_INTCFG_RDY = 0x0000;
679 M66591_INTCFG_NRDY = 0x0000;
680 M66591_INTCFG_EMP = 0x0000;
682 M66591_INTSTAT_MAIN = 0;
683 M66591_INTSTAT_RDY = 0;
684 M66591_INTSTAT_NRDY = 0;
685 M66591_INTSTAT_EMP = 0;
688 /* fully enable driver */
689 void usb_attach(void) {
690 int i;
692 /* Reset Endpoint states */
693 for(i=0; i<USB_NUM_ENDPOINTS; i++) {
694 M66591_eps[i].dir = -1;
695 M66591_eps[i].buf = (char *) 0;
696 M66591_eps[i].length = 0;
697 M66591_eps[i].count = 0;
698 M66591_eps[i].waiting = false;
699 M66591_eps[i].busy = false;
702 /* Issue a h/w reset */
703 usb_init_device();
704 usb_core_init();
706 /* USB Attach Process: This follows the flow diagram in the M66591GP
707 * Reference Manual Rev 1.00, p. 77 */
709 #if defined(HISPEED)
710 /* Run Hi-Speed */
711 M66591_TRN_CTRL |= 1<<7;
712 #else
713 /* Run Full-Speed */
714 M66591_TRN_CTRL &= ~(1<<7);
715 #endif
717 /* Enable oscillation buffer */
718 M66591_TRN_CTRL |= (1<<13);
720 udelay(1500);
722 /* Enable reference clock, PLL */
723 M66591_TRN_CTRL |= (3<<11);
725 udelay(9);
727 /* Enable internal clock supply */
728 M66591_TRN_CTRL |= (1<<10);
730 /* Disable PIPE ready interrupts */
731 M66591_INTCFG_RDY = 0;
733 /* Disable PIPE not-ready interrupts */
734 M66591_INTCFG_NRDY = 0;
736 /* Disable PIPE empyt/size error interrupts */
737 M66591_INTCFG_EMP = 0;
739 /* Enable all interrupts except NOT READY, RESUME, and VBUS */
740 M66591_INTCFG_MAIN = 0x1DFF;
742 pipe_c_select(0, false);
744 /* Enable continuous transfer mode on the DCP */
745 M66591_DCP_CNTMD |= (1<<8);
747 /* Set the threshold that the PHY will automatically transmit from EP0 */
748 M66591_DCP_CTRLEN = 128;
750 pipe_handshake(0, PIPE_SHAKE_NAK);
752 /* Set the Max packet size to 64 */
753 M66591_DCP_MXPKSZ = 64;
755 /* Attach notification to PC (D+ pull-up) */
756 M66591_TRN_CTRL |= (1<<4);
758 logf("mxx: attached");
761 void usb_drv_exit(void) {
762 /* USB Detach Process: This follows the flow diagram in the M66591GP
763 * Reference Manual Rev 1.00, p. 78.
766 /* Detach notification to PC (disable D+ pull-up) */
767 M66591_TRN_CTRL &= ~(1<<4);
769 /* Software reset */
770 M66591_TRN_CTRL &= ~0x01;
772 /* Disable internal clock supply */
773 M66591_TRN_CTRL &= ~(1<<10);
774 udelay(3);
776 /* Disable PLL */
777 M66591_TRN_CTRL &= ~(1<<11);
778 udelay(3);
780 /* Disable internal reference clock */
781 M66591_TRN_CTRL &= ~(1<<12);
782 udelay(3);
784 /* Disable oscillation buffer, reenable USB operation */
785 M66591_TRN_CTRL &= ~(1<<13);
787 M66591_TRN_CTRL |= 0x01;
789 logf("mxx: detached");
792 /* This function begins a transmit (on an IN endpoint), it should not block
793 * so the actual transmit is done in the interrupt handler.
795 int usb_drv_send_nonblocking(int endpoint, void* ptr, int length)
797 /* The last arguement for queue specifies the dir of data (true==send) */
798 return mxx_queue(endpoint, ptr, length, true);
801 /* This function begins a transmit (on an IN endpoint), it does not block
802 * so the actual transmit is done in the interrupt handler.
804 int usb_drv_send(int endpoint, void* ptr, int length)
806 /* The last arguement for queue specifies the dir of data (true==send) */
807 return mxx_queue(endpoint, ptr, length, true);
810 /* This function begins a receive (on an OUT endpoint), it should not block
811 * so the actual receive is done in the interrupt handler.
813 int usb_drv_recv(int endpoint, void* ptr, int length)
815 /* Last arguement for queue specifies the dir of data (false==receive) */
816 return mxx_queue(endpoint, ptr, length, false);
819 /* This function checks the reset handshake speed status
820 * (Fullspeed or Highspeed)
822 int usb_drv_port_speed(void)
824 int handshake = (M66591_HSFS & 0xFF);
826 if( handshake == 0x02) {
827 return 0; /* Handshook at Full-Speed */
828 } else if( handshake == 0x03) {
829 return 1; /* Handshook at Hi-Speed */
830 } else {
831 return -1; /* Error, handshake may not be complete */
835 /* This function checks if the endpoint is stalled (error). I am not sure what
836 * the "in" variable is intended for.
838 bool usb_drv_stalled(int endpoint,bool in)
840 (void) in;
842 bool stalled = (*(pipe_ctrl_addr(endpoint)) & (0x02)) ? true : false;
844 logf("mxx: stall?: %s ep: %d", stalled ? "true" : "false", endpoint);
846 if(stalled) {
847 return true;
848 } else {
849 return false;
853 /* This function stalls/unstalls the endpoint. Stalls only happen on error so
854 * if the endpoint is functioning properly this should not be called. I am
855 * not sure what the "in" variable is intended for.
857 void usb_drv_stall(int endpoint, bool stall,bool in)
859 (void) in;
861 logf("mxx: stall - ep: %d", endpoint);
863 if(stall) {
864 /* Stall the pipe (host needs to intervene/error) */
865 pipe_handshake(endpoint, PIPE_SHAKE_STALL);
866 } else {
867 /* Setting this to a NAK, not sure if it is appropriate */
868 pipe_handshake(endpoint, PIPE_SHAKE_NAK);
872 /* !!!!!!!!!!This function is likely incomplete!!!!!!!!!!!!!! */
873 void usb_drv_cancel_all_transfers(void)
875 int endpoint;
876 int flags;
878 logf("mxx: %s", __func__);
880 flags = disable_irq_save();
881 for (endpoint = 0; endpoint < USB_NUM_ENDPOINTS; endpoint++) {
882 if (M66591_eps[endpoint].buf) {
883 M66591_eps[endpoint].buf = NULL;
887 restore_irq(flags);