1
0
Fork 0
forked from len0rd/rockbox

Re-added USB charger detection and auto reboot on host connect.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15774 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Björn Stenberg 2007-11-23 15:02:26 +00:00
parent f7f7967943
commit 20dbc1b21f
3 changed files with 114 additions and 17 deletions

View file

@ -50,6 +50,7 @@ void usb_core_exit(void);
void usb_core_control_request(struct usb_ctrlrequest* req); void usb_core_control_request(struct usb_ctrlrequest* req);
void usb_core_transfer_complete(int endpoint, bool in); void usb_core_transfer_complete(int endpoint, bool in);
void usb_core_bus_reset(void); void usb_core_bus_reset(void);
bool usb_core_data_connection(void);
#endif #endif

View file

@ -56,34 +56,118 @@ void usb_init_device(void)
void usb_enable(bool on) void usb_enable(bool on)
{ {
if (on) if (on) {
usb_core_init(); /* until we have native mass-storage mode, we want to reboot on
usb host connect */
#if defined(IRIVER_H10) || defined (IRIVER_H10_5GB)
if (button_status()==BUTTON_RIGHT)
#endif /* defined(IRIVER_H10) || defined (IRIVER_H10_5GB) */
{
#ifndef HAVE_FLASH_STORAGE
ata_sleepnow(); /* Immediately spindown the disk. */
sleep(HZ*2);
#endif
#ifdef IPOD_ARCH /* The following code is based on ipodlinux */
#if CONFIG_CPU == PP5020
memcpy((void *)0x40017f00, "diskmode\0\0hotstuff\0\0\1", 21);
#elif CONFIG_CPU == PP5022
memcpy((void *)0x4001ff00, "diskmode\0\0hotstuff\0\0\1", 21);
#endif /* CONFIG_CPU */
#endif /* IPOD_ARCH */
system_reboot(); /* Reboot */
}
}
else else
usb_core_exit(); usb_core_exit();
} }
bool usb_pin_detect(void)
{
#if defined(IPOD_ARCH)
/* GPIO L bit 4 is usb detect */
if (GPIOL_INPUT_VAL & 0x10)
return true;
#elif defined(SANSA_C200)
/* GPIO H bit 1 is usb detect */
if (GPIOH_INPUT_VAL & 0x02)
return true;
#elif defined(SANSA_E200)
/* GPIO B bit 4 is usb detect */
if (GPIOB_INPUT_VAL & 0x10)
return true;
#elif defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
/* GPIO L bit 2 is usb detect */
if (GPIOL_INPUT_VAL & 0x4)
return true;
#endif
return false;
}
/* detect host or charger (INSERTED or POWERED) */
int usb_detect(void) int usb_detect(void)
{ {
static int countdown = 0;
static int status = USB_EXTRACTED;
static bool prev_usbstatus1 = false;
bool usbstatus1, usbstatus2;
#if defined(IPOD_COLOR) || defined(IPOD_4G) \ #if defined(IPOD_COLOR) || defined(IPOD_4G) \
|| defined(IPOD_MINI) || defined(IPOD_MINI2G) || defined(IPOD_MINI) || defined(IPOD_MINI2G)
/* GPIO C bit 1 is firewire detect */ /* GPIO C bit 1 is firewire detect */
if (!(GPIOC_INPUT_VAL & 0x02)) if (!(GPIOC_INPUT_VAL & 0x02))
return USB_INSERTED; /* no charger detection needed for firewire */
#elif defined(SANSA_C200)
/* GPIO H bit 1 is usb detect */
if (GPIOH_INPUT_VAL & 0x02)
return USB_INSERTED;
#elif defined(SANSA_E200)
/* GPIO B bit 4 is usb detect */
if (GPIOB_INPUT_VAL & 0x10)
return USB_INSERTED;
#elif defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
/* GPIO L bit 2 is usb detect */
if (GPIOL_INPUT_VAL & 0x4)
return USB_INSERTED; return USB_INSERTED;
#endif #endif
if (usb_drv_powered())
return USB_INSERTED;
return USB_EXTRACTED; if (countdown > 0)
{
countdown--;
usbstatus2 = usb_core_data_connection();
if ((countdown == 0) || usbstatus2)
{
/* We now know that we have been connected to either a charger
or a computer */
countdown = 0;
status = usbstatus2 ? USB_INSERTED : USB_POWERED;
}
return status;
}
usbstatus1 = usb_pin_detect();
if (usbstatus1 == prev_usbstatus1)
{
/* Nothing has changed, so just return previous status */
return status;
}
prev_usbstatus1 = usbstatus1;
if (!usbstatus1)
{ /* We have just been disconnected */
status = USB_EXTRACTED;
return status;
}
/* Run the USB stack to request full bus power */
usb_core_init();
if((button_status() & ~USBPOWER_BTN_IGNORE) == USBPOWER_BUTTON)
{
/* The user wants to charge, so it doesn't matter what we are
connected to. */
status = USB_POWERED;
return status;
}
/* Wait up to 50 ticks (500ms) before deciding there is no computer
attached. */
countdown = 50;
return status;
} }

View file

@ -292,6 +292,7 @@ static const struct {
static int usb_address = 0; static int usb_address = 0;
static bool initialized = false; static bool initialized = false;
static bool data_connection = false;
static struct event_queue usbcore_queue; static struct event_queue usbcore_queue;
#ifdef USB_STORAGE #ifdef USB_STORAGE
@ -305,6 +306,9 @@ static void ack_control(struct usb_ctrlrequest* req);
void usb_core_init(void) void usb_core_init(void)
{ {
if (initialized)
return;
queue_init(&usbcore_queue, false); queue_init(&usbcore_queue, false);
usb_drv_init(); usb_drv_init();
#ifdef USB_STORAGE #ifdef USB_STORAGE
@ -331,10 +335,16 @@ void usb_core_exit(void)
#ifdef USB_STORAGE #ifdef USB_STORAGE
remove_thread(usbcore_thread); remove_thread(usbcore_thread);
#endif #endif
data_connection = false;
} }
logf("usb_core_exit() finished"); logf("usb_core_exit() finished");
} }
bool usb_core_data_connection(void)
{
return data_connection;
}
#ifdef USB_STORAGE #ifdef USB_STORAGE
void usb_core_thread(void) void usb_core_thread(void)
{ {
@ -352,6 +362,7 @@ void usb_core_thread(void)
void usb_core_control_request(struct usb_ctrlrequest* req) void usb_core_control_request(struct usb_ctrlrequest* req)
{ {
/* note: interrupt context */ /* note: interrupt context */
data_connection = true;
#ifdef USB_BENCHMARK #ifdef USB_BENCHMARK
if ((req->bRequestType & 0x60) == USB_TYPE_VENDOR) { if ((req->bRequestType & 0x60) == USB_TYPE_VENDOR) {
@ -499,6 +510,7 @@ void usb_core_control_request(struct usb_ctrlrequest* req)
void usb_core_bus_reset(void) void usb_core_bus_reset(void)
{ {
usb_address = 0; usb_address = 0;
data_connection = false;
} }
/* called by usb_drv_transfer_completed() */ /* called by usb_drv_transfer_completed() */