summaryrefslogtreecommitdiff
path: root/firmware/target/arm
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm')
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/system-target.h8
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/usb-imx31.c35
-rw-r--r--firmware/target/arm/powermgmt-ascodec.c10
-rw-r--r--firmware/target/arm/usb-drv-arc.c186
-rw-r--r--firmware/target/arm/usb-fw-pp502x.c49
-rw-r--r--firmware/target/arm/usb-target.h7
6 files changed, 187 insertions, 108 deletions
diff --git a/firmware/target/arm/imx31/gigabeat-s/system-target.h b/firmware/target/arm/imx31/gigabeat-s/system-target.h
index 847e6cfc51..b99b31d1b4 100644
--- a/firmware/target/arm/imx31/gigabeat-s/system-target.h
+++ b/firmware/target/arm/imx31/gigabeat-s/system-target.h
@@ -31,6 +31,14 @@
31#define CPUFREQ_MAX CPU_FREQ 31#define CPUFREQ_MAX CPU_FREQ
32#endif 32#endif
33 33
34/* For USB driver - no accuracy assurance */
35static inline void udelay(unsigned int usecs)
36{
37 unsigned int x;
38 for (x = 0; x < 300*usecs; x++)
39 asm volatile ("");
40}
41
34#if 0 42#if 0
35static inline void udelay(unsigned int usecs) 43static inline void udelay(unsigned int usecs)
36{ 44{
diff --git a/firmware/target/arm/imx31/gigabeat-s/usb-imx31.c b/firmware/target/arm/imx31/gigabeat-s/usb-imx31.c
index cd8b513ecd..c0d7cb8d2a 100644
--- a/firmware/target/arm/imx31/gigabeat-s/usb-imx31.c
+++ b/firmware/target/arm/imx31/gigabeat-s/usb-imx31.c
@@ -29,6 +29,7 @@
29#include "usb-target.h" 29#include "usb-target.h"
30#include "clkctl-imx31.h" 30#include "clkctl-imx31.h"
31#include "power-imx31.h" 31#include "power-imx31.h"
32#include "avic-imx31.h"
32#include "mc13783.h" 33#include "mc13783.h"
33 34
34static int usb_status = USB_EXTRACTED; 35static int usb_status = USB_EXTRACTED;
@@ -75,11 +76,7 @@ bool usb_plugged(void)
75 76
76void usb_init_device(void) 77void usb_init_device(void)
77{ 78{
78 imx31_clkctl_module_clock_gating(CG_USBOTG, CGM_ON_ALL); 79 /* Do one-time inits */
79
80 enable_transceiver(true);
81
82 /* Module will be turned off later after firmware init */
83 usb_drv_startup(); 80 usb_drv_startup();
84 81
85 /* Initially poll */ 82 /* Initially poll */
@@ -91,19 +88,37 @@ void usb_init_device(void)
91 88
92void usb_enable(bool on) 89void usb_enable(bool on)
93{ 90{
91 /* Module clock should be on since since this could be called with
92 * OFF initially and writing module registers would hardlock otherwise. */
93 imx31_clkctl_module_clock_gating(CG_USBOTG, CGM_ON_ALL);
94 enable_transceiver(true);
95
94 if (on) 96 if (on)
95 { 97 {
96 imx31_clkctl_module_clock_gating(CG_USBOTG, CGM_ON_ALL);
97 enable_transceiver(true);
98 usb_core_init(); 98 usb_core_init();
99 } 99 }
100 else 100 else
101 { 101 {
102 /* Module clock should be on since this could be called first */
103 imx31_clkctl_module_clock_gating(CG_USBOTG, CGM_ON_ALL);
104 enable_transceiver(true);
105 usb_core_exit(); 102 usb_core_exit();
106 enable_transceiver(false); 103 enable_transceiver(false);
107 imx31_clkctl_module_clock_gating(CG_USBOTG, CGM_OFF); 104 imx31_clkctl_module_clock_gating(CG_USBOTG, CGM_OFF);
108 } 105 }
109} 106}
107
108void usb_attach(void)
109{
110 usb_enable(true);
111}
112
113static void __attribute__((interrupt("IRQ"))) USB_OTG_HANDLER(void)
114{
115 usb_drv_int(); /* Call driver handler */
116}
117
118void usb_drv_int_enable(bool enable)
119{
120 if (enable)
121 avic_enable_int(USB_OTG, IRQ, 7, USB_OTG_HANDLER);
122 else
123 avic_disable_int(USB_OTG);
124}
diff --git a/firmware/target/arm/powermgmt-ascodec.c b/firmware/target/arm/powermgmt-ascodec.c
index ab9fd7b490..6ee6209823 100644
--- a/firmware/target/arm/powermgmt-ascodec.c
+++ b/firmware/target/arm/powermgmt-ascodec.c
@@ -27,6 +27,8 @@
27#include "adc.h" 27#include "adc.h"
28#include "powermgmt.h" 28#include "powermgmt.h"
29#include "power.h" 29#include "power.h"
30#include "usb-target.h"
31#include "usb.h"
30 32
31/*=========================================================================== 33/*===========================================================================
32 * These parameters may be defined per target: 34 * These parameters may be defined per target:
@@ -132,6 +134,10 @@ static inline void charger_plugged(void)
132{ 134{
133 batt_threshold = BATT_FULL_VOLTAGE; /* Start with topped value. */ 135 batt_threshold = BATT_FULL_VOLTAGE; /* Start with topped value. */
134 battery_voltage_sync(); 136 battery_voltage_sync();
137#if defined(USB_STATUS_BY_EVENT) && defined(USB_DETECT_BY_DRV)
138 /* Charger pin detect is USB pin detect */
139 usb_connect_event(true);
140#endif
135} 141}
136 142
137static inline void charger_control(void) 143static inline void charger_control(void)
@@ -186,6 +192,10 @@ static inline void charger_unplugged(void)
186 disable_charger(); 192 disable_charger();
187 if (charge_state >= CHARGE_STATE_ERROR) 193 if (charge_state >= CHARGE_STATE_ERROR)
188 charge_state = DISCHARGING; /* Reset error */ 194 charge_state = DISCHARGING; /* Reset error */
195#if defined(USB_STATUS_BY_EVENT) && defined(USB_DETECT_BY_DRV)
196 /* Charger pin detect is USB pin detect */
197 usb_connect_event(false);
198#endif
189} 199}
190 200
191/* Main charging algorithm - called from powermgmt.c */ 201/* Main charging algorithm - called from powermgmt.c */
diff --git a/firmware/target/arm/usb-drv-arc.c b/firmware/target/arm/usb-drv-arc.c
index 1cdc0f9e90..99845c2a49 100644
--- a/firmware/target/arm/usb-drv-arc.c
+++ b/firmware/target/arm/usb-drv-arc.c
@@ -9,7 +9,7 @@
9 * 9 *
10 * Driver for ARC USBOTG Device Controller 10 * Driver for ARC USBOTG Device Controller
11 * 11 *
12 * Copyright (C) 2007 by Bjรถrn Stenberg 12 * Copyright (C) 2007 by Bjrn Stenberg
13 * 13 *
14 * This program is free software; you can redistribute it and/or 14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License 15 * modify it under the terms of the GNU General Public License
@@ -33,11 +33,6 @@
33//#define LOGF_ENABLE 33//#define LOGF_ENABLE
34#include "logf.h" 34#include "logf.h"
35 35
36#if CONFIG_CPU == IMX31L
37#include "avic-imx31.h"
38static void __attribute__((interrupt("IRQ"))) USB_OTG_HANDLER(void);
39#endif
40
41/* USB device mode registers (Little Endian) */ 36/* USB device mode registers (Little Endian) */
42 37
43#define REG_ID (*(volatile unsigned int *)(USB_BASE+0x000)) 38#define REG_ID (*(volatile unsigned int *)(USB_BASE+0x000))
@@ -326,8 +321,8 @@ struct transfer_descriptor {
326 unsigned int reserved; 321 unsigned int reserved;
327} __attribute__ ((packed)); 322} __attribute__ ((packed));
328 323
329static struct transfer_descriptor td_array[NUM_ENDPOINTS*2] 324static struct transfer_descriptor td_array[USB_NUM_ENDPOINTS*2]
330 USBDEVBSS_ATTR __attribute__((aligned(32))); 325 USB_DEVBSS_ATTR __attribute__((aligned(32)));
331 326
332/* manual: 32.13.1 Endpoint Queue Head (dQH) */ 327/* manual: 32.13.1 Endpoint Queue Head (dQH) */
333struct queue_head { 328struct queue_head {
@@ -342,17 +337,10 @@ struct queue_head {
342 unsigned int wait; /* for softwate use, indicates if the transfer is blocking */ 337 unsigned int wait; /* for softwate use, indicates if the transfer is blocking */
343} __attribute__((packed)); 338} __attribute__((packed));
344 339
345#if CONFIG_CPU == IMX31L 340static struct queue_head qh_array[USB_NUM_ENDPOINTS*2]
346static struct queue_head qh_array[NUM_ENDPOINTS*2] 341 USB_QHARRAY_ATTR;
347 QHARRAY_ATTR __attribute__((aligned (2048)));
348#else
349/* This still needs to be 2048 byte aligned, but QHARRAY_ATTR should take
350 care of that */
351static struct queue_head qh_array[NUM_ENDPOINTS*2]
352 QHARRAY_ATTR __attribute__((aligned (4)));
353#endif
354 342
355static struct wakeup transfer_completion_signal[NUM_ENDPOINTS*2] 343static struct wakeup transfer_completion_signal[USB_NUM_ENDPOINTS*2]
356 SHAREDBSS_ATTR; 344 SHAREDBSS_ATTR;
357 345
358static const unsigned int pipe2mask[] = { 346static const unsigned int pipe2mask[] = {
@@ -363,7 +351,7 @@ static const unsigned int pipe2mask[] = {
363 0x10, 0x100000, 351 0x10, 0x100000,
364}; 352};
365 353
366static char ep_allocation[NUM_ENDPOINTS]; 354static char ep_allocation[USB_NUM_ENDPOINTS];
367 355
368/*-------------------------------------------------------------------------*/ 356/*-------------------------------------------------------------------------*/
369static void transfer_completed(void); 357static void transfer_completed(void);
@@ -378,52 +366,46 @@ static void init_control_queue_heads(void);
378static void init_bulk_queue_heads(void); 366static void init_bulk_queue_heads(void);
379static void init_endpoints(void); 367static void init_endpoints(void);
380/*-------------------------------------------------------------------------*/ 368/*-------------------------------------------------------------------------*/
381 369static void usb_drv_stop(void)
382bool usb_drv_powered(void)
383{ 370{
384 return (REG_OTGSC & OTGSC_B_SESSION_VALID) ? true : false; 371 /* disable interrupts */
372 REG_USBINTR = 0;
373 /* stop usb controller (disconnect) */
374 REG_USBCMD &= ~USBCMD_RUN;
385} 375}
386 376
387/* One-time driver startup init */ 377void usb_drv_reset(void)
388void usb_drv_startup(void)
389{ 378{
390#if CONFIG_CPU == IMX31L && defined(BOOTLOADER) 379 int oldlevel = disable_irq_save();
391 /* This is the bootloader - activate the OTG controller or cold
392 * connect later could/will fail */
393 REG_USBCMD &= ~USBCMD_RUN; 380 REG_USBCMD &= ~USBCMD_RUN;
381 restore_irq(oldlevel);
394 382
383#ifdef USB_PORTSCX_PHY_TYPE
384 /* If a PHY type is specified, set it now */
385 REG_PORTSC1 = (REG_PORTSC1 & ~PORTSCX_PHY_TYPE_SEL) | USB_PORTSCX_PHY_TYPE;
386#endif
395 sleep(HZ/20); 387 sleep(HZ/20);
396 REG_USBCMD |= USBCMD_CTRL_RESET; 388 REG_USBCMD |= USBCMD_CTRL_RESET;
397 while (REG_USBCMD & USBCMD_CTRL_RESET); 389 while (REG_USBCMD & USBCMD_CTRL_RESET);
390}
398 391
399 /* Set to ULPI */ 392/* One-time driver startup init */
400 REG_PORTSC1 = (REG_PORTSC1 & ~PORTSCX_PHY_TYPE_SEL) | PORTSCX_PTS_ULPI; 393void usb_drv_startup(void)
401 sleep(HZ/10); 394{
402#endif
403
404 /* Initialize all the signal objects once */ 395 /* Initialize all the signal objects once */
405 int i; 396 int i;
406 for(i=0;i<NUM_ENDPOINTS*2;i++) { 397 for(i=0;i<USB_NUM_ENDPOINTS*2;i++) {
407 wakeup_init(&transfer_completion_signal[i]); 398 wakeup_init(&transfer_completion_signal[i]);
408 } 399 }
409} 400}
410 401
411/* manual: 32.14.1 Device Controller Initialization */ 402/* manual: 32.14.1 Device Controller Initialization */
412void usb_drv_init(void) 403static void _usb_drv_init(bool attach)
413{ 404{
414 REG_USBCMD &= ~USBCMD_RUN; 405 usb_drv_reset();
415 sleep(HZ/20);
416 REG_USBCMD |= USBCMD_CTRL_RESET;
417 while (REG_USBCMD & USBCMD_CTRL_RESET);
418
419 406
420 REG_USBMODE = USBMODE_CTRL_MODE_DEVICE; 407 REG_USBMODE = USBMODE_CTRL_MODE_DEVICE;
421 408
422#if CONFIG_CPU == IMX31L
423 /* Set to ULPI */
424 REG_PORTSC1 = (REG_PORTSC1 & ~PORTSCX_PHY_TYPE_SEL) | PORTSCX_PTS_ULPI;
425#endif
426
427#ifdef USB_NO_HIGH_SPEED 409#ifdef USB_NO_HIGH_SPEED
428 /* Force device to full speed */ 410 /* Force device to full speed */
429 /* See 32.9.5.9.2 */ 411 /* See 32.9.5.9.2 */
@@ -436,69 +418,76 @@ void usb_drv_init(void)
436 REG_ENDPOINTLISTADDR = (unsigned int)qh_array; 418 REG_ENDPOINTLISTADDR = (unsigned int)qh_array;
437 REG_DEVICEADDR = 0; 419 REG_DEVICEADDR = 0;
438 420
439 /* enable USB interrupts */ 421#ifdef USB_DETECT_BY_DRV
440 REG_USBINTR = 422 if (!attach) {
441 USBINTR_INT_EN | 423 /* enable RESET interrupt */
442 USBINTR_ERR_INT_EN | 424 REG_USBINTR = USBINTR_RESET_EN;
443 USBINTR_PTC_DETECT_EN | 425 }
444 USBINTR_RESET_EN | 426 else
445 USBINTR_SYS_ERR_EN;
446
447#if CONFIG_CPU == IMX31L
448 avic_enable_int(USB_OTG, IRQ, 7, USB_OTG_HANDLER);
449#else
450 /* enable USB IRQ in CPU */
451 CPU_INT_EN = USB_MASK;
452#endif 427#endif
428 {
429 /* enable USB interrupts */
430 REG_USBINTR =
431 USBINTR_INT_EN |
432 USBINTR_ERR_INT_EN |
433 USBINTR_PTC_DETECT_EN |
434 USBINTR_RESET_EN;
435 }
436
437 usb_drv_int_enable(true);
453 438
454 /* go go go */ 439 /* go go go */
455 REG_USBCMD |= USBCMD_RUN; 440 REG_USBCMD |= USBCMD_RUN;
456 441
457
458 logf("usb_drv_init() finished"); 442 logf("usb_drv_init() finished");
459 logf("usb id %x", REG_ID); 443 logf("usb id %x", REG_ID);
460 logf("usb dciversion %x", REG_DCIVERSION); 444 logf("usb dciversion %x", REG_DCIVERSION);
461 logf("usb dccparams %x", REG_DCCPARAMS); 445 logf("usb dccparams %x", REG_DCCPARAMS);
462 446
463 /* now a bus reset will occur. see bus_reset() */ 447 /* now a bus reset will occur. see bus_reset() */
448 (void)attach;
464} 449}
465 450
466void usb_drv_exit(void) 451/** With USB_DETECT_BY_DRV, attach is distinct from init, otherwise eqivalent. **/
452
453/* USB_DETECT_BY_DRV - enable bus reset detection only
454 * else fully enable driver */
455void usb_drv_init(void)
467{ 456{
468 /* disable interrupts */ 457 _usb_drv_init(false);
469 REG_USBINTR = 0; 458}
470 459
471 /* stop usb controller */ 460#ifdef USB_DETECT_BY_DRV
472 REG_USBCMD &= ~USBCMD_RUN; 461/* fully enable driver */
462void usb_drv_attach(void)
463{
464 sleep(HZ/10);
465 _usb_drv_init(true);
466}
467#endif /* USB_DETECT_BY_DRV */
468
469void usb_drv_exit(void)
470{
471 usb_drv_stop();
473 472
474 /* TODO : is one of these needed to save power ? 473 /* TODO : is one of these needed to save power ?
475 REG_PORTSC1 |= PORTSCX_PHY_LOW_POWER_SPD; 474 REG_PORTSC1 |= PORTSCX_PHY_LOW_POWER_SPD;
476 REG_USBCMD |= USBCMD_CTRL_RESET; 475 REG_USBCMD |= USBCMD_CTRL_RESET;
477 */ 476 */
478 477
479#if CONFIG_CPU == IMX31L 478 usb_drv_int_enable(false);
480 avic_disable_int(USB_OTG);
481#else
482 CPU_INT_DIS = USB_MASK;
483#endif
484
485 cancel_cpu_boost();
486} 479}
487 480
488#if CONFIG_CPU == IMX31L
489static void __attribute__((interrupt("IRQ"))) USB_OTG_HANDLER(void)
490#else
491void usb_drv_int(void) 481void usb_drv_int(void)
492#endif
493{ 482{
494 unsigned int status = REG_USBSTS; 483 unsigned int usbintr = REG_USBINTR; /* Only watch enabled ints */
484 unsigned int status = REG_USBSTS & usbintr;
495 485
496#if 0 486#if 0
497 if (status & USBSTS_INT) logf("int: usb ioc"); 487 if (status & USBSTS_INT) logf("int: usb ioc");
498 if (status & USBSTS_ERR) logf("int: usb err"); 488 if (status & USBSTS_ERR) logf("int: usb err");
499 if (status & USBSTS_PORT_CHANGE) logf("int: portchange"); 489 if (status & USBSTS_PORT_CHANGE) logf("int: portchange");
500 if (status & USBSTS_RESET) logf("int: reset"); 490 if (status & USBSTS_RESET) logf("int: reset");
501 if (status & USBSTS_SYS_ERR) logf("int: syserr");
502#endif 491#endif
503 492
504 /* usb transaction interrupt */ 493 /* usb transaction interrupt */
@@ -523,8 +512,18 @@ void usb_drv_int(void)
523 /* reset interrupt */ 512 /* reset interrupt */
524 if (status & USBSTS_RESET) { 513 if (status & USBSTS_RESET) {
525 REG_USBSTS = USBSTS_RESET; 514 REG_USBSTS = USBSTS_RESET;
526 bus_reset(); 515#ifdef USB_DETECT_BY_DRV
527 usb_core_bus_reset(); /* tell mom */ 516 if (UNLIKELY(usbintr == USBINTR_RESET_EN)) {
517 /* USB detected - detach and inform */
518 usb_drv_stop();
519 usb_drv_usb_detect_event();
520 }
521 else
522#endif
523 {
524 bus_reset();
525 usb_core_bus_reset(); /* tell mom */
526 }
528 } 527 }
529 528
530 /* port change */ 529 /* port change */
@@ -588,7 +587,14 @@ int usb_drv_port_speed(void)
588 587
589bool usb_drv_connected(void) 588bool usb_drv_connected(void)
590{ 589{
591 return ((REG_PORTSC1 & PORTSCX_CURRENT_CONNECT_STATUS) !=0); 590 return (REG_PORTSC1 &
591 (PORTSCX_PORT_SUSPEND | PORTSCX_CURRENT_CONNECT_STATUS))
592 == PORTSCX_CURRENT_CONNECT_STATUS;
593}
594
595bool usb_drv_powered(void)
596{
597 return (REG_OTGSC & OTGSC_B_SESSION_VALID) ? true : false;
592} 598}
593 599
594void usb_drv_set_address(int address) 600void usb_drv_set_address(int address)
@@ -628,10 +634,7 @@ void usb_drv_set_test_mode(int mode)
628 REG_PORTSC1 |= PORTSCX_PTC_FORCE_EN; 634 REG_PORTSC1 |= PORTSCX_PTC_FORCE_EN;
629 break; 635 break;
630 } 636 }
631 REG_USBCMD &= ~USBCMD_RUN; 637 usb_drv_reset();
632 sleep(HZ/20);
633 REG_USBCMD |= USBCMD_CTRL_RESET;
634 while (REG_USBCMD & USBCMD_CTRL_RESET);
635 REG_USBCMD |= USBCMD_RUN; 638 REG_USBCMD |= USBCMD_RUN;
636} 639}
637 640
@@ -735,7 +738,7 @@ void usb_drv_cancel_all_transfers(void)
735 while (REG_ENDPTFLUSH); 738 while (REG_ENDPTFLUSH);
736 739
737 memset(td_array, 0, sizeof td_array); 740 memset(td_array, 0, sizeof td_array);
738 for(i=0;i<NUM_ENDPOINTS*2;i++) { 741 for(i=0;i<USB_NUM_ENDPOINTS*2;i++) {
739 if(qh_array[i].wait) { 742 if(qh_array[i].wait) {
740 qh_array[i].wait=0; 743 qh_array[i].wait=0;
741 qh_array[i].status=DTD_STATUS_HALTED; 744 qh_array[i].status=DTD_STATUS_HALTED;
@@ -750,7 +753,7 @@ int usb_drv_request_endpoint(int dir)
750 753
751 bit=(dir & USB_DIR_IN)? 2:1; 754 bit=(dir & USB_DIR_IN)? 2:1;
752 755
753 for (i=1; i < NUM_ENDPOINTS; i++) { 756 for (i=1; i < USB_NUM_ENDPOINTS; i++) {
754 if((ep_allocation[i] & bit)!=0) 757 if((ep_allocation[i] & bit)!=0)
755 continue; 758 continue;
756 ep_allocation[i] |= bit; 759 ep_allocation[i] |= bit;
@@ -819,7 +822,7 @@ static void transfer_completed(void)
819 unsigned int mask = REG_ENDPTCOMPLETE; 822 unsigned int mask = REG_ENDPTCOMPLETE;
820 REG_ENDPTCOMPLETE = mask; 823 REG_ENDPTCOMPLETE = mask;
821 824
822 for (ep=0; ep<NUM_ENDPOINTS; ep++) { 825 for (ep=0; ep<USB_NUM_ENDPOINTS; ep++) {
823 int dir; 826 int dir;
824 for (dir=0; dir<2; dir++) { 827 for (dir=0; dir<2; dir++) {
825 int pipe = ep * 2 + dir; 828 int pipe = ep * 2 + dir;
@@ -869,13 +872,8 @@ static void bus_reset(void)
869 logf("usb: double reset"); 872 logf("usb: double reset");
870 return; 873 return;
871 } 874 }
872#if CONFIG_CPU == IMX31L 875
873 int x;
874 for (x = 0; x < 30000; x++)
875 asm volatile ("");
876#else
877 udelay(100); 876 udelay(100);
878#endif
879 } 877 }
880 if (REG_ENDPTPRIME) { 878 if (REG_ENDPTPRIME) {
881 logf("usb: short reset timeout"); 879 logf("usb: short reset timeout");
@@ -917,7 +915,7 @@ static void init_bulk_queue_heads(void)
917 /* TODO: this should take ep_allocation into account */ 915 /* TODO: this should take ep_allocation into account */
918 916
919 /*** bulk ***/ 917 /*** bulk ***/
920 for(i=1;i<NUM_ENDPOINTS;i++) { 918 for(i=1;i<USB_NUM_ENDPOINTS;i++) {
921 qh_array[i*2].max_pkt_length = rx_packetsize << QH_MAX_PKT_LEN_POS | QH_ZLT_SEL; 919 qh_array[i*2].max_pkt_length = rx_packetsize << QH_MAX_PKT_LEN_POS | QH_ZLT_SEL;
922 qh_array[i*2].dtd.next_td_ptr = QH_NEXT_TERMINATE; 920 qh_array[i*2].dtd.next_td_ptr = QH_NEXT_TERMINATE;
923 qh_array[i*2+1].max_pkt_length = tx_packetsize << QH_MAX_PKT_LEN_POS | QH_ZLT_SEL; 921 qh_array[i*2+1].max_pkt_length = tx_packetsize << QH_MAX_PKT_LEN_POS | QH_ZLT_SEL;
@@ -930,7 +928,7 @@ static void init_endpoints(void)
930 int i; 928 int i;
931 /* TODO: this should take ep_allocation into account */ 929 /* TODO: this should take ep_allocation into account */
932 /* bulk */ 930 /* bulk */
933 for(i=1;i<NUM_ENDPOINTS;i++) { 931 for(i=1;i<USB_NUM_ENDPOINTS;i++) {
934 REG_ENDPTCTRL(i) = 932 REG_ENDPTCTRL(i) =
935 EPCTRL_RX_DATA_TOGGLE_RST | EPCTRL_RX_ENABLE | 933 EPCTRL_RX_DATA_TOGGLE_RST | EPCTRL_RX_ENABLE |
936 EPCTRL_TX_DATA_TOGGLE_RST | EPCTRL_TX_ENABLE | 934 EPCTRL_TX_DATA_TOGGLE_RST | EPCTRL_TX_ENABLE |
diff --git a/firmware/target/arm/usb-fw-pp502x.c b/firmware/target/arm/usb-fw-pp502x.c
index a41ef9a598..8a6d78675f 100644
--- a/firmware/target/arm/usb-fw-pp502x.c
+++ b/firmware/target/arm/usb-fw-pp502x.c
@@ -25,13 +25,13 @@
25 ****************************************************************************/ 25 ****************************************************************************/
26#include "config.h" 26#include "config.h"
27#include "system.h" 27#include "system.h"
28#include "usb-target.h"
28#include "usb.h" 29#include "usb.h"
29#include "button.h" 30#include "button.h"
30#include "ata.h" 31#include "ata.h"
31#include "string.h" 32#include "string.h"
32#include "usb_core.h" 33#include "usb_core.h"
33#include "usb_drv.h" 34#include "usb_drv.h"
34#include "usb-target.h"
35 35
36void usb_init_device(void) 36void usb_init_device(void)
37{ 37{
@@ -94,6 +94,31 @@ void usb_enable(bool on)
94 } 94 }
95} 95}
96 96
97void usb_attach(void)
98{
99#ifdef USB_DETECT_BY_DRV
100 usb_drv_attach();
101#else
102 usb_enable(true);
103#endif
104}
105
106#ifdef USB_DETECT_BY_DRV
107/* Cannot tell charger pin from USB pin */
108static int usb_status = USB_EXTRACTED;
109
110void usb_connect_event(bool inserted)
111{
112 usb_status = inserted ? USB_INSERTED : USB_EXTRACTED;
113 usb_status_event(inserted ? USB_POWERED : USB_UNPOWERED);
114}
115
116/* Called during the bus reset interrupt when in detect mode */
117void usb_drv_usb_detect_event(void)
118{
119 usb_status_event(USB_INSERTED);
120}
121#else /* !USB_DETECT_BY_DRV */
97static bool usb_pin_detect(void) 122static bool usb_pin_detect(void)
98{ 123{
99 bool retval = false; 124 bool retval = false;
@@ -110,12 +135,12 @@ static bool usb_pin_detect(void)
110 retval = true; 135 retval = true;
111 136
112#elif defined(SANSA_C200) 137#elif defined(SANSA_C200)
113 /* GPIO H bit 1 is usb detect */ 138 /* GPIO H bit 1 is usb/charger detect */
114 if (GPIOH_INPUT_VAL & 0x02) 139 if (GPIOH_INPUT_VAL & 0x02)
115 retval = true; 140 retval = true;
116 141
117#elif defined(SANSA_E200) 142#elif defined(SANSA_E200)
118 /* GPIO B bit 4 is usb detect */ 143 /* GPIO B bit 4 is usb/charger detect */
119 if (GPIOB_INPUT_VAL & 0x10) 144 if (GPIOB_INPUT_VAL & 0x10)
120 retval = true; 145 retval = true;
121 146
@@ -137,16 +162,32 @@ static bool usb_pin_detect(void)
137 162
138 return retval; 163 return retval;
139} 164}
165#endif /* USB_DETECT_BY_DRV */
140 166
141/* detect host or charger (INSERTED or POWERED) */ 167void usb_drv_int_enable(bool enable)
168{
169 /* enable/disable USB IRQ in CPU */
170 if(enable) {
171 CPU_INT_EN = USB_MASK;
172 }
173 else {
174 CPU_INT_DIS = USB_MASK;
175 }
176}
177
178/* detect host or charger (INSERTED or EXTRACTED) */
142int usb_detect(void) 179int usb_detect(void)
143{ 180{
181#ifdef USB_DETECT_BY_DRV
182 return usb_status;
183#else
144 if(usb_pin_detect()) { 184 if(usb_pin_detect()) {
145 return USB_INSERTED; 185 return USB_INSERTED;
146 } 186 }
147 else { 187 else {
148 return USB_EXTRACTED; 188 return USB_EXTRACTED;
149 } 189 }
190#endif
150} 191}
151 192
152#if defined(IPOD_COLOR) || defined(IPOD_4G) \ 193#if defined(IPOD_COLOR) || defined(IPOD_4G) \
diff --git a/firmware/target/arm/usb-target.h b/firmware/target/arm/usb-target.h
index cdf6776cc1..913ad805ce 100644
--- a/firmware/target/arm/usb-target.h
+++ b/firmware/target/arm/usb-target.h
@@ -23,4 +23,11 @@
23 23
24void usb_init_device(void); 24void usb_init_device(void);
25 25
26#ifndef BOOTLOADER
27#if defined(SANSA_C200) || defined(SANSA_E200)
28#define USB_STATUS_BY_EVENT /* No USB tick */
29void usb_connect_event(bool inserted);
30#endif
31#endif /* BOOTLOADER */
32
26#endif 33#endif