diff options
author | Rafaël Carré <rafael.carre@gmail.com> | 2009-07-01 21:49:13 +0000 |
---|---|---|
committer | Rafaël Carré <rafael.carre@gmail.com> | 2009-07-01 21:49:13 +0000 |
commit | c0eb9aeb9e89ae33a9f084167147d8eacb9c7c60 (patch) | |
tree | 57e96460989d9cccc421486769befb5648601b8c /firmware/target/arm/ata-sd-pp.c | |
parent | 93f6e3df246ff50c24524c9d329f27a06e1845db (diff) | |
download | rockbox-c0eb9aeb9e89ae33a9f084167147d8eacb9c7c60.tar.gz rockbox-c0eb9aeb9e89ae33a9f084167147d8eacb9c7c60.zip |
add firmware/driver/sd.c which contains common code between SD drivers
ingenic SD driver needs more cleanup so it still doesn't use the common code
correct a comment in hotswap.c: card_extract_bits assume most significant word of register first (so, use this order)
fix debug menu which used MMC specific commands / bits positions in csd/cid
move the default block size of 512 into sd.h
move the mantissa & exponent table into a single file (sd.c) to reduce binsize. we don't need to export it anymore anyway
TODO : ingenic cleanup (will happen soon so building sd.c is not conditional)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21601 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm/ata-sd-pp.c')
-rw-r--r-- | firmware/target/arm/ata-sd-pp.c | 73 |
1 files changed, 16 insertions, 57 deletions
diff --git a/firmware/target/arm/ata-sd-pp.c b/firmware/target/arm/ata-sd-pp.c index 8f30195791..df13a119f8 100644 --- a/firmware/target/arm/ata-sd-pp.c +++ b/firmware/target/arm/ata-sd-pp.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include "sd.h" | 36 | #include "sd.h" |
37 | #include "storage.h" | 37 | #include "storage.h" |
38 | 38 | ||
39 | #define BLOCK_SIZE 512 | ||
40 | #define SECTOR_SIZE 512 | 39 | #define SECTOR_SIZE 512 |
41 | #define BLOCKS_PER_BANK 0x7a7800 | 40 | #define BLOCKS_PER_BANK 0x7a7800 |
42 | 41 | ||
@@ -552,7 +551,7 @@ static int sd_select_bank(unsigned char bank) | |||
552 | 551 | ||
553 | /* Write the card data */ | 552 | /* Write the card data */ |
554 | write_buf = card_data; | 553 | write_buf = card_data; |
555 | for (i = 0; i < BLOCK_SIZE/2; i += FIFO_LEN) | 554 | for (i = 0; i < SD_BLOCK_SIZE/2; i += FIFO_LEN) |
556 | { | 555 | { |
557 | /* Wait for the FIFO to empty */ | 556 | /* Wait for the FIFO to empty */ |
558 | if (sd_poll_status(STAT_XMIT_FIFO_EMPTY, 10000)) | 557 | if (sd_poll_status(STAT_XMIT_FIFO_EMPTY, 10000)) |
@@ -652,10 +651,9 @@ static void sd_init_device(int card_no) | |||
652 | unsigned long response = 0; | 651 | unsigned long response = 0; |
653 | #endif | 652 | #endif |
654 | unsigned int i; | 653 | unsigned int i; |
655 | unsigned int c_size; | ||
656 | unsigned long c_mult; | ||
657 | unsigned char carddata[512]; | 654 | unsigned char carddata[512]; |
658 | unsigned char *dataptr; | 655 | unsigned char *dataptr; |
656 | unsigned long temp_reg[4]; | ||
659 | int ret; | 657 | int ret; |
660 | 658 | ||
661 | /* Enable and initialise controller */ | 659 | /* Enable and initialise controller */ |
@@ -733,38 +731,25 @@ static void sd_init_device(int card_no) | |||
733 | } | 731 | } |
734 | } | 732 | } |
735 | 733 | ||
736 | ret = sd_command(SD_ALL_SEND_CID, 0, currcard->cid, CMDAT_RES_TYPE2); | 734 | ret = sd_command(SD_ALL_SEND_CID, 0, temp_reg, CMDAT_RES_TYPE2); |
737 | if (ret < 0) | 735 | if (ret < 0) |
738 | goto card_init_error; | 736 | goto card_init_error; |
739 | 737 | ||
738 | for(i=0; i<4; i++) | ||
739 | currcard->cid[i] = temp_reg[3-i]; | ||
740 | |||
740 | ret = sd_command(SD_SEND_RELATIVE_ADDR, 0, &currcard->rca, CMDAT_RES_TYPE1); | 741 | ret = sd_command(SD_SEND_RELATIVE_ADDR, 0, &currcard->rca, CMDAT_RES_TYPE1); |
741 | if (ret < 0) | 742 | if (ret < 0) |
742 | goto card_init_error; | 743 | goto card_init_error; |
743 | 744 | ||
744 | ret = sd_command(SD_SEND_CSD, currcard->rca, currcard->csd, CMDAT_RES_TYPE2); | 745 | ret = sd_command(SD_SEND_CSD, currcard->rca, temp_reg, CMDAT_RES_TYPE2); |
745 | if (ret < 0) | 746 | if (ret < 0) |
746 | goto card_init_error; | 747 | goto card_init_error; |
747 | 748 | ||
748 | /* These calculations come from the Sandisk SD card product manual */ | 749 | for(i=0; i<4; i++) |
749 | if( (currcard->csd[3]>>30) == 0) | 750 | currcard->csd[i] = temp_reg[3-i]; |
750 | { | 751 | |
751 | int max_read_bl_len; | 752 | sd_parse_csd(currcard); |
752 | /* CSD version 1.0 */ | ||
753 | c_size = ((currcard->csd[2] & 0x3ff) << 2) + (currcard->csd[1]>>30) + 1; | ||
754 | c_mult = 4 << ((currcard->csd[1] >> 15) & 7); | ||
755 | max_read_bl_len = 1 << ((currcard->csd[2] >> 16) & 15); | ||
756 | currcard->blocksize = BLOCK_SIZE; /* Always use 512 byte blocks */ | ||
757 | currcard->numblocks = c_size * c_mult * (max_read_bl_len/512); | ||
758 | } | ||
759 | #ifdef HAVE_HOTSWAP | ||
760 | else if( (currcard->csd[3]>>30) == 1) | ||
761 | { | ||
762 | /* CSD version 2.0 */ | ||
763 | c_size = ((currcard->csd[2] & 0x3f) << 16) + (currcard->csd[1]>>16) + 1; | ||
764 | currcard->blocksize = BLOCK_SIZE; /* Always use 512 byte blocks */ | ||
765 | currcard->numblocks = c_size << 10; | ||
766 | } | ||
767 | #endif /* HAVE_HOTSWAP */ | ||
768 | 753 | ||
769 | MMC_CLKRT = 0; /* switch to highest clock rate */ | 754 | MMC_CLKRT = 0; /* switch to highest clock rate */ |
770 | 755 | ||
@@ -805,7 +790,7 @@ static void sd_init_device(int card_no) | |||
805 | The first 512 bits contain the status information | 790 | The first 512 bits contain the status information |
806 | TODO: Do something useful with this! */ | 791 | TODO: Do something useful with this! */ |
807 | dataptr = carddata; | 792 | dataptr = carddata; |
808 | for (i = 0; i < BLOCK_SIZE/2; i += FIFO_LEN) | 793 | for (i = 0; i < SD_BLOCK_SIZE/2; i += FIFO_LEN) |
809 | { | 794 | { |
810 | /* Wait for the FIFO to be full */ | 795 | /* Wait for the FIFO to be full */ |
811 | if (sd_poll_status(STAT_RECV_FIFO_FULL, 100000)) | 796 | if (sd_poll_status(STAT_RECV_FIFO_FULL, 100000)) |
@@ -924,13 +909,13 @@ sd_read_retry: | |||
924 | else | 909 | else |
925 | #endif | 910 | #endif |
926 | { | 911 | { |
927 | ret = sd_command(SD_READ_MULTIPLE_BLOCK, start * BLOCK_SIZE, NULL, | 912 | ret = sd_command(SD_READ_MULTIPLE_BLOCK, start * SD_BLOCK_SIZE, NULL, |
928 | 0x1c00 | CMDAT_BUSY | CMDAT_DATA_EN | CMDAT_RES_TYPE1); | 913 | 0x1c00 | CMDAT_BUSY | CMDAT_DATA_EN | CMDAT_RES_TYPE1); |
929 | } | 914 | } |
930 | if (ret < 0) | 915 | if (ret < 0) |
931 | goto sd_read_error; | 916 | goto sd_read_error; |
932 | 917 | ||
933 | /* TODO: Don't assume BLOCK_SIZE == SECTOR_SIZE */ | 918 | /* TODO: Don't assume SD_BLOCK_SIZE == SECTOR_SIZE */ |
934 | 919 | ||
935 | buf_end = (unsigned char *)inbuf + incount * currcard->blocksize; | 920 | buf_end = (unsigned char *)inbuf + incount * currcard->blocksize; |
936 | for (buf = inbuf; buf < buf_end;) | 921 | for (buf = inbuf; buf < buf_end;) |
@@ -1042,7 +1027,7 @@ sd_write_retry: | |||
1042 | else | 1027 | else |
1043 | #endif | 1028 | #endif |
1044 | { | 1029 | { |
1045 | ret = sd_command(SD_WRITE_MULTIPLE_BLOCK, start*BLOCK_SIZE, NULL, | 1030 | ret = sd_command(SD_WRITE_MULTIPLE_BLOCK, start*SD_BLOCK_SIZE, NULL, |
1046 | CMDAT_WR_RD | CMDAT_DATA_EN | CMDAT_RES_TYPE1); | 1031 | CMDAT_WR_RD | CMDAT_DATA_EN | CMDAT_RES_TYPE1); |
1047 | } | 1032 | } |
1048 | if (ret < 0) | 1033 | if (ret < 0) |
@@ -1290,35 +1275,9 @@ int sd_init(void) | |||
1290 | return ret; | 1275 | return ret; |
1291 | } | 1276 | } |
1292 | 1277 | ||
1293 | /* move the sd-card info to mmc struct */ | ||
1294 | tCardInfo *card_get_info_target(int card_no) | 1278 | tCardInfo *card_get_info_target(int card_no) |
1295 | { | 1279 | { |
1296 | int i, temp; | 1280 | return &card_info[card_no]; |
1297 | static tCardInfo card; | ||
1298 | static const char mantissa[] = { /* *10 */ | ||
1299 | 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80 }; | ||
1300 | static const int exponent[] = { /* use varies */ | ||
1301 | 1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000 }; | ||
1302 | |||
1303 | card.initialized = card_info[card_no].initialized; | ||
1304 | card.ocr = card_info[card_no].ocr; | ||
1305 | for(i=0; i<4; i++) card.csd[i] = card_info[card_no].csd[3-i]; | ||
1306 | for(i=0; i<4; i++) card.cid[i] = card_info[card_no].cid[3-i]; | ||
1307 | card.numblocks = card_info[card_no].numblocks; | ||
1308 | card.blocksize = card_info[card_no].blocksize; | ||
1309 | temp = card_extract_bits(card.csd, 98, 3); | ||
1310 | card.speed = mantissa[card_extract_bits(card.csd, 102, 4)] | ||
1311 | * exponent[temp > 2 ? 7 : temp + 4]; | ||
1312 | card.nsac = 100 * card_extract_bits(card.csd, 111, 8); | ||
1313 | temp = card_extract_bits(card.csd, 114, 3); | ||
1314 | card.taac = mantissa[card_extract_bits(card.csd, 118, 4)] | ||
1315 | * exponent[temp] / 10; | ||
1316 | card.cid[0] = htobe32(card.cid[0]); /* ascii chars here */ | ||
1317 | card.cid[1] = htobe32(card.cid[1]); /* ascii chars here */ | ||
1318 | temp = *((char*)card.cid+13); /* adjust year<=>month, 1997 <=> 2000 */ | ||
1319 | *((char*)card.cid+13) = (unsigned char)((temp >> 4) | (temp << 4)) + 3; | ||
1320 | |||
1321 | return &card; | ||
1322 | } | 1281 | } |
1323 | 1282 | ||
1324 | bool card_detect_target(void) | 1283 | bool card_detect_target(void) |