From da76a3469437261bd8857c6eddeaafcc601f373e Mon Sep 17 00:00:00 2001 From: Michael Sevakis Date: Thu, 22 Jan 2009 22:05:04 +0000 Subject: 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 --- firmware/target/arm/usb-fw-pp502x.c | 215 +++++++++++++++++++++++------------- 1 file changed, 137 insertions(+), 78 deletions(-) (limited to 'firmware/target/arm/usb-fw-pp502x.c') diff --git a/firmware/target/arm/usb-fw-pp502x.c b/firmware/target/arm/usb-fw-pp502x.c index 8a6d78675f..883ca1e8e2 100644 --- a/firmware/target/arm/usb-fw-pp502x.c +++ b/firmware/target/arm/usb-fw-pp502x.c @@ -33,6 +33,60 @@ #include "usb_core.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) { /* enable usb module */ @@ -52,7 +106,10 @@ void usb_init_device(void) while ((inl(0x70000028) & 0x80) == 0); outl(inl(0x70000028) | 0x2, 0x70000028); udelay(100000); - + + /* Do one-time inits */ + usb_drv_startup(); + /* disable USB-devices until USB is detected via GPIO */ #ifndef BOOTLOADER /* Disabling USB0 in the bootloader makes the OF not load, @@ -63,17 +120,38 @@ void usb_init_device(void) DEV_INIT2 &= ~INIT_USB; #endif -#if defined(IPOD_COLOR) || defined(IPOD_4G) \ - || defined(IPOD_MINI) || defined(IPOD_MINI2G) + /* These set INV_LEV to the inserted level so it will fire if already + * inserted at the time they are enabled. */ +#ifdef USB_STATUS_BY_EVENT + GPIO_CLEAR_BITWISE(USB_GPIO_INT_EN, USB_GPIO_MASK); + GPIO_CLEAR_BITWISE(USB_GPIO_OUTPUT_EN, USB_GPIO_MASK); + 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 USB_FIREWIRE_HANDLING /* GPIO C bit 1 is firewire detect */ - GPIOC_ENABLE |= 0x02; - GPIOC_OUTPUT_EN &= ~0x02; + 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 - -#ifdef HAVE_USBSTACK - /* Do one-time inits */ - usb_drv_startup(); + 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) @@ -96,21 +174,27 @@ void usb_enable(bool on) void usb_attach(void) { -#ifdef USB_DETECT_BY_DRV usb_drv_attach(); -#else - usb_enable(true); -#endif } -#ifdef USB_DETECT_BY_DRV -/* Cannot tell charger pin from USB pin */ +#ifdef USB_STATUS_BY_EVENT +/* Cannot always tell power pin from USB pin */ static int usb_status = USB_EXTRACTED; -void usb_connect_event(bool inserted) +static int usb_timeout_event(struct timeout *tmo) +{ + usb_status_event(tmo->data == USB_GPIO_VAL ? USB_POWERED : USB_UNPOWERED); + return 0; +} + +void usb_insert_int(void) { - usb_status = inserted ? USB_INSERTED : USB_EXTRACTED; - usb_status_event(inserted ? USB_POWERED : USB_UNPOWERED); + 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 */ @@ -118,51 +202,7 @@ void usb_drv_usb_detect_event(void) { usb_status_event(USB_INSERTED); } -#else /* !USB_DETECT_BY_DRV */ -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 */ +#endif /* USB_STATUS_BY_EVENT */ 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) */ int usb_detect(void) { -#ifdef USB_DETECT_BY_DRV +#ifdef USB_STATUS_BY_EVENT return usb_status; #else - if(usb_pin_detect()) { - return USB_INSERTED; - } - else { - return USB_EXTRACTED; - } + return ((USB_GPIO_INPUT_VAL & USB_GPIO_MASK) == USB_GPIO_VAL) ? + USB_INSERTED : USB_EXTRACTED; #endif } -#if defined(IPOD_COLOR) || defined(IPOD_4G) \ - || defined(IPOD_MINI) || defined(IPOD_MINI2G) +#ifdef USB_FIREWIRE_HANDLING +#ifdef USB_STATUS_BY_EVENT +static bool firewire_status = false; +#endif + bool firewire_detect(void) { +#ifdef USB_STATUS_BY_EVENT + return firewire_status; +#else /* GPIO C bit 1 is firewire detect */ - if (!(GPIOC_INPUT_VAL & 0x02)) - /* no charger detection needed for firewire */ - return true; - else - return false; -} + /* no charger detection needed for firewire */ + return (GPIOC_INPUT_VAL & 0x02) == 0x00; #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 */ -- cgit v1.2.3