diff options
author | Frank Gevaerts <frank@gevaerts.be> | 2008-12-15 23:37:16 +0000 |
---|---|---|
committer | Frank Gevaerts <frank@gevaerts.be> | 2008-12-15 23:37:16 +0000 |
commit | 9f37f04619feb93a6a5adb36e7db6d7ace3c227c (patch) | |
tree | 0f0cc36d84fac34f2d2399ab12058c8cc32f6b95 /firmware/target/arm | |
parent | 1388bd343036c1ad3c15d465ad1aaccfda9d20bf (diff) | |
download | rockbox-9f37f04619feb93a6a5adb36e7db6d7ace3c227c.tar.gz rockbox-9f37f04619feb93a6a5adb36e7db6d7ace3c227c.zip |
Apply FS#9650 (by Thomas Martitz). This adds hotswap and microSD support for the Fuze. It doesn't seem to work for all cards yet.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19447 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm')
-rw-r--r-- | firmware/target/arm/as3525/ata_sd_as3525.c | 87 |
1 files changed, 73 insertions, 14 deletions
diff --git a/firmware/target/arm/as3525/ata_sd_as3525.c b/firmware/target/arm/as3525/ata_sd_as3525.c index edde02b593..4eb6ce8f1d 100644 --- a/firmware/target/arm/as3525/ata_sd_as3525.c +++ b/firmware/target/arm/as3525/ata_sd_as3525.c | |||
@@ -84,6 +84,8 @@ static const int pl180_base[NUM_VOLUMES] = { | |||
84 | #endif | 84 | #endif |
85 | }; | 85 | }; |
86 | 86 | ||
87 | static int sd_init_card(const int drive); | ||
88 | static void init_pl180_controller(const int drive); | ||
87 | /* TODO : BLOCK_SIZE != SECTOR_SIZE ? */ | 89 | /* TODO : BLOCK_SIZE != SECTOR_SIZE ? */ |
88 | #define BLOCK_SIZE 512 | 90 | #define BLOCK_SIZE 512 |
89 | #define SECTOR_SIZE 512 | 91 | #define SECTOR_SIZE 512 |
@@ -100,6 +102,7 @@ static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x200)/sizeof(long)]; | |||
100 | static const char sd_thread_name[] = "ata/sd"; | 102 | static const char sd_thread_name[] = "ata/sd"; |
101 | static struct mutex sd_mtx SHAREDBSS_ATTR; | 103 | static struct mutex sd_mtx SHAREDBSS_ATTR; |
102 | static struct event_queue sd_queue; | 104 | static struct event_queue sd_queue; |
105 | static bool sd_enabled = false; | ||
103 | 106 | ||
104 | static inline void mci_delay(void) { int i = 0xffff; while(i--) ; } | 107 | static inline void mci_delay(void) { int i = 0xffff; while(i--) ; } |
105 | 108 | ||
@@ -148,6 +151,33 @@ static void sd_panic(IF_MV2(const int drive,) const int status) | |||
148 | (status & MCI_TX_FIFO_EMPTY) ? "TX FIFO EMPTY" : ""); | 151 | (status & MCI_TX_FIFO_EMPTY) ? "TX FIFO EMPTY" : ""); |
149 | } | 152 | } |
150 | 153 | ||
154 | #ifdef HAVE_HOTSWAP | ||
155 | #ifdef SANSA_FUZE | ||
156 | static bool sd1_oneshot_callback(struct timeout *tmo) | ||
157 | { | ||
158 | (void)tmo; | ||
159 | |||
160 | /* This is called only if the state was stable for 300ms - check state | ||
161 | * and post appropriate event. */ | ||
162 | if (card_detect_target()) | ||
163 | { | ||
164 | queue_broadcast(SYS_HOTSWAP_INSERTED, 0); | ||
165 | } | ||
166 | else | ||
167 | queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0); | ||
168 | |||
169 | return false; | ||
170 | } | ||
171 | void INT_GPIOA(void) | ||
172 | { | ||
173 | static struct timeout sd1_oneshot; | ||
174 | /* reset irq */ | ||
175 | GPIOA_IC = (1<<2); | ||
176 | timeout_register(&sd1_oneshot, sd1_oneshot_callback, (3*HZ/10), 0); | ||
177 | } | ||
178 | #endif | ||
179 | #endif | ||
180 | |||
151 | void INT_NAND(void) | 181 | void INT_NAND(void) |
152 | { | 182 | { |
153 | sd_panic(IF_MV2(INTERNAL_AS3525,) MCI_STATUS(INTERNAL_AS3525)); | 183 | sd_panic(IF_MV2(INTERNAL_AS3525,) MCI_STATUS(INTERNAL_AS3525)); |
@@ -348,7 +378,13 @@ static void sd_thread(void) | |||
348 | card_info[1].initialized = 0; | 378 | card_info[1].initialized = 0; |
349 | 379 | ||
350 | if (ev.id == SYS_HOTSWAP_INSERTED) | 380 | if (ev.id == SYS_HOTSWAP_INSERTED) |
381 | { | ||
351 | disk_mount(1); | 382 | disk_mount(1); |
383 | } | ||
384 | else | ||
385 | { | ||
386 | init_pl180_controller(SD_SLOT_AS3525); | ||
387 | } | ||
352 | 388 | ||
353 | queue_broadcast(SYS_FS_CHANGED, 0); | 389 | queue_broadcast(SYS_FS_CHANGED, 0); |
354 | 390 | ||
@@ -399,6 +435,18 @@ static void init_pl180_controller(const int drive) | |||
399 | #ifdef HAVE_MULTIVOLUME | 435 | #ifdef HAVE_MULTIVOLUME |
400 | VIC_INT_ENABLE |= | 436 | VIC_INT_ENABLE |= |
401 | (drive == INTERNAL_AS3525) ? INTERRUPT_NAND : INTERRUPT_MCI0; | 437 | (drive == INTERNAL_AS3525) ? INTERRUPT_NAND : INTERRUPT_MCI0; |
438 | |||
439 | #ifdef SANSA_FUZE | ||
440 | /* setup isr for microsd monitoring */ | ||
441 | VIC_INT_ENABLE |= (INTERRUPT_GPIOA); | ||
442 | /* clear previous irq */ | ||
443 | GPIOA_IC |= (1<<2); | ||
444 | /* enable edge detecting */ | ||
445 | GPIOA_IS &= ~(1<<2); | ||
446 | /* detect both raising and falling edges */ | ||
447 | GPIOA_IBE |= (1<<2); | ||
448 | #endif | ||
449 | |||
402 | #else | 450 | #else |
403 | VIC_INT_ENABLE |= INTERRUPT_NAND; | 451 | VIC_INT_ENABLE |= INTERRUPT_NAND; |
404 | #endif | 452 | #endif |
@@ -496,7 +544,6 @@ static int sd_wait_for_state(const int drive, unsigned int state) | |||
496 | { | 544 | { |
497 | unsigned int response = 0; | 545 | unsigned int response = 0; |
498 | unsigned int timeout = 100; /* ticks */ | 546 | unsigned int timeout = 100; /* ticks */ |
499 | |||
500 | long t = current_tick; | 547 | long t = current_tick; |
501 | 548 | ||
502 | while (1) | 549 | while (1) |
@@ -528,7 +575,7 @@ static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start, | |||
528 | #ifndef HAVE_MULTIVOLUME | 575 | #ifndef HAVE_MULTIVOLUME |
529 | const int drive = 0; | 576 | const int drive = 0; |
530 | #endif | 577 | #endif |
531 | int ret; | 578 | int ret = 0; |
532 | 579 | ||
533 | /* skip SanDisk OF */ | 580 | /* skip SanDisk OF */ |
534 | if (drive == INTERNAL_AS3525) | 581 | if (drive == INTERNAL_AS3525) |
@@ -552,19 +599,21 @@ static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start, | |||
552 | } | 599 | } |
553 | #endif | 600 | #endif |
554 | 601 | ||
555 | if (card_info[drive].initialized < 0) | 602 | if (card_info[drive].initialized <= 0) |
556 | { | 603 | { |
557 | ret = card_info[drive].initialized; | 604 | sd_init_card(drive); |
558 | panicf("card not initialised"); | 605 | if (!(card_info[drive].initialized)) |
559 | goto sd_transfer_error; | 606 | { |
607 | panicf("card not initialised"); | ||
608 | goto sd_transfer_error; | ||
609 | } | ||
560 | } | 610 | } |
561 | 611 | ||
562 | last_disk_activity = current_tick; | 612 | last_disk_activity = current_tick; |
563 | |||
564 | ret = sd_wait_for_state(drive, SD_TRAN); | 613 | ret = sd_wait_for_state(drive, SD_TRAN); |
565 | if (ret < 0) | 614 | if (ret < 0) |
566 | { | 615 | { |
567 | panicf("wait for state failed"); | 616 | panicf("wait for state failed on drive %d", drive); |
568 | goto sd_transfer_error; | 617 | goto sd_transfer_error; |
569 | } | 618 | } |
570 | 619 | ||
@@ -689,6 +738,8 @@ long sd_last_disk_activity(void) | |||
689 | 738 | ||
690 | void sd_enable(bool on) | 739 | void sd_enable(bool on) |
691 | { | 740 | { |
741 | if (sd_enabled == on) | ||
742 | return; /* nothing to do */ | ||
692 | if(on) | 743 | if(on) |
693 | { | 744 | { |
694 | CGU_PERI |= CGU_NAF_CLOCK_ENABLE; | 745 | CGU_PERI |= CGU_NAF_CLOCK_ENABLE; |
@@ -742,11 +793,12 @@ tCardInfo *card_get_info_target(int card_no) | |||
742 | bool card_detect_target(void) | 793 | bool card_detect_target(void) |
743 | { | 794 | { |
744 | #ifdef HAVE_HOTSWAP | 795 | #ifdef HAVE_HOTSWAP |
745 | /* TODO */ | 796 | /* TODO: add e200/c200 */ |
746 | return false; | 797 | #if defined(SANSA_FUZE) |
747 | #else | 798 | return !(GPIOA_PIN(2)); |
748 | return false; | ||
749 | #endif | 799 | #endif |
800 | #endif | ||
801 | return false; | ||
750 | } | 802 | } |
751 | 803 | ||
752 | #ifdef HAVE_HOTSWAP | 804 | #ifdef HAVE_HOTSWAP |
@@ -754,11 +806,18 @@ void card_enable_monitoring_target(bool on) | |||
754 | { | 806 | { |
755 | if (on) | 807 | if (on) |
756 | { | 808 | { |
757 | /* TODO */ | 809 | /* add e200v2/c200v2 here */ |
810 | #ifdef SANSA_FUZE | ||
811 | /* enable isr*/ | ||
812 | GPIOA_IE |= (1<<2); | ||
813 | #endif | ||
758 | } | 814 | } |
759 | else | 815 | else |
760 | { | 816 | { |
761 | /* TODO */ | 817 | #ifdef SANSA_FUZE |
818 | /* edisable isr*/ | ||
819 | GPIOA_IE &= ~(1<<2); | ||
820 | #endif | ||
762 | } | 821 | } |
763 | } | 822 | } |
764 | #endif | 823 | #endif |