1
0
Fork 0
forked from len0rd/rockbox

Use bus reset detection for all ARC OTG devices. Remove conflict from LV24020LP driver with some GPIO-by-number macros for PP502x. Start monitoring for USB stack once all core threads and queues are created otherwise queues will likely be registered after USB acks. Putting PP502x system_reboot in IRAM (unmapped, uncached) memory seems to help it work more consistently. Hopefully I got all the PP USB connect handlers in the right spot in irq_handler. If device seems unresponsive to cable, check there first.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19819 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Michael Sevakis 2009-01-22 22:05:04 +00:00
parent 81df953da5
commit da76a34694
16 changed files with 345 additions and 188 deletions

View file

@ -141,6 +141,10 @@ static void app_main(void)
viewportmanager_set_statusbar(true); viewportmanager_set_statusbar(true);
add_event(GUI_EVENT_STATUSBAR_TOGGLE, false, add_event(GUI_EVENT_STATUSBAR_TOGGLE, false,
viewportmanager_statusbar_changed); viewportmanager_statusbar_changed);
#ifdef HAVE_USBSTACK
/* All threads should be created and public queues registered by now */
usb_start_monitoring();
#endif
root_menu(); root_menu();
} }
@ -454,8 +458,8 @@ static void init(void)
eeprom_settings_init(); eeprom_settings_init();
#endif #endif
usb_start_monitoring();
#ifndef HAVE_USBSTACK #ifndef HAVE_USBSTACK
usb_start_monitoring();
while (usb_detect() == USB_INSERTED) while (usb_detect() == USB_INSERTED)
{ {
#ifdef HAVE_EEPROM_SETTINGS #ifdef HAVE_EEPROM_SETTINGS

View file

@ -61,16 +61,17 @@ static int fd_log = -1;
/** tuner register defines **/ /** tuner register defines **/
#if defined(SANSA_E200) || defined(SANSA_C200) #if defined(SANSA_E200) || defined(SANSA_C200)
#define GPIO_OUTPUT_EN GPIOH_OUTPUT_EN #define TUNER_GPIO_OUTPUT_EN GPIOH_OUTPUT_EN
#define GPIO_OUTPUT_VAL GPIOH_OUTPUT_VAL #define TUNER_GPIO_OUTPUT_VAL GPIOH_OUTPUT_VAL
#define GPIO_INPUT_VAL GPIOH_INPUT_VAL #define TUNER_GPIO_INPUT_VAL GPIOH_INPUT_VAL
#define FM_NRW_PIN 3 #define FM_NRW_PIN 3
#define FM_CLOCK_PIN 4 #define FM_CLOCK_PIN 4
#define FM_DATA_PIN 5 #define FM_DATA_PIN 5
#elif defined(IAUDIO_7) #elif defined(IAUDIO_7)
#define GPIO_OUTPUT_EN GPIOA_DIR #define TUNER_GPIO_OUTPUT_EN GPIOA_DIR
#define GPIO_OUTPUT_VAL GPIOA #define TUNER_GPIO_OUTPUT_VAL GPIOA
#define GPIO_INPUT_VAL GPIOA #define TUNER_GPIO_INPUT_VAL GPIOA
#define FM_CLOCK_PIN 5 #define FM_CLOCK_PIN 5
#define FM_DATA_PIN 6 #define FM_DATA_PIN 6
#define FM_NRW_PIN 7 #define FM_NRW_PIN 7
@ -83,9 +84,9 @@ static void udelay(int usecs)
} }
#elif defined(COWON_D2) #elif defined(COWON_D2)
#define GPIO_OUTPUT_EN GPIOC_DIR #define TUNER_GPIO_OUTPUT_EN GPIOC_DIR
#define GPIO_OUTPUT_VAL GPIOC #define TUNER_GPIO_OUTPUT_VAL GPIOC
#define GPIO_INPUT_VAL GPIOC #define TUNER_GPIO_INPUT_VAL GPIOC
#define FM_NRW_PIN 31 #define FM_NRW_PIN 31
#define FM_CLOCK_PIN 29 #define FM_CLOCK_PIN 29
#define FM_DATA_PIN 30 #define FM_DATA_PIN 30
@ -292,16 +293,16 @@ static void lv24020lp_send_byte(unsigned int byte)
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
{ {
GPIO_OUTPUT_VAL &= ~(1 << FM_CLOCK_PIN); TUNER_GPIO_OUTPUT_VAL &= ~(1 << FM_CLOCK_PIN);
if (byte & 1) if (byte & 1)
GPIO_OUTPUT_VAL |= (1 << FM_DATA_PIN); TUNER_GPIO_OUTPUT_VAL |= (1 << FM_DATA_PIN);
else else
GPIO_OUTPUT_VAL &= ~(1 << FM_DATA_PIN); TUNER_GPIO_OUTPUT_VAL &= ~(1 << FM_DATA_PIN);
udelay(FM_CLK_DELAY); udelay(FM_CLK_DELAY);
GPIO_OUTPUT_VAL |= (1 << FM_CLOCK_PIN); TUNER_GPIO_OUTPUT_VAL |= (1 << FM_CLOCK_PIN);
udelay(FM_CLK_DELAY); udelay(FM_CLK_DELAY);
byte >>= 1; byte >>= 1;
@ -312,8 +313,8 @@ static void lv24020lp_send_byte(unsigned int byte)
static void lv24020lp_end_write(void) static void lv24020lp_end_write(void)
{ {
/* switch back to read mode */ /* switch back to read mode */
GPIO_OUTPUT_EN &= ~(1 << FM_DATA_PIN); TUNER_GPIO_OUTPUT_EN &= ~(1 << FM_DATA_PIN);
GPIO_OUTPUT_VAL &= ~(1 << FM_NRW_PIN); TUNER_GPIO_OUTPUT_VAL &= ~(1 << FM_NRW_PIN);
udelay(FM_CLK_DELAY); udelay(FM_CLK_DELAY);
} }
@ -327,8 +328,8 @@ static unsigned int lv24020lp_begin_write(unsigned int address)
for (;;) for (;;)
{ {
/* Prepare 3-wire bus pins for write cycle */ /* Prepare 3-wire bus pins for write cycle */
GPIO_OUTPUT_VAL |= (1 << FM_NRW_PIN); TUNER_GPIO_OUTPUT_VAL |= (1 << FM_NRW_PIN);
GPIO_OUTPUT_EN |= (1 << FM_DATA_PIN); TUNER_GPIO_OUTPUT_EN |= (1 << FM_DATA_PIN);
udelay(FM_CLK_DELAY); udelay(FM_CLK_DELAY);
/* current block == register block? */ /* current block == register block? */
@ -419,13 +420,13 @@ static unsigned int lv24020lp_read(unsigned int address)
toread = 0; toread = 0;
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
{ {
GPIO_OUTPUT_VAL &= ~(1 << FM_CLOCK_PIN); TUNER_GPIO_OUTPUT_VAL &= ~(1 << FM_CLOCK_PIN);
udelay(FM_CLK_DELAY); udelay(FM_CLK_DELAY);
if (GPIO_INPUT_VAL & (1 << FM_DATA_PIN)) if (TUNER_GPIO_INPUT_VAL & (1 << FM_DATA_PIN))
toread |= (1 << i); toread |= (1 << i);
GPIO_OUTPUT_VAL |= (1 << FM_CLOCK_PIN); TUNER_GPIO_OUTPUT_VAL |= (1 << FM_CLOCK_PIN);
udelay(FM_CLK_DELAY); udelay(FM_CLK_DELAY);
} }

View file

@ -180,9 +180,6 @@
/* enable these for the experimental usb stack */ /* enable these for the experimental usb stack */
#define HAVE_USBSTACK #define HAVE_USBSTACK
#ifndef BOOTLOADER
#define USB_DETECT_BY_DRV
#endif
#define USB_VENDOR_ID 0x0781 #define USB_VENDOR_ID 0x0781
#define USB_PRODUCT_ID 0x7450 #define USB_PRODUCT_ID 0x7450

View file

@ -177,9 +177,6 @@
/* enable these for the experimental usb stack */ /* enable these for the experimental usb stack */
#define HAVE_USBSTACK #define HAVE_USBSTACK
#ifndef BOOTLOADER
#define USB_DETECT_BY_DRV
#endif
#define USB_VENDOR_ID 0x0781 #define USB_VENDOR_ID 0x0781
#define USB_PRODUCT_ID 0x7421 #define USB_PRODUCT_ID 0x7421

View file

@ -439,6 +439,8 @@
#if CONFIG_CPU == IMX31L #if CONFIG_CPU == IMX31L
/* Priority in bootloader is wanted */ /* Priority in bootloader is wanted */
#define HAVE_PRIORITY_SCHEDULING #define HAVE_PRIORITY_SCHEDULING
#define USB_STATUS_BY_EVENT
#define USB_DETECT_BY_DRV
#endif #endif
#else /* !BOOTLOADER */ #else /* !BOOTLOADER */
@ -452,13 +454,18 @@
#define HAVE_SEMAPHORE_OBJECTS #define HAVE_SEMAPHORE_OBJECTS
#ifdef TOSHIBA_GIGABEAT_F #if defined(HAVE_USBSTACK) && CONFIG_USBOTG == USBOTG_ARC
#define HAVE_WAKEUP_OBJECTS #define USB_STATUS_BY_EVENT
#define USB_DETECT_BY_DRV
#if CONFIG_CPU != IMX31L
#define INCLUDE_TIMEOUT_API
#endif #endif
#endif /* HAVE_USBSTACK */
#endif /* BOOTLOADER */ #endif /* BOOTLOADER */
#if defined(HAVE_USBSTACK) || (CONFIG_CPU == JZ4732) || (CONFIG_CPU == AS3525) #if defined(HAVE_USBSTACK) || (CONFIG_CPU == JZ4732) \
|| (CONFIG_CPU == AS3525) || (CONFIG_CPU == S3C2440)
#define HAVE_WAKEUP_OBJECTS #define HAVE_WAKEUP_OBJECTS
#endif #endif

View file

@ -218,6 +218,7 @@
#define CACHE_OP_INVALIDATE 0x0004 #define CACHE_OP_INVALIDATE 0x0004
/* GPIO Ports */ /* GPIO Ports */
#define GPIO_BASE_ADDR 0x6000d000
#define GPIOA_ENABLE (*(volatile unsigned long *)(0x6000d000)) #define GPIOA_ENABLE (*(volatile unsigned long *)(0x6000d000))
#define GPIOB_ENABLE (*(volatile unsigned long *)(0x6000d004)) #define GPIOB_ENABLE (*(volatile unsigned long *)(0x6000d004))
#define GPIOC_ENABLE (*(volatile unsigned long *)(0x6000d008)) #define GPIOC_ENABLE (*(volatile unsigned long *)(0x6000d008))
@ -322,10 +323,41 @@
* define the value of those bits. */ * define the value of those bits. */
#define GPIO_SET_BITWISE(port, mask) \ #define GPIO_SET_BITWISE(port, mask) \
do { *(&port + (0x800/sizeof(long))) = (mask << 8) | mask; } while(0) do { *(&(port) + (0x800/sizeof(long))) = ((mask) << 8) | (mask); } while(0)
#define GPIO_CLEAR_BITWISE(port, mask) \ #define GPIO_CLEAR_BITWISE(port, mask) \
do { *(&port + (0x800/sizeof(long))) = mask << 8; } while(0) do { *(&(port) + (0x800/sizeof(long))) = (mask) << 8; } while(0)
#define GPIO_WRITE_BITWISE(port, val, mask) \
do { *(&(port) + (0x800/sizeof(long))) = ((mask) << 8) | (val); } while(0)
/* GPIO Module 0 */
#define GPIOA 0
#define GPIOB 1
#define GPIOC 2
#define GPIOD 3
/* GPIO Module 1 */
#define GPIOE 4
#define GPIOF 5
#define GPIOG 6
#define GPIOH 7
/* GPIO Module 2 */
#define GPIOI 8
#define GPIOJ 9
#define GPIOK 10
#define GPIOL 11
#define GPIO_MODULE_NUM(gpio) ((gpio)>>2)
#define GPIO_MAP_ADDR(gpio) (GPIO_BASE_ADDR+(GPIO_MODULE_NUM(gpio)<<7)+(((gpio)&3)<<2))
#define GPIO_ENABLE(gpio) (*(volatile unsigned long *)(GPIO_MAP_ADDR(gpio)+0x00))
#define GPIO_OUTPUT_EN(gpio) (*(volatile unsigned long *)(GPIO_MAP_ADDR(gpio)+0x10))
#define GPIO_OUTPUT_VAL(gpio) (*(volatile unsigned long *)(GPIO_MAP_ADDR(gpio)+0x20))
#define GPIO_INPUT_VAL(gpio) (*(volatile unsigned long *)(GPIO_MAP_ADDR(gpio)+0x30))
#define GPIO_INT_STAT(gpio) (*(volatile unsigned long *)(GPIO_MAP_ADDR(gpio)+0x40))
#define GPIO_INT_EN(gpio) (*(volatile unsigned long *)(GPIO_MAP_ADDR(gpio)+0x50))
#define GPIO_INT_LEV(gpio) (*(volatile unsigned long *)(GPIO_MAP_ADDR(gpio)+0x60))
#define GPIO_INT_CLR(gpio) (*(volatile unsigned long *)(GPIO_MAP_ADDR(gpio)+0x70))
#define GPIO_HI_INT_MASK(gpio) (1ul << GPIO_MODULE_NUM(gpio))
/* Device initialization */ /* Device initialization */
#define PP_VER1 (*(volatile unsigned long *)(0x70000000)) #define PP_VER1 (*(volatile unsigned long *)(0x70000000))

View file

@ -31,8 +31,8 @@
/* Messages from usb_tick and thread states */ /* Messages from usb_tick and thread states */
enum { enum {
USB_EXTRACTED = 0, /* Event+State */
USB_INSERTED, /* Event+State */ USB_INSERTED, /* Event+State */
USB_EXTRACTED, /* Event+State */
#if defined(HAVE_USB_POWER) || defined(USB_DETECT_BY_DRV) #if defined(HAVE_USB_POWER) || defined(USB_DETECT_BY_DRV)
USB_POWERED, /* Event+State */ USB_POWERED, /* Event+State */
#endif #endif
@ -135,6 +135,7 @@ bool usb_exclusive_storage(void); /* storage is available for usb */
#ifdef USB_FIREWIRE_HANDLING #ifdef USB_FIREWIRE_HANDLING
bool firewire_detect(void); bool firewire_detect(void);
void usb_firewire_connect_event(void);
#endif #endif
#endif #endif

View file

@ -1247,7 +1247,6 @@ void microsd_int(void)
GPIO_SET_BITWISE(GPIOL_INT_EN, 0x08); GPIO_SET_BITWISE(GPIOL_INT_EN, 0x08);
#endif #endif
timeout_register(&sd1_oneshot, sd1_oneshot_callback, (3*HZ/10), 0); timeout_register(&sd1_oneshot, sd1_oneshot_callback, (3*HZ/10), 0);
} }
#endif /* HAVE_HOTSWAP */ #endif /* HAVE_HOTSWAP */

View file

@ -53,14 +53,19 @@ static void enable_transceiver(bool enable)
} }
} }
/* Read the immediate state of the cable from the PMIC */
bool usb_plugged(void)
{
return mc13783_read(MC13783_INTERRUPT_SENSE0) & MC13783_USB4V4S;
}
void usb_connect_event(void) void usb_connect_event(void)
{ {
uint32_t status = mc13783_read(MC13783_INTERRUPT_SENSE0); int status = usb_plugged() ? USB_INSERTED : USB_EXTRACTED;
usb_status = (status & MC13783_USB4V4S) ? usb_status = status;
USB_INSERTED : USB_EXTRACTED;
/* Notify power that USB charging is potentially available */ /* Notify power that USB charging is potentially available */
charger_usb_detect_event(usb_status); charger_usb_detect_event(status);
usb_status_event(usb_status); usb_status_event((status == USB_INSERTED) ? USB_POWERED : USB_UNPOWERED);
} }
int usb_detect(void) int usb_detect(void)
@ -68,12 +73,6 @@ int usb_detect(void)
return usb_status; return usb_status;
} }
/* Read the immediate state of the cable from the PMIC */
bool usb_plugged(void)
{
return mc13783_read(MC13783_INTERRUPT_SENSE0) & MC13783_USB4V4S;
}
void usb_init_device(void) void usb_init_device(void)
{ {
/* Do one-time inits */ /* Do one-time inits */
@ -107,7 +106,7 @@ void usb_enable(bool on)
void usb_attach(void) void usb_attach(void)
{ {
usb_enable(true); usb_drv_attach();
} }
static void __attribute__((interrupt("IRQ"))) USB_OTG_HANDLER(void) static void __attribute__((interrupt("IRQ"))) USB_OTG_HANDLER(void)
@ -122,3 +121,9 @@ void usb_drv_int_enable(bool enable)
else else
avic_disable_int(USB_OTG); avic_disable_int(USB_OTG);
} }
/* Called during the bus reset interrupt when in detect mode */
void usb_drv_usb_detect_event(void)
{
usb_status_event(USB_INSERTED);
}

