diff options
Diffstat (limited to 'firmware/target/arm/sandisk/sansa-e200/ata-e200.c')
-rw-r--r-- | firmware/target/arm/sandisk/sansa-e200/ata-e200.c | 125 |
1 files changed, 93 insertions, 32 deletions
diff --git a/firmware/target/arm/sandisk/sansa-e200/ata-e200.c b/firmware/target/arm/sandisk/sansa-e200/ata-e200.c index ff277ec8a3..a61e2ab610 100644 --- a/firmware/target/arm/sandisk/sansa-e200/ata-e200.c +++ b/firmware/target/arm/sandisk/sansa-e200/ata-e200.c | |||
@@ -57,7 +57,8 @@ | |||
57 | #define FIFO_EMPTY (1 << 6) | 57 | #define FIFO_EMPTY (1 << 6) |
58 | 58 | ||
59 | #define CMD_OK 0x0 /* Command was successful */ | 59 | #define CMD_OK 0x0 /* Command was successful */ |
60 | #define CMD_ERROR_2 0x2 /* Seen when SD card is not inserted */ | 60 | #define CMD_ERROR_2 0x2 /* SD did not respond to command (either it doesn't |
61 | understand the command or is not inserted) */ | ||
61 | 62 | ||
62 | /* SD States */ | 63 | /* SD States */ |
63 | #define IDLE 0 | 64 | #define IDLE 0 |
@@ -80,6 +81,7 @@ | |||
80 | #define SWITCH_FUNC 6 | 81 | #define SWITCH_FUNC 6 |
81 | #define SELECT_CARD 7 | 82 | #define SELECT_CARD 7 |
82 | #define DESELECT_CARD 7 | 83 | #define DESELECT_CARD 7 |
84 | #define SEND_IF_COND 8 | ||
83 | #define SEND_CSD 9 | 85 | #define SEND_CSD 9 |
84 | #define SEND_CID 10 | 86 | #define SEND_CID 10 |
85 | #define STOP_TRANSMISSION 12 | 87 | #define STOP_TRANSMISSION 12 |
@@ -244,12 +246,12 @@ static int sd_command(unsigned int cmd, unsigned long arg1, | |||
244 | } | 246 | } |
245 | else | 247 | else |
246 | { | 248 | { |
247 | /* Response types 1, 1b, 3, 6 have the following structure: | 249 | /* Response types 1, 1b, 3, 6, 7 have the following structure: |
248 | * Types 4 and 5 are not supported. | 250 | * Types 4 and 5 are not supported. |
249 | * | 251 | * |
250 | * [47] Start bit - '0' | 252 | * [47] Start bit - '0' |
251 | * [46] Transmission bit - '0' | 253 | * [46] Transmission bit - '0' |
252 | * [45:40] R1, R1b, R6: Command index | 254 | * [45:40] R1, R1b, R6, R7: Command index |
253 | * R3: Reserved - '111111' | 255 | * R3: Reserved - '111111' |
254 | * [39:8] R1, R1b: Card Status | 256 | * [39:8] R1, R1b: Card Status |
255 | * R3: OCR Register | 257 | * R3: OCR Register |
@@ -266,6 +268,8 @@ static int sd_command(unsigned int cmd, unsigned long arg1, | |||
266 | * [3] AKE_SEQ_ERROR | 268 | * [3] AKE_SEQ_ERROR |
267 | * [2] Reserved | 269 | * [2] Reserved |
268 | * [1:0] Reserved for test mode | 270 | * [1:0] Reserved for test mode |
271 | * R7: [19:16] Voltage accepted | ||
272 | * [15:8] echo-back of check pattern | ||
269 | * [7:1] R1, R1b: CRC7 | 273 | * [7:1] R1, R1b: CRC7 |
270 | * R3: Reserved - '1111111' | 274 | * R3: Reserved - '1111111' |
271 | * [0] End Bit - '1' | 275 | * [0] End Bit - '1' |
@@ -544,6 +548,7 @@ static void sd_card_mux(int card_no) | |||
544 | static void sd_init_device(int card_no) | 548 | static void sd_init_device(int card_no) |
545 | { | 549 | { |
546 | /* SD Protocol registers */ | 550 | /* SD Protocol registers */ |
551 | unsigned int response = 0; | ||
547 | unsigned int i; | 552 | unsigned int i; |
548 | unsigned int c_size; | 553 | unsigned int c_size; |
549 | unsigned long c_mult; | 554 | unsigned long c_mult; |
@@ -581,13 +586,32 @@ static void sd_init_device(int card_no) | |||
581 | goto card_init_error; | 586 | goto card_init_error; |
582 | 587 | ||
583 | check_time[EC_POWER_UP] = USEC_TIMER; | 588 | check_time[EC_POWER_UP] = USEC_TIMER; |
589 | |||
590 | /* Check for SDHC: | ||
591 | - non-SDHC cards simply ignore SEND_IF_COND (CMD8) and we get error -219, | ||
592 | which we can just ignore and assume we're dealing with standard SD. | ||
593 | - SDHC cards echo back the argument into the response. This is how we | ||
594 | tell if the card is SDHC. | ||
595 | */ | ||
596 | ret = sd_command(SEND_IF_COND,0x1aa, &response,7); | ||
597 | if ( (ret < 0) && (ret!=-219) ) | ||
598 | goto card_init_error; | ||
599 | |||
584 | while ((currcard->ocr & (1 << 31)) == 0) /* until card is powered up */ | 600 | while ((currcard->ocr & (1 << 31)) == 0) /* until card is powered up */ |
585 | { | 601 | { |
586 | ret = sd_command(APP_CMD, currcard->rca, NULL, 1); | 602 | ret = sd_command(APP_CMD, currcard->rca, NULL, 1); |
587 | if (ret < 0) | 603 | if (ret < 0) |
588 | goto card_init_error; | 604 | goto card_init_error; |
589 | 605 | ||
590 | ret = sd_command(SD_APP_OP_COND, 0x100000, &currcard->ocr, 3); | 606 | if(response == 0x1aa) |
607 | { | ||
608 | /* SDHC */ | ||
609 | ret = sd_command(SD_APP_OP_COND, (1<<30)|0x100000, | ||
610 | &currcard->ocr, 3); | ||
611 | } else { | ||
612 | /* SD Standard */ | ||
613 | ret = sd_command(SD_APP_OP_COND, 0x100000, &currcard->ocr, 3); | ||
614 | } | ||
591 | if (ret < 0) | 615 | if (ret < 0) |
592 | goto card_init_error; | 616 | goto card_init_error; |
593 | 617 | ||
@@ -611,13 +635,26 @@ static void sd_init_device(int card_no) | |||
611 | goto card_init_error; | 635 | goto card_init_error; |
612 | 636 | ||
613 | /* These calculations come from the Sandisk SD card product manual */ | 637 | /* These calculations come from the Sandisk SD card product manual */ |
614 | c_size = ((currcard->csd[2] & 0x3ff) << 2) + (currcard->csd[1] >> 30) + 1; | 638 | if( (currcard->csd[3]>>30) == 0) |
615 | c_mult = 4 << ((currcard->csd[1] >> 15) & 7); | 639 | { |
616 | currcard->max_read_bl_len = 1 << ((currcard->csd[2] >> 16) & 15); | 640 | /* CSD version 1.0 */ |
617 | currcard->block_size = BLOCK_SIZE; /* Always use 512 byte blocks */ | 641 | c_size = ((currcard->csd[2] & 0x3ff) << 2) + (currcard->csd[1]>>30) + 1; |
618 | currcard->numblocks = c_size * c_mult * (currcard->max_read_bl_len / 512); | 642 | c_mult = 4 << ((currcard->csd[1] >> 15) & 7); |
619 | currcard->capacity = currcard->numblocks * currcard->block_size; | 643 | currcard->max_read_bl_len = 1 << ((currcard->csd[2] >> 16) & 15); |
620 | 644 | currcard->block_size = BLOCK_SIZE; /* Always use 512 byte blocks */ | |
645 | currcard->numblocks = c_size * c_mult * (currcard->max_read_bl_len/512); | ||
646 | currcard->capacity = currcard->numblocks * currcard->block_size; | ||
647 | } | ||
648 | else if( (currcard->csd[3]>>30) == 1) | ||
649 | { | ||
650 | /* CSD version 2.0 */ | ||
651 | c_size = ((currcard->csd[2] & 0x3f) << 16) + (currcard->csd[1]>>16) + 1; | ||
652 | currcard->max_read_bl_len = 1 << ((currcard->csd[2] >> 16) & 0xf); | ||
653 | currcard->block_size = BLOCK_SIZE; /* Always use 512 byte blocks */ | ||
654 | currcard->numblocks = c_size; | ||
655 | currcard->capacity = currcard->numblocks * currcard->block_size; | ||
656 | } | ||
657 | |||
621 | REG_1 = 0; | 658 | REG_1 = 0; |
622 | 659 | ||
623 | ret = sd_command(SELECT_CARD, currcard->rca, NULL, 129); | 660 | ret = sd_command(SELECT_CARD, currcard->rca, NULL, 129); |
@@ -638,8 +675,9 @@ static void sd_init_device(int card_no) | |||
638 | 675 | ||
639 | BLOCK_SIZE_REG = currcard->block_size; | 676 | BLOCK_SIZE_REG = currcard->block_size; |
640 | 677 | ||
641 | /* If this card is > 4Gb, then we need to enable bank switching */ | 678 | /* If this card is >4GB & not SDHC, then we need to enable bank switching */ |
642 | if (currcard->numblocks >= BLOCKS_PER_BANK) | 679 | if( (currcard->numblocks >= BLOCKS_PER_BANK) && |
680 | ((currcard->ocr & (1<<30)) == 0) ) | ||
643 | { | 681 | { |
644 | SD_STATE_REG = TRAN; | 682 | SD_STATE_REG = TRAN; |
645 | BLOCK_COUNT_REG = 1; | 683 | BLOCK_COUNT_REG = 1; |
@@ -737,16 +775,20 @@ ata_read_retry: | |||
737 | 775 | ||
738 | last_disk_activity = current_tick; | 776 | last_disk_activity = current_tick; |
739 | 777 | ||
740 | bank = start / BLOCKS_PER_BANK; | 778 | /* Only switch banks with non-SDHC cards */ |
741 | 779 | if((currcard->ocr & (1<<30))==0) | |
742 | if (currcard->current_bank != bank) | ||
743 | { | 780 | { |
744 | ret = sd_select_bank(bank); | 781 | bank = start / BLOCKS_PER_BANK; |
745 | if (ret < 0) | ||
746 | goto ata_read_error; | ||
747 | } | ||
748 | 782 | ||
749 | start -= bank * BLOCKS_PER_BANK; | 783 | if (currcard->current_bank != bank) |
784 | { | ||
785 | ret = sd_select_bank(bank); | ||
786 | if (ret < 0) | ||
787 | goto ata_read_error; | ||
788 | } | ||
789 | |||
790 | start -= bank * BLOCKS_PER_BANK; | ||
791 | } | ||
750 | 792 | ||
751 | ret = sd_wait_for_state(TRAN, EC_TRAN_READ_ENTRY); | 793 | ret = sd_wait_for_state(TRAN, EC_TRAN_READ_ENTRY); |
752 | if (ret < 0) | 794 | if (ret < 0) |
@@ -754,7 +796,15 @@ ata_read_retry: | |||
754 | 796 | ||
755 | BLOCK_COUNT_REG = incount; | 797 | BLOCK_COUNT_REG = incount; |
756 | 798 | ||
757 | ret = sd_command(READ_MULTIPLE_BLOCK, start * BLOCK_SIZE, NULL, 0x1c25); | 799 | if(currcard->ocr & (1<<30) ) |
800 | { | ||
801 | /* SDHC */ | ||
802 | ret = sd_command(READ_MULTIPLE_BLOCK, start, NULL, 0x1c25); | ||
803 | } | ||
804 | else | ||
805 | { | ||
806 | ret = sd_command(READ_MULTIPLE_BLOCK, start * BLOCK_SIZE, NULL, 0x1c25); | ||
807 | } | ||
758 | if (ret < 0) | 808 | if (ret < 0) |
759 | goto ata_read_error; | 809 | goto ata_read_error; |
760 | 810 | ||
@@ -833,16 +883,20 @@ ata_write_retry: | |||
833 | goto ata_write_error; | 883 | goto ata_write_error; |
834 | } | 884 | } |
835 | 885 | ||
836 | bank = start / BLOCKS_PER_BANK; | 886 | /* Only switch banks with non-SDHC cards */ |
837 | 887 | if((currcard->ocr & (1<<30))==0) | |
838 | if (currcard->current_bank != bank) | ||
839 | { | 888 | { |
840 | ret = sd_select_bank(bank); | 889 | bank = start / BLOCKS_PER_BANK; |
841 | if (ret < 0) | ||
842 | goto ata_write_error; | ||
843 | } | ||
844 | 890 | ||
845 | start -= bank * BLOCKS_PER_BANK; | 891 | if (currcard->current_bank != bank) |
892 | { | ||
893 | ret = sd_select_bank(bank); | ||
894 | if (ret < 0) | ||
895 | goto ata_write_error; | ||
896 | } | ||
897 | |||
898 | start -= bank * BLOCKS_PER_BANK; | ||
899 | } | ||
846 | 900 | ||
847 | check_time[EC_WRITE_TIMEOUT] = USEC_TIMER; | 901 | check_time[EC_WRITE_TIMEOUT] = USEC_TIMER; |
848 | 902 | ||
@@ -852,8 +906,15 @@ ata_write_retry: | |||
852 | 906 | ||
853 | BLOCK_COUNT_REG = count; | 907 | BLOCK_COUNT_REG = count; |
854 | 908 | ||
855 | ret = sd_command(WRITE_MULTIPLE_BLOCK, start * SECTOR_SIZE, | 909 | if(currcard->ocr & (1<<30) ) |
856 | NULL, 0x1c2d); | 910 | { |
911 | /* SDHC */ | ||
912 | ret = sd_command(WRITE_MULTIPLE_BLOCK, start, NULL, 0x1c2d); | ||
913 | } | ||
914 | else | ||
915 | { | ||
916 | ret = sd_command(WRITE_MULTIPLE_BLOCK, start*BLOCK_SIZE, NULL, 0x1c2d); | ||
917 | } | ||
857 | if (ret < 0) | 918 | if (ret < 0) |
858 | goto ata_write_error; | 919 | goto ata_write_error; |
859 | 920 | ||