diff options
Diffstat (limited to 'firmware/target/arm')
-rw-r--r-- | firmware/target/arm/sandisk/ata-c200_e200.c | 49 |
1 files changed, 41 insertions, 8 deletions
diff --git a/firmware/target/arm/sandisk/ata-c200_e200.c b/firmware/target/arm/sandisk/ata-c200_e200.c index addc490417..14be27e19d 100644 --- a/firmware/target/arm/sandisk/ata-c200_e200.c +++ b/firmware/target/arm/sandisk/ata-c200_e200.c | |||
@@ -125,6 +125,11 @@ | |||
125 | #define SD_APP_OP_COND 41 | 125 | #define SD_APP_OP_COND 41 |
126 | 126 | ||
127 | /** global, exported variables **/ | 127 | /** global, exported variables **/ |
128 | #ifdef HAVE_HOTSWAP | ||
129 | #define NUM_VOLUMES 2 | ||
130 | #else | ||
131 | #define NUM_VOLUMES 1 | ||
132 | #endif | ||
128 | 133 | ||
129 | /* for compatibility */ | 134 | /* for compatibility */ |
130 | int ata_spinup_time = 0; | 135 | int ata_spinup_time = 0; |
@@ -146,10 +151,12 @@ struct sd_card_status | |||
146 | int retry_max; | 151 | int retry_max; |
147 | }; | 152 | }; |
148 | 153 | ||
149 | static struct sd_card_status sd_status[2] = | 154 | static struct sd_card_status sd_status[NUM_VOLUMES] = |
150 | { | 155 | { |
151 | { 0, 1 }, | 156 | { 0, 1 }, |
157 | #ifdef HAVE_HOTSWAP | ||
152 | { 0, 10 } | 158 | { 0, 10 } |
159 | #endif | ||
153 | }; | 160 | }; |
154 | 161 | ||
155 | /* Shoot for around 75% usage */ | 162 | /* Shoot for around 75% usage */ |
@@ -575,7 +582,9 @@ static void sd_card_mux(int card_no) | |||
575 | static void sd_init_device(int card_no) | 582 | static void sd_init_device(int card_no) |
576 | { | 583 | { |
577 | /* SD Protocol registers */ | 584 | /* SD Protocol registers */ |
585 | #ifdef HAVE_HOTSWAP | ||
578 | unsigned int response = 0; | 586 | unsigned int response = 0; |
587 | #endif | ||
579 | unsigned int i; | 588 | unsigned int i; |
580 | unsigned int c_size; | 589 | unsigned int c_size; |
581 | unsigned long c_mult; | 590 | unsigned long c_mult; |
@@ -613,7 +622,8 @@ static void sd_init_device(int card_no) | |||
613 | goto card_init_error; | 622 | goto card_init_error; |
614 | 623 | ||
615 | check_time[EC_POWER_UP] = USEC_TIMER; | 624 | check_time[EC_POWER_UP] = USEC_TIMER; |
616 | 625 | ||
626 | #ifdef HAVE_HOTSWAP | ||
617 | /* Check for SDHC: | 627 | /* Check for SDHC: |
618 | - non-SDHC cards simply ignore SEND_IF_COND (CMD8) and we get error -219, | 628 | - non-SDHC cards simply ignore SEND_IF_COND (CMD8) and we get error -219, |
619 | which we can just ignore and assume we're dealing with standard SD. | 629 | which we can just ignore and assume we're dealing with standard SD. |
@@ -623,6 +633,7 @@ static void sd_init_device(int card_no) | |||
623 | ret = sd_command(SEND_IF_COND,0x1aa, &response,7); | 633 | ret = sd_command(SEND_IF_COND,0x1aa, &response,7); |
624 | if ( (ret < 0) && (ret!=-219) ) | 634 | if ( (ret < 0) && (ret!=-219) ) |
625 | goto card_init_error; | 635 | goto card_init_error; |
636 | #endif | ||
626 | 637 | ||
627 | while ((currcard->ocr & (1 << 31)) == 0) /* until card is powered up */ | 638 | while ((currcard->ocr & (1 << 31)) == 0) /* until card is powered up */ |
628 | { | 639 | { |
@@ -630,15 +641,20 @@ static void sd_init_device(int card_no) | |||
630 | if (ret < 0) | 641 | if (ret < 0) |
631 | goto card_init_error; | 642 | goto card_init_error; |
632 | 643 | ||
644 | #ifdef HAVE_HOTSWAP | ||
633 | if(response == 0x1aa) | 645 | if(response == 0x1aa) |
634 | { | 646 | { |
635 | /* SDHC */ | 647 | /* SDHC */ |
636 | ret = sd_command(SD_APP_OP_COND, (1<<30)|0x100000, | 648 | ret = sd_command(SD_APP_OP_COND, (1<<30)|0x100000, |
637 | &currcard->ocr, 3); | 649 | &currcard->ocr, 3); |
638 | } else { | 650 | } |
651 | else | ||
652 | #endif /* HAVE_HOTSWAP */ | ||
653 | { | ||
639 | /* SD Standard */ | 654 | /* SD Standard */ |
640 | ret = sd_command(SD_APP_OP_COND, 0x100000, &currcard->ocr, 3); | 655 | ret = sd_command(SD_APP_OP_COND, 0x100000, &currcard->ocr, 3); |
641 | } | 656 | } |
657 | |||
642 | if (ret < 0) | 658 | if (ret < 0) |
643 | goto card_init_error; | 659 | goto card_init_error; |
644 | 660 | ||
@@ -672,6 +688,7 @@ static void sd_init_device(int card_no) | |||
672 | currcard->numblocks = c_size * c_mult * (currcard->max_read_bl_len/512); | 688 | currcard->numblocks = c_size * c_mult * (currcard->max_read_bl_len/512); |
673 | currcard->capacity = currcard->numblocks * currcard->block_size; | 689 | currcard->capacity = currcard->numblocks * currcard->block_size; |
674 | } | 690 | } |
691 | #ifdef HAVE_HOTSWAP | ||
675 | else if( (currcard->csd[3]>>30) == 1) | 692 | else if( (currcard->csd[3]>>30) == 1) |
676 | { | 693 | { |
677 | /* CSD version 2.0 */ | 694 | /* CSD version 2.0 */ |
@@ -681,6 +698,7 @@ static void sd_init_device(int card_no) | |||
681 | currcard->numblocks = c_size; | 698 | currcard->numblocks = c_size; |
682 | currcard->capacity = currcard->numblocks * currcard->block_size; | 699 | currcard->capacity = currcard->numblocks * currcard->block_size; |
683 | } | 700 | } |
701 | #endif /* HAVE_HOTSWAP */ | ||
684 | 702 | ||
685 | REG_1 = 0; | 703 | REG_1 = 0; |
686 | 704 | ||
@@ -771,9 +789,12 @@ void ata_led(bool onoff) | |||
771 | led(onoff); | 789 | led(onoff); |
772 | } | 790 | } |
773 | 791 | ||
774 | int ata_read_sectors(int drive, unsigned long start, int incount, | 792 | int ata_read_sectors(IF_MV2(int drive,) unsigned long start, int incount, |
775 | void* inbuf) | 793 | void* inbuf) |
776 | { | 794 | { |
795 | #ifndef HAVE_HOTSWAP | ||
796 | const int drive = 0; | ||
797 | #endif | ||
777 | int ret; | 798 | int ret; |
778 | unsigned char *buf, *buf_end; | 799 | unsigned char *buf, *buf_end; |
779 | int bank; | 800 | int bank; |
@@ -823,12 +844,14 @@ ata_read_retry: | |||
823 | 844 | ||
824 | BLOCK_COUNT_REG = incount; | 845 | BLOCK_COUNT_REG = incount; |
825 | 846 | ||
847 | #ifdef HAVE_HOTSWAP | ||
826 | if(currcard->ocr & (1<<30) ) | 848 | if(currcard->ocr & (1<<30) ) |
827 | { | 849 | { |
828 | /* SDHC */ | 850 | /* SDHC */ |
829 | ret = sd_command(READ_MULTIPLE_BLOCK, start, NULL, 0x1c25); | 851 | ret = sd_command(READ_MULTIPLE_BLOCK, start, NULL, 0x1c25); |
830 | } | 852 | } |
831 | else | 853 | else |
854 | #endif | ||
832 | { | 855 | { |
833 | ret = sd_command(READ_MULTIPLE_BLOCK, start * BLOCK_SIZE, NULL, 0x1c25); | 856 | ret = sd_command(READ_MULTIPLE_BLOCK, start * BLOCK_SIZE, NULL, 0x1c25); |
834 | } | 857 | } |
@@ -880,12 +903,15 @@ ata_read_error: | |||
880 | } | 903 | } |
881 | } | 904 | } |
882 | 905 | ||
883 | int ata_write_sectors(int drive, unsigned long start, int count, | 906 | int ata_write_sectors(IF_MV2(int drive,) unsigned long start, int count, |
884 | const void* outbuf) | 907 | const void* outbuf) |
885 | { | 908 | { |
886 | /* Write support is not finished yet */ | 909 | /* Write support is not finished yet */ |
887 | /* TODO: The standard suggests using ACMD23 prior to writing multiple blocks | 910 | /* TODO: The standard suggests using ACMD23 prior to writing multiple blocks |
888 | to improve performance */ | 911 | to improve performance */ |
912 | #ifndef HAVE_HOTSWAP | ||
913 | const int drive = 0; | ||
914 | #endif | ||
889 | int ret; | 915 | int ret; |
890 | const unsigned char *buf, *buf_end; | 916 | const unsigned char *buf, *buf_end; |
891 | int bank; | 917 | int bank; |
@@ -933,12 +959,14 @@ ata_write_retry: | |||
933 | 959 | ||
934 | BLOCK_COUNT_REG = count; | 960 | BLOCK_COUNT_REG = count; |
935 | 961 | ||
962 | #ifdef HAVE_HOTSWAP | ||
936 | if(currcard->ocr & (1<<30) ) | 963 | if(currcard->ocr & (1<<30) ) |
937 | { | 964 | { |
938 | /* SDHC */ | 965 | /* SDHC */ |
939 | ret = sd_command(WRITE_MULTIPLE_BLOCK, start, NULL, 0x1c2d); | 966 | ret = sd_command(WRITE_MULTIPLE_BLOCK, start, NULL, 0x1c2d); |
940 | } | 967 | } |
941 | else | 968 | else |
969 | #endif | ||
942 | { | 970 | { |
943 | ret = sd_command(WRITE_MULTIPLE_BLOCK, start*BLOCK_SIZE, NULL, 0x1c2d); | 971 | ret = sd_command(WRITE_MULTIPLE_BLOCK, start*BLOCK_SIZE, NULL, 0x1c2d); |
944 | } | 972 | } |
@@ -1015,6 +1043,7 @@ static void sd_thread(void) | |||
1015 | 1043 | ||
1016 | switch ( ev.id ) | 1044 | switch ( ev.id ) |
1017 | { | 1045 | { |
1046 | #ifdef HAVE_HOTSWAP | ||
1018 | case SD_HOTSWAP: | 1047 | case SD_HOTSWAP: |
1019 | { | 1048 | { |
1020 | int action = SDA_NONE; | 1049 | int action = SDA_NONE; |
@@ -1046,6 +1075,7 @@ static void sd_thread(void) | |||
1046 | queue_broadcast(SYS_FS_CHANGED, 0); | 1075 | queue_broadcast(SYS_FS_CHANGED, 0); |
1047 | break; | 1076 | break; |
1048 | } /* SD_HOTSWAP */ | 1077 | } /* SD_HOTSWAP */ |
1078 | #endif /* HAVE_HOTSWAP */ | ||
1049 | case SYS_TIMEOUT: | 1079 | case SYS_TIMEOUT: |
1050 | if (TIME_BEFORE(current_tick, last_disk_activity+(3*HZ))) | 1080 | if (TIME_BEFORE(current_tick, last_disk_activity+(3*HZ))) |
1051 | { | 1081 | { |
@@ -1138,12 +1168,13 @@ int ata_init(void) | |||
1138 | GPIOG_OUTPUT_EN |= (0x3 << 5); | 1168 | GPIOG_OUTPUT_EN |= (0x3 << 5); |
1139 | GPIOG_OUTPUT_VAL |= (0x3 << 5); | 1169 | GPIOG_OUTPUT_VAL |= (0x3 << 5); |
1140 | 1170 | ||
1171 | #ifdef HAVE_HOTSWAP | ||
1141 | /* enable card detection port - mask interrupt first */ | 1172 | /* enable card detection port - mask interrupt first */ |
1142 | GPIOA_INT_EN &= ~0x80; | 1173 | GPIOA_INT_EN &= ~0x80; |
1143 | 1174 | ||
1144 | GPIOA_OUTPUT_EN &= ~0x80; | 1175 | GPIOA_OUTPUT_EN &= ~0x80; |
1145 | GPIOA_ENABLE |= 0x80; | 1176 | GPIOA_ENABLE |= 0x80; |
1146 | 1177 | #endif | |
1147 | sd_select_device(0); | 1178 | sd_select_device(0); |
1148 | 1179 | ||
1149 | if (currcard->initialized < 0) | 1180 | if (currcard->initialized < 0) |
@@ -1155,7 +1186,7 @@ int ata_init(void) | |||
1155 | 1186 | ||
1156 | /* enable interupt for the mSD card */ | 1187 | /* enable interupt for the mSD card */ |
1157 | sleep(HZ/10); | 1188 | sleep(HZ/10); |
1158 | 1189 | #ifdef HAVE_HOTSWAP | |
1159 | CPU_INT_EN = HI_MASK; | 1190 | CPU_INT_EN = HI_MASK; |
1160 | CPU_HI_INT_EN = GPIO0_MASK; | 1191 | CPU_HI_INT_EN = GPIO0_MASK; |
1161 | 1192 | ||
@@ -1163,7 +1194,7 @@ int ata_init(void) | |||
1163 | 1194 | ||
1164 | GPIOA_INT_CLR = 0x80; | 1195 | GPIOA_INT_CLR = 0x80; |
1165 | GPIOA_INT_EN |= 0x80; | 1196 | GPIOA_INT_EN |= 0x80; |
1166 | 1197 | #endif | |
1167 | spinlock_unlock(&sd_mtx); | 1198 | spinlock_unlock(&sd_mtx); |
1168 | } | 1199 | } |
1169 | 1200 | ||
@@ -1204,6 +1235,7 @@ tCardInfo *card_get_info_target(int card_no) | |||
1204 | return &card; | 1235 | return &card; |
1205 | } | 1236 | } |
1206 | 1237 | ||
1238 | #ifdef HAVE_HOTSWAP | ||
1207 | bool card_detect_target(void) | 1239 | bool card_detect_target(void) |
1208 | { | 1240 | { |
1209 | /* 0x00:inserted, 0x80:not inserted */ | 1241 | /* 0x00:inserted, 0x80:not inserted */ |
@@ -1231,3 +1263,4 @@ void microsd_int(void) | |||
1231 | timeout_register(&sd1_oneshot, sd1_oneshot_callback, | 1263 | timeout_register(&sd1_oneshot, sd1_oneshot_callback, |
1232 | detect ? 1 : HZ/2, detect == 0); | 1264 | detect ? 1 : HZ/2, detect == 0); |
1233 | } | 1265 | } |
1266 | #endif /* HAVE_HOTSWAP */ | ||