View file

@ -25,9 +25,6 @@
#define USB_DRIVER_CLOSE #define USB_DRIVER_CLOSE
#endif #endif
/* Connect by events, not by tick polling */
#define USB_STATUS_BY_EVENT
void usb_connect_event(void); void usb_connect_event(void);
void usb_init_device(void); void usb_init_device(void);
int usb_detect(void); int usb_detect(void);

View file

@ -134,10 +134,6 @@ static inline void charger_plugged(void)
{ {
batt_threshold = BATT_FULL_VOLTAGE; /* Start with topped value. */ batt_threshold = BATT_FULL_VOLTAGE; /* Start with topped value. */
battery_voltage_sync(); battery_voltage_sync();
#if defined(USB_STATUS_BY_EVENT) && defined(USB_DETECT_BY_DRV)
/* Charger pin detect is USB pin detect */
usb_connect_event(true);
#endif
} }
static inline void charger_control(void) static inline void charger_control(void)
@ -192,10 +188,6 @@ static inline void charger_unplugged(void)
disable_charger(); disable_charger();
if (charge_state >= CHARGE_STATE_ERROR) if (charge_state >= CHARGE_STATE_ERROR)
charge_state = DISCHARGING; /* Reset error */ charge_state = DISCHARGING; /* Reset error */
#if defined(USB_STATUS_BY_EVENT) && defined(USB_DETECT_BY_DRV)
/* Charger pin detect is USB pin detect */
usb_connect_event(false);
#endif
} }
/* Main charging algorithm - called from powermgmt.c */ /* Main charging algorithm - called from powermgmt.c */

