diff options
Diffstat (limited to 'firmware/target/arm')
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/system-target.h | 8 | ||||
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/usb-imx31.c | 35 | ||||
-rw-r--r-- | firmware/target/arm/powermgmt-ascodec.c | 10 | ||||
-rw-r--r-- | firmware/target/arm/usb-drv-arc.c | 186 | ||||
-rw-r--r-- | firmware/target/arm/usb-fw-pp502x.c | 49 | ||||
-rw-r--r-- | firmware/target/arm/usb-target.h | 7 |
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 */ | ||
35 | static 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 |
35 | static inline void udelay(unsigned int usecs) | 43 | static 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 | ||
34 | static int usb_status = USB_EXTRACTED; | 35 | static int usb_status = USB_EXTRACTED; |
@@ -75,11 +76,7 @@ bool usb_plugged(void) | |||
75 | 76 | ||
76 | void usb_init_device(void) | 77 | void 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 | ||
92 | void usb_enable(bool on) | 89 | void 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 | |||
108 | void usb_attach(void) | ||
109 | { | ||
110 | usb_enable(true); | ||
111 | } | ||
112 | |||
113 | static void __attribute__((interrupt("IRQ"))) USB_OTG_HANDLER(void) | ||
114 | { | ||
115 | usb_drv_int(); /* Call driver handler */ | ||
116 | } | ||
117 | |||
118 | void 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 | ||
137 | static inline void charger_control(void) | 143 | static 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 Bj๖rn 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" | ||
38 | static 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 | ||
329 | static struct transfer_descriptor td_array[NUM_ENDPOINTS*2] | 324 | static 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) */ |
333 | struct queue_head { | 328 | struct 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 | 340 | static struct queue_head qh_array[USB_NUM_ENDPOINTS*2] |
346 | static 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 */ | ||
351 | static struct queue_head qh_array[NUM_ENDPOINTS*2] | ||
352 | QHARRAY_ATTR __attribute__((aligned (4))); | ||
353 | #endif | ||
354 | 342 | ||
355 | static struct wakeup transfer_completion_signal[NUM_ENDPOINTS*2] | 343 | static struct wakeup transfer_completion_signal[USB_NUM_ENDPOINTS*2] |
356 | SHAREDBSS_ATTR; | 344 | SHAREDBSS_ATTR; |
357 | 345 | ||
358 | static const unsigned int pipe2mask[] = { | 346 | static const unsigned int pipe2mask[] = { |
@@ -363,7 +351,7 @@ static const unsigned int pipe2mask[] = { | |||
363 | 0x10, 0x100000, | 351 | 0x10, 0x100000, |
364 | }; | 352 | }; |
365 | 353 | ||
366 | static char ep_allocation[NUM_ENDPOINTS]; | 354 | static char ep_allocation[USB_NUM_ENDPOINTS]; |
367 | 355 | ||
368 | /*-------------------------------------------------------------------------*/ | 356 | /*-------------------------------------------------------------------------*/ |
369 | static void transfer_completed(void); | 357 | static void transfer_completed(void); |
@@ -378,52 +366,46 @@ static void init_control_queue_heads(void); | |||
378 | static void init_bulk_queue_heads(void); | 366 | static void init_bulk_queue_heads(void); |
379 | static void init_endpoints(void); | 367 | static void init_endpoints(void); |
380 | /*-------------------------------------------------------------------------*/ | 368 | /*-------------------------------------------------------------------------*/ |
381 | 369 | static void usb_drv_stop(void) | |
382 | bool 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 */ | 377 | void usb_drv_reset(void) |
388 | void 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; | 393 | void 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 */ |
412 | void usb_drv_init(void) | 403 | static 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 | ||
466 | void 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 */ | ||
455 | void 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 */ |
462 | void usb_drv_attach(void) | ||
463 | { | ||
464 | sleep(HZ/10); | ||
465 | _usb_drv_init(true); | ||
466 | } | ||
467 | #endif /* USB_DETECT_BY_DRV */ | ||
468 | |||
469 | void 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 | ||
489 | static void __attribute__((interrupt("IRQ"))) USB_OTG_HANDLER(void) | ||
490 | #else | ||
491 | void usb_drv_int(void) | 481 | void 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 | ||
589 | bool usb_drv_connected(void) | 588 | bool 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 | |||
595 | bool usb_drv_powered(void) | ||
596 | { | ||
597 | return (REG_OTGSC & OTGSC_B_SESSION_VALID) ? true : false; | ||
592 | } | 598 | } |
593 | 599 | ||
594 | void usb_drv_set_address(int address) | 600 | void 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 | ||
36 | void usb_init_device(void) | 36 | void usb_init_device(void) |
37 | { | 37 | { |
@@ -94,6 +94,31 @@ void usb_enable(bool on) | |||
94 | } | 94 | } |
95 | } | 95 | } |
96 | 96 | ||
97 | void 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 */ | ||
108 | static int usb_status = USB_EXTRACTED; | ||
109 | |||
110 | void 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 */ | ||
117 | void usb_drv_usb_detect_event(void) | ||
118 | { | ||
119 | usb_status_event(USB_INSERTED); | ||
120 | } | ||
121 | #else /* !USB_DETECT_BY_DRV */ | ||
97 | static bool usb_pin_detect(void) | 122 | static 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) */ | 167 | void 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) */ | ||
142 | int usb_detect(void) | 179 | int 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 | ||
24 | void usb_init_device(void); | 24 | void 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 */ | ||
29 | void usb_connect_event(bool inserted); | ||
30 | #endif | ||
31 | #endif /* BOOTLOADER */ | ||
32 | |||
26 | #endif | 33 | #endif |