imx233: rework frequency scaling
[maemo-rb.git] / firmware / target / arm / usb-tcc.c
blob1b5f16c22302e93fcd395343e228aba00d51d499
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2008 by Vitja Makarov
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include "config.h"
23 #include "usb.h"
25 #include "usb-tcc.h"
27 #include "cpu.h"
28 #include "system.h"
29 #include "kernel.h"
30 #include "panic.h"
32 #ifdef HAVE_USBSTACK
33 #include "usb_ch9.h"
34 #include "usb_core.h"
36 #define TCC7xx_USB_EPIF_IRQ_MASK 0xf
38 static int dbg_level = 0x00;
39 static int global_ep_irq_mask = 0x1;
40 #define DEBUG(level, fmt, args...) do { if (dbg_level & (level)) printf(fmt, ## args); } while (0)
42 #include <inttypes.h>
45 #include "power.h"
47 #ifndef BOOTLOADER
48 #define printf(...) do {} while (0)
49 #define panicf_my panicf
50 #else
51 int printf(const char *fmt, ...);
52 #define panicf_my(fmt, args...) { \
53 int flags = disable_irq_save(); \
54 printf("*** PANIC ***"); \
55 printf(fmt, ## args); \
56 printf("*** PANIC ***"); \
57 while (usb_detect() == USB_INSERTED) \
58 ; \
59 power_off(); \
60 while(1); \
61 restore_irq(flags); \
63 #endif
65 struct tcc_ep {
66 unsigned char dir; /* endpoint direction */
67 volatile uint16_t *ep; /* hw ep buffer */
68 int id; /* Endpoint id */
69 int mask; /* Endpoint bit mask */
70 char *buf; /* user buffer to store data */
71 int max_len; /* how match data will fit */
72 int count; /* actual data count */
73 bool busy;
74 } ;
76 static struct tcc_ep tcc_endpoints[] = {
77 /* control */
79 .dir = -1,
80 .ep = &TCC7xx_USB_EP0_BUF,
81 }, { /* bulk */
82 .dir = -1,
83 .ep = &TCC7xx_USB_EP1_BUF,
84 }, { /* bulk */
85 .dir = -1,
86 .ep = &TCC7xx_USB_EP2_BUF,
87 }, { /* interrupt */
88 .dir = -1,
89 .ep = &TCC7xx_USB_EP3_BUF,
91 } ;
93 static bool usb_drv_write_ep(struct tcc_ep *ep);
94 static void usb_set_speed(int);
96 int usb_drv_request_endpoint(int type, int dir)
98 int flags = disable_irq_save();
99 size_t ep;
100 int ret = 0;
102 if (type != USB_ENDPOINT_XFER_BULK)
103 return -1;
105 if (dir == USB_DIR_IN)
106 ep = 1;
107 else
108 ep = 2;
110 if (!tcc_endpoints[ep].busy) {
111 tcc_endpoints[ep].busy = true;
112 tcc_endpoints[ep].dir = dir;
113 ret = ep | dir;
114 } else {
115 ret = -1;
118 restore_irq(flags);
119 return ret;
122 void usb_drv_release_endpoint(int ep)
124 int flags;
125 ep = ep & 0x7f;
127 if (ep < 1 || ep > USB_NUM_ENDPOINTS)
128 return ;
130 flags = disable_irq_save();
132 tcc_endpoints[ep].busy = false;
133 tcc_endpoints[ep].dir = -1;
135 restore_irq(flags);
138 static inline void pullup_on(void)
140 TCC7xx_USB_PHY_CFG = 0x000c;
143 static inline void pullup_off(void)
145 TCC7xx_USB_PHY_CFG = 0x3e4c;
148 #if 0
149 static
150 char *dump_data(char *data, int count)
152 static char buf[1024];
153 char *dump = buf;
154 int i;
156 for (i = 0; i < count; i++)
157 dump += snprintf(dump, sizeof(buf) - (dump - buf), "%02x", data[i]);
158 return buf;
160 #endif
162 static
163 void handle_control(void)
165 /* control are always 8 bytes len */
166 static unsigned char ep_control[8];
167 struct usb_ctrlrequest *req =
168 (struct usb_ctrlrequest *) ep_control;
169 unsigned short stat;
170 unsigned short count = 0;
171 int i;
172 int type;
174 /* select control endpoint */
175 TCC7xx_USB_INDEX = 0x00;
176 stat = TCC7xx_USB_EP0_STAT;
178 if (stat & 0x10) {
179 DEBUG(2, "stall");
180 TCC7xx_USB_EP0_STAT = 0x10;
183 if (TCC7xx_USB_EP0_STAT & 0x01) { /* RX */
184 uint16_t *ptr = (uint16_t *) ep_control;
186 count = TCC7xx_USB_EP_BRCR;
188 if (TCC7xx_USB_EP0_STAT & 0x2)
189 TCC7xx_USB_EP0_STAT = 0x02;
191 if (count != 4) { /* bad control? */
192 unsigned short dummy;
194 while (count--)
195 dummy = TCC7xx_USB_EP0_BUF;
196 DEBUG(1, "WTF: count = %d", count);
197 } else {
198 /* simply read control packet */
199 for (i = 0; i < count; i++)
200 ptr[i] = TCC7xx_USB_EP0_BUF;
203 count *= 2;
204 TCC7xx_USB_EP0_STAT = 0x01;
205 DEBUG(1, "CTRL: len = %d %04x", count, stat);
206 } else if (TCC7xx_USB_EP0_STAT & 0x02) { /* TX */
207 TCC7xx_USB_EP0_STAT = 0x02;
208 DEBUG(2, "TX Done\n");
209 } else {
210 DEBUG(1, "stat: %04x", stat);
213 TCC7xx_USB_EPIF = 1;
215 if (0 == (stat & 0x1) || count != 8)
216 return ;
217 #if 1 /* TODO: remove me someday */
219 int i;
220 uint16_t *ptr = (uint16_t *) ep_control;
221 for (i = 1; i < (count>>1); i++) {
222 if (ptr[i] != ptr[0])
223 break;
225 if (i == (count>>1)) {
226 /*DEBUG(2, */panicf_my("sanity failed");
227 return ;
230 #endif
231 type = req->bRequestType;
233 /* TODO: don't pass some kinds of requests to upper level */
234 switch (req->bRequest) {
235 case USB_REQ_CLEAR_FEATURE:
236 DEBUG(2, "USB_REQ_CLEAR_FEATURE");
237 DEBUG(2, "...%04x %04x", req->wValue, req->wIndex);
238 break;
239 case USB_REQ_SET_ADDRESS:
240 //DEBUG(2, "USB_REQ_SET_ADDRESS, %d %d", req->wValue, TCC7xx_USB_FUNC);
241 /* seems we don't have to set it manually
242 TCC7xx_USB_FUNC = req->wValue; */
243 break;
244 case USB_REQ_GET_DESCRIPTOR:
245 DEBUG(2, "gd, %02x %02x", req->wValue, req->wIndex);
246 break;
247 case USB_REQ_GET_CONFIGURATION:
248 DEBUG(2, "USB_REQ_GET_CONFIGURATION");
249 break;
250 default:
251 DEBUG(2, "req: %02x %02d", req->bRequestType, req->bRequest);
254 usb_core_control_request(req);
257 static
258 void handle_ep_in(struct tcc_ep *tcc_ep, uint16_t stat)
260 uint8_t *buf = tcc_ep->buf;
261 uint16_t *wbuf = (uint16_t *) buf;
262 int wcount;
263 int count;
264 int i;
266 if (tcc_ep->dir != USB_DIR_OUT) {
267 panicf_my("ep%d: is input only", tcc_ep->id);
270 wcount = TCC7xx_USB_EP_BRCR;
272 DEBUG(2, "ep%d: %04x %04x", tcc_ep->id, stat, wcount);
274 /* read data */
275 count = wcount * 2;
276 if (stat & TCC7xx_USP_EP_STAT_LWO) {
277 count--;
278 wcount--;
281 if (buf == NULL)
282 panicf_my("ep%d: Unexpected packet! %d %x", tcc_ep->id, count, TCC7xx_USB_EP_CTRL);
283 if (tcc_ep->max_len < count)
284 panicf_my("Too big packet: %d excepted %d %x", count, tcc_ep->max_len, TCC7xx_USB_EP_CTRL);
286 for (i = 0; i < wcount; i++)
287 wbuf[i] = *tcc_ep->ep;
289 if (count & 1) { /* lwo */
290 uint16_t tmp = *tcc_ep->ep;
291 buf[count - 1] = tmp & 0xff;
294 tcc_ep->buf = NULL;
296 TCC7xx_USB_EP_STAT = TCC7xx_USB_EP_STAT;
297 TCC7xx_USB_EPIF = tcc_ep->mask;
298 TCC7xx_USB_EPIE &= ~tcc_ep->mask; /* TODO: use INGLD? */
299 global_ep_irq_mask &= ~tcc_ep->mask;
301 if (TCC7xx_USB_EP_STAT & 0x1)
302 panicf_my("One more packet?");
304 TCC7xx_USB_EP_CTRL |= TCC7xx_USB_EP_CTRL_OUTHD;
306 usb_core_transfer_complete(tcc_ep->id, USB_DIR_OUT, 0, count);
309 static
310 void handle_ep_out(struct tcc_ep *tcc_ep, uint16_t stat)
312 bool done;
313 (void) stat;
315 if (tcc_ep->dir != USB_DIR_IN) {
316 panicf_my("ep%d: is out only", tcc_ep->id);
319 // if (tcc_ep->buf == NULL) {
320 // panicf_my("%s:%d", __FILE__, __LINE__);
321 // }
323 done = usb_drv_write_ep(tcc_ep);
325 // TCC7xx_USB_EP_STAT = 0x2; /* Clear TX stat */
326 TCC7xx_USB_EPIF = tcc_ep->mask;
328 if (done) { // tcc_ep->buf == NULL) {
329 TCC7xx_USB_EPIE &= ~tcc_ep->mask;
330 global_ep_irq_mask &= ~tcc_ep->mask;
332 // usb_core_transfer_complete(tcc_ep->id, USB_DIR_IN, 0, tcc_ep->count);
336 static
337 void handle_ep(unsigned short ep_irq)
339 if (ep_irq & 0x1) {
340 handle_control();
343 if (ep_irq & 0xe) {
344 int endpoint;
346 for (endpoint = 1; endpoint < 4; endpoint++) {
347 struct tcc_ep *tcc_ep = &tcc_endpoints[endpoint];
348 uint16_t stat;
350 if (0 == (ep_irq & (1 << endpoint)))
351 continue;
352 if (!tcc_ep->busy)
353 panicf_my("ep%d: wasn't requested", endpoint);
355 TCC7xx_USB_INDEX = endpoint;
356 stat = TCC7xx_USB_EP_STAT;
358 DEBUG(1, "ep%d: %04x", endpoint, stat);
360 if (stat & 0x1)
361 handle_ep_in(tcc_ep, stat);
362 else if (stat & 0x2)
363 handle_ep_out(tcc_ep, stat);
364 else /* TODO: remove me? */
365 panicf_my("Unhandled ep%d state: %x, %d", endpoint, TCC7xx_USB_EP_STAT, TCC7xx_USB_INDEX);
370 static void usb_set_speed(int high_speed)
372 TCC7xx_USB_EP_DIR = 0x0000;
374 /* control endpoint */
375 TCC7xx_USB_INDEX = 0;
376 TCC7xx_USB_EP0_CTRL = 0x0000;
377 TCC7xx_USB_EP_MAXP = 64;
378 TCC7xx_USB_EP_CTRL = TCC7xx_USB_EP_CTRL_CDP | TCC7xx_USB_EP_CTRL_FLUSH;
380 /* ep1: bulk-in, to host */
381 TCC7xx_USB_INDEX = 1;
382 TCC7xx_USB_EP_DIR |= (1 << 1);
383 TCC7xx_USB_EP_CTRL = TCC7xx_USB_EP_CTRL_CDP;
385 if (high_speed)
386 TCC7xx_USB_EP_MAXP = 512;
387 else
388 TCC7xx_USB_EP_MAXP = 64;
390 TCC7xx_USB_EP_DMA_CTRL = 0x0;
392 /* ep2: bulk-out, from host */
393 TCC7xx_USB_INDEX = 2;
394 TCC7xx_USB_EP_DIR &= ~(1 << 2);
395 TCC7xx_USB_EP_CTRL = TCC7xx_USB_EP_CTRL_CDP;
397 if (high_speed)
398 TCC7xx_USB_EP_MAXP = 512;
399 else
400 TCC7xx_USB_EP_MAXP = 64;
402 TCC7xx_USB_EP_DMA_CTRL = 0x0;
404 /* ep3: interrupt in */
405 TCC7xx_USB_INDEX = 3;
406 TCC7xx_USB_EP_DIR &= ~(1 << 3);
407 TCC7xx_USB_EP_CTRL = TCC7xx_USB_EP_CTRL_CDP;
408 TCC7xx_USB_EP_MAXP = 64;
410 TCC7xx_USB_EP_DMA_CTRL = 0x0;
414 Reset TCC7xx usb device
416 static void usb_reset(void)
418 pullup_on();
420 TCC7xx_USB_DELAY_CTRL |= 0x81;
422 TCC7xx_USB_SYS_CTRL = 0xa000 |
423 TCC7xx_USB_SYS_CTRL_RESET |
424 TCC7xx_USB_SYS_CTRL_RFRE |
425 TCC7xx_USB_SYS_CTRL_SPDEN |
426 TCC7xx_USB_SYS_CTRL_VBONE |
427 TCC7xx_USB_SYS_CTRL_VBOFE;
429 usb_set_speed(1);
430 pullup_on();
432 TCC7xx_USB_EPIF = TCC7xx_USB_EPIF_IRQ_MASK;
433 global_ep_irq_mask = 0x1;
434 TCC7xx_USB_EPIE = global_ep_irq_mask;
436 usb_core_bus_reset();
439 /* IRQ handler */
440 void USB_DEVICE(void)
442 unsigned short sys_stat;
443 unsigned short ep_irq;
444 unsigned short index_save;
446 sys_stat = TCC7xx_USB_SYS_STAT;
448 if (sys_stat & TCC7xx_USB_SYS_STAT_RESET) {
449 TCC7xx_USB_SYS_STAT = TCC7xx_USB_SYS_STAT_RESET;
450 usb_reset();
451 TCC7xx_USB_SYS_CTRL |= TCC7xx_USB_SYS_CTRL_SUSPEND;
452 DEBUG(2, "reset");
455 if (sys_stat & TCC7xx_USB_SYS_STAT_RESUME) {
456 TCC7xx_USB_SYS_STAT = TCC7xx_USB_SYS_STAT_RESUME;
457 usb_reset();
458 TCC7xx_USB_SYS_CTRL |= TCC7xx_USB_SYS_CTRL_SUSPEND;
459 DEBUG(2, "resume");
462 if (sys_stat & TCC7xx_USB_SYS_STAT_SPD_END) {
463 usb_set_speed(1);
464 TCC7xx_USB_SYS_STAT = TCC7xx_USB_SYS_STAT_SPD_END;
465 DEBUG(2, "spd end");
468 if (sys_stat & TCC7xx_USB_SYS_STAT_ERRORS) {
469 DEBUG(2, "errors: %4x", sys_stat & TCC7xx_USB_SYS_STAT_ERRORS);
470 TCC7xx_USB_SYS_STAT = sys_stat & TCC7xx_USB_SYS_STAT_ERRORS;
473 // TCC7xx_USB_SYS_STAT = sys_stat;
475 index_save = TCC7xx_USB_INDEX;
477 ep_irq = TCC7xx_USB_EPIF & global_ep_irq_mask;
479 while (ep_irq & TCC7xx_USB_EPIF_IRQ_MASK) {
480 handle_ep(ep_irq);
482 /* is that really needed, btw not a problem for rockbox */
483 udelay(50);
484 ep_irq = TCC7xx_USB_EPIF & global_ep_irq_mask;
487 TCC7xx_USB_INDEX = index_save;
490 void usb_drv_set_address(int address)
492 (void) address;
493 DEBUG(2, "setting address %d %d", address, TCC7xx_USB_FUNC);
496 int usb_drv_port_speed(void)
498 return (TCC7xx_USB_SYS_STAT & 0x10) ? 1 : 0;
501 static int usb_drv_write_packet(volatile unsigned short *buf, unsigned char *data, int len, int max)
503 uint16_t *wbuf = (uint16_t *) data;
504 int count, i;
506 len = MIN(len, max);
507 count = (len + 1) / 2;
509 TCC7xx_USB_EP_BWCR = len;
511 for (i = 0; i < count; i++)
512 *buf = *wbuf++;
514 return len;
517 static bool usb_drv_write_ep(struct tcc_ep *ep)
519 int count;
521 if (ep->max_len == 0)
522 return true;
524 count = usb_drv_write_packet(ep->ep, ep->buf, ep->max_len, 512);
525 TCC7xx_USB_EP_STAT = 0x2; /* Clear TX stat */
527 ep->buf += count;
528 ep->count += count;
529 ep->max_len -= count;
531 if (ep->max_len == 0) {
532 usb_core_transfer_complete(ep->id, USB_DIR_IN, 0, ep->count);
533 ep->buf = NULL;
534 // return true;
537 return false;
540 int usb_drv_send(int endpoint, void *ptr, int length)
542 int flags = disable_irq_save();
543 int rc = 0;
544 char *data = (unsigned char*) ptr;
546 DEBUG(2, "%s(%d,%d)" , __func__, endpoint, length);
548 if (endpoint != 0)
549 panicf_my("%s(%d,%d)", __func__, endpoint, length);
551 TCC7xx_USB_INDEX = 0;
552 while (length > 0) {
553 int ret;
555 ret = usb_drv_write_packet(&TCC7xx_USB_EP0_BUF, data, length, 64);
556 length -= ret;
557 data += ret;
559 while (0 == (TCC7xx_USB_EP0_STAT & 0x2))
561 TCC7xx_USB_EP0_STAT = 0x2;
564 restore_irq(flags);
565 return rc;
569 int usb_drv_send_nonblocking(int endpoint, void *ptr, int length)
571 int flags;
572 int rc = 0, count = length;
573 char *data = (unsigned char*) ptr;
574 struct tcc_ep *ep = &tcc_endpoints[endpoint & 0x7f];
576 if (ep->dir != USB_DIR_IN || length == 0)
577 panicf_my("%s(%d,%d): Not supported", __func__, endpoint, length);
579 DEBUG(2, "%s(%d,%d):", __func__, endpoint, length);
581 flags = disable_irq_save();
583 if(ep->buf != NULL) {
584 panicf_my("%s: ep is already busy", __func__);
587 ep->buf = data;
588 ep->max_len = length;
589 ep->count = count;
591 TCC7xx_USB_INDEX = ep->id;
592 #if 1
593 TCC7xx_USB_EP_STAT = 0x2;
594 /* TODO: use interrupts instead */
595 while (!usb_drv_write_ep(ep)) {
596 while (0==(TCC7xx_USB_EP_STAT & 0x2))
599 #else
600 if (!usb_drv_write_ep(ep)) {
601 TCC7xx_USB_EPIE |= ep->mask;
602 global_ep_irq_mask |= ep->mask;
604 #endif
605 restore_irq(flags);
607 DEBUG(2, "%s end", __func__);
609 return rc;
612 int usb_drv_recv(int endpoint, void* ptr, int length)
614 volatile struct tcc_ep *tcc_ep = &tcc_endpoints[endpoint & 0x7f];
615 int flags;
617 if (length == 0) {
618 if (endpoint != 0)
619 panicf_my("%s(%d,%d) zero length?", __func__, endpoint, length);
620 return 0;
622 // TODO: check ep
623 if (tcc_ep->dir != USB_DIR_OUT)
624 panicf_my("%s(%d,%d)", __func__, endpoint, length);
626 DEBUG(2, "%s(%d,%d)", __func__, endpoint, length);
628 flags = disable_irq_save();
630 if (tcc_ep->buf) {
631 panicf_my("%s: overrun: %x %x", __func__,
632 (unsigned int)tcc_ep->buf, (unsigned int)tcc_ep);
635 tcc_ep->buf = ptr;
636 tcc_ep->max_len = length;
637 tcc_ep->count = 0;
639 TCC7xx_USB_INDEX = tcc_ep->id;
641 TCC7xx_USB_EP_CTRL &= ~TCC7xx_USB_EP_CTRL_OUTHD;
642 TCC7xx_USB_EPIE |= tcc_ep->mask;
643 global_ep_irq_mask |= tcc_ep->mask;
645 restore_irq(flags);
647 return 0;
650 void usb_drv_cancel_all_transfers(void)
652 int endpoint;
653 int flags;
655 DEBUG(2, "%s", __func__);
657 flags = disable_irq_save();
658 for (endpoint = 0; endpoint < 4; endpoint++) {
659 if (tcc_endpoints[endpoint].buf) {
660 /* usb_core_transfer_complete(tcc_endpoints[endpoint].id,
661 tcc_endpoints[endpoint].dir, -1, 0); */
662 tcc_endpoints[endpoint].buf = NULL;
666 global_ep_irq_mask = 1;
667 TCC7xx_USB_EPIE = global_ep_irq_mask;
668 TCC7xx_USB_EPIF = TCC7xx_USB_EPIF_IRQ_MASK;
669 restore_irq(flags);
672 void usb_drv_set_test_mode(int mode)
674 panicf_my("%s(%d)", __func__, mode);
677 bool usb_drv_stalled(int endpoint, bool in)
679 panicf_my("%s(%d,%d)", __func__, endpoint, in);
680 return false;
683 void usb_drv_stall(int endpoint, bool stall,bool in)
685 (void) endpoint;
686 (void) stall;
687 (void) in;
688 printf("%s(%d,%d,%d)", __func__, endpoint, stall, in);
691 void usb_drv_init(void)
693 size_t i;
695 DEBUG(2, "%s", __func__);
697 for (i = 0; i < sizeof(tcc_endpoints)/sizeof(struct tcc_ep); i++) {
698 tcc_endpoints[i].id = i;
699 tcc_endpoints[i].mask = 1 << i;
700 tcc_endpoints[i].buf = NULL;
701 tcc_endpoints[i].busy = false;
702 tcc_endpoints[i].dir = -1;
705 /* Enable USB clock */
706 BCLKCTR |= DEV_USBD;
708 /* switch USB to host and then reset */
709 TCC7xx_USB_PHY_CFG = 0x3e4c;
710 SWRESET |= DEV_USBD;
711 udelay(50);
712 SWRESET &= ~DEV_USBD;
714 usb_reset();
716 /* unmask irq */
717 CREQ = USBD_IRQ_MASK;
718 IRQSEL |= USBD_IRQ_MASK;
719 TMODE &= ~USBD_IRQ_MASK;
720 IEN |= USBD_IRQ_MASK;
723 void usb_drv_exit(void)
725 TCC7xx_USB_EPIE = 0;
726 BCLKCTR &= ~DEV_USBD;
728 SWRESET |= DEV_USBD;
729 udelay(50);
730 SWRESET &= ~DEV_USBD;
732 pullup_off();
735 void usb_init_device(void)
739 void usb_enable(bool on)
741 if (on)
742 usb_core_init();
743 else
744 usb_core_exit();
747 void usb_attach(void)
749 usb_enable(true);
752 int usb_detect(void)
754 /* TODO: not correct for all targets, we should poll VBUS
755 signal on USB bus. */
756 if (charger_inserted())
757 return USB_INSERTED;
758 return USB_EXTRACTED;
761 #ifdef BOOTLOADER
762 #include "ata.h"
763 void usb_test(void)
765 int rc;
767 printf("ATA");
768 rc = ata_init();
770 if(rc) {
771 panicf("ata_init failed");
774 usb_init();
775 usb_start_monitoring();
776 usb_acknowledge(SYS_USB_CONNECTED_ACK);
778 while (1) {
779 sleep(HZ);
780 // usb_serial_send("Hello\r\n", 7);
783 #endif
784 #else
785 void usb_init_device(void)
787 /* simply switch USB off for now */
788 BCLKCTR |= DEV_USBD;
789 TCC7xx_USB_PHY_CFG = 0x3e4c;
790 BCLKCTR &= ~DEV_USBD;
793 void usb_enable(bool on)
795 (void)on;
798 /* Always return false for now */
799 int usb_detect(void)
801 return USB_EXTRACTED;
803 #endif