View file

@ -25,9 +25,8 @@
#include "as3514.h" #include "as3514.h"
#include "ata-sd-target.h" #include "ata-sd-target.h"
#include "button-target.h" #include "button-target.h"
#ifdef HAVE_USBSTACK #include "usb-target.h"
#include "usb_drv.h" #include "usb_drv.h"
#endif
#ifndef BOOTLOADER #ifndef BOOTLOADER
extern void TIMER1(void); extern void TIMER1(void);
@ -42,51 +41,108 @@ void __attribute__((interrupt("IRQ"))) irq_handler(void)
{ {
if (CPU_INT_STAT & TIMER1_MASK) { if (CPU_INT_STAT & TIMER1_MASK) {
TIMER1(); TIMER1();
} else if (CPU_INT_STAT & TIMER2_MASK) }
else if (CPU_INT_STAT & TIMER2_MASK) {
TIMER2(); TIMER2();
#if defined(IPOD_MINI) /* Mini 1st gen only, mini 2nd gen uses iPod 4G code */ }
else if (CPU_HI_INT_STAT & GPIO0_MASK) #ifdef HAVE_USBSTACK
ipod_mini_button_int(); /* Rather high priority - place near front */
#elif CONFIG_KEYPAD == IPOD_4G_PAD /* except Mini 1st gen, handled above */ else if (CPU_INT_STAT & USB_MASK) {
else if (CPU_HI_INT_STAT & I2C_MASK) usb_drv_int();
ipod_4g_button_int();
#elif defined(SANSA_E200)
#ifdef HAVE_HOTSWAP
else if (CPU_HI_INT_STAT & GPIO0_MASK) {
if (GPIOA_INT_STAT & 0x80)
microsd_int();
} }
#endif #endif
#if defined(IPOD_MINI) /* Mini 1st gen only, mini 2nd gen uses iPod 4G code */
else if (CPU_HI_INT_STAT & GPIO0_MASK) {
if ((GPIOA_INT_STAT & 0x3f) || (GPIOB_INT_STAT & 0x30))
ipod_mini_button_int();
if (GPIOC_INT_STAT & 0x02)
firewire_insert_int();
if (GPIOD_INT_STAT & 0x08)
usb_insert_int();
}
/* end IPOD_MINI */
#elif CONFIG_KEYPAD == IPOD_4G_PAD /* except Mini 1st gen, handled above */
else if (CPU_HI_INT_STAT & I2C_MASK) {
ipod_4g_button_int();
}
#if defined(IPOD_COLOR) || defined(IPOD_MINI2G) || defined(IPOD_4G)
else if (CPU_HI_INT_STAT & GPIO0_MASK) {
if (GPIOC_INT_STAT & 0x02)
firewire_insert_int();
if (GPIOD_INT_STAT & 0x08)
usb_insert_int();
}
#elif defined(IPOD_NANO) || defined(IPOD_VIDEO)
else if (CPU_HI_INT_STAT & GPIO2_MASK) {
if (GPIOL_INT_STAT & 0x10)
usb_insert_int();
}
#endif
/* end CONFIG_KEYPAD == IPOD_4G_PAD */
#elif defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
else if (CPU_HI_INT_STAT & GPIO2_MASK) {
if (GPIOL_INT_STAT & 0x04)
usb_insert_int();
}
/* end IRIVER_H10 || IRIVER_H10_5GB */
#elif defined(SANSA_E200)
else if (CPU_HI_INT_STAT & GPIO0_MASK) {
#ifdef HAVE_HOTSWAP
if (GPIOA_INT_STAT & 0x80)
microsd_int();
#endif
if (GPIOB_INT_STAT & 0x10)
usb_insert_int();
}
else if (CPU_HI_INT_STAT & GPIO1_MASK) { else if (CPU_HI_INT_STAT & GPIO1_MASK) {
if (GPIOF_INT_STAT & 0xff) if (GPIOF_INT_STAT & 0xff)
button_int(); button_int();
if (GPIOH_INT_STAT & 0xc0) if (GPIOH_INT_STAT & 0xc0)
clickwheel_int(); clickwheel_int();
} }
#elif defined(SANSA_C200) && defined(HAVE_HOTSWAP) /* end SANSA_E200 */
#elif defined(SANSA_C200)
else if (CPU_HI_INT_STAT & GPIO1_MASK) {
if (GPIOH_INT_STAT & 0x02)
usb_insert_int();
}
#ifdef HAVE_HOTSWAP
else if (CPU_HI_INT_STAT & GPIO2_MASK) { else if (CPU_HI_INT_STAT & GPIO2_MASK) {
if (GPIOL_INT_STAT & 0x08) if (GPIOL_INT_STAT & 0x08)
microsd_int(); microsd_int();
} }
#endif
/* end SANSA_C200 */
#elif defined(MROBE_100) #elif defined(MROBE_100)
else if (CPU_HI_INT_STAT & GPIO0_MASK) { else if (CPU_HI_INT_STAT & GPIO0_MASK) {
if (GPIOD_INT_STAT & 0x2) if (GPIOD_INT_STAT & 0x02)
button_int(); button_int();
} }
else if (CPU_HI_INT_STAT & GPIO2_MASK) {
if (GPIOL_INT_STAT & 0x04)
usb_insert_int();
}
/* end MROBE_100 */
#elif defined(PHILIPS_SA9200)
else if (CPU_HI_INT_STAT & GPIO1_MASK) {
if (GPIOF_INT_STAT & 0x80)
usb_insert_int();
}
/* end PHILIPS_SA9200 */
#elif defined(PHILIPS_HDD1630) #elif defined(PHILIPS_HDD1630)
else if (CPU_HI_INT_STAT & GPIO0_MASK) { else if (CPU_HI_INT_STAT & GPIO0_MASK) {
if (GPIOA_INT_STAT & 0x20) if (GPIOA_INT_STAT & 0x20)
button_int(); button_int();
} }
else if (CPU_HI_INT_STAT & GPIO1_MASK) {
if (GPIOE_INT_STAT & 0x04)
usb_insert_int();
}
/* end PHILIPS_HDD1630 */
#endif #endif
#ifdef IPOD_ACCESSORY_PROTOCOL #ifdef IPOD_ACCESSORY_PROTOCOL
else if (CPU_HI_INT_STAT & SER0_MASK) { else if (CPU_HI_INT_STAT & SER0_MASK) {
SERIAL0(); SERIAL0();
}
#endif
#ifdef HAVE_USBSTACK
else if (CPU_INT_STAT & USB_MASK) {
usb_drv_int();
} }
#endif #endif
} else { } else {
@ -437,8 +493,12 @@ void system_init(void)
#endif /* BOOTLOADER */ #endif /* BOOTLOADER */
} }
void system_reboot(void) void ICODE_ATTR system_reboot(void)
{ {
disable_interrupt(IRQ_FIQ_STATUS);
CPU_INT_DIS = -1;
COP_INT_DIS = -1;
/* Reboot */ /* Reboot */
#if defined(SANSA_E200) || defined(SANSA_C200) || defined(PHILIPS_SA9200) #if defined(SANSA_E200) || defined(SANSA_C200) || defined(PHILIPS_SA9200)
CACHE_CTL &= ~CACHE_CTL_VECT_REMAP; CACHE_CTL &= ~CACHE_CTL_VECT_REMAP;

View file

@ -419,13 +419,11 @@ static void _usb_drv_init(bool attach)
REG_ENDPOINTLISTADDR = (unsigned int)qh_array; REG_ENDPOINTLISTADDR = (unsigned int)qh_array;
REG_DEVICEADDR = 0; REG_DEVICEADDR = 0;
#ifdef USB_DETECT_BY_DRV
if (!attach) { if (!attach) {
/* enable RESET interrupt */ /* enable RESET interrupt */
REG_USBINTR = USBINTR_RESET_EN; REG_USBINTR = USBINTR_RESET_EN;
} }
else else
#endif
{ {
/* enable USB interrupts */ /* enable USB interrupts */
REG_USBINTR = REG_USBINTR =
@ -449,23 +447,17 @@ static void _usb_drv_init(bool attach)
(void)attach; (void)attach;
} }
/** With USB_DETECT_BY_DRV, attach is distinct from init, otherwise eqivalent. **/
/* USB_DETECT_BY_DRV - enable bus reset detection only
* else fully enable driver */
void usb_drv_init(void) void usb_drv_init(void)
{ {
_usb_drv_init(false); _usb_drv_init(false);
} }
#ifdef USB_DETECT_BY_DRV
/* fully enable driver */ /* fully enable driver */
void usb_drv_attach(void) void usb_drv_attach(void)
{ {
sleep(HZ/10); sleep(HZ/10);
_usb_drv_init(true); _usb_drv_init(true);
} }
#endif /* USB_DETECT_BY_DRV */
void usb_drv_exit(void) void usb_drv_exit(void)
{ {
@ -513,7 +505,7 @@ void usb_drv_int(void)
/* reset interrupt */ /* reset interrupt */
if (status & USBSTS_RESET) { if (status & USBSTS_RESET) {
REG_USBSTS = USBSTS_RESET; REG_USBSTS = USBSTS_RESET;
#ifdef USB_DETECT_BY_DRV
if (UNLIKELY(usbintr == USBINTR_RESET_EN)) { if (UNLIKELY(usbintr == USBINTR_RESET_EN)) {
/* USB detected - detach and inform */ /* USB detected - detach and inform */
usb_drv_stop(); usb_drv_stop();
@ -523,7 +515,6 @@ void usb_drv_int(void)
usb_drv_usb_detect_event(); usb_drv_usb_detect_event();
} }
else else
#endif
{ {
bus_reset(); bus_reset();
usb_core_bus_reset(); /* tell mom */ usb_core_bus_reset(); /* tell mom */

View file

@ -33,6 +33,60 @@
#include "usb_core.h" #include "usb_core.h"
#include "usb_drv.h" #include "usb_drv.h"
#if defined(IPOD_4G) || defined(IPOD_COLOR) \
|| defined(IPOD_MINI) || defined(IPOD_MINI2G)
/* GPIO D bit 3 is usb detect */
#define USB_GPIO GPIOD
#define USB_GPIO_MASK 0x08
#define USB_GPIO_VAL 0x08
#elif defined(IPOD_NANO) || defined(IPOD_VIDEO)
/* GPIO L bit 4 is usb detect */
#define USB_GPIO GPIOL
#define USB_GPIO_MASK 0x10
#define USB_GPIO_VAL 0x10
#elif defined(SANSA_C200)
/* GPIO H bit 1 is usb/charger detect */
#define USB_GPIO GPIOH
#define USB_GPIO_MASK 0x02
#define USB_GPIO_VAL 0x02
#elif defined(SANSA_E200)
/* GPIO B bit 4 is usb/charger detect */
#define USB_GPIO GPIOB
#define USB_GPIO_MASK 0x10
#define USB_GPIO_VAL 0x10
#elif defined(IRIVER_H10) || defined(IRIVER_H10_5GB) || defined(MROBE_100)
/* GPIO L bit 2 is usb detect */
#define USB_GPIO GPIOL
#define USB_GPIO_MASK 0x04
#define USB_GPIO_VAL 0x04
#elif defined(PHILIPS_SA9200)
/* GPIO F bit 7 (low) is usb detect */
#define USB_GPIO GPIOF
#define USB_GPIO_MASK 0x80
#define USB_GPIO_VAL 0x00
#elif defined(PHILIPS_HDD1630)
/* GPIO E bit 2 is usb detect */
#define USB_GPIO GPIOE
#define USB_GPIO_MASK 0x04
#define USB_GPIO_VAL 0x04
#else
#error No USB GPIO config specified
#endif
#define USB_GPIO_ENABLE GPIO_ENABLE(USB_GPIO)
#define USB_GPIO_OUTPUT_EN GPIO_OUTPUT_EN(USB_GPIO)
#define USB_GPIO_INPUT_VAL GPIO_INPUT_VAL(USB_GPIO)
#define USB_GPIO_INT_EN GPIO_INT_EN(USB_GPIO)
#define USB_GPIO_INT_LEV GPIO_INT_LEV(USB_GPIO)
#define USB_GPIO_INT_CLR GPIO_INT_CLR(USB_GPIO)
#define USB_GPIO_HI_INT_MASK GPIO_HI_INT_MASK(USB_GPIO)
void usb_init_device(void) void usb_init_device(void)
{ {
/* enable usb module */ /* enable usb module */
@ -53,6 +107,9 @@ void usb_init_device(void)
outl(inl(0x70000028) | 0x2, 0x70000028); outl(inl(0x70000028) | 0x2, 0x70000028);
udelay(100000); udelay(100000);
/* Do one-time inits */
usb_drv_startup();
/* disable USB-devices until USB is detected via GPIO */ /* disable USB-devices until USB is detected via GPIO */
#ifndef BOOTLOADER #ifndef BOOTLOADER
/* Disabling USB0 in the bootloader makes the OF not load, /* Disabling USB0 in the bootloader makes the OF not load,
@ -63,17 +120,38 @@ void usb_init_device(void)
DEV_INIT2 &= ~INIT_USB; DEV_INIT2 &= ~INIT_USB;
#endif #endif
#if defined(IPOD_COLOR) || defined(IPOD_4G) \ /* These set INV_LEV to the inserted level so it will fire if already
|| defined(IPOD_MINI) || defined(IPOD_MINI2G) * inserted at the time they are enabled. */
/* GPIO C bit 1 is firewire detect */ #ifdef USB_STATUS_BY_EVENT
GPIOC_ENABLE |= 0x02; GPIO_CLEAR_BITWISE(USB_GPIO_INT_EN, USB_GPIO_MASK);
GPIOC_OUTPUT_EN &= ~0x02; GPIO_CLEAR_BITWISE(USB_GPIO_OUTPUT_EN, USB_GPIO_MASK);
#endif GPIO_SET_BITWISE(USB_GPIO_ENABLE, USB_GPIO_MASK);
GPIO_WRITE_BITWISE(USB_GPIO_INT_LEV, USB_GPIO_VAL, USB_GPIO_MASK);
USB_GPIO_INT_CLR = USB_GPIO_MASK;
GPIO_SET_BITWISE(USB_GPIO_INT_EN, USB_GPIO_MASK);
CPU_HI_INT_EN = USB_GPIO_HI_INT_MASK;
#ifdef HAVE_USBSTACK #ifdef USB_FIREWIRE_HANDLING
/* Do one-time inits */ /* GPIO C bit 1 is firewire detect */
usb_drv_startup(); GPIO_CLEAR_BITWISE(GPIOC_INT_EN, 0x02);
GPIO_CLEAR_BITWISE(GPIOC_OUTPUT_EN, 0x02);
GPIO_SET_BITWISE(GPIOC_ENABLE, 0x02);
GPIO_WRITE_BITWISE(GPIOC_INT_LEV, 0x00, 0x02);
GPIOC_INT_CLR = 0x02;
GPIO_SET_BITWISE(GPIOC_INT_EN, 0x02);
CPU_HI_INT_EN = GPIO0_MASK;
#endif #endif
CPU_INT_EN = HI_MASK;
#else
/* No interrupt - setup pin read only (BOOTLOADER) */
GPIO_CLEAR_BITWISE(USB_GPIO_OUTPUT_EN, USB_GPIO_MASK);
GPIO_SET_BITWISE(USB_GPIO_ENABLE, USB_GPIO_MASK);
#ifdef USB_FIREWIRE_HANDLING
/* GPIO C bit 1 is firewire detect */
GPIO_CLEAR_BITWISE(GPIOC_OUTPUT_EN, 0x02);
GPIO_SET_BITWISE(GPIOC_ENABLE, 0x02);
#endif
#endif /* USB_STATUS_BY_EVENT */
} }
void usb_enable(bool on) void usb_enable(bool on)
@ -96,21 +174,27 @@ void usb_enable(bool on)
void usb_attach(void) void usb_attach(void)
{ {
#ifdef USB_DETECT_BY_DRV
usb_drv_attach(); usb_drv_attach();
#else
usb_enable(true);
#endif
} }
#ifdef USB_DETECT_BY_DRV #ifdef USB_STATUS_BY_EVENT
/* Cannot tell charger pin from USB pin */ /* Cannot always tell power pin from USB pin */
static int usb_status = USB_EXTRACTED; static int usb_status = USB_EXTRACTED;
void usb_connect_event(bool inserted) static int usb_timeout_event(struct timeout *tmo)
{ {
usb_status = inserted ? USB_INSERTED : USB_EXTRACTED; usb_status_event(tmo->data == USB_GPIO_VAL ? USB_POWERED : USB_UNPOWERED);
usb_status_event(inserted ? USB_POWERED : USB_UNPOWERED); return 0;
}
void usb_insert_int(void)
{
static struct timeout usb_oneshot;
unsigned long val = USB_GPIO_INPUT_VAL & USB_GPIO_MASK;
usb_status = (val == USB_GPIO_VAL) ? USB_INSERTED : USB_EXTRACTED;
GPIO_WRITE_BITWISE(USB_GPIO_INT_LEV, val ^ USB_GPIO_MASK, USB_GPIO_MASK);
USB_GPIO_INT_CLR = USB_GPIO_MASK;
timeout_register(&usb_oneshot, usb_timeout_event, HZ/5, val);
} }
/* Called during the bus reset interrupt when in detect mode */ /* Called during the bus reset interrupt when in detect mode */
@ -118,51 +202,7 @@ void usb_drv_usb_detect_event(void)
{ {
usb_status_event(USB_INSERTED); usb_status_event(USB_INSERTED);
} }
#else /* !USB_DETECT_BY_DRV */ #endif /* USB_STATUS_BY_EVENT */
static bool usb_pin_detect(void)
{
bool retval = false;
#if defined(IPOD_4G) || defined(IPOD_COLOR) \
|| defined(IPOD_MINI) || defined(IPOD_MINI2G)
/* GPIO D bit 3 is usb detect */
if (GPIOD_INPUT_VAL & 0x08)
retval = true;
#elif defined(IPOD_NANO) || defined(IPOD_VIDEO)
/* GPIO L bit 4 is usb detect */
if (GPIOL_INPUT_VAL & 0x10)
retval = true;
#elif defined(SANSA_C200)
/* GPIO H bit 1 is usb/charger detect */
if (GPIOH_INPUT_VAL & 0x02)
retval = true;
#elif defined(SANSA_E200)
/* GPIO B bit 4 is usb/charger detect */
if (GPIOB_INPUT_VAL & 0x10)
retval = true;
#elif defined(IRIVER_H10) || defined(IRIVER_H10_5GB) || defined(MROBE_100)
/* GPIO L bit 2 is usb detect */
if (GPIOL_INPUT_VAL & 0x4)
retval = true;
#elif defined(PHILIPS_SA9200)
/* GPIO F bit 7 is usb detect */
if (!(GPIOF_INPUT_VAL & 0x80))
retval = true;
#elif defined(PHILIPS_HDD1630)
/* GPIO E bit 2 is usb detect */
if (GPIOE_INPUT_VAL & 0x4)
retval = true;
#endif
return retval;
}
#endif /* USB_DETECT_BY_DRV */
void usb_drv_int_enable(bool enable) void usb_drv_int_enable(bool enable)
{ {
@ -178,27 +218,46 @@ void usb_drv_int_enable(bool enable)
/* detect host or charger (INSERTED or EXTRACTED) */ /* detect host or charger (INSERTED or EXTRACTED) */
int usb_detect(void) int usb_detect(void)
{ {
#ifdef USB_DETECT_BY_DRV #ifdef USB_STATUS_BY_EVENT
return usb_status; return usb_status;
#else #else
if(usb_pin_detect()) { return ((USB_GPIO_INPUT_VAL & USB_GPIO_MASK) == USB_GPIO_VAL) ?
return USB_INSERTED; USB_INSERTED : USB_EXTRACTED;
}
else {
return USB_EXTRACTED;
}
#endif #endif
} }
#if defined(IPOD_COLOR) || defined(IPOD_4G) \ #ifdef USB_FIREWIRE_HANDLING
|| defined(IPOD_MINI) || defined(IPOD_MINI2G) #ifdef USB_STATUS_BY_EVENT
static bool firewire_status = false;
#endif
bool firewire_detect(void) bool firewire_detect(void)
{ {
#ifdef USB_STATUS_BY_EVENT
return firewire_status;
#else
/* GPIO C bit 1 is firewire detect */ /* GPIO C bit 1 is firewire detect */
if (!(GPIOC_INPUT_VAL & 0x02)) /* no charger detection needed for firewire */
/* no charger detection needed for firewire */ return (GPIOC_INPUT_VAL & 0x02) == 0x00;
return true;
else
return false;
}
#endif #endif
}
#ifdef USB_STATUS_BY_EVENT
static int firewire_timeout_event(struct timeout *tmo)
{
if (tmo->data == 0x00)
usb_firewire_connect_event();
return 0;
}
void firewire_insert_int(void)
{
static struct timeout firewire_oneshot;
unsigned long val = GPIOC_INPUT_VAL & 0x02;
firewire_status = val == 0x00;
GPIO_WRITE_BITWISE(GPIOC_INT_LEV, val ^ 0x02, 0x02);
GPIOC_INT_CLR = 0x02;
timeout_register(&firewire_oneshot, firewire_timeout_event, HZ/5, val);
}
#endif /* USB_STATUS_BY_EVENT */
#endif /* USB_FIREWIRE_HANDLING */

View file

@ -22,12 +22,7 @@
#define USB_TARGET_H #define USB_TARGET_H
void usb_init_device(void); void usb_init_device(void);
void usb_insert_int(void);
#ifndef BOOTLOADER void firewire_insert_int(void);
#if defined(SANSA_C200) || defined(SANSA_E200)
#define USB_STATUS_BY_EVENT /* No USB tick */
void usb_connect_event(bool inserted);
#endif
#endif /* BOOTLOADER */
#endif #endif

View file

@ -416,9 +416,11 @@ static void usb_thread(void)
#ifdef USB_STATUS_BY_EVENT #ifdef USB_STATUS_BY_EVENT
void usb_status_event(int current_status) void usb_status_event(int current_status)
{ {
/* Status should be USB_POWERED, USB_UNPOWERED, USB_INSERTED or /* Caller isn't expected to filter for changes in status.
* USB_EXTRACTED. * current_status:
* Caller isn't expected to filter for changes in status. */ * USB_DETECT_BY_DRV: USB_POWERED, USB_UNPOWERED, USB_INSERTED (driver)
* else: USB_INSERTED, USB_EXTRACTED
*/
if(usb_monitor_enabled) if(usb_monitor_enabled)
{ {
int oldstatus = disable_irq_save(); /* Dual-use function */ int oldstatus = disable_irq_save(); /* Dual-use function */
@ -435,16 +437,30 @@ void usb_status_event(int current_status)
void usb_start_monitoring(void) void usb_start_monitoring(void)
{ {
int oldstatus = disable_irq_save(); /* Sync to event */
int status = usb_detect(); int status = usb_detect();
#ifdef USB_DETECT_BY_DRV
/* USB detection begins by USB_POWERED, not USB_INSERTED. If it is
* USB_EXTRACTED, then nothing changes and post will be skipped. */
if(USB_INSERTED == status)
status = USB_POWERED;
#endif
usb_monitor_enabled = true; usb_monitor_enabled = true;
#ifdef USB_DETECT_BY_DRV
status = (status == USB_INSERTED) ? USB_POWERED : USB_UNPOWERED;
#endif
usb_status_event(status); usb_status_event(status);
#ifdef USB_FIREWIRE_HANDLING
if (firewire_detect())
usb_firewire_connect_event();
#endif
restore_irq(oldstatus);
} }
#ifdef USB_FIREWIRE_HANDLING
void usb_firewire_connect_event(void)
{
queue_post(&usb_queue, USB_REQUEST_REBOOT, 0);
}
#endif /* USB_FIREWIRE_HANDLING */
#else /* !USB_STATUS_BY_EVENT */ #else /* !USB_STATUS_BY_EVENT */
static void usb_tick(void) static void usb_tick(void)
{ {
@ -522,7 +538,11 @@ void usb_init(void)
{ {
/* We assume that the USB cable is extracted */ /* We assume that the USB cable is extracted */
usb_state = USB_EXTRACTED; usb_state = USB_EXTRACTED;
#ifdef USB_DETECT_BY_DRV
last_usb_status = USB_UNPOWERED;
#else
last_usb_status = USB_EXTRACTED; last_usb_status = USB_EXTRACTED;
#endif
usb_monitor_enabled = false; usb_monitor_enabled = false;
#ifdef HAVE_USBSTACK #ifdef HAVE_USBSTACK