Port greylib blitting optimisation to MPIO HD200. ISR speedup is ~10%; further speedu...
[kugel-rb.git] / firmware / drivers / m66591.c
bloba0ef3c3c00984256da975493321de483ac8381fd
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 "cpu.h"
35 #include "ata.h"
36 #include "usb.h"
37 #include "usb-target.h"
38 #include "m66591.h"
40 /*******************************************************************************
41 * These are the driver specific defines.
42 ******************************************************************************/
44 /* This define is primarily intended for testing, using HISPEED all the time
45 * should be acceptable since the device should down-train if the host does not
46 * support HISPEED.
48 #define HISPEED
50 /* Right now sending blocks till the full transfer has completed. The driver
51 * will work without USB_TRAN_BLOCK set, but it is more than 50% slower.
52 * The driver is more "Proper" without USB_TRAN_BLOCK defined so if you start
53 * having freezeups or trouble using USB undefine this option.
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,
74 bool wait);
76 struct M66591_epstat {
77 unsigned char dir; /* endpoint direction */
78 char *buf; /* user buffer to store data */
79 int length; /* how match data will fit */
80 volatile int count; /* actual data count */
81 bool waiting; /* is there data to transfer? */
82 bool busy; /* has the pipe been requested for use? */
83 } ;
85 static struct M66591_epstat M66591_eps[USB_NUM_ENDPOINTS];
87 /* This function is used to return the control address for each pipe */
88 static volatile unsigned short * pipe_ctrl_addr(int pipe) {
89 if(pipe==0) {
90 return &M66591_DCPCTRL;
91 } else {
92 return &M66591_PIPECTRL1 + (pipe-1);
96 static void pipe_init(int pipe) {
97 volatile unsigned short *pipe_cfg;
98 pipe_cfg = pipe_ctrl_addr(pipe);
100 *pipe_cfg |= 1<<9; /* ACLR */
101 *pipe_cfg &= ~(1<<9); /* Force de-assertion */
102 *pipe_cfg |= 1<<8; /* SQCLR */
105 /* This function sets the pipe/endpoint handshake */
106 static void pipe_handshake(int pipe, int handshake) {
107 handshake&=0x03;
109 if(handshake == PIPE_SHAKE_STALL) {
110 if( *(pipe_ctrl_addr(pipe)) & 0x03 ) {
111 *(pipe_ctrl_addr(pipe)) = 0x03;
112 } else {
113 *(pipe_ctrl_addr(pipe)) = 0x02;
115 } else {
116 *(pipe_ctrl_addr(pipe)) = handshake;
120 /* This function chooses the pipe desired and waits the required time before
121 * warites/reads are valid */
122 static void pipe_c_select (int pipe, bool dir) {
123 M66591_CPORT_CTRL0 = pipe | (1<<10) | (dir<<5);
125 // Wait for the Pipe to be valid;
126 udelay(2);
129 #if !defined(USB_TRAN_BLOCK)
130 /* This returns the maximum buffer size of each pipe. On this device the size
131 * is fixed.
133 static int pipe_buffer_size (int pipe) {
134 switch(pipe) {
135 case 0:
136 return 256;
137 case 1:
138 case 2:
139 if(M66591_PIPE_CFGWND & (1<<9) )
140 return 1024;
141 else
142 return 512;
143 case 3:
144 case 4:
145 return 512;
146 case 5:
147 case 6:
148 return 64;
149 default:
150 return 0;
153 #endif
155 /* This function returns the maximum packet size for each endpoint/pipe. The
156 * max packet size is dependent on whether the device is running High or Full
157 * speed.
159 static int pipe_maxpack_size (int pipe) {
160 if( (M66591_HSFS & 0xFF) == 0x03 ) { /* Device is running Highspeed */
161 switch(pipe) {
162 case 0:
163 /* DCP max packet size is configurable */
164 return M66591_DCP_MXPKSZ;
165 case 1:
166 case 2:
167 case 3:
168 case 4:
169 return 512;
170 case 5:
171 case 6:
172 return 64;
173 default:
174 return 0;
176 } else { /* Device is running Full speed */
177 switch(pipe) {
178 case 0:
179 /* DCP max packet size is configurable */
180 return M66591_DCP_MXPKSZ;
181 case 1:
182 case 2:
183 case 3:
184 case 4:
185 return 64;
186 case 5:
187 case 6:
188 return 64;
189 default:
190 return 0;
195 /* This is a helper function that is only called from the interupt handler. It
196 * copies the control packet information from the PHY and notifies the stack.
198 static void control_received(void) {
199 /* copy setup data from packet */
200 static struct usb_ctrlrequest temp;
202 memcpy(&temp, (unsigned char*)&M66591_USB_REQ0, 8);
204 logf("mxx: bReqType=0x%02x bReq=0x%02x wVal=0x%04x"
205 " wIdx=0x%04x wLen=0x%04x",
206 temp.bRequestType, temp.bRequest, temp.wValue,
207 temp.wIndex, temp.wLength);
209 /* acknowledge packet recieved (clear valid) */
210 M66591_INTSTAT_MAIN &= ~(1<<3);
212 usb_core_control_request(&temp);
215 /* This is a helper function, it is used to notife the stack that a transfer is
216 * done.
218 static void transfer_complete(int endpoint) {
219 M66591_INTCFG_EMP &= ~(1 << endpoint);
220 logf("mxx: ep %d transfer complete", endpoint);
221 int temp=M66591_eps[endpoint].dir ? USB_DIR_IN : USB_DIR_OUT;
222 usb_core_transfer_complete(endpoint, temp, 0,
223 M66591_eps[endpoint].count);
226 /* This is the main transmit routine that is typically called from the interrupt
227 * handler (the queue function calls it in some situations)
229 static int mxx_transmit_receive(int endpoint) {
230 logf("mxx: do start");
232 /* Only the lower 15 bits of the endpoint correlate to the pipe number.
233 * For example pipe 2 will corelate to endpoint 0x82, so the upper bits
234 * need to be masked out.
236 endpoint &= 0x7F;
238 int i; /* Used as a loop counter */
239 int length; /* Used in transfers to determine the amount to send/receive */
241 bool send=M66591_eps[endpoint].dir;
243 /* This is used as the internal buffer pointer */
244 unsigned short *ptrs;
246 /* Choose the pipe that data is being transfered on */
247 pipe_c_select(endpoint, send);
249 /* Check to see if the endpoint is ready and give it some time to become
250 * ready. If it runs out of time exit out as an error.
252 i = 0;
253 while (!(M66591_CPORT_CTRL1&(1<<13))) {
254 if (i++ > 100000) {
255 logf("mxx: FIFO %d not ready", endpoint);
256 return -1;
260 /* Write to FIFO */
261 if(send) {
262 int maxpack=pipe_maxpack_size(endpoint);
263 #if defined(USB_TRAN_BLOCK)
264 length = M66591_eps[endpoint].length;
265 #else
266 int bufsize=pipe_buffer_size(endpoint);
267 length=MIN(M66591_eps[endpoint].length - M66591_eps[endpoint].count,
268 bufsize);
269 #endif
271 /* Calculate the position in the buffer, all transfers should be 2-byte
272 * aligned till the last packet or short packet.
274 ptrs = (unsigned short *)(M66591_eps[endpoint].buf
275 + M66591_eps[endpoint].count);
277 /* Check if the buffer is alligned */
278 if( LIKELY(((int)ptrs) & 0x01) == 0 )
280 /* Start sending data in 16-bit words (fast) */
281 for (i = 0; i < (length>>1); i++) {
282 #if defined(USB_TRAN_BLOCK)
283 /* This wait is dangerous in the event that something happens
284 * to the PHY pipe where it never becomes ready again, should
285 * probably add a timeout, and ideally completely remove.
287 while(!(M66591_CPORT_CTRL1&(1<<13))){};
288 #endif
290 M66591_CPORT = *ptrs++;
291 M66591_eps[endpoint].count+=2;
294 /* If the length is odd, send the last byte after setting the byte
295 * width of the FIFO.
297 if(length & 0x01) {
298 /* Unset MBW (8-bit transfer) */
299 M66591_CPORT_CTRL0 &= ~(1<<10);
300 M66591_CPORT = *((unsigned char *)ptrs);
301 M66591_eps[endpoint].count++;
304 else
306 /* The buffer is mis-aligned - data needs to be organized first.
307 * This is slower than the above method.
309 unsigned short sbuf;
310 unsigned char *ptrc = (unsigned char*)ptrs;
312 /* Start sending data in 16-bit words */
313 for (i = 0; i < (length>>1); i++) {
314 #if defined(USB_TRAN_BLOCK)
315 /* This wait is dangerous in the event that something happens
316 * to the PHY pipe where it never becomes ready again, should
317 * probably add a timeout, and ideally completely remove.
319 while(!(M66591_CPORT_CTRL1&(1<<13))){};
320 #endif
322 /* These are mis-aligned accesses so the data nees to be
323 * arranged.
325 sbuf = (*(ptrc+1) << 8) | *ptrc;
326 ptrc += 2;
328 M66591_CPORT = sbuf;
329 M66591_eps[endpoint].count+=2;
332 /* If the length is odd, send the last byte after setting the byte
333 * width of the FIFO.
335 if(length & 0x01) {
336 /* Unset MBW (8-bit transfer) */
337 M66591_CPORT_CTRL0 &= ~(1<<10);
338 M66591_CPORT = *ptrc;
339 M66591_eps[endpoint].count++;
343 /* If the transfer is complete set up interrupts to notify when FIFO is
344 * EMPTY, disable READY and let the handler know that there is nothing
345 * left to transfer on this pipe.
347 if(M66591_eps[endpoint].count == M66591_eps[endpoint].length) {
348 /* Enable Empty flag */
349 M66591_INTCFG_EMP |= 1 << endpoint;
350 /* Disable ready flag */
351 M66591_INTCFG_RDY &= ~(1 << endpoint);
352 /* Nothing left to transfer */
353 M66591_eps[endpoint].waiting=false;
354 } else {
355 /* There is still data to transfer, make sure READY is enabled */
356 M66591_INTCFG_RDY |= 1 << endpoint;
359 /* Set BVAL if length is not a multiple of the maximum packet size */
360 if( (length == 0) || (length % maxpack != 0) ) {
361 logf("mxx: do set BVAL");
362 M66591_CPORT_CTRL1 |= (1<<15) | ((length == 0) << 14);
364 } else {
365 /* Read data from FIFO */
367 /* Read the number of bytes that the PHY received */
368 int receive_length=M66591_CPORT_CTRL1 & 0x03FF;
370 /* The number of bytes to actually read is either what's left of the
371 * amount requested, or the amount that the PHY received. Choose the
372 * smaller of the two.
374 length = MIN(M66591_eps[endpoint].length - M66591_eps[endpoint].count,
375 receive_length);
377 /* If the length is zero, just clear the buffer as specified in the
378 * datasheet. Otherwise read in the data (in 16-bit pieces */
379 if(length==0) {
380 /* Set the BCLR bit */
381 M66591_CPORT_CTRL1 |= 1<<14;
382 } else {
383 /* Set the position in the buffer */
384 ptrs = (unsigned short *)(M66591_eps[endpoint].buf
385 + M66591_eps[endpoint].count);
387 /* Read in the data (buffer size should be even). The PHY cannot
388 * switch from 16-bit mode to 8-bit mode on an OUT buffer.
390 for (i = 0; i < ((length+1)>>1); i++) {
391 *ptrs++ = M66591_CPORT;
392 M66591_eps[endpoint].count+=2;
396 /* If the length was odd subtract 1 from the count */
397 M66591_eps[endpoint].count -= (length&0x01);
399 /* If the requested size of data was received, or the data received was
400 * less than the maximum packet size end the transfer.
402 if( (M66591_eps[endpoint].count == M66591_eps[endpoint].length)
403 || (length % pipe_maxpack_size(endpoint)) ) {
405 /* If the host tries to send anything else the FIFO is not ready/
406 * enabled yet (NAK).
408 pipe_handshake(endpoint, PIPE_SHAKE_NAK);
409 /* Tell the interrupt handler that transfer is complete. */
410 M66591_eps[endpoint].waiting=false;
411 /* Disable ready */
412 M66591_INTCFG_RDY &= ~(1 << endpoint);
414 /* Let the stack know that the transfer is complete */
415 if(endpoint!=0)
416 transfer_complete(endpoint);
420 logf("mxx: do done ep %d %s len: %d cnt: %d", endpoint,
421 send ? "out" : "in", length, M66591_eps[endpoint].count);
423 return 0;
426 /* This function is used to start transfers. It is a helper function for the
427 * usb_drv_send_nonblocking, usb_drv_send, and usb_drv_receive functions.
429 * The functionality for wait needs to be added. Currently the driver is
430 * always used in a blocking mode(USB_TRAN_BLOCK) so it is not required.
432 static int mxx_queue(int endpoint, void * ptr, int length, bool send,
433 bool wait)
435 #if defined(USB_TRAN_BLOCK) && !defined(LOGF_ENABLE)
436 (void) wait;
437 #endif
439 /* Disable IRQs */
440 int flags = disable_irq_save();
442 /* Only the lower 15 bits of the endpoint correlate to the pipe number.
443 * For example pipe 2 will corelate to endpoint 0x82, so the upper bits
444 * need to be masked out.
446 endpoint &= 0x7F;
448 /* Initialize the enpoint status registers used for the transfer */
449 M66591_eps[endpoint].buf=ptr;
450 M66591_eps[endpoint].length=length;
451 M66591_eps[endpoint].count=0;
452 M66591_eps[endpoint].dir=send;
453 M66591_eps[endpoint].waiting=true;
455 logf("mxx: queue ep %d %s, len: %d, wait: %d",
456 endpoint, send ? "out" : "in", length, wait);
458 /* Pick the pipe that communications are happening on */
459 pipe_c_select(endpoint, send);
461 /* All transfers start with a BUF handshake */
462 pipe_handshake(endpoint, PIPE_SHAKE_BUF);
464 /* This USB PHY takes care of control completion packets by setting the
465 * CCPL bit in EP0 (endpoint 0, or DCP). If the control state is "write no
466 * data tranfer" then we just need to set the CCPL bit (hopefully)
467 * regardless of what the stack said to send.
469 int control_state = (M66591_INTSTAT_MAIN & 0x07);
470 if(endpoint==0 && control_state==CTRL_WTND) {
471 logf("mxx: queue ep 0 ctls: 5, set ccpl");
473 /* Set CCPL */
474 M66591_DCPCTRL |= 1<<2;
475 } else {
476 /* This is the standard case for transmitting data */
477 if(send) {
478 /* If the pipe is not ready don't try and send right away; instead
479 * just set the READY interrupt so that the handler can initiate
480 * the transfer.
482 if((M66591_CPORT_CTRL1&(1<<13))) {
483 mxx_transmit_receive(endpoint);
484 } else {
485 M66591_INTCFG_RDY |= 1 << endpoint;
488 if(length==0) {
489 transfer_complete(endpoint);
491 } else {
492 /* When receiving data, just enable the ready interrupt, the PHY
493 * will trigger it and then the reads can start.
495 M66591_INTCFG_RDY |= 1 << endpoint;
499 /* Re-enable IRQs */
500 restore_irq(flags);
501 return 0;
504 /*******************************************************************************
505 * This is the interrupt handler for this driver. It should be called from the
506 * target interrupt handler routine (eg. GPIO3 on M:Robe 500).
507 ******************************************************************************/
508 void USB_DEVICE(void) __attribute__ ((section(".icode")));
509 void USB_DEVICE(void) {
510 int pipe_restore=M66591_CPORT_CTRL0;
511 logf("\nmxx: INT BEGIN tick: %d", (int) current_tick);
513 logf("mxx: sMAIN0: 0x%04x, sRDY: 0x%04x",
514 M66591_INTSTAT_MAIN, M66591_INTSTAT_RDY);
515 logf("mxx: sNRDY: 0x%04x, sEMP: 0x%04x",
516 M66591_INTSTAT_NRDY, M66591_INTSTAT_EMP);
518 /* VBUS (connected) interrupt */
519 while ( M66591_INTSTAT_MAIN & (1<<15) ) {
520 M66591_INTSTAT_MAIN &= ~(1<<15);
522 /* If device is not clocked, interrupt flag must be set manually */
523 if ( !(M66591_TRN_CTRL & (1<<10)) ) {
524 M66591_INTSTAT_MAIN |= (1<<15);
528 /* Resume interrupt: This is not used. Extra logic needs to be added similar
529 * to the VBUS interrupt incase the PHY clock is not running.
531 if(M66591_INTSTAT_MAIN & (1<<14)) {
532 M66591_INTSTAT_MAIN &= ~(1<<14);
533 logf("mxx: RESUME");
536 /* Device state transition interrupt: Not used, but useful for debugging */
537 if(M66591_INTSTAT_MAIN & (1<<12)) {
538 M66591_INTSTAT_MAIN &= ~(1<<12);
539 logf("mxx: DEV state CHANGE=%d",
540 ((M66591_INTSTAT_MAIN & (0x07<<4)) >> 4) );
543 /* Control transfer stage interrupt */
544 if(M66591_INTSTAT_MAIN & (1<<11)) {
545 M66591_INTSTAT_MAIN &= ~(1<<11);
546 int control_state = (M66591_INTSTAT_MAIN & 0x07);
548 logf("mxx: CTRT with CTSQ=%d", control_state);
550 switch ( control_state ) {
551 case CTRL_IDLE:
552 transfer_complete(0);
553 break;
554 case CTRL_RTDS:
555 case CTRL_WTDS:
556 case CTRL_WTND:
557 /* If data is not valid stop */
558 if(!(M66591_INTSTAT_MAIN & (1<<3)) ) {
559 logf("mxx: CTRT interrupt but VALID is false");
560 break;
562 control_received();
563 break;
564 case CTRL_RTSS:
565 case CTRL_WTSS:
566 pipe_handshake(0, PIPE_SHAKE_BUF);
567 M66591_DCPCTRL |= 1<<2; /* Set CCPL */
568 break;
569 default:
570 logf("mxx: CTRT with unknown CTSQ");
571 break;
575 /* FIFO EMPTY interrupt: when this happens the transfer should be complete.
576 * When the interrupt occurs notify the stack.
578 if(M66591_INTSTAT_MAIN & (1<<10)) {
579 int i;
580 logf("mxx: INT EMPTY: 0x%04x", M66591_INTSTAT_EMP);
582 for(i=0; i<USB_NUM_ENDPOINTS; i++) {
583 if(M66591_INTSTAT_EMP&(1<<i)) {
584 /* Clear the empty flag */
585 M66591_INTSTAT_EMP=~(1<<i);
586 /* Notify the stack */
587 transfer_complete(i);
592 /* FIFO NOT READY interrupt: This is not used, but included incase the
593 * interrupt is endabled.
595 if(M66591_INTSTAT_MAIN & (1<<9)) {
596 logf("mxx: INT NOT READY: 0x%04x", M66591_INTSTAT_NRDY);
597 M66591_INTSTAT_NRDY = 0;
600 /* FIFO READY interrupt: This just initiates transfers if they are needed */
601 if(M66591_INTSTAT_MAIN & (1<<8)) {
602 int i;
603 logf("mxx: INT READY: 0x%04x", M66591_INTSTAT_RDY);
605 for(i=0; i<USB_NUM_ENDPOINTS; i++) {
606 /* Was this endpoint ready and waiting */
607 if(M66591_INTSTAT_RDY&(1<<i) && M66591_eps[i].waiting) {
608 /* Clear the ready flag */
609 M66591_INTSTAT_RDY=~(1<<i);
610 /* It was ready and waiting so start a transfer */
611 mxx_transmit_receive(i);
616 /* Make sure that the INTStatus register is completely cleared. */
617 M66591_INTSTAT_MAIN = 0;
619 /* Restore the pipe state before the interrupt occured */
620 M66591_CPORT_CTRL0=pipe_restore;
621 logf("mxx: INT END\n");
624 /*******************************************************************************
625 * The following functions are all called by and visible to the USB stack.
626 ******************************************************************************/
628 /* The M55691 handles this automatically, nothing to do */
629 void usb_drv_set_address(int address) {
630 (void) address;
633 /* This function sets the standard test modes, it is not required, but might as
634 * well implement it since the hardware supports it
636 void usb_drv_set_test_mode(int mode) {
637 /* This sets the test bits and assumes that mode is from 0 to 0x04 */
638 M66591_TESTMODE &= 0x0007;
639 M66591_TESTMODE |= mode;
642 /* Request an unused endpoint */
643 int usb_drv_request_endpoint(int type, int dir) {
644 int ep;
645 int pipecfg = 0;
647 if (type == USB_ENDPOINT_XFER_BULK) {
648 /* Enable double buffer mode (only used for ep 1 and 2) */
649 pipecfg |= 1<<9 | 1<<8;
651 /* Bulk endpoints must be between 1 and 4 inclusive */
652 ep=1;
654 while(M66591_eps[ep].busy && ep++<5);
656 /* If this reached 5 the endpoints were all busy */
657 if(ep==5) {
658 logf("mxx: ep %d busy", ep);
659 return -1;
661 } else if (type == USB_ENDPOINT_XFER_INT) {
662 ep=5;
664 pipecfg |= 1<<13;
666 while(M66591_eps[ep].busy && ep++<7);
668 /* If this reached 7 the endpoints were all busy */
669 if(ep==7) {
670 logf("mxx: ep %d busy", ep);
671 return -1;
673 } else {
674 /* Not a supported type */
675 return -1;
678 if (dir == USB_DIR_IN) {
679 pipecfg |= (1<<4);
682 M66591_eps[ep].busy = true;
683 M66591_eps[ep].dir = dir;
685 M66591_PIPE_CFGSEL=ep;
687 /* Enable pipe (15) */
688 pipecfg |= 1<<15;
690 pipe_handshake(ep, PIPE_SHAKE_NAK);
692 /* Setup the flags */
693 M66591_PIPE_CFGWND=pipecfg;
695 pipe_init(ep);
697 logf("mxx: ep req ep#: %d config: 0x%04x", ep, M66591_PIPE_CFGWND);
699 return ep | dir;
702 /* Used by stack to tell the helper functions that the pipe is not in use */
703 void usb_drv_release_endpoint(int ep) {
704 int flags;
705 ep &= 0x7f;
707 if (ep < 1 || ep > USB_NUM_ENDPOINTS || M66591_eps[ep].busy == false)
708 return ;
710 flags = disable_irq_save();
712 logf("mxx: ep %d release", ep);
714 M66591_eps[ep].busy = false;
715 M66591_eps[ep].dir = -1;
717 restore_irq(flags);
720 /* Periodically called to check if a cable was plugged into the device */
721 inline int usb_detect(void)
723 if(M66591_INTSTAT_MAIN&(1<<7))
724 return USB_INSERTED;
725 else
726 return USB_EXTRACTED;
729 void usb_enable(bool on) {
730 logf("mxx: %s: %s", __FUNCTION__, on ? "true" : "false");
731 if (on)
732 usb_core_init();
733 else
734 usb_core_exit();
737 /* This is where the driver stuff starts */
738 void usb_drv_init(void) {
739 logf("mxx: Device Init");
741 M66591_PIN_CFG1 = 0x8000; /* Drive Current: 3.3V setting */
742 M66591_PIN_CFG2 = 0x0000;
744 M66591_TRN_CTRL = 0x8000; /* External 48 MHz clock */
745 M66591_TRN_CTRL |=0x0001;
747 M66591_INTCFG_MAIN |=0x8000; /* Enable VBUS interrupt */
750 /* fully enable driver */
751 void usb_attach(void) {
752 int i;
754 /* Reset Endpoint states */
755 for(i=0; i<USB_NUM_ENDPOINTS; i++) {
756 M66591_eps[i].dir = -1;
757 M66591_eps[i].buf = (char *) 0;
758 M66591_eps[i].length = 0;
759 M66591_eps[i].count = 0;
760 M66591_eps[i].waiting = false;
761 M66591_eps[i].busy = false;
764 /* Issue a h/w reset */
765 usb_init_device();
766 usb_core_init();
768 /* USB Attach Process: This follows the flow diagram in the M66591GP
769 * Reference Manual Rev 1.00, p. 77 */
771 #if defined(HISPEED)
772 /* Run Hi-Speed */
773 M66591_TRN_CTRL |= 1<<7;
774 #else
775 /* Run Full-Speed */
776 M66591_TRN_CTRL &= ~(1<<7);
777 #endif
779 /* Enable oscillation buffer XCKE */
780 M66591_TRN_CTRL |= (1<<13);
782 udelay(1500);
784 /* Enable reference clock, PLL RCKE */
785 M66591_TRN_CTRL |= (3<<11);
787 udelay(9);
789 /* Enable internal clock supply SCKE */
790 M66591_TRN_CTRL |= (1<<10);
792 /* Disable PIPE ready interrupts */
793 M66591_INTCFG_RDY = 0;
795 /* Disable PIPE not-ready interrupts */
796 M66591_INTCFG_NRDY = 0;
798 /* Disable PIPE empyt/size error interrupts */
799 M66591_INTCFG_EMP = 0;
801 /* Enable all interrupts except NOT READY, RESUME, and VBUS */
802 M66591_INTCFG_MAIN = 0x1DFF;
804 pipe_c_select(0, false);
806 /* Enable continuous transfer mode on the DCP */
807 M66591_DCP_CNTMD |= (1<<8);
809 /* Set the threshold that the PHY will automatically transmit from EP0 */
810 M66591_DCP_CTRLEN = 256;
812 pipe_handshake(0, PIPE_SHAKE_NAK);
814 /* Set the Max packet size to 64 */
815 M66591_DCP_MXPKSZ = 64;
817 /* Attach notification to PC (D+ pull-up) */
818 M66591_TRN_CTRL |= (1<<4);
820 logf("mxx: attached");
823 void usb_drv_exit(void) {
824 /* USB Detach Process: This follows the flow diagram in the M66591GP
825 * Reference Manual Rev 1.00, p. 78.
828 /* Detach notification to PC (disable D+ pull-up) */
829 M66591_TRN_CTRL &= ~(1<<4);
831 /* Software reset */
832 M66591_TRN_CTRL &= ~0x01;
834 /* Disable internal clock supply */
835 M66591_TRN_CTRL &= ~(1<<10);
836 udelay(3);
838 /* Disable PLL */
839 M66591_TRN_CTRL &= ~(1<<11);
840 udelay(3);
842 /* Disable internal reference clock */
843 M66591_TRN_CTRL &= ~(1<<12);
844 udelay(3);
846 /* Disable oscillation buffer, reenable USB operation */
847 M66591_TRN_CTRL &= ~(1<<13);
849 M66591_TRN_CTRL |= 0x01;
851 logf("mxx: detached");
854 /* This function begins a transmit (on an IN endpoint), it should not block
855 * so the actual transmit is done in the interrupt handler.
857 int usb_drv_send_nonblocking(int endpoint, void* ptr, int length)
859 return mxx_queue(endpoint, ptr, length, true, false);
862 /* This function begins a transmit (on an IN endpoint), it does not block
863 * so the actual transmit is done in the interrupt handler.
865 int usb_drv_send(int endpoint, void* ptr, int length)
867 return mxx_queue(endpoint, ptr, length, true, true);
870 /* This function begins a receive (on an OUT endpoint), it should not block
871 * so the actual receive is done in the interrupt handler.
873 int usb_drv_recv(int endpoint, void* ptr, int length)
875 return mxx_queue(endpoint, ptr, length, false, false);
878 /* This function checks the reset handshake speed status
879 * (Fullspeed or Highspeed)
881 int usb_drv_port_speed(void)
883 int handshake = (M66591_HSFS & 0xFF);
885 if( handshake == 0x02) {
886 return 0; /* Handshook at Full-Speed */
887 } else if( handshake == 0x03) {
888 return 1; /* Handshook at Hi-Speed */
889 } else {
890 return -1; /* Error, handshake may not be complete */
894 /* This function checks if the endpoint is stalled (error). I am not sure what
895 * the "in" variable is intended for.
897 bool usb_drv_stalled(int endpoint,bool in)
899 (void) in;
901 bool stalled = (*(pipe_ctrl_addr(endpoint)) & (0x02)) ? true : false;
903 logf("mxx: stall?: %s ep: %d", stalled ? "true" : "false", endpoint);
905 if(stalled) {
906 return true;
907 } else {
908 return false;
912 /* This function stalls/unstalls the endpoint. Stalls only happen on error so
913 * if the endpoint is functioning properly this should not be called. I am
914 * not sure what the "in" variable is intended for.
916 void usb_drv_stall(int endpoint, bool stall,bool in)
918 (void) in;
920 logf("mxx: stall - ep: %d", endpoint);
922 if(stall) {
923 /* Stall the pipe (host needs to intervene/error) */
924 pipe_handshake(endpoint, PIPE_SHAKE_STALL);
925 } else {
926 /* Setting this to a NAK, not sure if it is appropriate */
927 pipe_handshake(endpoint, PIPE_SHAKE_NAK);
931 /* !!!!!!!!!!This function is likely incomplete!!!!!!!!!!!!!! */
932 void usb_drv_cancel_all_transfers(void)
934 int endpoint;
935 int flags;
937 logf("mxx: %s", __func__);
939 flags = disable_irq_save();
940 for (endpoint = 0; endpoint < USB_NUM_ENDPOINTS; endpoint++) {
941 if (M66591_eps[endpoint].buf) {
942 M66591_eps[endpoint].buf = NULL;
946 restore_irq(flags);