diff options
Diffstat (limited to 'firmware/target/arm/as3525/ata_sd_as3525.c')
-rw-r--r-- | firmware/target/arm/as3525/ata_sd_as3525.c | 66 |
1 files changed, 13 insertions, 53 deletions
diff --git a/firmware/target/arm/as3525/ata_sd_as3525.c b/firmware/target/arm/as3525/ata_sd_as3525.c index c0fad722b6..74bdb90ed0 100644 --- a/firmware/target/arm/as3525/ata_sd_as3525.c +++ b/firmware/target/arm/as3525/ata_sd_as3525.c | |||
@@ -94,9 +94,7 @@ static const int pl180_base[NUM_VOLUMES] = { | |||
94 | static int sd_select_bank(signed char bank); | 94 | static int sd_select_bank(signed char bank); |
95 | static int sd_init_card(const int drive); | 95 | static int sd_init_card(const int drive); |
96 | static void init_pl180_controller(const int drive); | 96 | static void init_pl180_controller(const int drive); |
97 | /* TODO : BLOCK_SIZE != SECTOR_SIZE ? */ | 97 | #define SECTOR_SIZE 512 /* XXX: different sector sizes ? */ |
98 | #define BLOCK_SIZE 512 | ||
99 | #define SECTOR_SIZE 512 | ||
100 | #define BLOCKS_PER_BANK 0x7a7800 | 98 | #define BLOCKS_PER_BANK 0x7a7800 |
101 | 99 | ||
102 | static tCardInfo card_info[NUM_VOLUMES]; | 100 | static tCardInfo card_info[NUM_VOLUMES]; |
@@ -241,12 +239,11 @@ static bool send_cmd(const int drive, const int cmd, const int arg, | |||
241 | 239 | ||
242 | static int sd_init_card(const int drive) | 240 | static int sd_init_card(const int drive) |
243 | { | 241 | { |
244 | unsigned int c_size; | ||
245 | unsigned long c_mult; | ||
246 | unsigned long response; | 242 | unsigned long response; |
247 | int max_tries = 100; /* max acmd41 attemps */ | 243 | int max_tries = 100; /* max acmd41 attemps */ |
248 | bool sdhc; | 244 | bool sdhc; |
249 | unsigned char temp; | 245 | unsigned long temp_reg[4]; |
246 | int i; | ||
250 | 247 | ||
251 | if(!send_cmd(drive, SD_GO_IDLE_STATE, 0, MCI_NO_FLAGS, NULL)) | 248 | if(!send_cmd(drive, SD_GO_IDLE_STATE, 0, MCI_NO_FLAGS, NULL)) |
252 | return -1; | 249 | return -1; |
@@ -284,17 +281,11 @@ static int sd_init_card(const int drive) | |||
284 | 281 | ||
285 | /* send CID */ | 282 | /* send CID */ |
286 | if(!send_cmd(drive, SD_ALL_SEND_CID, 0, MCI_RESP|MCI_LONG_RESP|MCI_ARG, | 283 | if(!send_cmd(drive, SD_ALL_SEND_CID, 0, MCI_RESP|MCI_LONG_RESP|MCI_ARG, |
287 | card_info[drive].cid)) | 284 | temp_reg)) |
288 | return -5; | 285 | return -5; |
289 | 286 | ||
290 | /* ascii chars here */ | 287 | for(i=0; i<4; i++) |
291 | card_info[drive].cid[0] = htobe32(card_info[drive].cid[0]); | 288 | card_info[drive].cid[3-i] = temp_reg[i]; |
292 | card_info[drive].cid[1] = htobe32(card_info[drive].cid[1]); | ||
293 | |||
294 | /* adjust year<=>month, 1997 <=> 2000 */ | ||
295 | temp = *((char*)card_info[drive].cid+13); | ||
296 | *((char*)card_info[drive].cid+13) = | ||
297 | (unsigned char)((temp >> 4) | (temp << 4)) + 3; | ||
298 | 289 | ||
299 | /* send RCA */ | 290 | /* send RCA */ |
300 | if(!send_cmd(drive, SD_SEND_RELATIVE_ADDR, 0, MCI_RESP|MCI_ARG, | 291 | if(!send_cmd(drive, SD_SEND_RELATIVE_ADDR, 0, MCI_RESP|MCI_ARG, |
@@ -303,29 +294,13 @@ static int sd_init_card(const int drive) | |||
303 | 294 | ||
304 | /* send CSD */ | 295 | /* send CSD */ |
305 | if(!send_cmd(drive, SD_SEND_CSD, card_info[drive].rca, | 296 | if(!send_cmd(drive, SD_SEND_CSD, card_info[drive].rca, |
306 | MCI_RESP|MCI_LONG_RESP|MCI_ARG, card_info[drive].csd)) | 297 | MCI_RESP|MCI_LONG_RESP|MCI_ARG, temp_reg)) |
307 | return -7; | 298 | return -7; |
308 | 299 | ||
309 | /* These calculations come from the Sandisk SD card product manual */ | 300 | for(i=0; i<4; i++) |
310 | if( (card_info[drive].csd[3]>>30) == 0) | 301 | card_info[drive].csd[3-i] = temp_reg[i]; |
311 | { | 302 | |
312 | int max_read_bl_len; | 303 | sd_parse_csd(&card_info[drive]); |
313 | /* CSD version 1.0 */ | ||
314 | c_size = ((card_info[drive].csd[2] & 0x3ff) << 2) + (card_info[drive].csd[1]>>30) + 1; | ||
315 | c_mult = 4 << ((card_info[drive].csd[1] >> 15) & 7); | ||
316 | max_read_bl_len = 1 << ((card_info[drive].csd[2] >> 16) & 15); | ||
317 | card_info[drive].blocksize = BLOCK_SIZE; /* Always use 512 byte blocks */ | ||
318 | card_info[drive].numblocks = c_size * c_mult * (max_read_bl_len/512); | ||
319 | } | ||
320 | #ifdef HAVE_MULTIVOLUME | ||
321 | else if( (card_info[drive].csd[3]>>30) == 1) | ||
322 | { | ||
323 | /* CSD version 2.0 */ | ||
324 | c_size = ((card_info[drive].csd[2] & 0x3f) << 16) + (card_info[drive].csd[1]>>16) + 1; | ||
325 | card_info[drive].blocksize = BLOCK_SIZE; /* Always use 512 byte blocks */ | ||
326 | card_info[drive].numblocks = c_size << 10; | ||
327 | } | ||
328 | #endif | ||
329 | 304 | ||
330 | if(!send_cmd(drive, SD_SELECT_CARD, card_info[drive].rca, MCI_ARG, NULL)) | 305 | if(!send_cmd(drive, SD_SELECT_CARD, card_info[drive].rca, MCI_ARG, NULL)) |
331 | return -9; | 306 | return -9; |
@@ -723,7 +698,7 @@ static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start, | |||
723 | 698 | ||
724 | /* Set bank_start to the correct unit (blocks or bytes) */ | 699 | /* Set bank_start to the correct unit (blocks or bytes) */ |
725 | if(!(card_info[drive].ocr & (1<<30))) /* not SDHC */ | 700 | if(!(card_info[drive].ocr & (1<<30))) /* not SDHC */ |
726 | bank_start *= BLOCK_SIZE; | 701 | bank_start *= SD_BLOCK_SIZE; |
727 | 702 | ||
728 | if(!send_cmd(drive, cmd, bank_start, MCI_ARG, NULL)) | 703 | if(!send_cmd(drive, cmd, bank_start, MCI_ARG, NULL)) |
729 | { | 704 | { |
@@ -877,22 +852,7 @@ void sd_enable(bool on) | |||
877 | 852 | ||
878 | tCardInfo *card_get_info_target(int card_no) | 853 | tCardInfo *card_get_info_target(int card_no) |
879 | { | 854 | { |
880 | unsigned char temp; | 855 | return &card_info[card_no]; |
881 | tCardInfo *card = &card_info[card_no]; | ||
882 | |||
883 | temp = card->csd[3]; | ||
884 | card->speed = sd_mantissa[temp & 7] * sd_exponent[(temp >> 3) & 0xf]; | ||
885 | |||
886 | temp = card->csd[3] >> 8; | ||
887 | card->nsac = 100 * temp; | ||
888 | |||
889 | temp = (card->csd[3] >> 16) & 0x7f; /* bit 7 reserved */ | ||
890 | card->taac = sd_mantissa[temp >> 3] * sd_exponent[temp & 7]; | ||
891 | |||
892 | temp = (card->csd[0] >> 26) & 7; | ||
893 | card->r2w_factor = temp; | ||
894 | |||
895 | return card; | ||
896 | } | 856 | } |
897 | 857 | ||
898 | bool card_detect_target(void) | 858 | bool card_detect_target(void) |