summaryrefslogtreecommitdiff
path: root/firmware/target/arm
diff options
context:
space:
mode:
authorFrank Gevaerts <frank@gevaerts.be>2008-12-15 23:37:16 +0000
committerFrank Gevaerts <frank@gevaerts.be>2008-12-15 23:37:16 +0000
commit9f37f04619feb93a6a5adb36e7db6d7ace3c227c (patch)
tree0f0cc36d84fac34f2d2399ab12058c8cc32f6b95 /firmware/target/arm
parent1388bd343036c1ad3c15d465ad1aaccfda9d20bf (diff)
downloadrockbox-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.c87
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
87static int sd_init_card(const int drive);
88static 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)];
100static const char sd_thread_name[] = "ata/sd"; 102static const char sd_thread_name[] = "ata/sd";
101static struct mutex sd_mtx SHAREDBSS_ATTR; 103static struct mutex sd_mtx SHAREDBSS_ATTR;
102static struct event_queue sd_queue; 104static struct event_queue sd_queue;
105static bool sd_enabled = false;
103 106
104static inline void mci_delay(void) { int i = 0xffff; while(i--) ; } 107static 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
156static 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}
171void 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
151void INT_NAND(void) 181void 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
690void sd_enable(bool on) 739void 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)
742bool card_detect_target(void) 793bool 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