diff options
author | Jens Arnold <amiconn@rockbox.org> | 2004-10-10 19:51:11 +0000 |
---|---|---|
committer | Jens Arnold <amiconn@rockbox.org> | 2004-10-10 19:51:11 +0000 |
commit | 5789ee99286a487e1764bd9b52562e1a79b5d4e7 (patch) | |
tree | e4a9eb64f5b8f58def41faa2e123e553b2bdf5d8 | |
parent | 120d863c68a6c4489357f1ae11db3e96a0124ded (diff) |
MMC hotswap handling in USB mode
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@5247 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | firmware/drivers/ata_mmc.c | 11 | ||||
-rw-r--r-- | firmware/export/ata_mmc.h | 2 | ||||
-rw-r--r-- | firmware/usb.c | 37 |
3 files changed, 46 insertions, 4 deletions
diff --git a/firmware/drivers/ata_mmc.c b/firmware/drivers/ata_mmc.c index 7b3b8d1ea8..faa4c1f187 100644 --- a/firmware/drivers/ata_mmc.c +++ b/firmware/drivers/ata_mmc.c @@ -135,18 +135,21 @@ static void swapcopy_sector(const unsigned char *buf); static int send_sector(const unsigned char *nextbuf, int timeout); static int send_single_sector(const unsigned char *buf, int timeout); -static bool mmc_detect(void); static void mmc_tick(void); /* implementation */ -static int select_card(int card_no) +void mmc_select_clock(int card_no) { if (card_no == 0) /* internal */ or_b(0x10, &PADRH); /* set clock gate PA12 CHECKME: mask? */ else /* external */ and_b(~0x10, &PADRH); /* clear clock gate PA12 CHECKME: mask?*/ - +} + +static int select_card(int card_no) +{ + mmc_select_clock(card_no); last_disk_activity = current_tick; if (!card_info[card_no].initialized) @@ -760,7 +763,7 @@ void ata_spin(void) { } -static bool mmc_detect(void) +bool mmc_detect(void) { return adc_read(ADC_MMC_SWITCH) < 0x200 ? true : false; } diff --git a/firmware/export/ata_mmc.h b/firmware/export/ata_mmc.h index afc0dc24af..3e88b0e019 100644 --- a/firmware/export/ata_mmc.h +++ b/firmware/export/ata_mmc.h @@ -35,6 +35,8 @@ typedef struct unsigned int r2w_factor; } tCardInfo; +void mmc_select_clock(int card_no); +bool mmc_detect(void); unsigned long mmc_extract_bits(const unsigned long *p, unsigned int start, unsigned int size); tCardInfo *mmc_card_info(int card_no); diff --git a/firmware/usb.c b/firmware/usb.c index 8f3169e5df..65069c486a 100644 --- a/firmware/usb.c +++ b/firmware/usb.c @@ -32,6 +32,9 @@ #include "button.h" #include "sprintf.h" #include "hwcompat.h" +#ifdef HAVE_MMC +#include "ata_mmc.h" +#endif extern void dbg_ports(void); /* NASTY! defined in apps/ */ @@ -47,6 +50,9 @@ void screen_dump(void); /* Nasty again. Defined in apps/ too */ /* Messages from usb_tick */ #define USB_INSERTED 1 #define USB_EXTRACTED 2 +#ifdef HAVE_MMC +#define USB_REENABLE 3 +#endif /* Thread states */ #define EXTRACTING 1 @@ -62,6 +68,10 @@ static int countdown; static int usb_state; +#ifdef HAVE_MMC +static int usb_mmc_countdown = 0; +#endif + /* FIXME: The extra 0x400 is consumed by fat_mount() when the fsinfo needs updating */ static char usb_stack[DEFAULT_STACK_SIZE + 0x400]; @@ -75,6 +85,9 @@ static void usb_enable(bool on) #ifdef USB_ENABLE_ONDIOSTYLE if(on) { +#ifdef HAVE_MMC + mmc_select_clock(mmc_detect() ? 1 : 0); +#endif or_b(0x20, &PADRL); /* enable USB */ and_b(~0x08, &PADRL); /* assert card detect */ } @@ -255,6 +268,22 @@ static void usb_thread(void) } } break; + +#ifdef HAVE_MMC + case SYS_MMC_INSERTED: + case SYS_MMC_EXTRACTED: + if(usb_state == USB_INSERTED) + { + usb_enable(false); + usb_mmc_countdown = HZ/2; /* re-enable after 0.5 sec */ + } + break; + + case USB_REENABLE: + if(usb_state == USB_INSERTED) + usb_enable(true); /* reenable only if still inserted */ + break; +#endif } } } @@ -308,6 +337,14 @@ static void usb_tick(void) } } } +#ifdef HAVE_MMC + if(usb_mmc_countdown > 0) + { + usb_mmc_countdown--; + if (usb_mmc_countdown == 0) + queue_post(&usb_queue, USB_REENABLE, NULL); + } +#endif } void usb_acknowledge(int id) |