diff --git a/firmware/export/config.h b/firmware/export/config.h index 95f38c5995..f5ee003308 100644 --- a/firmware/export/config.h +++ b/firmware/export/config.h @@ -733,6 +733,12 @@ Lyre prototype 1 */ #endif /* BOOTLOADER */ +#ifdef PHILIPS_SA9200 +/* Instead use the request for a device descriptor to detect a host */ +#undef USB_DETECT_BY_DRV +#define USB_DETECT_BY_CORE +#endif + #if defined(HAVE_USBSTACK) || (CONFIG_CPU == JZ4732) \ || (CONFIG_CPU == AS3525) || (CONFIG_CPU == AS3525v2) \ || defined(CPU_S5L870X) || (CONFIG_CPU == S3C2440) \ diff --git a/firmware/export/usb.h b/firmware/export/usb.h index e192748e4d..aceecb55ae 100644 --- a/firmware/export/usb.h +++ b/firmware/export/usb.h @@ -33,10 +33,11 @@ enum { USB_EXTRACTED = 0, /* Event+State */ USB_INSERTED, /* Event+State */ -#if defined(HAVE_USB_POWER) || defined(USB_DETECT_BY_DRV) +#if defined(HAVE_USB_POWER) || defined(USB_DETECT_BY_DRV) || \ + defined(USB_DETECT_BY_CORE) USB_POWERED, /* Event+State */ #endif -#ifdef USB_DETECT_BY_DRV +#if defined(USB_DETECT_BY_DRV) || defined(USB_DETECT_BY_CORE) USB_UNPOWERED, /* Event */ #endif #ifdef HAVE_LCD_BITMAP diff --git a/firmware/target/arm/system-pp502x.c b/firmware/target/arm/system-pp502x.c index bd71d28417..0422ea7d9c 100644 --- a/firmware/target/arm/system-pp502x.c +++ b/firmware/target/arm/system-pp502x.c @@ -141,9 +141,7 @@ void __attribute__((interrupt("IRQ"))) irq_handler(void) else if (CPU_HI_INT_STAT & GPIO0_MASK) { if (GPIOD_INT_STAT & 0x02) button_int(); - } - else if (CPU_HI_INT_STAT & GPIO1_MASK) { - if (GPIOF_INT_STAT & 0x80) + if (GPIOB_INT_STAT & 0x40) usb_insert_int(); } /* end PHILIPS_SA9200 */ diff --git a/firmware/target/arm/usb-drv-arc.c b/firmware/target/arm/usb-drv-arc.c index 86a1637bc8..fc74ce5bf0 100644 --- a/firmware/target/arm/usb-drv-arc.c +++ b/firmware/target/arm/usb-drv-arc.c @@ -498,15 +498,23 @@ static void log_ep(int ep_num, int ep_dir, char* prefix) void usb_drv_init(void) { +#ifdef USB_DETECT_BY_CORE + /* USB core decides */ + _usb_drv_init(true); +#else + /* Use bus reset condition */ _usb_drv_init(false); +#endif } /* fully enable driver */ void usb_drv_attach(void) { logf("usb_drv_attach"); +#ifndef USB_DETECT_BY_CORE sleep(HZ/10); _usb_drv_init(true); +#endif } void usb_drv_exit(void) diff --git a/firmware/target/arm/usb-fw-pp502x.c b/firmware/target/arm/usb-fw-pp502x.c index 8f754fd04b..536535e059 100644 --- a/firmware/target/arm/usb-fw-pp502x.c +++ b/firmware/target/arm/usb-fw-pp502x.c @@ -65,10 +65,10 @@ #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 + /* GPIO B bit 6 (high) is usb bus power detect */ +#define USB_GPIO GPIOB +#define USB_GPIO_MASK 0x40 +#define USB_GPIO_VAL 0x40 #elif defined(PHILIPS_HDD1630) || defined(PHILIPS_HDD6330) /* GPIO E bit 2 is usb detect */ @@ -225,10 +225,12 @@ void usb_insert_int(void) timeout_register(&usb_oneshot, usb_timeout_event, HZ/5, val); } -/* Called during the bus reset interrupt when in detect mode - filter for - * invalid bus reset when unplugging by checking the pin state. */ +/* USB_DETECT_BY_DRV: Called during the bus reset interrupt when in detect mode + * USB_DETECT_BY_CORE: Called when device descriptor is requested + */ void usb_drv_usb_detect_event(void) { + /* Filter for invalid bus reset when unplugging by checking the pin state. */ if(usb_plugged()) { usb_status_event(USB_INSERTED); } diff --git a/firmware/usb.c b/firmware/usb.c index c8f0118730..ca0e86b478 100644 --- a/firmware/usb.c +++ b/firmware/usb.c @@ -136,7 +136,7 @@ static inline void usb_slave_mode(bool on) } else /* usb_state == USB_INSERTED (only!) */ { -#ifndef USB_DETECT_BY_DRV +#if !defined(USB_DETECT_BY_DRV) && !defined(USB_DETECT_BY_CORE) usb_enable(false); #endif #ifdef HAVE_PRIORITY_SCHEDULING @@ -244,7 +244,7 @@ static void usb_thread(void) (struct usb_transfer_completion_event_data*)ev.data); break; #endif -#ifdef USB_DETECT_BY_DRV +#if defined(USB_DETECT_BY_DRV) || defined(USB_DETECT_BY_CORE) /* In this case, these events the handle cable insertion USB * driver determines INSERTED/EXTRACTED state. */ case USB_POWERED: @@ -263,7 +263,7 @@ static void usb_thread(void) * available. */ queue_post(&usb_queue, USB_EXTRACTED, 0); break; -#endif /* USB_DETECT_BY_DRV */ +#endif /* USB_DETECT_BY_DRV || USB_DETECT_BY_CORE */ case USB_INSERTED: #ifdef HAVE_LCD_BITMAP if(do_screendump_instead_of_usb) @@ -379,7 +379,8 @@ static void usb_thread(void) #ifdef HAVE_USBSTACK if(!exclusive_storage_access) { -#ifndef USB_DETECT_BY_DRV /* Disabled handling USB_UNPOWERED */ +#if !defined(USB_DETECT_BY_DRV) && !defined(USB_DETECT_BY_CORE) + /* Disabled handling USB_UNPOWERED */ usb_enable(false); #endif break; @@ -457,7 +458,8 @@ void usb_status_event(int current_status) { /* Caller isn't expected to filter for changes in status. * current_status: - * USB_DETECT_BY_DRV: USB_POWERED, USB_UNPOWERED, USB_INSERTED (driver) + * USB_DETECT_BY_DRV/CORE: USB_POWERED, USB_UNPOWERED, + USB_INSERTED (driver/core) * else: USB_INSERTED, USB_EXTRACTED */ if(usb_monitor_enabled) @@ -481,7 +483,10 @@ void usb_start_monitoring(void) usb_monitor_enabled = true; -#ifdef USB_DETECT_BY_DRV +#ifdef USB_STATUS_BY_EVENT + /* Filter the status - an event may have been missed because it was + * sent before monitoring was enabled due to the connector already + * having been inserted before before or during boot. */ status = (status == USB_INSERTED) ? USB_POWERED : USB_UNPOWERED; #endif usb_status_event(status); @@ -577,7 +582,7 @@ void usb_init(void) { /* We assume that the USB cable is extracted */ usb_state = USB_EXTRACTED; -#ifdef USB_DETECT_BY_DRV +#if defined(USB_DETECT_BY_DRV) || defined(USB_DETECT_BY_CORE) last_usb_status = USB_UNPOWERED; #else last_usb_status = USB_EXTRACTED; diff --git a/firmware/usbstack/usb_core.c b/firmware/usbstack/usb_core.c index 2ff3f325a2..aa96fff17f 100644 --- a/firmware/usbstack/usb_core.c +++ b/firmware/usbstack/usb_core.c @@ -559,6 +559,11 @@ static void request_handler_device_get_descriptor(struct usb_ctrlrequest* req) case USB_DT_DEVICE: ptr = &device_descriptor; size = sizeof(struct usb_device_descriptor); +#ifdef USB_DETECT_BY_CORE + /* Something requested a device descriptor; consider this a legit + connection */ + usb_drv_usb_detect_event(); +#endif break; case USB_DT_OTHER_SPEED_CONFIG: