summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVitja Makarov <vitja.makarov@gmail.com>2008-10-14 05:13:21 +0000
committerVitja Makarov <vitja.makarov@gmail.com>2008-10-14 05:13:21 +0000
commit91b9c6139b3447d7c0f4f2924ef73a9dc323703b (patch)
treeacd74d0da5dcfa1e6d831fe8f50861d6d8d6def4
parent1620d1fd0328b02664036900c990883984ca94fa (diff)
downloadrockbox-91b9c6139b3447d7c0f4f2924ef73a9dc323703b.tar.gz
rockbox-91b9c6139b3447d7c0f4f2924ef73a9dc323703b.zip
telechips usb: not ready for use but, something is working, needs improvement.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18806 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--bootloader/telechips.c2
-rw-r--r--firmware/target/arm/tcc77x/system-tcc77x.c6
-rw-r--r--firmware/target/arm/tcc77x/usb-tcc77x.c738
-rw-r--r--firmware/usb.c3
4 files changed, 744 insertions, 5 deletions
diff --git a/bootloader/telechips.c b/bootloader/telechips.c
index a4f4d36c11..7e00e52142 100644
--- a/bootloader/telechips.c
+++ b/bootloader/telechips.c
@@ -240,6 +240,7 @@ void* main(void)
240 return 0; 240 return 0;
241} 241}
242 242
243#ifndef HAVE_USBSTACK
243/* These functions are present in the firmware library, but we reimplement 244/* These functions are present in the firmware library, but we reimplement
244 them here because the originals do a lot more than we want */ 245 them here because the originals do a lot more than we want */
245void usb_acknowledge(void) 246void usb_acknowledge(void)
@@ -249,3 +250,4 @@ void usb_acknowledge(void)
249void usb_wait_for_disconnect(void) 250void usb_wait_for_disconnect(void)
250{ 251{
251} 252}
253#endif
diff --git a/firmware/target/arm/tcc77x/system-tcc77x.c b/firmware/target/arm/tcc77x/system-tcc77x.c
index 2c8959fded..38004851bd 100644
--- a/firmware/target/arm/tcc77x/system-tcc77x.c
+++ b/firmware/target/arm/tcc77x/system-tcc77x.c
@@ -26,7 +26,7 @@
26/* Externally defined interrupt handlers */ 26/* Externally defined interrupt handlers */
27extern void TIMER(void); 27extern void TIMER(void);
28extern void ADC(void); 28extern void ADC(void);
29extern void USBD_IRQ(void); 29extern void USB_DEVICE(void);
30 30
31void irq(void) 31void irq(void)
32{ 32{
@@ -37,9 +37,9 @@ void irq(void)
37 TIMER(); 37 TIMER();
38 else if (irq & ADC_IRQ_MASK) 38 else if (irq & ADC_IRQ_MASK)
39 ADC(); 39 ADC();
40#ifdef HAVE_USBSTACK 40#ifdef HAVE_USBSTACK
41 else if (irq & USBD_IRQ_MASK) 41 else if (irq & USBD_IRQ_MASK)
42 USBD_IRQ(); 42 USB_DEVICE();
43#endif 43#endif
44 else 44 else
45 panicf("Unhandled IRQ 0x%08X", irq); 45 panicf("Unhandled IRQ 0x%08X", irq);
diff --git a/firmware/target/arm/tcc77x/usb-tcc77x.c b/firmware/target/arm/tcc77x/usb-tcc77x.c
index 9cfcb503e0..1092ed60a1 100644
--- a/firmware/target/arm/tcc77x/usb-tcc77x.c
+++ b/firmware/target/arm/tcc77x/usb-tcc77x.c
@@ -21,9 +21,744 @@
21 21
22#include "config.h" 22#include "config.h"
23#include "usb.h" 23#include "usb.h"
24#include "system.h" 24
25#include "usb-tcc7xx.h" 25#include "usb-tcc7xx.h"
26 26
27#include "cpu.h"
28#include "system.h"
29#include "kernel.h"
30#include "panic.h"
31
32#ifdef HAVE_USBSTACK
33#include "usb_ch9.h"
34#include "usb_core.h"
35
36#define TCC7xx_USB_EPIF_IRQ_MASK 0xf
37
38static int dbg_level = 0x02;
39static int global_ep_irq_mask = 0x1;
40#define DEBUG(level, fmt, args...) do { if (dbg_level & (level)) printf(fmt, ## args); } while (0)
41
42#include <inttypes.h>
43
44
45#include "sprintf.h"
46#include "power.h"
47
48#ifndef BOOTLOADER
49#define printf(...) do {} while (0)
50#define panicf_my panicf
51#else
52int printf(const char *fmt, ...);
53#define panicf_my(fmt, args...) { \
54 int flags = disable_irq_save(); \
55 printf("*** PANIC ***"); \
56 printf(fmt, ## args); \
57 printf("*** PANIC ***"); \
58 while (usb_detect() == USB_INSERTED) \
59 ; \
60 power_off(); \
61 while(1); \
62 restore_irq(flags); \
63}
64#endif
65
66struct tcc_ep {
67 unsigned char dir; /* endpoint direction */
68 volatile uint16_t *ep; /* hw ep buffer */
69 int id; /* Endpoint id */
70 int mask; /* Endpoint bit mask */
71 char *buf; /* user buffer to store data */
72 int max_len; /* how match data will fit */
73 int count; /* actual data count */
74 bool busy;
75} ;
76
77static struct tcc_ep tcc_endpoints[] = {
78 /* control */
79 {
80 .dir = -1,
81 .ep = &TCC7xx_USB_EP0_BUF,
82 }, { /* bulk */
83 .dir = -1,
84 .ep = &TCC7xx_USB_EP1_BUF,
85 }, { /* bulk */
86 .dir = -1,
87 .ep = &TCC7xx_USB_EP2_BUF,
88 }, { /* interrupt */
89 .dir = -1,
90 .ep = &TCC7xx_USB_EP3_BUF,
91 },
92} ;
93
94static int usb_drv_write_packet(volatile unsigned short *buf, unsigned char *data, int len, int max);
95static void usb_set_speed(int);
96
97int usb_drv_request_endpoint(int dir)
98{
99 int flags = disable_irq_save();
100 size_t ep;
101 int ret = 0;
102
103 if (dir == USB_DIR_IN)
104 ep = 1;
105 else
106 ep = 2;
107
108 if (!tcc_endpoints[ep].busy) {
109 tcc_endpoints[ep].busy = true;
110 tcc_endpoints[ep].dir = dir;
111 ret = ep | dir;
112 } else {
113 ret = -1;
114 }
115
116 restore_irq(flags);
117 return ret;
118}
119
120void usb_drv_release_endpoint(int ep)
121{
122 int flags;
123 ep = ep & 0x7f;
124
125 if (ep < 1 || ep > NUM_ENDPOINTS)
126 return ;
127
128 flags = disable_irq_save();
129
130 tcc_endpoints[ep].busy = false;
131 tcc_endpoints[ep].dir = -1;
132
133 restore_irq(flags);
134}
135
136static void udelay(unsigned long msecs)
137{
138 /* TODO: implement me other way */
139 msecs*=126;
140 while (msecs--)
141 asm("nop;");
142}
143
144static inline void pullup_on(void)
145{
146 TCC7xx_USB_PHY_CFG = 0x000c;
147}
148
149static inline void pullup_off(void)
150{
151 TCC7xx_USB_PHY_CFG = 0x3e4c;
152}
153
154#if 0
155static
156char *dump_data(char *data, int count)
157{
158 static char buf[1024];
159 char *dump = buf;
160 int i;
161
162 for (i = 0; i < count; i++)
163 dump += snprintf(dump, sizeof(buf) - (dump - buf), "%02x", data[i]);
164 return buf;
165}
166#endif
167
168static
169void handle_control(void)
170{
171 /* control are always 8 bytes len */
172 static unsigned char ep_control[8];
173 struct usb_ctrlrequest *req =
174 (struct usb_ctrlrequest *) ep_control;
175 unsigned short stat;
176 unsigned short count = 0;
177 int i;
178 int type;
179
180 /* select control endpoint */
181 TCC7xx_USB_INDEX = 0x00;
182 stat = TCC7xx_USB_EP0_STAT;
183
184 if (stat & 0x10) {
185 DEBUG(2, "stall");
186 TCC7xx_USB_EP0_STAT = 0x10;
187 }
188
189 if (TCC7xx_USB_EP0_STAT & 0x01) { /* RX */
190 uint16_t *ptr = (uint16_t *) ep_control;
191
192 count = TCC7xx_USB_EP_BRCR;
193
194 if (TCC7xx_USB_EP0_STAT & 0x2)
195 TCC7xx_USB_EP0_STAT = 0x02;
196
197 if (count != 4) { /* bad control? */
198 unsigned short dummy;
199
200 while (count--)
201 dummy = TCC7xx_USB_EP0_BUF;
202 DEBUG(1, "WTF: count = %d", count);
203 } else {
204 /* simply read control packet */
205 for (i = 0; i < count; i++)
206 ptr[i] = TCC7xx_USB_EP0_BUF;
207 }
208
209 count *= 2;
210 TCC7xx_USB_EP0_STAT = 0x01;
211 DEBUG(1, "CTRL: len = %d %04x", count, stat);
212 } else if (TCC7xx_USB_EP0_STAT & 0x02) { /* TX */
213 TCC7xx_USB_EP0_STAT = 0x02;
214 DEBUG(2, "TX Done\n");
215 } else {
216 DEBUG(1, "stat: %04x", stat);
217 }
218
219 TCC7xx_USB_EPIF = 1;
220
221 if (0 == (stat & 0x1) || count != 8)
222 return ;
223#if 1 /* TODO: remove me someday */
224 {
225 int i;
226 uint16_t *ptr = (uint16_t *) ep_control;
227 for (i = 1; i < (count>>1); i++) {
228 if (ptr[i] != ptr[0])
229 break;
230 }
231 if (i == (count>>1)) {
232 /*DEBUG(2, */panicf_my("sanity failed");
233 return ;
234 }
235 }
236#endif
237 type = req->bRequestType;
238
239 /* TODO: don't pass some kinds of requests to upper level */
240 switch (req->bRequest) {
241 case USB_REQ_CLEAR_FEATURE:
242 DEBUG(2, "USB_REQ_CLEAR_FEATURE");
243 DEBUG(2, "...%04x %04x", req->wValue, req->wIndex);
244 break;
245 case USB_REQ_SET_ADDRESS:
246 //DEBUG(2, "USB_REQ_SET_ADDRESS, %d %d", req->wValue, TCC7xx_USB_FUNC);
247 /* seems we don't have to set it manually
248 TCC7xx_USB_FUNC = req->wValue; */
249 break;
250 case USB_REQ_GET_DESCRIPTOR:
251 DEBUG(2, "gd, %02x %02x", req->wValue, req->wIndex);
252 break;
253 case USB_REQ_GET_CONFIGURATION:
254 DEBUG(2, "USB_REQ_GET_CONFIGURATION");
255 break;
256 default:
257 DEBUG(2, "req: %02x %02d", req->bRequestType, req->bRequest);
258 }
259
260 usb_core_control_request(req);
261}
262
263static
264void handle_ep_in(struct tcc_ep *tcc_ep, uint16_t stat)
265{
266 uint8_t *buf = tcc_ep->buf;
267 uint16_t *wbuf = (uint16_t *) buf;
268 int wcount;
269 int count;
270 int i;
271
272 if (tcc_ep->dir != USB_DIR_OUT) {
273 panicf_my("ep%d: is input only", tcc_ep->id);
274 }
275
276 wcount = TCC7xx_USB_EP_BRCR;
277
278 DEBUG(2, "ep%d: %04x %04x", tcc_ep->id, stat, wcount);
279
280 /* read data */
281 count = wcount * 2;
282 if (stat & TCC7xx_USP_EP_STAT_LWO) {
283 count--;
284 wcount--;
285 }
286
287 if (buf == NULL)
288 panicf_my("ep%d: Unexpected packet! %d %x", tcc_ep->id, count, TCC7xx_USB_EP_CTRL);
289 if (tcc_ep->max_len < count)
290 panicf_my("Too big packet: %d excepted %d %x", count, tcc_ep->max_len, TCC7xx_USB_EP_CTRL);
291
292 for (i = 0; i < wcount; i++)
293 wbuf[i] = *tcc_ep->ep;
294
295 if (count & 1) { /* lwo */
296 uint16_t tmp = *tcc_ep->ep;
297 buf[count - 1] = tmp & 0xff;
298 }
299
300 tcc_ep->buf = NULL;
301
302 TCC7xx_USB_EP_STAT = TCC7xx_USB_EP_STAT;
303 TCC7xx_USB_EPIF = tcc_ep->mask;
304 TCC7xx_USB_EPIE &= ~tcc_ep->mask; /* TODO: use INGLD? */
305 global_ep_irq_mask &= ~tcc_ep->mask;
306
307 if (TCC7xx_USB_EP_STAT & 0x1)
308 panicf_my("One more packet?");
309
310 TCC7xx_USB_EP_CTRL |= TCC7xx_USB_EP_CTRL_OUTHD;
311
312 usb_core_transfer_complete(tcc_ep->id, USB_DIR_OUT, 0, count);
313}
314
315static
316void handle_ep_out(struct tcc_ep *tcc_ep, uint16_t stat)
317{
318 (void) stat;
319
320 if (tcc_ep->dir != USB_DIR_IN) {
321 panicf_my("ep%d: is out only", tcc_ep->id);
322 }
323
324 if (tcc_ep->buf == NULL) {
325 panicf_my("%s:%d", __FILE__, __LINE__);
326 }
327
328 if (tcc_ep->max_len) {
329 int count = usb_drv_write_packet(tcc_ep->ep,
330 tcc_ep->buf,
331 tcc_ep->max_len,
332 512);
333 tcc_ep->buf += count;
334 tcc_ep->max_len -= count;
335 tcc_ep->count += count;
336 } else {
337 tcc_ep->buf = NULL;
338 }
339
340 TCC7xx_USB_EP_STAT = 0x2; /* Clear TX stat */
341 TCC7xx_USB_EPIF = tcc_ep->mask;
342
343 if (tcc_ep->buf == NULL) {
344 TCC7xx_USB_EPIE &= ~tcc_ep->mask;
345 global_ep_irq_mask &= ~tcc_ep->mask;
346
347 usb_core_transfer_complete(tcc_ep->id, USB_DIR_IN, 0, tcc_ep->count);
348 }
349}
350
351static
352void handle_ep(unsigned short ep_irq)
353{
354 if (ep_irq & 0x1) {
355 handle_control();
356 }
357
358 if (ep_irq & 0xe) {
359 int endpoint;
360
361 for (endpoint = 1; endpoint < 4; endpoint++) {
362 struct tcc_ep *tcc_ep = &tcc_endpoints[endpoint];
363 uint16_t stat;
364
365 if (0 == (ep_irq & (1 << endpoint)))
366 continue;
367 if (!tcc_ep->busy)
368 panicf_my("ep%d: wasn't requested", endpoint);
369
370 TCC7xx_USB_INDEX = endpoint;
371 stat = TCC7xx_USB_EP_STAT;
372
373 DEBUG(1, "ep%d: %04x", endpoint, stat);
374
375 if (stat & 0x1)
376 handle_ep_in(tcc_ep, stat);
377 else if (stat & 0x2)
378 handle_ep_out(tcc_ep, stat);
379 else /* TODO: remove me? */
380 panicf_my("Unhandled ep%d state: %x, %d", endpoint, TCC7xx_USB_EP_STAT, TCC7xx_USB_INDEX);
381 }
382 }
383}
384
385static void usb_set_speed(int high_speed)
386{
387 TCC7xx_USB_EP_DIR = 0x0000;
388
389 /* control endpoint */
390 TCC7xx_USB_INDEX = 0;
391 TCC7xx_USB_EP0_CTRL = 0x0000;
392 TCC7xx_USB_EP_MAXP = 64;
393 TCC7xx_USB_EP_CTRL = TCC7xx_USB_EP_CTRL_CDP | TCC7xx_USB_EP_CTRL_FLUSH;
394
395 /* ep1: bulk-in, to host */
396 TCC7xx_USB_INDEX = 1;
397 TCC7xx_USB_EP_DIR |= (1 << 1);
398 TCC7xx_USB_EP_CTRL = TCC7xx_USB_EP_CTRL_CDP;
399
400 if (high_speed)
401 TCC7xx_USB_EP_MAXP = 512;
402 else
403 TCC7xx_USB_EP_MAXP = 64;
404
405 TCC7xx_USB_EP_DMA_CTRL = 0x0;
406
407 /* ep2: bulk-out, from host */
408 TCC7xx_USB_INDEX = 2;
409 TCC7xx_USB_EP_DIR &= ~(1 << 2);
410 TCC7xx_USB_EP_CTRL = TCC7xx_USB_EP_CTRL_CDP;
411
412 if (high_speed)
413 TCC7xx_USB_EP_MAXP = 512;
414 else
415 TCC7xx_USB_EP_MAXP = 64;
416
417 TCC7xx_USB_EP_DMA_CTRL = 0x0;
418
419 /* ep3: interrupt in */
420 TCC7xx_USB_INDEX = 3;
421 TCC7xx_USB_EP_DIR &= ~(1 << 3);
422 TCC7xx_USB_EP_CTRL = TCC7xx_USB_EP_CTRL_CDP;
423 TCC7xx_USB_EP_MAXP = 64;
424
425 TCC7xx_USB_EP_DMA_CTRL = 0x0;
426}
427
428/*
429 Reset TCC7xx usb device
430 */
431static void usb_reset(void)
432{
433 pullup_on();
434
435 TCC7xx_USB_DELAY_CTRL |= 0x81;
436
437 TCC7xx_USB_SYS_CTRL = 0xa000 |
438 TCC7xx_USB_SYS_CTRL_RESET |
439 TCC7xx_USB_SYS_CTRL_RFRE |
440 TCC7xx_USB_SYS_CTRL_SPDEN |
441 TCC7xx_USB_SYS_CTRL_VBONE |
442 TCC7xx_USB_SYS_CTRL_VBOFE;
443
444 usb_set_speed(1);
445 pullup_on();
446
447 TCC7xx_USB_EPIF = TCC7xx_USB_EPIF_IRQ_MASK;
448 global_ep_irq_mask = 0x1;
449 TCC7xx_USB_EPIE = global_ep_irq_mask;
450
451 usb_core_bus_reset();
452}
453
454/* IRQ handler */
455void USB_DEVICE(void)
456{
457 unsigned short sys_stat;
458 unsigned short ep_irq;
459 unsigned short index_save;
460
461 sys_stat = TCC7xx_USB_SYS_STAT;
462
463 if (sys_stat & TCC7xx_USB_SYS_STAT_RESET) {
464 TCC7xx_USB_SYS_STAT = TCC7xx_USB_SYS_STAT_RESET;
465 usb_reset();
466 TCC7xx_USB_SYS_CTRL |= TCC7xx_USB_SYS_CTRL_SUSPEND;
467 DEBUG(2, "reset");
468 }
469
470 if (sys_stat & TCC7xx_USB_SYS_STAT_RESUME) {
471 TCC7xx_USB_SYS_STAT = TCC7xx_USB_SYS_STAT_RESUME;
472 usb_reset();
473 TCC7xx_USB_SYS_CTRL |= TCC7xx_USB_SYS_CTRL_SUSPEND;
474 DEBUG(2, "resume");
475 }
476
477 if (sys_stat & TCC7xx_USB_SYS_STAT_SPD_END) {
478 usb_set_speed(1);
479 TCC7xx_USB_SYS_STAT = TCC7xx_USB_SYS_STAT_SPD_END;
480 DEBUG(2, "spd end");
481 }
482
483 if (sys_stat & TCC7xx_USB_SYS_STAT_ERRORS) {
484 DEBUG(2, "errors: %4x", sys_stat & TCC7xx_USB_SYS_STAT_ERRORS);
485 TCC7xx_USB_SYS_STAT = sys_stat & TCC7xx_USB_SYS_STAT_ERRORS;
486 }
487
488// TCC7xx_USB_SYS_STAT = sys_stat;
489
490 index_save = TCC7xx_USB_INDEX;
491
492 ep_irq = TCC7xx_USB_EPIF & global_ep_irq_mask;
493
494 while (ep_irq & TCC7xx_USB_EPIF_IRQ_MASK) {
495 handle_ep(ep_irq);
496
497 /* is that really needed, btw not a problem for rockbox */
498 udelay(50);
499 ep_irq = TCC7xx_USB_EPIF & global_ep_irq_mask;
500 }
501
502 TCC7xx_USB_INDEX = index_save;
503}
504
505void usb_drv_set_address(int address)
506{
507 DEBUG(2, "setting address %d %d", address, TCC7xx_USB_FUNC);
508}
509
510int usb_drv_port_speed(void)
511{
512 return (TCC7xx_USB_SYS_STAT & 0x10) ? 1 : 0;
513}
514
515static int usb_drv_write_packet(volatile unsigned short *buf, unsigned char *data, int len, int max)
516{
517 uint16_t *wbuf = (uint16_t *) data;
518 int count, i;
519
520 len = MIN(len, max);
521 count = (len + 1) / 2;
522
523 TCC7xx_USB_EP_BWCR = len;
524
525 for (i = 0; i < count; i++)
526 *buf = *wbuf++;
527
528 return len;
529}
530
531int usb_drv_send(int endpoint, void *ptr, int length)
532{
533 int flags = disable_irq_save();
534 int rc = 0;
535 char *data = (unsigned char*) ptr;;
536
537 DEBUG(2, "%s(%d,%d)" , __func__, endpoint, length);
538
539 if (endpoint != 0)
540 panicf_my("%s(%d,%d)", __func__, endpoint, length);
541
542 TCC7xx_USB_INDEX = 0;
543 while (length > 0) {
544 int ret;
545
546 ret = usb_drv_write_packet(&TCC7xx_USB_EP0_BUF, data, length, 64);
547 length -= ret;
548 data += ret;
549
550 while (0 == (TCC7xx_USB_EP0_STAT & 0x2))
551 ;
552 TCC7xx_USB_EP0_STAT = 0x2;
553 }
554
555 restore_irq(flags);
556 return rc;
557}
558
559int usb_drv_send_nonblocking(int endpoint, void *ptr, int length)
560{
561 int flags;
562 int rc = 0, count = length;
563 char *data = (unsigned char*) ptr;
564 struct tcc_ep *ep = &tcc_endpoints[endpoint & 0x7f];
565
566 if (ep->dir != USB_DIR_IN || length == 0)
567 panicf_my("%s(%d,%d): Not supported", __func__, endpoint, length);
568
569 DEBUG(2, "%s(%d,%d):", __func__, endpoint, length);
570
571 flags = disable_irq_save();
572
573 if(ep->buf != NULL) {
574 panicf_my("%s: ep is already busy", __func__);
575 }
576
577 TCC7xx_USB_INDEX = ep->id;
578
579 count = usb_drv_write_packet(ep->ep, data, length, 512);
580
581 data += count;
582 length -= count;
583
584 ep->buf = data;
585 ep->max_len = length;
586 ep->count = count;
587
588 TCC7xx_USB_EPIE |= ep->mask;
589 global_ep_irq_mask |= ep->mask;
590
591 restore_irq(flags);
592
593 DEBUG(2, "%s end", __func__);
594
595 return rc;
596}
597
598int usb_drv_recv(int endpoint, void* ptr, int length)
599{
600 volatile struct tcc_ep *tcc_ep = &tcc_endpoints[endpoint & 0x7f];
601 int flags;
602
603 if (length == 0) {
604 if (endpoint != 0)
605 panicf_my("%s(%d,%d) zero length?", __func__, endpoint, length);
606 return 0;
607 }
608 // TODO: check ep
609 if (tcc_ep->dir != USB_DIR_OUT)
610 panicf_my("%s(%d,%d)", __func__, endpoint, length);
611
612 DEBUG(2, "%s(%d,%d)", __func__, endpoint, length);
613
614 flags = disable_irq_save();
615
616 if (tcc_ep->buf) {
617 panicf_my("%s: overrun: %x %x", __func__, tcc_ep->buf, tcc_ep);
618 }
619
620 tcc_ep->buf = ptr;
621 tcc_ep->max_len = length;
622 tcc_ep->count = 0;
623
624 TCC7xx_USB_INDEX = tcc_ep->id;
625
626 TCC7xx_USB_EP_CTRL &= ~TCC7xx_USB_EP_CTRL_OUTHD;
627 TCC7xx_USB_EPIE |= tcc_ep->mask;
628 global_ep_irq_mask |= tcc_ep->mask;
629
630 restore_irq(flags);
631
632 return 0;
633}
634
635void usb_drv_cancel_all_transfers(void)
636{
637 int endpoint;
638 int flags;
639
640 DEBUG(2, "%s", __func__);
641
642 flags = disable_irq_save();
643 for (endpoint = 0; endpoint < 4; endpoint++) {
644 if (tcc_endpoints[endpoint].buf) {
645/* usb_core_transfer_complete(tcc_endpoints[endpoint].id,
646 tcc_endpoints[endpoint].dir, -1, 0); */
647 tcc_endpoints[endpoint].buf = NULL;
648 }
649 }
650
651 global_ep_irq_mask = 1;
652 TCC7xx_USB_EPIE = global_ep_irq_mask;
653 TCC7xx_USB_EPIF = TCC7xx_USB_EPIF_IRQ_MASK;
654 restore_irq(flags);
655}
656
657void usb_drv_set_test_mode(int mode)
658{
659 panicf_my("%s(%d)", __func__, mode);
660}
661
662bool usb_drv_stalled(int endpoint, bool in)
663{
664 panicf_my("%s(%d,%d)", __func__, endpoint, in);
665}
666
667void usb_drv_stall(int endpoint, bool stall,bool in)
668{
669 printf("%s(%d,%d,%d)", __func__, endpoint, stall, in);
670}
671
672void usb_drv_init(void)
673{
674 size_t i;
675
676 DEBUG(2, "%s", __func__);
677
678 for (i = 0; i < sizeof(tcc_endpoints)/sizeof(struct tcc_ep); i++) {
679 tcc_endpoints[i].id = i;
680 tcc_endpoints[i].mask = 1 << i;
681 tcc_endpoints[i].buf = NULL;
682 tcc_endpoints[i].busy = false;
683 tcc_endpoints[i].dir = -1;
684 }
685
686 /* Enable USB clock */
687 BCLKCTR |= DEV_USBD;
688
689 /* switch USB to host and then reset */
690 TCC7xx_USB_PHY_CFG = 0x3e4c;
691 SWRESET |= DEV_USBD;
692 udelay(50);
693 SWRESET &= ~DEV_USBD;
694
695 usb_reset();
696
697 /* unmask irq */
698 CREQ = USBD_IRQ_MASK;
699 IRQSEL |= USBD_IRQ_MASK;
700 TMODE &= ~USBD_IRQ_MASK;
701 IEN |= USBD_IRQ_MASK;
702}
703
704void usb_drv_exit(void)
705{
706 TCC7xx_USB_EPIE = 0;
707 BCLKCTR &= ~DEV_USBD;
708
709 SWRESET |= DEV_USBD;
710 udelay(50);
711 SWRESET &= ~DEV_USBD;
712
713 pullup_off();
714}
715
716void usb_init_device(void)
717{
718}
719
720void usb_enable(bool on)
721{
722 if (on)
723 usb_core_init();
724 else
725 usb_core_exit();
726}
727
728
729int usb_detect(void)
730{
731 /* TODO: not correct for all targets, we should poll VBUS
732 signal on USB bus. */
733 if (charger_inserted())
734 return USB_INSERTED;
735 return USB_EXTRACTED;
736}
737
738#ifdef BOOTLOADER
739#include "ata.h"
740void usb_test(void)
741{
742 int rc;
743
744 printf("ATA");
745 rc = ata_init();
746
747 if(rc) {
748 panicf("ata_init failed");
749 }
750
751 usb_init();
752 usb_start_monitoring();
753 usb_acknowledge(SYS_USB_CONNECTED_ACK);
754
755 while (1) {
756 sleep(HZ);
757// usb_serial_send("Hello\r\n", 7);
758 }
759}
760#endif
761#else
27void usb_init_device(void) 762void usb_init_device(void)
28{ 763{
29 /* simply switch USB off for now */ 764 /* simply switch USB off for now */
@@ -42,3 +777,4 @@ int usb_detect(void)
42{ 777{
43 return USB_EXTRACTED; 778 return USB_EXTRACTED;
44} 779}
780#endif
diff --git a/firmware/usb.c b/firmware/usb.c
index ab4f0403b9..e5c7565d39 100644
--- a/firmware/usb.c
+++ b/firmware/usb.c
@@ -50,7 +50,8 @@
50/* Conditions under which we want the entire driver */ 50/* Conditions under which we want the entire driver */
51#if !defined(BOOTLOADER) || (CONFIG_CPU == SH7034) || \ 51#if !defined(BOOTLOADER) || (CONFIG_CPU == SH7034) || \
52 (defined(TOSHIBA_GIGABEAT_S) && defined(USE_ROCKBOX_USB) && defined(USB_STORAGE)) || \ 52 (defined(TOSHIBA_GIGABEAT_S) && defined(USE_ROCKBOX_USB) && defined(USB_STORAGE)) || \
53 (defined(CREATIVE_ZVx) && defined(HAVE_USBSTACK)) 53 (defined(HAVE_USBSTACK) && (defined(CREATIVE_ZVx) || \
54 defined(CPU_TCC77X) || defined(CPU_TCC780X)))
54#define USB_FULL_INIT 55#define USB_FULL_INIT
55#endif 56#endif
56 57