summaryrefslogtreecommitdiff
path: root/firmware/target/arm/as3525
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/as3525')
-rw-r--r--firmware/target/arm/as3525/sd-as3525.c276
-rw-r--r--firmware/target/arm/as3525/sd-as3525v2.c188
2 files changed, 182 insertions, 282 deletions
diff --git a/firmware/target/arm/as3525/sd-as3525.c b/firmware/target/arm/as3525/sd-as3525.c
index e65a7525b6..d6c6654319 100644
--- a/firmware/target/arm/as3525/sd-as3525.c
+++ b/firmware/target/arm/as3525/sd-as3525.c
@@ -24,7 +24,6 @@
24 24
25#include "config.h" /* for HAVE_MULTIDRIVE & AMS_OF_SIZE */ 25#include "config.h" /* for HAVE_MULTIDRIVE & AMS_OF_SIZE */
26#include "fs_defines.h" 26#include "fs_defines.h"
27#include "thread.h"
28#include "led.h" 27#include "led.h"
29#include "sdmmc.h" 28#include "sdmmc.h"
30#include "system.h" 29#include "system.h"
@@ -39,20 +38,15 @@
39#include "dma-target.h" /* DMA request lines */ 38#include "dma-target.h" /* DMA request lines */
40#include "clock-target.h" 39#include "clock-target.h"
41#include "panic.h" 40#include "panic.h"
41#include "storage.h"
42
42#ifdef HAVE_BUTTON_LIGHT 43#ifdef HAVE_BUTTON_LIGHT
43#include "backlight-target.h" 44#include "backlight-target.h"
44#endif 45#endif
45#include "stdbool.h" 46
46#include "ata_idle_notify.h"
47#include "sd.h"
48#include "usb.h"
49/*#define LOGF_ENABLE*/ 47/*#define LOGF_ENABLE*/
50#include "logf.h" 48#include "logf.h"
51 49
52#ifdef HAVE_HOTSWAP
53#include "disk.h"
54#endif
55
56//#define VERIFY_WRITE 1 50//#define VERIFY_WRITE 1
57 51
58/* command flags */ 52/* command flags */
@@ -119,16 +113,19 @@ static tCardInfo card_info[NUM_DRIVES];
119#define SD_MAX_READ_TIMEOUT ((AS3525_PCLK_FREQ) / 1000 * 100) /* 100 ms */ 113#define SD_MAX_READ_TIMEOUT ((AS3525_PCLK_FREQ) / 1000 * 100) /* 100 ms */
120#define SD_MAX_WRITE_TIMEOUT ((AS3525_PCLK_FREQ) / 1000 * 250) /* 250 ms */ 114#define SD_MAX_WRITE_TIMEOUT ((AS3525_PCLK_FREQ) / 1000 * 250) /* 250 ms */
121 115
116#ifdef CONFIG_STORAGE_MULTI
117static int sd_first_drive = 0;
118#else
119#define sd_first_drive 0
120#endif
121
122/* for compatibility */ 122/* for compatibility */
123static long last_disk_activity = -1; 123static long last_disk_activity = -1;
124 124
125#define MIN_YIELD_PERIOD 5 /* ticks */ 125#define MIN_YIELD_PERIOD 5 /* ticks */
126static long next_yield = 0; 126static long next_yield = 0;
127 127
128static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x200)/sizeof(long)]; 128static struct mutex sd_mtx;
129static const char sd_thread_name[] = "ata/sd";
130static struct mutex sd_mtx;
131static struct event_queue sd_queue;
132bool sd_enabled = false; 129bool sd_enabled = false;
133 130
134#if defined(HAVE_MULTIDRIVE) 131#if defined(HAVE_MULTIDRIVE)
@@ -147,6 +144,59 @@ static unsigned char *uncached_buffer = AS3525_UNCACHED_ADDR(&aligned_buffer[0])
147 144
148static inline void mci_delay(void) { udelay(1000) ; } 145static inline void mci_delay(void) { udelay(1000) ; }
149 146
147static void enable_controller(bool on)
148{
149
150#if defined(HAVE_BUTTON_LIGHT) && defined(HAVE_MULTIDRIVE)
151 extern int buttonlight_is_on;
152#endif
153
154#if defined(HAVE_HOTSWAP) && defined (HAVE_ADJUSTABLE_CPU_VOLTAGE)
155 static bool cpu_boosted = false;
156#endif
157
158 if (sd_enabled == on)
159 return; /* nothing to do */
160
161 sd_enabled = on;
162
163 if(on)
164 {
165#if defined(HAVE_BUTTON_LIGHT) && defined(HAVE_MULTIDRIVE)
166 /* buttonlight AMSes need a bit of special handling for the buttonlight
167 * here due to the dual mapping of GPIOD and XPD */
168 bitmod32(&CCU_IO, 1<<2, 3<<2); /* XPD is SD-MCI interface (b3:2 = 01) */
169 if (buttonlight_is_on)
170 GPIOD_DIR &= ~(1<<7);
171 else
172 buttonlight_hw_off();
173#endif
174
175#if defined(HAVE_HOTSWAP) && defined (HAVE_ADJUSTABLE_CPU_VOLTAGE)
176 if(card_detect_target()) /* If SD card present Boost cpu for voltage */
177 {
178 cpu_boosted = true;
179 cpu_boost(true);
180 }
181#endif /* defined(HAVE_HOTSWAP) && defined (HAVE_ADJUSTABLE_CPU_VOLTAGE) */
182 }
183 else
184 {
185#if defined(HAVE_HOTSWAP) && defined (HAVE_ADJUSTABLE_CPU_VOLTAGE)
186 if(cpu_boosted)
187 {
188 cpu_boost(false);
189 cpu_boosted = false;
190 }
191#endif /* defined(HAVE_HOTSWAP) && defined (HAVE_ADJUSTABLE_CPU_VOLTAGE) */
192
193#if defined(HAVE_BUTTON_LIGHT) && defined(HAVE_MULTIDRIVE)
194 bitmod32(&CCU_IO, 0<<2, 3<<2); /* XPD is general purpose IO (b3:2 = 00) */
195 if (buttonlight_is_on)
196 buttonlight_hw_on();
197#endif
198 }
199}
150 200
151static inline bool card_detect_target(void) 201static inline bool card_detect_target(void)
152{ 202{
@@ -161,18 +211,13 @@ static inline bool card_detect_target(void)
161#ifdef HAVE_HOTSWAP 211#ifdef HAVE_HOTSWAP
162static int sd1_oneshot_callback(struct timeout *tmo) 212static int sd1_oneshot_callback(struct timeout *tmo)
163{ 213{
164 (void)tmo;
165
166 /* This is called only if the state was stable for 300ms - check state 214 /* This is called only if the state was stable for 300ms - check state
167 * and post appropriate event. */ 215 * and post appropriate event. */
168 if (card_detect_target()) 216 queue_broadcast(card_detect_target() ? SYS_HOTSWAP_INSERTED :
169 { 217 SYS_HOTSWAP_EXTRACTED,
170 queue_broadcast(SYS_HOTSWAP_INSERTED, 0); 218 sd_first_drive + SD_SLOT_AS3525);
171 }
172 else
173 queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0);
174
175 return 0; 219 return 0;
220 (void)tmo;
176} 221}
177 222
178void sd_gpioa_isr(void) 223void sd_gpioa_isr(void)
@@ -435,87 +480,6 @@ static int sd_init_card(const int drive)
435 return 0; 480 return 0;
436} 481}
437 482
438static void sd_thread(void) NORETURN_ATTR;
439static void sd_thread(void)
440{
441 struct queue_event ev;
442 bool idle_notified = false;
443
444 while (1)
445 {
446 queue_wait_w_tmo(&sd_queue, &ev, HZ);
447
448 switch ( ev.id )
449 {
450#ifdef HAVE_HOTSWAP
451 case SYS_HOTSWAP_INSERTED:
452 case SYS_HOTSWAP_EXTRACTED:;
453 int success = 1;
454
455 disk_unmount(SD_SLOT_AS3525); /* release "by force" */
456
457 mutex_lock(&sd_mtx); /* lock-out card activity */
458
459 /* Force card init for new card, re-init for re-inserted one or
460 * clear if the last attempt to init failed with an error. */
461 card_info[SD_SLOT_AS3525].initialized = 0;
462
463 if (ev.id == SYS_HOTSWAP_INSERTED)
464 {
465 success = 0;
466 sd_enable(true);
467 init_pl180_controller(SD_SLOT_AS3525);
468 int rc = sd_init_card(SD_SLOT_AS3525);
469 sd_enable(false);
470 if (rc >= 0)
471 success = 2;
472 else /* initialisation failed */
473 panicf("microSD init failed : %d", rc);
474 }
475
476 mutex_unlock(&sd_mtx);
477
478 if (success > 1)
479 success = disk_mount(SD_SLOT_AS3525); /* 0 if fail */
480
481 /*
482 * Mount succeeded, or this was an EXTRACTED event,
483 * in both cases notify the system about the changed filesystems
484 */
485 if (success)
486 queue_broadcast(SYS_FS_CHANGED, 0);
487
488 break;
489#endif /* HAVE_HOTSWAP */
490
491 case SYS_TIMEOUT:
492 if (TIME_BEFORE(current_tick, last_disk_activity+(3*HZ)))
493 {
494 idle_notified = false;
495 }
496 else
497 {
498 /* never let a timer wrap confuse us */
499 next_yield = current_tick;
500
501 if (!idle_notified)
502 {
503 call_storage_idle_notifys(false);
504 idle_notified = true;
505 }
506 }
507 break;
508
509 case SYS_USB_CONNECTED:
510 usb_acknowledge(SYS_USB_CONNECTED_ACK);
511 /* Wait until the USB cable is extracted again */
512 usb_wait_for_disconnect(&sd_queue);
513
514 break;
515 }
516 }
517}
518
519static void init_pl180_controller(const int drive) 483static void init_pl180_controller(const int drive)
520{ 484{
521 MCI_COMMAND(drive) = MCI_DATA_CTRL(drive) = 0; 485 MCI_COMMAND(drive) = MCI_DATA_CTRL(drive) = 0;
@@ -576,12 +540,8 @@ int sd_init(void)
576 /* init mutex */ 540 /* init mutex */
577 mutex_init(&sd_mtx); 541 mutex_init(&sd_mtx);
578 542
579 queue_init(&sd_queue, true); 543 sd_enabled = true; /* force action on next call */
580 create_thread(sd_thread, sd_stack, sizeof(sd_stack), 0, 544 enable_controller(false);
581 sd_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE) IF_COP(, CPU));
582
583 sd_enabled = true;
584 sd_enable(false);
585 545
586 return 0; 546 return 0;
587} 547}
@@ -698,7 +658,7 @@ static int sd_transfer_sectors(IF_MD(int drive,) unsigned long start,
698 unsigned long response; 658 unsigned long response;
699 bool aligned = !((uintptr_t)buf & (CACHEALIGN_SIZE - 1)); 659 bool aligned = !((uintptr_t)buf & (CACHEALIGN_SIZE - 1));
700 660
701 sd_enable(true); 661 enable_controller(true);
702 led(true); 662 led(true);
703 663
704 if (card_info[drive].initialized <= 0) 664 if (card_info[drive].initialized <= 0)
@@ -873,7 +833,7 @@ sd_transfer_error:
873sd_transfer_error_nodma: 833sd_transfer_error_nodma:
874 834
875 led(false); 835 led(false);
876 sd_enable(false); 836 enable_controller(false);
877 837
878 if (ret) /* error */ 838 if (ret) /* error */
879 card_info[drive].initialized = 0; 839 card_info[drive].initialized = 0;
@@ -947,55 +907,9 @@ long sd_last_disk_activity(void)
947 907
948void sd_enable(bool on) 908void sd_enable(bool on)
949{ 909{
950#if defined(HAVE_BUTTON_LIGHT) && defined(HAVE_MULTIDRIVE) 910 mutex_lock(&sd_mtx);
951 extern int buttonlight_is_on; 911 enable_controller(on);
952#endif 912 mutex_unlock(&sd_mtx);
953
954#if defined(HAVE_HOTSWAP) && defined (HAVE_ADJUSTABLE_CPU_VOLTAGE)
955 static bool cpu_boosted = false;
956#endif
957
958 if (sd_enabled == on)
959 return; /* nothing to do */
960
961 sd_enabled = on;
962
963 if(on)
964 {
965#if defined(HAVE_BUTTON_LIGHT) && defined(HAVE_MULTIDRIVE)
966 /* buttonlight AMSes need a bit of special handling for the buttonlight
967 * here due to the dual mapping of GPIOD and XPD */
968 bitmod32(&CCU_IO, 1<<2, 3<<2); /* XPD is SD-MCI interface (b3:2 = 01) */
969 if (buttonlight_is_on)
970 GPIOD_DIR &= ~(1<<7);
971 else
972 buttonlight_hw_off();
973#endif
974
975#if defined(HAVE_HOTSWAP) && defined (HAVE_ADJUSTABLE_CPU_VOLTAGE)
976 if(card_detect_target()) /* If SD card present Boost cpu for voltage */
977 {
978 cpu_boosted = true;
979 cpu_boost(true);
980 }
981#endif /* defined(HAVE_HOTSWAP) && defined (HAVE_ADJUSTABLE_CPU_VOLTAGE) */
982 }
983 else
984 {
985#if defined(HAVE_HOTSWAP) && defined (HAVE_ADJUSTABLE_CPU_VOLTAGE)
986 if(cpu_boosted)
987 {
988 cpu_boost(false);
989 cpu_boosted = false;
990 }
991#endif /* defined(HAVE_HOTSWAP) && defined (HAVE_ADJUSTABLE_CPU_VOLTAGE) */
992
993#if defined(HAVE_BUTTON_LIGHT) && defined(HAVE_MULTIDRIVE)
994 bitmod32(&CCU_IO, 0<<2, 3<<2); /* XPD is general purpose IO (b3:2 = 00) */
995 if (buttonlight_is_on)
996 buttonlight_hw_on();
997#endif
998 }
999} 913}
1000 914
1001tCardInfo *card_get_info_target(int card_no) 915tCardInfo *card_get_info_target(int card_no)
@@ -1006,9 +920,45 @@ tCardInfo *card_get_info_target(int card_no)
1006#ifdef CONFIG_STORAGE_MULTI 920#ifdef CONFIG_STORAGE_MULTI
1007int sd_num_drives(int first_drive) 921int sd_num_drives(int first_drive)
1008{ 922{
1009 /* We don't care which logical drive number(s) we have been assigned */ 923 sd_first_drive = first_drive;
1010 (void)first_drive;
1011
1012 return NUM_DRIVES; 924 return NUM_DRIVES;
1013} 925}
1014#endif /* CONFIG_STORAGE_MULTI */ 926#endif /* CONFIG_STORAGE_MULTI */
927
928int sd_event(long id, intptr_t data)
929{
930 int rc = 0;
931
932 switch (id)
933 {
934#ifdef HAVE_HOTSWAP
935 case SYS_HOTSWAP_INSERTED:
936 case SYS_HOTSWAP_EXTRACTED:
937 mutex_lock(&sd_mtx); /* lock-out card activity */
938
939 /* Force card init for new card, re-init for re-inserted one or
940 * clear if the last attempt to init failed with an error. */
941 card_info[data].initialized = 0;
942
943 if (id == SYS_HOTSWAP_INSERTED)
944 {
945 enable_controller(true);
946 init_pl180_controller(data);
947 rc = sd_init_card(data);
948 enable_controller(false);
949 }
950
951 mutex_unlock(&sd_mtx);
952 break;
953#endif /* HAVE_HOTSWAP */
954 case Q_STORAGE_TICK:
955 /* never let a timer wrap confuse us */
956 next_yield = current_tick;
957 default:
958 rc = storage_event_default_handler(id, data, last_disk_activity,
959 STORAGE_SD);
960 break;
961 }
962
963 return rc;
964}
diff --git a/firmware/target/arm/as3525/sd-as3525v2.c b/firmware/target/arm/as3525/sd-as3525v2.c
index 3f39629e0b..f78345577c 100644
--- a/firmware/target/arm/as3525/sd-as3525v2.c
+++ b/firmware/target/arm/as3525/sd-as3525v2.c
@@ -22,7 +22,6 @@
22 22
23#include "config.h" /* for HAVE_MULTIVOLUME */ 23#include "config.h" /* for HAVE_MULTIVOLUME */
24#include "fs_defines.h" 24#include "fs_defines.h"
25#include "thread.h"
26#include "gcc_extensions.h" 25#include "gcc_extensions.h"
27#include "led.h" 26#include "led.h"
28#include "sdmmc.h" 27#include "sdmmc.h"
@@ -36,19 +35,7 @@
36#include "pl081.h" /* DMA controller */ 35#include "pl081.h" /* DMA controller */
37#include "dma-target.h" /* DMA request lines */ 36#include "dma-target.h" /* DMA request lines */
38#include "clock-target.h" 37#include "clock-target.h"
39#include "panic.h" 38#include "storage.h"
40#include "stdbool.h"
41#include "ata_idle_notify.h"
42#include "sd.h"
43#include "usb.h"
44
45#ifdef HAVE_HOTSWAP
46#include "disk.h"
47#endif
48
49#include "lcd.h"
50#include <stdarg.h>
51#include "sysfont.h"
52 39
53#define INTERNAL_AS3525 0 /* embedded SD card */ 40#define INTERNAL_AS3525 0 /* embedded SD card */
54#define SD_SLOT_AS3525 1 /* SD slot if present */ 41#define SD_SLOT_AS3525 1 /* SD slot if present */
@@ -327,13 +314,15 @@ static unsigned char *uncached_buffer = AS3525_UNCACHED_ADDR(&aligned_buffer[0])
327 314
328static tCardInfo card_info[NUM_DRIVES]; 315static tCardInfo card_info[NUM_DRIVES];
329 316
317#ifdef CONFIG_STORAGE_MULTI
318static int sd_first_drive = 0;
319#else
320#define sd_first_drive 0
321#endif
322
330/* for compatibility */ 323/* for compatibility */
331static long last_disk_activity = -1; 324static long last_disk_activity = -1;
332
333static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x200)/sizeof(long)];
334static const char sd_thread_name[] = "ata/sd";
335static struct mutex sd_mtx SHAREDBSS_ATTR; 325static struct mutex sd_mtx SHAREDBSS_ATTR;
336static struct event_queue sd_queue;
337#ifndef BOOTLOADER 326#ifndef BOOTLOADER
338bool sd_enabled = false; 327bool sd_enabled = false;
339#endif 328#endif
@@ -371,6 +360,22 @@ void INT_NAND(void)
371 MCI_CTRL |= INT_ENABLE; 360 MCI_CTRL |= INT_ENABLE;
372} 361}
373 362
363#ifndef BOOTLOADER
364static void enable_controller(bool on)
365{
366 if (on)
367 {
368 bitset32(&CGU_PERI, CGU_MCI_CLOCK_ENABLE);
369 CGU_SDSLOT |= (1<<7); /* interface enable */
370 }
371 else
372 {
373 CGU_SDSLOT &= ~(1<<7); /* interface enable */
374 bitclr32(&CGU_PERI, CGU_MCI_CLOCK_ENABLE);
375 }
376}
377#endif /* BOOTLOADER */
378
374static inline bool card_detect_target(void) 379static inline bool card_detect_target(void)
375{ 380{
376#if defined(HAVE_MULTIDRIVE) 381#if defined(HAVE_MULTIDRIVE)
@@ -577,75 +582,6 @@ static int sd_init_card(const int drive)
577 return 0; 582 return 0;
578} 583}
579 584
580static void sd_thread(void) NORETURN_ATTR;
581static void sd_thread(void)
582{
583 struct queue_event ev;
584 bool idle_notified = false;
585
586 while (1)
587 {
588 queue_wait_w_tmo(&sd_queue, &ev, HZ);
589
590 switch ( ev.id )
591 {
592#ifdef HAVE_HOTSWAP
593 case SYS_HOTSWAP_INSERTED:
594 case SYS_HOTSWAP_EXTRACTED:;
595 int success = 1;
596
597 disk_unmount(SD_SLOT_AS3525); /* release "by force" */
598
599 mutex_lock(&sd_mtx); /* lock-out card activity */
600
601 /* Force card init for new card, re-init for re-inserted one or
602 * clear if the last attempt to init failed with an error. */
603 card_info[SD_SLOT_AS3525].initialized = 0;
604
605 if (ev.id == SYS_HOTSWAP_INSERTED)
606 {
607 sd_enable(true);
608 success = sd_init_card(SD_SLOT_AS3525) == 0 ? 2 : 0;
609 sd_enable(false);
610 }
611
612 mutex_unlock(&sd_mtx);
613
614 if (success > 1)
615 success = disk_mount(SD_SLOT_AS3525); /* 0 if fail */
616
617 /*
618 * Mount succeeded, or this was an EXTRACTED event,
619 * in both cases notify the system about the changed filesystems
620 */
621 if (success)
622 queue_broadcast(SYS_FS_CHANGED, 0);
623
624 break;
625#endif /* HAVE_HOTSWAP */
626
627 case SYS_TIMEOUT:
628 if (TIME_BEFORE(current_tick, last_disk_activity+(3*HZ)))
629 {
630 idle_notified = false;
631 }
632 else if (!idle_notified)
633 {
634 call_storage_idle_notifys(false);
635 idle_notified = true;
636 }
637 break;
638
639 case SYS_USB_CONNECTED:
640 usb_acknowledge(SYS_USB_CONNECTED_ACK);
641 /* Wait until the USB cable is extracted again */
642 usb_wait_for_disconnect(&sd_queue);
643
644 break;
645 }
646 }
647}
648
649static void init_controller(void) 585static void init_controller(void)
650{ 586{
651 int hcon_numcards = ((MCI_HCON>>1) & 0x1F) + 1; 587 int hcon_numcards = ((MCI_HCON>>1) & 0x1F) + 1;
@@ -706,6 +642,7 @@ int sd_init(void)
706 | (AS3525_SDSLOT_DIV << 2) 642 | (AS3525_SDSLOT_DIV << 2)
707 | 1; /* clock source = PLLA */ 643 | 1; /* clock source = PLLA */
708 644
645 mutex_init(&sd_mtx);
709 semaphore_init(&transfer_completion_signal, 1, 0); 646 semaphore_init(&transfer_completion_signal, 1, 0);
710 semaphore_init(&command_completion_signal, 1, 0); 647 semaphore_init(&command_completion_signal, 1, 0);
711 648
@@ -737,16 +674,9 @@ int sd_init(void)
737 if(ret < 0) 674 if(ret < 0)
738 return ret; 675 return ret;
739 676
740 /* init mutex */
741 mutex_init(&sd_mtx);
742
743 queue_init(&sd_queue, true);
744 create_thread(sd_thread, sd_stack, sizeof(sd_stack), 0,
745 sd_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE) IF_COP(, CPU));
746
747#ifndef BOOTLOADER 677#ifndef BOOTLOADER
748 sd_enabled = true; 678 sd_enabled = true;
749 sd_enable(false); 679 enable_controller(false);
750#endif 680#endif
751 return 0; 681 return 0;
752} 682}
@@ -767,7 +697,7 @@ static int sd_transfer_sectors(IF_MD(int drive,) unsigned long start,
767 697
768 mutex_lock(&sd_mtx); 698 mutex_lock(&sd_mtx);
769#ifndef BOOTLOADER 699#ifndef BOOTLOADER
770 sd_enable(true); 700 enable_controller(true);
771 led(true); 701 led(true);
772#endif 702#endif
773 703
@@ -925,7 +855,7 @@ retry_with_reinit:
925 855
926exit: 856exit:
927#ifndef BOOTLOADER 857#ifndef BOOTLOADER
928 sd_enable(false); 858 enable_controller(false);
929 led(false); 859 led(false);
930#endif 860#endif
931 mutex_unlock(&sd_mtx); 861 mutex_unlock(&sd_mtx);
@@ -952,16 +882,9 @@ long sd_last_disk_activity(void)
952 882
953void sd_enable(bool on) 883void sd_enable(bool on)
954{ 884{
955 if (on) 885 mutex_lock(&sd_mtx);
956 { 886 enable_controller(on);
957 bitset32(&CGU_PERI, CGU_MCI_CLOCK_ENABLE); 887 mutex_unlock(&sd_mtx);
958 CGU_SDSLOT |= (1<<7); /* interface enable */
959 }
960 else
961 {
962 CGU_SDSLOT &= ~(1<<7); /* interface enable */
963 bitclr32(&CGU_PERI, CGU_MCI_CLOCK_ENABLE);
964 }
965} 888}
966#endif /* BOOTLOADER */ 889#endif /* BOOTLOADER */
967 890
@@ -983,18 +906,13 @@ bool sd_present(IF_MD_NONVOID(int drive))
983 906
984static int sd1_oneshot_callback(struct timeout *tmo) 907static int sd1_oneshot_callback(struct timeout *tmo)
985{ 908{
986 (void)tmo;
987
988 /* This is called only if the state was stable for 300ms - check state 909 /* This is called only if the state was stable for 300ms - check state
989 * and post appropriate event. */ 910 * and post appropriate event. */
990 if (card_detect_target()) 911 queue_broadcast(card_detect_target() ? SYS_HOTSWAP_INSERTED :
991 { 912 SYS_HOTSWAP_EXTRACTED,
992 queue_broadcast(SYS_HOTSWAP_INSERTED, 0); 913 sd_first_drive + SD_SLOT_AS3525);
993 }
994 else
995 queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0);
996
997 return 0; 914 return 0;
915 (void)tmo;
998} 916}
999 917
1000void sd_gpioa_isr(void) 918void sd_gpioa_isr(void)
@@ -1012,9 +930,41 @@ void sd_gpioa_isr(void)
1012#ifdef CONFIG_STORAGE_MULTI 930#ifdef CONFIG_STORAGE_MULTI
1013int sd_num_drives(int first_drive) 931int sd_num_drives(int first_drive)
1014{ 932{
1015 /* We don't care which logical drive number(s) we have been assigned */ 933 sd_first_drive = first_drive;
1016 (void)first_drive;
1017
1018 return NUM_DRIVES; 934 return NUM_DRIVES;
1019} 935}
1020#endif /* CONFIG_STORAGE_MULTI */ 936#endif /* CONFIG_STORAGE_MULTI */
937
938int sd_event(long id, intptr_t data)
939{
940 int rc = 0;
941
942 switch (id)
943 {
944#ifdef HAVE_HOTSWAP
945 case SYS_HOTSWAP_INSERTED:
946 case SYS_HOTSWAP_EXTRACTED:
947 mutex_lock(&sd_mtx); /* lock-out card activity */
948
949 /* Force card init for new card, re-init for re-inserted one or
950 * clear if the last attempt to init failed with an error. */
951 card_info[data].initialized = 0;
952
953 if (id == SYS_HOTSWAP_INSERTED)
954 {
955 enable_controller(true);
956 rc = sd_init_card(data);
957 enable_controller(false);
958 }
959
960 mutex_unlock(&sd_mtx);
961 break;
962#endif /* HAVE_HOTSWAP */
963 default:
964 rc = storage_event_default_handler(id, data, last_disk_activity,
965 STORAGE_SD);
966 break;
967 }
968
969 return rc;
970}