Commit da7fbe58d2d347e95af699ddf04d885be6362bbe
1 parent
aaac1b470b
Exists in
master
and in
7 other branches
mmc: Separate out protocol ops
Move protocol operations and definitions into their own files in an effort to separate protocol handling and bus arbitration more clearly. Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Showing 14 changed files with 1099 additions and 772 deletions Side-by-side Diff
- drivers/mmc/card/block.c
- drivers/mmc/core/Makefile
- drivers/mmc/core/core.c
- drivers/mmc/core/core.h
- drivers/mmc/core/mmc_ops.c
- drivers/mmc/core/mmc_ops.h
- drivers/mmc/core/sd_ops.c
- drivers/mmc/core/sd_ops.h
- drivers/mmc/core/sysfs.c
- drivers/mmc/core/sysfs.h
- include/linux/mmc/core.h
- include/linux/mmc/mmc.h
- include/linux/mmc/protocol.h
- include/linux/mmc/sd.h
drivers/mmc/card/block.c
drivers/mmc/core/Makefile
drivers/mmc/core/core.c
... | ... | @@ -23,10 +23,15 @@ |
23 | 23 | |
24 | 24 | #include <linux/mmc/card.h> |
25 | 25 | #include <linux/mmc/host.h> |
26 | -#include <linux/mmc/protocol.h> | |
26 | +#include <linux/mmc/mmc.h> | |
27 | +#include <linux/mmc/sd.h> | |
27 | 28 | |
28 | 29 | #include "core.h" |
30 | +#include "sysfs.h" | |
29 | 31 | |
32 | +#include "mmc_ops.h" | |
33 | +#include "sd_ops.h" | |
34 | + | |
30 | 35 | #define CMD_RETRIES 3 |
31 | 36 | |
32 | 37 | /* |
... | ... | @@ -191,80 +196,6 @@ |
191 | 196 | EXPORT_SYMBOL(mmc_wait_for_cmd); |
192 | 197 | |
193 | 198 | /** |
194 | - * mmc_wait_for_app_cmd - start an application command and wait for | |
195 | - completion | |
196 | - * @host: MMC host to start command | |
197 | - * @rca: RCA to send MMC_APP_CMD to | |
198 | - * @cmd: MMC command to start | |
199 | - * @retries: maximum number of retries | |
200 | - * | |
201 | - * Sends a MMC_APP_CMD, checks the card response, sends the command | |
202 | - * in the parameter and waits for it to complete. Return any error | |
203 | - * that occurred while the command was executing. Do not attempt to | |
204 | - * parse the response. | |
205 | - */ | |
206 | -int mmc_wait_for_app_cmd(struct mmc_host *host, unsigned int rca, | |
207 | - struct mmc_command *cmd, int retries) | |
208 | -{ | |
209 | - struct mmc_request mrq; | |
210 | - struct mmc_command appcmd; | |
211 | - | |
212 | - int i, err; | |
213 | - | |
214 | - BUG_ON(!host->claimed); | |
215 | - BUG_ON(retries < 0); | |
216 | - | |
217 | - err = MMC_ERR_INVALID; | |
218 | - | |
219 | - /* | |
220 | - * We have to resend MMC_APP_CMD for each attempt so | |
221 | - * we cannot use the retries field in mmc_command. | |
222 | - */ | |
223 | - for (i = 0;i <= retries;i++) { | |
224 | - memset(&mrq, 0, sizeof(struct mmc_request)); | |
225 | - | |
226 | - appcmd.opcode = MMC_APP_CMD; | |
227 | - appcmd.arg = rca << 16; | |
228 | - appcmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | |
229 | - appcmd.retries = 0; | |
230 | - memset(appcmd.resp, 0, sizeof(appcmd.resp)); | |
231 | - appcmd.data = NULL; | |
232 | - | |
233 | - mrq.cmd = &appcmd; | |
234 | - appcmd.data = NULL; | |
235 | - | |
236 | - mmc_wait_for_req(host, &mrq); | |
237 | - | |
238 | - if (appcmd.error) { | |
239 | - err = appcmd.error; | |
240 | - continue; | |
241 | - } | |
242 | - | |
243 | - /* Check that card supported application commands */ | |
244 | - if (!(appcmd.resp[0] & R1_APP_CMD)) | |
245 | - return MMC_ERR_FAILED; | |
246 | - | |
247 | - memset(&mrq, 0, sizeof(struct mmc_request)); | |
248 | - | |
249 | - memset(cmd->resp, 0, sizeof(cmd->resp)); | |
250 | - cmd->retries = 0; | |
251 | - | |
252 | - mrq.cmd = cmd; | |
253 | - cmd->data = NULL; | |
254 | - | |
255 | - mmc_wait_for_req(host, &mrq); | |
256 | - | |
257 | - err = cmd->error; | |
258 | - if (cmd->error == MMC_ERR_NONE) | |
259 | - break; | |
260 | - } | |
261 | - | |
262 | - return err; | |
263 | -} | |
264 | - | |
265 | -EXPORT_SYMBOL(mmc_wait_for_app_cmd); | |
266 | - | |
267 | -/** | |
268 | 199 | * mmc_set_data_timeout - set the timeout for a data command |
269 | 200 | * @data: data phase for command |
270 | 201 | * @card: the MMC card associated with the data transfer |
271 | 202 | |
272 | 203 | |
... | ... | @@ -385,62 +316,12 @@ |
385 | 316 | host->ops->set_ios(host, ios); |
386 | 317 | } |
387 | 318 | |
388 | -static int mmc_select_card(struct mmc_card *card) | |
319 | +void mmc_set_chip_select(struct mmc_host *host, int mode) | |
389 | 320 | { |
390 | - int err; | |
391 | - struct mmc_command cmd; | |
392 | - | |
393 | - BUG_ON(!card->host->claimed); | |
394 | - | |
395 | - cmd.opcode = MMC_SELECT_CARD; | |
396 | - cmd.arg = card->rca << 16; | |
397 | - cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | |
398 | - | |
399 | - err = mmc_wait_for_cmd(card->host, &cmd, CMD_RETRIES); | |
400 | - if (err != MMC_ERR_NONE) | |
401 | - return err; | |
402 | - | |
403 | - /* | |
404 | - * We can only change the bus width of SD cards when | |
405 | - * they are selected so we have to put the handling | |
406 | - * here. | |
407 | - * | |
408 | - * The card is in 1 bit mode by default so | |
409 | - * we only need to change if it supports the | |
410 | - * wider version. | |
411 | - */ | |
412 | - if (mmc_card_sd(card) && | |
413 | - (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4) && | |
414 | - (card->host->caps & MMC_CAP_4_BIT_DATA)) { | |
415 | - | |
416 | - struct mmc_command cmd; | |
417 | - cmd.opcode = SD_APP_SET_BUS_WIDTH; | |
418 | - cmd.arg = SD_BUS_WIDTH_4; | |
419 | - cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | |
420 | - | |
421 | - err = mmc_wait_for_app_cmd(card->host, card->rca, | |
422 | - &cmd, CMD_RETRIES); | |
423 | - if (err != MMC_ERR_NONE) | |
424 | - return err; | |
425 | - | |
426 | - card->host->ios.bus_width = MMC_BUS_WIDTH_4; | |
427 | - mmc_set_ios(card->host); | |
428 | - } | |
429 | - | |
430 | - return MMC_ERR_NONE; | |
321 | + host->ios.chip_select = mode; | |
322 | + mmc_set_ios(host); | |
431 | 323 | } |
432 | 324 | |
433 | - | |
434 | -static inline void mmc_delay(unsigned int ms) | |
435 | -{ | |
436 | - if (ms < 1000 / HZ) { | |
437 | - cond_resched(); | |
438 | - mdelay(ms); | |
439 | - } else { | |
440 | - msleep(ms); | |
441 | - } | |
442 | -} | |
443 | - | |
444 | 325 | /* |
445 | 326 | * Mask off any voltages we don't support and select |
446 | 327 | * the lowest voltage |
... | ... | @@ -709,32 +590,6 @@ |
709 | 590 | } |
710 | 591 | |
711 | 592 | /* |
712 | - * Tell attached cards to go to IDLE state | |
713 | - */ | |
714 | -static void mmc_idle_cards(struct mmc_host *host) | |
715 | -{ | |
716 | - struct mmc_command cmd; | |
717 | - | |
718 | - host->ios.chip_select = MMC_CS_HIGH; | |
719 | - mmc_set_ios(host); | |
720 | - | |
721 | - mmc_delay(1); | |
722 | - | |
723 | - cmd.opcode = MMC_GO_IDLE_STATE; | |
724 | - cmd.arg = 0; | |
725 | - cmd.flags = MMC_RSP_NONE | MMC_CMD_BC; | |
726 | - | |
727 | - mmc_wait_for_cmd(host, &cmd, 0); | |
728 | - | |
729 | - mmc_delay(1); | |
730 | - | |
731 | - host->ios.chip_select = MMC_CS_DONTCARE; | |
732 | - mmc_set_ios(host); | |
733 | - | |
734 | - mmc_delay(1); | |
735 | -} | |
736 | - | |
737 | -/* | |
738 | 593 | * Apply power to the MMC stack. This is a two-stage process. |
739 | 594 | * First, we enable power to the card without the clock running. |
740 | 595 | * We then wait a bit for the power to stabilise. Finally, |
... | ... | @@ -778,97 +633,6 @@ |
778 | 633 | mmc_set_ios(host); |
779 | 634 | } |
780 | 635 | |
781 | -static int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) | |
782 | -{ | |
783 | - struct mmc_command cmd; | |
784 | - int i, err = 0; | |
785 | - | |
786 | - cmd.opcode = MMC_SEND_OP_COND; | |
787 | - cmd.arg = ocr; | |
788 | - cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; | |
789 | - | |
790 | - for (i = 100; i; i--) { | |
791 | - err = mmc_wait_for_cmd(host, &cmd, 0); | |
792 | - if (err != MMC_ERR_NONE) | |
793 | - break; | |
794 | - | |
795 | - if (cmd.resp[0] & MMC_CARD_BUSY || ocr == 0) | |
796 | - break; | |
797 | - | |
798 | - err = MMC_ERR_TIMEOUT; | |
799 | - | |
800 | - mmc_delay(10); | |
801 | - } | |
802 | - | |
803 | - if (rocr) | |
804 | - *rocr = cmd.resp[0]; | |
805 | - | |
806 | - return err; | |
807 | -} | |
808 | - | |
809 | -static int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) | |
810 | -{ | |
811 | - struct mmc_command cmd; | |
812 | - int i, err = 0; | |
813 | - | |
814 | - cmd.opcode = SD_APP_OP_COND; | |
815 | - cmd.arg = ocr; | |
816 | - cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; | |
817 | - | |
818 | - for (i = 100; i; i--) { | |
819 | - err = mmc_wait_for_app_cmd(host, 0, &cmd, CMD_RETRIES); | |
820 | - if (err != MMC_ERR_NONE) | |
821 | - break; | |
822 | - | |
823 | - if (cmd.resp[0] & MMC_CARD_BUSY || ocr == 0) | |
824 | - break; | |
825 | - | |
826 | - err = MMC_ERR_TIMEOUT; | |
827 | - | |
828 | - mmc_delay(10); | |
829 | - } | |
830 | - | |
831 | - if (rocr) | |
832 | - *rocr = cmd.resp[0]; | |
833 | - | |
834 | - return err; | |
835 | -} | |
836 | - | |
837 | -static int mmc_send_if_cond(struct mmc_host *host, u32 ocr, int *rsd2) | |
838 | -{ | |
839 | - struct mmc_command cmd; | |
840 | - int err, sd2; | |
841 | - static const u8 test_pattern = 0xAA; | |
842 | - | |
843 | - /* | |
844 | - * To support SD 2.0 cards, we must always invoke SD_SEND_IF_COND | |
845 | - * before SD_APP_OP_COND. This command will harmlessly fail for | |
846 | - * SD 1.0 cards. | |
847 | - */ | |
848 | - cmd.opcode = SD_SEND_IF_COND; | |
849 | - cmd.arg = ((ocr & 0xFF8000) != 0) << 8 | test_pattern; | |
850 | - cmd.flags = MMC_RSP_R7 | MMC_CMD_BCR; | |
851 | - | |
852 | - err = mmc_wait_for_cmd(host, &cmd, 0); | |
853 | - if (err == MMC_ERR_NONE) { | |
854 | - if ((cmd.resp[0] & 0xFF) == test_pattern) { | |
855 | - sd2 = 1; | |
856 | - } else { | |
857 | - sd2 = 0; | |
858 | - err = MMC_ERR_FAILED; | |
859 | - } | |
860 | - } else { | |
861 | - /* | |
862 | - * Treat errors as SD 1.0 card. | |
863 | - */ | |
864 | - sd2 = 0; | |
865 | - err = MMC_ERR_NONE; | |
866 | - } | |
867 | - if (rsd2) | |
868 | - *rsd2 = sd2; | |
869 | - return err; | |
870 | -} | |
871 | - | |
872 | 636 | /* |
873 | 637 | * Discover the card by requesting its CID. |
874 | 638 | * |
875 | 639 | |
876 | 640 | |
877 | 641 | |
... | ... | @@ -878,27 +642,18 @@ |
878 | 642 | static void mmc_discover_card(struct mmc_host *host) |
879 | 643 | { |
880 | 644 | unsigned int err; |
645 | + u32 cid[4]; | |
881 | 646 | |
882 | - struct mmc_command cmd; | |
883 | - | |
884 | 647 | BUG_ON(host->card); |
885 | 648 | |
886 | - cmd.opcode = MMC_ALL_SEND_CID; | |
887 | - cmd.arg = 0; | |
888 | - cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR; | |
889 | - | |
890 | - err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | |
891 | - if (err == MMC_ERR_TIMEOUT) { | |
892 | - err = MMC_ERR_NONE; | |
893 | - return; | |
894 | - } | |
649 | + err = mmc_all_send_cid(host, cid); | |
895 | 650 | if (err != MMC_ERR_NONE) { |
896 | 651 | printk(KERN_ERR "%s: error requesting CID: %d\n", |
897 | 652 | mmc_hostname(host), err); |
898 | 653 | return; |
899 | 654 | } |
900 | 655 | |
901 | - host->card = mmc_alloc_card(host, cmd.resp); | |
656 | + host->card = mmc_alloc_card(host, cid); | |
902 | 657 | if (IS_ERR(host->card)) { |
903 | 658 | err = PTR_ERR(host->card); |
904 | 659 | host->card = NULL; |
905 | 660 | |
... | ... | @@ -908,16 +663,10 @@ |
908 | 663 | if (host->mode == MMC_MODE_SD) { |
909 | 664 | host->card->type = MMC_TYPE_SD; |
910 | 665 | |
911 | - cmd.opcode = SD_SEND_RELATIVE_ADDR; | |
912 | - cmd.arg = 0; | |
913 | - cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR; | |
914 | - | |
915 | - err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | |
666 | + err = mmc_send_relative_addr(host, &host->card->rca); | |
916 | 667 | if (err != MMC_ERR_NONE) |
917 | 668 | mmc_card_set_dead(host->card); |
918 | 669 | else { |
919 | - host->card->rca = cmd.resp[0] >> 16; | |
920 | - | |
921 | 670 | if (!host->ops->get_ro) { |
922 | 671 | printk(KERN_WARNING "%s: host does not " |
923 | 672 | "support reading read-only " |
... | ... | @@ -932,11 +681,7 @@ |
932 | 681 | host->card->type = MMC_TYPE_MMC; |
933 | 682 | host->card->rca = 1; |
934 | 683 | |
935 | - cmd.opcode = MMC_SET_RELATIVE_ADDR; | |
936 | - cmd.arg = host->card->rca << 16; | |
937 | - cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | |
938 | - | |
939 | - err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | |
684 | + err = mmc_set_relative_addr(host->card); | |
940 | 685 | if (err != MMC_ERR_NONE) |
941 | 686 | mmc_card_set_dead(host->card); |
942 | 687 | } |
... | ... | @@ -944,7 +689,6 @@ |
944 | 689 | |
945 | 690 | static void mmc_read_csd(struct mmc_host *host) |
946 | 691 | { |
947 | - struct mmc_command cmd; | |
948 | 692 | int err; |
949 | 693 | |
950 | 694 | if (!host->card) |
951 | 695 | |
... | ... | @@ -952,18 +696,12 @@ |
952 | 696 | if (mmc_card_dead(host->card)) |
953 | 697 | return; |
954 | 698 | |
955 | - cmd.opcode = MMC_SEND_CSD; | |
956 | - cmd.arg = host->card->rca << 16; | |
957 | - cmd.flags = MMC_RSP_R2 | MMC_CMD_AC; | |
958 | - | |
959 | - err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | |
699 | + err = mmc_send_csd(host->card, host->card->raw_csd); | |
960 | 700 | if (err != MMC_ERR_NONE) { |
961 | 701 | mmc_card_set_dead(host->card); |
962 | 702 | return; |
963 | 703 | } |
964 | 704 | |
965 | - memcpy(host->card->raw_csd, cmd.resp, sizeof(host->card->raw_csd)); | |
966 | - | |
967 | 705 | mmc_decode_csd(host->card); |
968 | 706 | mmc_decode_cid(host->card); |
969 | 707 | } |
970 | 708 | |
... | ... | @@ -971,13 +709,7 @@ |
971 | 709 | static void mmc_process_ext_csd(struct mmc_host *host) |
972 | 710 | { |
973 | 711 | int err; |
974 | - | |
975 | - struct mmc_request mrq; | |
976 | - struct mmc_command cmd; | |
977 | - struct mmc_data data; | |
978 | - | |
979 | 712 | u8 *ext_csd; |
980 | - struct scatterlist sg; | |
981 | 713 | |
982 | 714 | if (!host->card) |
983 | 715 | return; |
... | ... | @@ -1000,32 +732,8 @@ |
1000 | 732 | return; |
1001 | 733 | } |
1002 | 734 | |
1003 | - memset(&cmd, 0, sizeof(struct mmc_command)); | |
1004 | - | |
1005 | - cmd.opcode = MMC_SEND_EXT_CSD; | |
1006 | - cmd.arg = 0; | |
1007 | - cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | |
1008 | - | |
1009 | - memset(&data, 0, sizeof(struct mmc_data)); | |
1010 | - | |
1011 | - mmc_set_data_timeout(&data, host->card, 0); | |
1012 | - | |
1013 | - data.blksz = 512; | |
1014 | - data.blocks = 1; | |
1015 | - data.flags = MMC_DATA_READ; | |
1016 | - data.sg = &sg; | |
1017 | - data.sg_len = 1; | |
1018 | - | |
1019 | - memset(&mrq, 0, sizeof(struct mmc_request)); | |
1020 | - | |
1021 | - mrq.cmd = &cmd; | |
1022 | - mrq.data = &data; | |
1023 | - | |
1024 | - sg_init_one(&sg, ext_csd, 512); | |
1025 | - | |
1026 | - mmc_wait_for_req(host, &mrq); | |
1027 | - | |
1028 | - if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) { | |
735 | + err = mmc_send_ext_csd(host->card, ext_csd); | |
736 | + if (err != MMC_ERR_NONE) { | |
1029 | 737 | if (host->card->csd.capacity == (4096 * 512)) { |
1030 | 738 | printk(KERN_ERR "%s: unable to read EXT_CSD " |
1031 | 739 | "on a possible high capacity card. " |
... | ... | @@ -1066,14 +774,8 @@ |
1066 | 774 | |
1067 | 775 | if (host->caps & MMC_CAP_MMC_HIGHSPEED) { |
1068 | 776 | /* Activate highspeed support. */ |
1069 | - cmd.opcode = MMC_SWITCH; | |
1070 | - cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | | |
1071 | - (EXT_CSD_HS_TIMING << 16) | | |
1072 | - (1 << 8) | | |
1073 | - EXT_CSD_CMD_SET_NORMAL; | |
1074 | - cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; | |
1075 | - | |
1076 | - err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | |
777 | + err = mmc_switch(host->card, MMC_SWITCH_MODE_WRITE_BYTE, | |
778 | + EXT_CSD_HS_TIMING, 1); | |
1077 | 779 | if (err != MMC_ERR_NONE) { |
1078 | 780 | printk("%s: failed to switch card to mmc v4 " |
1079 | 781 | "high-speed mode.\n", |
... | ... | @@ -1090,14 +792,9 @@ |
1090 | 792 | /* Check for host support for wide-bus modes. */ |
1091 | 793 | if (host->caps & MMC_CAP_4_BIT_DATA) { |
1092 | 794 | /* Activate 4-bit support. */ |
1093 | - cmd.opcode = MMC_SWITCH; | |
1094 | - cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | | |
1095 | - (EXT_CSD_BUS_WIDTH << 16) | | |
1096 | - (EXT_CSD_BUS_WIDTH_4 << 8) | | |
1097 | - EXT_CSD_CMD_SET_NORMAL; | |
1098 | - cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; | |
1099 | - | |
1100 | - err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | |
795 | + err = mmc_switch(host->card, MMC_SWITCH_MODE_WRITE_BYTE, | |
796 | + EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_4 | | |
797 | + EXT_CSD_CMD_SET_NORMAL); | |
1101 | 798 | if (err != MMC_ERR_NONE) { |
1102 | 799 | printk("%s: failed to switch card to " |
1103 | 800 | "mmc v4 4-bit bus mode.\n", |
... | ... | @@ -1116,10 +813,6 @@ |
1116 | 813 | static void mmc_read_scr(struct mmc_host *host) |
1117 | 814 | { |
1118 | 815 | int err; |
1119 | - struct mmc_request mrq; | |
1120 | - struct mmc_command cmd; | |
1121 | - struct mmc_data data; | |
1122 | - struct scatterlist sg; | |
1123 | 816 | |
1124 | 817 | if (!host->card) |
1125 | 818 | return; |
1126 | 819 | |
1127 | 820 | |
1128 | 821 | |
... | ... | @@ -1128,61 +821,19 @@ |
1128 | 821 | if (!mmc_card_sd(host->card)) |
1129 | 822 | return; |
1130 | 823 | |
1131 | - memset(&cmd, 0, sizeof(struct mmc_command)); | |
1132 | - | |
1133 | - cmd.opcode = MMC_APP_CMD; | |
1134 | - cmd.arg = host->card->rca << 16; | |
1135 | - cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | |
1136 | - | |
1137 | - err = mmc_wait_for_cmd(host, &cmd, 0); | |
1138 | - if ((err != MMC_ERR_NONE) || !(cmd.resp[0] & R1_APP_CMD)) { | |
824 | + err = mmc_app_send_scr(host->card, host->card->raw_scr); | |
825 | + if (err != MMC_ERR_NONE) { | |
1139 | 826 | mmc_card_set_dead(host->card); |
1140 | 827 | return; |
1141 | 828 | } |
1142 | 829 | |
1143 | - memset(&cmd, 0, sizeof(struct mmc_command)); | |
1144 | - | |
1145 | - cmd.opcode = SD_APP_SEND_SCR; | |
1146 | - cmd.arg = 0; | |
1147 | - cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | |
1148 | - | |
1149 | - memset(&data, 0, sizeof(struct mmc_data)); | |
1150 | - | |
1151 | - mmc_set_data_timeout(&data, host->card, 0); | |
1152 | - | |
1153 | - data.blksz = 1 << 3; | |
1154 | - data.blocks = 1; | |
1155 | - data.flags = MMC_DATA_READ; | |
1156 | - data.sg = &sg; | |
1157 | - data.sg_len = 1; | |
1158 | - | |
1159 | - memset(&mrq, 0, sizeof(struct mmc_request)); | |
1160 | - | |
1161 | - mrq.cmd = &cmd; | |
1162 | - mrq.data = &data; | |
1163 | - | |
1164 | - sg_init_one(&sg, (u8*)host->card->raw_scr, 8); | |
1165 | - | |
1166 | - mmc_wait_for_req(host, &mrq); | |
1167 | - | |
1168 | - if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) { | |
1169 | - mmc_card_set_dead(host->card); | |
1170 | - return; | |
1171 | - } | |
1172 | - | |
1173 | - host->card->raw_scr[0] = ntohl(host->card->raw_scr[0]); | |
1174 | - host->card->raw_scr[1] = ntohl(host->card->raw_scr[1]); | |
1175 | - | |
1176 | 830 | mmc_decode_scr(host->card); |
1177 | 831 | } |
1178 | 832 | |
1179 | 833 | static void mmc_read_switch_caps(struct mmc_host *host) |
1180 | 834 | { |
1181 | - struct mmc_request mrq; | |
1182 | - struct mmc_command cmd; | |
1183 | - struct mmc_data data; | |
835 | + int err; | |
1184 | 836 | unsigned char *status; |
1185 | - struct scatterlist sg; | |
1186 | 837 | |
1187 | 838 | if (!(host->caps & MMC_CAP_SD_HIGHSPEED)) |
1188 | 839 | return; |
... | ... | @@ -1204,32 +855,9 @@ |
1204 | 855 | return; |
1205 | 856 | } |
1206 | 857 | |
1207 | - memset(&cmd, 0, sizeof(struct mmc_command)); | |
1208 | - | |
1209 | - cmd.opcode = SD_SWITCH; | |
1210 | - cmd.arg = 0x00FFFFF1; | |
1211 | - cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | |
1212 | - | |
1213 | - memset(&data, 0, sizeof(struct mmc_data)); | |
1214 | - | |
1215 | - mmc_set_data_timeout(&data, host->card, 0); | |
1216 | - | |
1217 | - data.blksz = 64; | |
1218 | - data.blocks = 1; | |
1219 | - data.flags = MMC_DATA_READ; | |
1220 | - data.sg = &sg; | |
1221 | - data.sg_len = 1; | |
1222 | - | |
1223 | - memset(&mrq, 0, sizeof(struct mmc_request)); | |
1224 | - | |
1225 | - mrq.cmd = &cmd; | |
1226 | - mrq.data = &data; | |
1227 | - | |
1228 | - sg_init_one(&sg, status, 64); | |
1229 | - | |
1230 | - mmc_wait_for_req(host, &mrq); | |
1231 | - | |
1232 | - if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) { | |
858 | + err = mmc_sd_switch(host->card, SD_SWITCH_CHECK, | |
859 | + SD_SWITCH_GRP_ACCESS, SD_SWITCH_ACCESS_HS, status); | |
860 | + if (err != MMC_ERR_NONE) { | |
1233 | 861 | printk("%s: unable to read switch capabilities, " |
1234 | 862 | "performance might suffer.\n", |
1235 | 863 | mmc_hostname(host)); |
... | ... | @@ -1239,33 +867,9 @@ |
1239 | 867 | if (status[13] & 0x02) |
1240 | 868 | host->card->sw_caps.hs_max_dtr = 50000000; |
1241 | 869 | |
1242 | - memset(&cmd, 0, sizeof(struct mmc_command)); | |
1243 | - | |
1244 | - cmd.opcode = SD_SWITCH; | |
1245 | - cmd.arg = 0x80FFFFF1; | |
1246 | - cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | |
1247 | - | |
1248 | - memset(&data, 0, sizeof(struct mmc_data)); | |
1249 | - | |
1250 | - mmc_set_data_timeout(&data, host->card, 0); | |
1251 | - | |
1252 | - data.blksz = 64; | |
1253 | - data.blocks = 1; | |
1254 | - data.flags = MMC_DATA_READ; | |
1255 | - data.sg = &sg; | |
1256 | - data.sg_len = 1; | |
1257 | - | |
1258 | - memset(&mrq, 0, sizeof(struct mmc_request)); | |
1259 | - | |
1260 | - mrq.cmd = &cmd; | |
1261 | - mrq.data = &data; | |
1262 | - | |
1263 | - sg_init_one(&sg, status, 64); | |
1264 | - | |
1265 | - mmc_wait_for_req(host, &mrq); | |
1266 | - | |
1267 | - if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE || | |
1268 | - (status[16] & 0xF) != 1) { | |
870 | + err = mmc_sd_switch(host->card, SD_SWITCH_SET, | |
871 | + SD_SWITCH_GRP_ACCESS, SD_SWITCH_ACCESS_HS, status); | |
872 | + if (err != MMC_ERR_NONE || (status[16] & 0xF) != 1) { | |
1269 | 873 | printk(KERN_WARNING "%s: Problem switching card " |
1270 | 874 | "into high-speed mode!\n", |
1271 | 875 | mmc_hostname(host)); |
1272 | 876 | |
... | ... | @@ -1314,16 +918,11 @@ |
1314 | 918 | */ |
1315 | 919 | static void mmc_check_card(struct mmc_card *card) |
1316 | 920 | { |
1317 | - struct mmc_command cmd; | |
1318 | 921 | int err; |
1319 | 922 | |
1320 | 923 | BUG_ON(!card); |
1321 | 924 | |
1322 | - cmd.opcode = MMC_SEND_STATUS; | |
1323 | - cmd.arg = card->rca << 16; | |
1324 | - cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | |
1325 | - | |
1326 | - err = mmc_wait_for_cmd(card->host, &cmd, CMD_RETRIES); | |
925 | + err = mmc_send_status(card, NULL); | |
1327 | 926 | if (err == MMC_ERR_NONE) |
1328 | 927 | return; |
1329 | 928 | |
1330 | 929 | |
... | ... | @@ -1338,9 +937,9 @@ |
1338 | 937 | host->mode = MMC_MODE_SD; |
1339 | 938 | |
1340 | 939 | mmc_power_up(host); |
1341 | - mmc_idle_cards(host); | |
940 | + mmc_go_idle(host); | |
1342 | 941 | |
1343 | - err = mmc_send_if_cond(host, host->ocr_avail, NULL); | |
942 | + err = mmc_send_if_cond(host, host->ocr_avail); | |
1344 | 943 | if (err != MMC_ERR_NONE) { |
1345 | 944 | return; |
1346 | 945 | } |
... | ... | @@ -1369,7 +968,7 @@ |
1369 | 968 | * state. We wait 1ms to give cards time to |
1370 | 969 | * respond. |
1371 | 970 | */ |
1372 | - mmc_idle_cards(host); | |
971 | + mmc_go_idle(host); | |
1373 | 972 | |
1374 | 973 | /* |
1375 | 974 | * Send the selected OCR multiple times... until the cards |
... | ... | @@ -1377,17 +976,17 @@ |
1377 | 976 | * (My SanDisk card seems to need this.) |
1378 | 977 | */ |
1379 | 978 | if (host->mode == MMC_MODE_SD) { |
1380 | - int err, sd2; | |
1381 | - err = mmc_send_if_cond(host, host->ocr, &sd2); | |
1382 | - if (err == MMC_ERR_NONE) { | |
1383 | - /* | |
1384 | - * If SD_SEND_IF_COND indicates an SD 2.0 | |
1385 | - * compliant card and we should set bit 30 | |
1386 | - * of the ocr to indicate that we can handle | |
1387 | - * block-addressed SDHC cards. | |
1388 | - */ | |
1389 | - mmc_send_app_op_cond(host, host->ocr | (sd2 << 30), NULL); | |
1390 | - } | |
979 | + /* | |
980 | + * If SD_SEND_IF_COND indicates an SD 2.0 | |
981 | + * compliant card and we should set bit 30 | |
982 | + * of the ocr to indicate that we can handle | |
983 | + * block-addressed SDHC cards. | |
984 | + */ | |
985 | + err = mmc_send_if_cond(host, host->ocr); | |
986 | + if (err == MMC_ERR_NONE) | |
987 | + ocr = host->ocr | (1 << 30); | |
988 | + | |
989 | + mmc_send_app_op_cond(host, ocr, NULL); | |
1391 | 990 | } else { |
1392 | 991 | /* The extra bit indicates that we support high capacity */ |
1393 | 992 | mmc_send_op_cond(host, host->ocr | (1 << 30), NULL); |
... | ... | @@ -1407,6 +1006,24 @@ |
1407 | 1006 | err = mmc_select_card(host->card); |
1408 | 1007 | if (err != MMC_ERR_NONE) |
1409 | 1008 | mmc_card_set_dead(host->card); |
1009 | + } | |
1010 | + | |
1011 | + /* | |
1012 | + * The card is in 1 bit mode by default so | |
1013 | + * we only need to change if it supports the | |
1014 | + * wider version. | |
1015 | + */ | |
1016 | + if (host->card && !mmc_card_dead(host->card) && | |
1017 | + mmc_card_sd(host->card) && | |
1018 | + (host->card->scr.bus_widths & SD_SCR_BUS_WIDTH_4) && | |
1019 | + (host->card->host->caps & MMC_CAP_4_BIT_DATA)) { | |
1020 | + err = mmc_app_set_bus_width(host->card, SD_BUS_WIDTH_4); | |
1021 | + if (err != MMC_ERR_NONE) | |
1022 | + mmc_card_set_dead(host->card); | |
1023 | + else { | |
1024 | + host->ios.bus_width = MMC_BUS_WIDTH_4; | |
1025 | + mmc_set_ios(host); | |
1026 | + } | |
1410 | 1027 | } |
1411 | 1028 | |
1412 | 1029 | if (host->mode == MMC_MODE_SD) { |
drivers/mmc/core/core.h
... | ... | @@ -2,25 +2,30 @@ |
2 | 2 | * linux/drivers/mmc/core/core.h |
3 | 3 | * |
4 | 4 | * Copyright (C) 2003 Russell King, All Rights Reserved. |
5 | + * Copyright 2007 Pierre Ossman | |
5 | 6 | * |
6 | 7 | * This program is free software; you can redistribute it and/or modify |
7 | 8 | * it under the terms of the GNU General Public License version 2 as |
8 | 9 | * published by the Free Software Foundation. |
9 | 10 | */ |
10 | -#ifndef _MMC_CORE_H | |
11 | -#define _MMC_CORE_H | |
12 | -/* core-internal functions */ | |
13 | -void mmc_init_card(struct mmc_card *card, struct mmc_host *host); | |
14 | -int mmc_register_card(struct mmc_card *card); | |
15 | -void mmc_remove_card(struct mmc_card *card); | |
11 | +#ifndef _MMC_CORE_CORE_H | |
12 | +#define _MMC_CORE_CORE_H | |
16 | 13 | |
17 | -struct mmc_host *mmc_alloc_host_sysfs(int extra, struct device *dev); | |
18 | -int mmc_add_host_sysfs(struct mmc_host *host); | |
19 | -void mmc_remove_host_sysfs(struct mmc_host *host); | |
20 | -void mmc_free_host_sysfs(struct mmc_host *host); | |
14 | +#include <linux/delay.h> | |
21 | 15 | |
22 | -int mmc_schedule_work(struct work_struct *work); | |
23 | -int mmc_schedule_delayed_work(struct delayed_work *work, unsigned long delay); | |
24 | -void mmc_flush_scheduled_work(void); | |
16 | +#define MMC_CMD_RETRIES 3 | |
17 | + | |
18 | +void mmc_set_chip_select(struct mmc_host *host, int mode); | |
19 | + | |
20 | +static inline void mmc_delay(unsigned int ms) | |
21 | +{ | |
22 | + if (ms < 1000 / HZ) { | |
23 | + cond_resched(); | |
24 | + mdelay(ms); | |
25 | + } else { | |
26 | + msleep(ms); | |
27 | + } | |
28 | +} | |
29 | + | |
25 | 30 | #endif |
drivers/mmc/core/mmc_ops.c
1 | +/* | |
2 | + * linux/drivers/mmc/mmc_ops.h | |
3 | + * | |
4 | + * Copyright 2006-2007 Pierre Ossman | |
5 | + * | |
6 | + * This program is free software; you can redistribute it and/or modify | |
7 | + * it under the terms of the GNU General Public License as published by | |
8 | + * the Free Software Foundation; either version 2 of the License, or (at | |
9 | + * your option) any later version. | |
10 | + */ | |
11 | + | |
12 | +#include <linux/types.h> | |
13 | +#include <asm/scatterlist.h> | |
14 | +#include <linux/scatterlist.h> | |
15 | + | |
16 | +#include <linux/mmc/host.h> | |
17 | +#include <linux/mmc/card.h> | |
18 | +#include <linux/mmc/mmc.h> | |
19 | + | |
20 | +#include "core.h" | |
21 | +#include "mmc_ops.h" | |
22 | + | |
23 | +static int _mmc_select_card(struct mmc_host *host, struct mmc_card *card) | |
24 | +{ | |
25 | + int err; | |
26 | + struct mmc_command cmd; | |
27 | + | |
28 | + BUG_ON(!host); | |
29 | + | |
30 | + memset(&cmd, 0, sizeof(struct mmc_command)); | |
31 | + | |
32 | + cmd.opcode = MMC_SELECT_CARD; | |
33 | + | |
34 | + if (card) { | |
35 | + cmd.arg = card->rca << 16; | |
36 | + cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | |
37 | + } else { | |
38 | + cmd.arg = 0; | |
39 | + cmd.flags = MMC_RSP_NONE | MMC_CMD_AC; | |
40 | + } | |
41 | + | |
42 | + err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); | |
43 | + if (err != MMC_ERR_NONE) | |
44 | + return err; | |
45 | + | |
46 | + return MMC_ERR_NONE; | |
47 | +} | |
48 | + | |
49 | +int mmc_select_card(struct mmc_card *card) | |
50 | +{ | |
51 | + BUG_ON(!card); | |
52 | + | |
53 | + return _mmc_select_card(card->host, card); | |
54 | +} | |
55 | + | |
56 | +int mmc_deselect_cards(struct mmc_host *host) | |
57 | +{ | |
58 | + return _mmc_select_card(host, NULL); | |
59 | +} | |
60 | + | |
61 | +int mmc_go_idle(struct mmc_host *host) | |
62 | +{ | |
63 | + int err; | |
64 | + struct mmc_command cmd; | |
65 | + | |
66 | + mmc_set_chip_select(host, MMC_CS_HIGH); | |
67 | + | |
68 | + mmc_delay(1); | |
69 | + | |
70 | + memset(&cmd, 0, sizeof(struct mmc_command)); | |
71 | + | |
72 | + cmd.opcode = MMC_GO_IDLE_STATE; | |
73 | + cmd.arg = 0; | |
74 | + cmd.flags = MMC_RSP_NONE | MMC_CMD_BC; | |
75 | + | |
76 | + err = mmc_wait_for_cmd(host, &cmd, 0); | |
77 | + | |
78 | + mmc_delay(1); | |
79 | + | |
80 | + mmc_set_chip_select(host, MMC_CS_DONTCARE); | |
81 | + | |
82 | + mmc_delay(1); | |
83 | + | |
84 | + return err; | |
85 | +} | |
86 | + | |
87 | +int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) | |
88 | +{ | |
89 | + struct mmc_command cmd; | |
90 | + int i, err = 0; | |
91 | + | |
92 | + BUG_ON(!host); | |
93 | + | |
94 | + memset(&cmd, 0, sizeof(struct mmc_command)); | |
95 | + | |
96 | + cmd.opcode = MMC_SEND_OP_COND; | |
97 | + cmd.arg = ocr; | |
98 | + cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; | |
99 | + | |
100 | + for (i = 100; i; i--) { | |
101 | + err = mmc_wait_for_cmd(host, &cmd, 0); | |
102 | + if (err != MMC_ERR_NONE) | |
103 | + break; | |
104 | + | |
105 | + if (cmd.resp[0] & MMC_CARD_BUSY || ocr == 0) | |
106 | + break; | |
107 | + | |
108 | + err = MMC_ERR_TIMEOUT; | |
109 | + | |
110 | + mmc_delay(10); | |
111 | + } | |
112 | + | |
113 | + if (rocr) | |
114 | + *rocr = cmd.resp[0]; | |
115 | + | |
116 | + return err; | |
117 | +} | |
118 | + | |
119 | +int mmc_all_send_cid(struct mmc_host *host, u32 *cid) | |
120 | +{ | |
121 | + int err; | |
122 | + struct mmc_command cmd; | |
123 | + | |
124 | + BUG_ON(!host); | |
125 | + BUG_ON(!cid); | |
126 | + | |
127 | + memset(&cmd, 0, sizeof(struct mmc_command)); | |
128 | + | |
129 | + cmd.opcode = MMC_ALL_SEND_CID; | |
130 | + cmd.arg = 0; | |
131 | + cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR; | |
132 | + | |
133 | + err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); | |
134 | + if (err != MMC_ERR_NONE) | |
135 | + return err; | |
136 | + | |
137 | + memcpy(cid, cmd.resp, sizeof(u32) * 4); | |
138 | + | |
139 | + return MMC_ERR_NONE; | |
140 | +} | |
141 | + | |
142 | +int mmc_set_relative_addr(struct mmc_card *card) | |
143 | +{ | |
144 | + int err; | |
145 | + struct mmc_command cmd; | |
146 | + | |
147 | + BUG_ON(!card); | |
148 | + BUG_ON(!card->host); | |
149 | + | |
150 | + memset(&cmd, 0, sizeof(struct mmc_command)); | |
151 | + | |
152 | + cmd.opcode = MMC_SET_RELATIVE_ADDR; | |
153 | + cmd.arg = card->rca << 16; | |
154 | + cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | |
155 | + | |
156 | + err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); | |
157 | + if (err != MMC_ERR_NONE) | |
158 | + return err; | |
159 | + | |
160 | + return MMC_ERR_NONE; | |
161 | +} | |
162 | + | |
163 | +int mmc_send_csd(struct mmc_card *card, u32 *csd) | |
164 | +{ | |
165 | + int err; | |
166 | + struct mmc_command cmd; | |
167 | + | |
168 | + BUG_ON(!card); | |
169 | + BUG_ON(!card->host); | |
170 | + BUG_ON(!csd); | |
171 | + | |
172 | + memset(&cmd, 0, sizeof(struct mmc_command)); | |
173 | + | |
174 | + cmd.opcode = MMC_SEND_CSD; | |
175 | + cmd.arg = card->rca << 16; | |
176 | + cmd.flags = MMC_RSP_R2 | MMC_CMD_AC; | |
177 | + | |
178 | + err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); | |
179 | + if (err != MMC_ERR_NONE) | |
180 | + return err; | |
181 | + | |
182 | + memcpy(csd, cmd.resp, sizeof(u32) * 4); | |
183 | + | |
184 | + return MMC_ERR_NONE; | |
185 | +} | |
186 | + | |
187 | +int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd) | |
188 | +{ | |
189 | + struct mmc_request mrq; | |
190 | + struct mmc_command cmd; | |
191 | + struct mmc_data data; | |
192 | + struct scatterlist sg; | |
193 | + | |
194 | + BUG_ON(!card); | |
195 | + BUG_ON(!card->host); | |
196 | + BUG_ON(!ext_csd); | |
197 | + | |
198 | + memset(&mrq, 0, sizeof(struct mmc_request)); | |
199 | + memset(&cmd, 0, sizeof(struct mmc_command)); | |
200 | + memset(&data, 0, sizeof(struct mmc_data)); | |
201 | + | |
202 | + mrq.cmd = &cmd; | |
203 | + mrq.data = &data; | |
204 | + | |
205 | + cmd.opcode = MMC_SEND_EXT_CSD; | |
206 | + cmd.arg = 0; | |
207 | + cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | |
208 | + | |
209 | + data.blksz = 512; | |
210 | + data.blocks = 1; | |
211 | + data.flags = MMC_DATA_READ; | |
212 | + data.sg = &sg; | |
213 | + data.sg_len = 1; | |
214 | + | |
215 | + sg_init_one(&sg, ext_csd, 512); | |
216 | + | |
217 | + mmc_set_data_timeout(&data, card, 0); | |
218 | + | |
219 | + mmc_wait_for_req(card->host, &mrq); | |
220 | + | |
221 | + if (cmd.error != MMC_ERR_NONE) | |
222 | + return cmd.error; | |
223 | + if (data.error != MMC_ERR_NONE) | |
224 | + return data.error; | |
225 | + | |
226 | + return MMC_ERR_NONE; | |
227 | +} | |
228 | + | |
229 | +int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value) | |
230 | +{ | |
231 | + int err; | |
232 | + struct mmc_command cmd; | |
233 | + | |
234 | + BUG_ON(!card); | |
235 | + BUG_ON(!card->host); | |
236 | + | |
237 | + memset(&cmd, 0, sizeof(struct mmc_command)); | |
238 | + | |
239 | + cmd.opcode = MMC_SWITCH; | |
240 | + cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | | |
241 | + (index << 16) | | |
242 | + (value << 8) | | |
243 | + set; | |
244 | + cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; | |
245 | + | |
246 | + err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); | |
247 | + if (err != MMC_ERR_NONE) | |
248 | + return err; | |
249 | + | |
250 | + return MMC_ERR_NONE; | |
251 | +} | |
252 | + | |
253 | +int mmc_send_status(struct mmc_card *card, u32 *status) | |
254 | +{ | |
255 | + int err; | |
256 | + struct mmc_command cmd; | |
257 | + | |
258 | + BUG_ON(!card); | |
259 | + BUG_ON(!card->host); | |
260 | + | |
261 | + memset(&cmd, 0, sizeof(struct mmc_command)); | |
262 | + | |
263 | + cmd.opcode = MMC_SEND_STATUS; | |
264 | + cmd.arg = card->rca << 16; | |
265 | + cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | |
266 | + | |
267 | + err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); | |
268 | + if (err != MMC_ERR_NONE) | |
269 | + return err; | |
270 | + | |
271 | + if (status) | |
272 | + *status = cmd.resp[0]; | |
273 | + | |
274 | + return MMC_ERR_NONE; | |
275 | +} |
drivers/mmc/core/mmc_ops.h
1 | +/* | |
2 | + * linux/drivers/mmc/mmc_ops.h | |
3 | + * | |
4 | + * Copyright 2006-2007 Pierre Ossman | |
5 | + * | |
6 | + * This program is free software; you can redistribute it and/or modify | |
7 | + * it under the terms of the GNU General Public License as published by | |
8 | + * the Free Software Foundation; either version 2 of the License, or (at | |
9 | + * your option) any later version. | |
10 | + */ | |
11 | + | |
12 | +#ifndef _MMC_MMC_OPS_H | |
13 | +#define _MMC_MMC_OPS_H | |
14 | + | |
15 | +int mmc_select_card(struct mmc_card *card); | |
16 | +int mmc_deselect_cards(struct mmc_host *host); | |
17 | +int mmc_go_idle(struct mmc_host *host); | |
18 | +int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr); | |
19 | +int mmc_all_send_cid(struct mmc_host *host, u32 *cid); | |
20 | +int mmc_set_relative_addr(struct mmc_card *card); | |
21 | +int mmc_send_csd(struct mmc_card *card, u32 *csd); | |
22 | +int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd); | |
23 | +int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value); | |
24 | +int mmc_send_status(struct mmc_card *card, u32 *status); | |
25 | + | |
26 | +#endif |
drivers/mmc/core/sd_ops.c
1 | +/* | |
2 | + * linux/drivers/mmc/sd_ops.h | |
3 | + * | |
4 | + * Copyright 2006-2007 Pierre Ossman | |
5 | + * | |
6 | + * This program is free software; you can redistribute it and/or modify | |
7 | + * it under the terms of the GNU General Public License as published by | |
8 | + * the Free Software Foundation; either version 2 of the License, or (at | |
9 | + * your option) any later version. | |
10 | + */ | |
11 | + | |
12 | +#include <linux/types.h> | |
13 | +#include <asm/scatterlist.h> | |
14 | +#include <linux/scatterlist.h> | |
15 | + | |
16 | +#include <linux/mmc/host.h> | |
17 | +#include <linux/mmc/card.h> | |
18 | +#include <linux/mmc/mmc.h> | |
19 | +#include <linux/mmc/sd.h> | |
20 | + | |
21 | +#include "core.h" | |
22 | +#include "sd_ops.h" | |
23 | + | |
24 | +/** | |
25 | + * mmc_wait_for_app_cmd - start an application command and wait for | |
26 | + completion | |
27 | + * @host: MMC host to start command | |
28 | + * @rca: RCA to send MMC_APP_CMD to | |
29 | + * @cmd: MMC command to start | |
30 | + * @retries: maximum number of retries | |
31 | + * | |
32 | + * Sends a MMC_APP_CMD, checks the card response, sends the command | |
33 | + * in the parameter and waits for it to complete. Return any error | |
34 | + * that occurred while the command was executing. Do not attempt to | |
35 | + * parse the response. | |
36 | + */ | |
37 | +int mmc_wait_for_app_cmd(struct mmc_host *host, struct mmc_card *card, | |
38 | + struct mmc_command *cmd, int retries) | |
39 | +{ | |
40 | + struct mmc_request mrq; | |
41 | + | |
42 | + int i, err; | |
43 | + | |
44 | + BUG_ON(!cmd); | |
45 | + BUG_ON(retries < 0); | |
46 | + | |
47 | + err = MMC_ERR_INVALID; | |
48 | + | |
49 | + /* | |
50 | + * We have to resend MMC_APP_CMD for each attempt so | |
51 | + * we cannot use the retries field in mmc_command. | |
52 | + */ | |
53 | + for (i = 0;i <= retries;i++) { | |
54 | + memset(&mrq, 0, sizeof(struct mmc_request)); | |
55 | + | |
56 | + err = mmc_app_cmd(host, card); | |
57 | + if (err != MMC_ERR_NONE) | |
58 | + continue; | |
59 | + | |
60 | + memset(&mrq, 0, sizeof(struct mmc_request)); | |
61 | + | |
62 | + memset(cmd->resp, 0, sizeof(cmd->resp)); | |
63 | + cmd->retries = 0; | |
64 | + | |
65 | + mrq.cmd = cmd; | |
66 | + cmd->data = NULL; | |
67 | + | |
68 | + mmc_wait_for_req(host, &mrq); | |
69 | + | |
70 | + err = cmd->error; | |
71 | + if (cmd->error == MMC_ERR_NONE) | |
72 | + break; | |
73 | + } | |
74 | + | |
75 | + return err; | |
76 | +} | |
77 | + | |
78 | +EXPORT_SYMBOL(mmc_wait_for_app_cmd); | |
79 | + | |
80 | +int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card) | |
81 | +{ | |
82 | + int err; | |
83 | + struct mmc_command cmd; | |
84 | + | |
85 | + BUG_ON(!host); | |
86 | + BUG_ON(card && (card->host != host)); | |
87 | + | |
88 | + cmd.opcode = MMC_APP_CMD; | |
89 | + | |
90 | + if (card) { | |
91 | + cmd.arg = card->rca << 16; | |
92 | + cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | |
93 | + } else { | |
94 | + cmd.arg = 0; | |
95 | + cmd.flags = MMC_RSP_R1 | MMC_CMD_BCR; | |
96 | + } | |
97 | + | |
98 | + err = mmc_wait_for_cmd(host, &cmd, 0); | |
99 | + if (err != MMC_ERR_NONE) | |
100 | + return err; | |
101 | + | |
102 | + /* Check that card supported application commands */ | |
103 | + if (!(cmd.resp[0] & R1_APP_CMD)) | |
104 | + return MMC_ERR_FAILED; | |
105 | + | |
106 | + return MMC_ERR_NONE; | |
107 | +} | |
108 | + | |
109 | +int mmc_app_set_bus_width(struct mmc_card *card, int width) | |
110 | +{ | |
111 | + int err; | |
112 | + struct mmc_command cmd; | |
113 | + | |
114 | + BUG_ON(!card); | |
115 | + BUG_ON(!card->host); | |
116 | + | |
117 | + memset(&cmd, 0, sizeof(struct mmc_command)); | |
118 | + | |
119 | + cmd.opcode = SD_APP_SET_BUS_WIDTH; | |
120 | + cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | |
121 | + | |
122 | + switch (width) { | |
123 | + case MMC_BUS_WIDTH_1: | |
124 | + cmd.arg = SD_BUS_WIDTH_1; | |
125 | + break; | |
126 | + case MMC_BUS_WIDTH_4: | |
127 | + cmd.arg = SD_BUS_WIDTH_4; | |
128 | + break; | |
129 | + default: | |
130 | + return MMC_ERR_INVALID; | |
131 | + } | |
132 | + | |
133 | + err = mmc_wait_for_app_cmd(card->host, card, &cmd, MMC_CMD_RETRIES); | |
134 | + if (err != MMC_ERR_NONE) | |
135 | + return err; | |
136 | + | |
137 | + return MMC_ERR_NONE; | |
138 | +} | |
139 | + | |
140 | +int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) | |
141 | +{ | |
142 | + struct mmc_command cmd; | |
143 | + int i, err = 0; | |
144 | + | |
145 | + BUG_ON(!host); | |
146 | + | |
147 | + memset(&cmd, 0, sizeof(struct mmc_command)); | |
148 | + | |
149 | + cmd.opcode = SD_APP_OP_COND; | |
150 | + cmd.arg = ocr; | |
151 | + cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; | |
152 | + | |
153 | + for (i = 100; i; i--) { | |
154 | + err = mmc_wait_for_app_cmd(host, NULL, &cmd, MMC_CMD_RETRIES); | |
155 | + if (err != MMC_ERR_NONE) | |
156 | + break; | |
157 | + | |
158 | + if (cmd.resp[0] & MMC_CARD_BUSY || ocr == 0) | |
159 | + break; | |
160 | + | |
161 | + err = MMC_ERR_TIMEOUT; | |
162 | + | |
163 | + mmc_delay(10); | |
164 | + } | |
165 | + | |
166 | + if (rocr) | |
167 | + *rocr = cmd.resp[0]; | |
168 | + | |
169 | + return err; | |
170 | +} | |
171 | + | |
172 | +int mmc_send_if_cond(struct mmc_host *host, u32 ocr) | |
173 | +{ | |
174 | + struct mmc_command cmd; | |
175 | + int err; | |
176 | + static const u8 test_pattern = 0xAA; | |
177 | + | |
178 | + /* | |
179 | + * To support SD 2.0 cards, we must always invoke SD_SEND_IF_COND | |
180 | + * before SD_APP_OP_COND. This command will harmlessly fail for | |
181 | + * SD 1.0 cards. | |
182 | + */ | |
183 | + cmd.opcode = SD_SEND_IF_COND; | |
184 | + cmd.arg = ((ocr & 0xFF8000) != 0) << 8 | test_pattern; | |
185 | + cmd.flags = MMC_RSP_R7 | MMC_CMD_BCR; | |
186 | + | |
187 | + err = mmc_wait_for_cmd(host, &cmd, 0); | |
188 | + if (err != MMC_ERR_NONE) | |
189 | + return err; | |
190 | + | |
191 | + if ((cmd.resp[0] & 0xFF) != test_pattern) | |
192 | + return MMC_ERR_FAILED; | |
193 | + | |
194 | + return MMC_ERR_NONE; | |
195 | +} | |
196 | + | |
197 | +int mmc_send_relative_addr(struct mmc_host *host, unsigned int *rca) | |
198 | +{ | |
199 | + int err; | |
200 | + struct mmc_command cmd; | |
201 | + | |
202 | + BUG_ON(!host); | |
203 | + BUG_ON(!rca); | |
204 | + | |
205 | + memset(&cmd, 0, sizeof(struct mmc_command)); | |
206 | + | |
207 | + cmd.opcode = SD_SEND_RELATIVE_ADDR; | |
208 | + cmd.arg = 0; | |
209 | + cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR; | |
210 | + | |
211 | + err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); | |
212 | + if (err != MMC_ERR_NONE) | |
213 | + return err; | |
214 | + | |
215 | + *rca = cmd.resp[0] >> 16; | |
216 | + | |
217 | + return MMC_ERR_NONE; | |
218 | +} | |
219 | + | |
220 | +int mmc_app_send_scr(struct mmc_card *card, u32 *scr) | |
221 | +{ | |
222 | + int err; | |
223 | + struct mmc_request mrq; | |
224 | + struct mmc_command cmd; | |
225 | + struct mmc_data data; | |
226 | + struct scatterlist sg; | |
227 | + | |
228 | + BUG_ON(!card); | |
229 | + BUG_ON(!card->host); | |
230 | + BUG_ON(!scr); | |
231 | + | |
232 | + err = mmc_app_cmd(card->host, card); | |
233 | + if (err != MMC_ERR_NONE) | |
234 | + return err; | |
235 | + | |
236 | + memset(&mrq, 0, sizeof(struct mmc_request)); | |
237 | + memset(&cmd, 0, sizeof(struct mmc_command)); | |
238 | + memset(&data, 0, sizeof(struct mmc_data)); | |
239 | + | |
240 | + mrq.cmd = &cmd; | |
241 | + mrq.data = &data; | |
242 | + | |
243 | + cmd.opcode = SD_APP_SEND_SCR; | |
244 | + cmd.arg = 0; | |
245 | + cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | |
246 | + | |
247 | + data.blksz = 8; | |
248 | + data.blocks = 1; | |
249 | + data.flags = MMC_DATA_READ; | |
250 | + data.sg = &sg; | |
251 | + data.sg_len = 1; | |
252 | + | |
253 | + sg_init_one(&sg, scr, 8); | |
254 | + | |
255 | + mmc_set_data_timeout(&data, card, 0); | |
256 | + | |
257 | + mmc_wait_for_req(card->host, &mrq); | |
258 | + | |
259 | + if (cmd.error != MMC_ERR_NONE) | |
260 | + return cmd.error; | |
261 | + if (data.error != MMC_ERR_NONE) | |
262 | + return data.error; | |
263 | + | |
264 | + scr[0] = ntohl(scr[0]); | |
265 | + scr[1] = ntohl(scr[1]); | |
266 | + | |
267 | + return MMC_ERR_NONE; | |
268 | +} | |
269 | + | |
270 | +int mmc_sd_switch(struct mmc_card *card, int mode, int group, | |
271 | + u8 value, u8 *resp) | |
272 | +{ | |
273 | + struct mmc_request mrq; | |
274 | + struct mmc_command cmd; | |
275 | + struct mmc_data data; | |
276 | + struct scatterlist sg; | |
277 | + | |
278 | + BUG_ON(!card); | |
279 | + BUG_ON(!card->host); | |
280 | + | |
281 | + mode = !!mode; | |
282 | + value &= 0xF; | |
283 | + | |
284 | + memset(&mrq, 0, sizeof(struct mmc_request)); | |
285 | + memset(&cmd, 0, sizeof(struct mmc_command)); | |
286 | + memset(&data, 0, sizeof(struct mmc_data)); | |
287 | + | |
288 | + mrq.cmd = &cmd; | |
289 | + mrq.data = &data; | |
290 | + | |
291 | + cmd.opcode = SD_SWITCH; | |
292 | + cmd.arg = mode << 31 | 0x00FFFFFF; | |
293 | + cmd.arg &= ~(0xF << (group * 4)); | |
294 | + cmd.arg |= value << (group * 4); | |
295 | + cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | |
296 | + | |
297 | + data.blksz = 64; | |
298 | + data.blocks = 1; | |
299 | + data.flags = MMC_DATA_READ; | |
300 | + data.sg = &sg; | |
301 | + data.sg_len = 1; | |
302 | + | |
303 | + sg_init_one(&sg, resp, 64); | |
304 | + | |
305 | + mmc_set_data_timeout(&data, card, 0); | |
306 | + | |
307 | + mmc_wait_for_req(card->host, &mrq); | |
308 | + | |
309 | + if (cmd.error != MMC_ERR_NONE) | |
310 | + return cmd.error; | |
311 | + if (data.error != MMC_ERR_NONE) | |
312 | + return data.error; | |
313 | + | |
314 | + return MMC_ERR_NONE; | |
315 | +} |
drivers/mmc/core/sd_ops.h
1 | +/* | |
2 | + * linux/drivers/mmc/sd_ops.h | |
3 | + * | |
4 | + * Copyright 2006-2007 Pierre Ossman | |
5 | + * | |
6 | + * This program is free software; you can redistribute it and/or modify | |
7 | + * it under the terms of the GNU General Public License as published by | |
8 | + * the Free Software Foundation; either version 2 of the License, or (at | |
9 | + * your option) any later version. | |
10 | + */ | |
11 | + | |
12 | +#ifndef _MMC_SD_OPS_H | |
13 | +#define _MMC_SD_OPS_H | |
14 | + | |
15 | +int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card); | |
16 | +int mmc_app_set_bus_width(struct mmc_card *card, int width); | |
17 | +int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr); | |
18 | +int mmc_send_if_cond(struct mmc_host *host, u32 ocr); | |
19 | +int mmc_send_relative_addr(struct mmc_host *host, unsigned int *rca); | |
20 | +int mmc_app_send_scr(struct mmc_card *card, u32 *scr); | |
21 | +int mmc_sd_switch(struct mmc_card *card, int mode, int group, | |
22 | + u8 value, u8 *resp); | |
23 | + | |
24 | +#endif |
drivers/mmc/core/sysfs.c
drivers/mmc/core/sysfs.h
1 | +/* | |
2 | + * linux/drivers/mmc/core/sysfs.h | |
3 | + * | |
4 | + * Copyright (C) 2003 Russell King, All Rights Reserved. | |
5 | + * Copyright 2007 Pierre Ossman | |
6 | + * | |
7 | + * This program is free software; you can redistribute it and/or modify | |
8 | + * it under the terms of the GNU General Public License version 2 as | |
9 | + * published by the Free Software Foundation. | |
10 | + */ | |
11 | +#ifndef _MMC_CORE_SYSFS_H | |
12 | +#define _MMC_CORE_SYSFS_H | |
13 | + | |
14 | +void mmc_init_card(struct mmc_card *card, struct mmc_host *host); | |
15 | +int mmc_register_card(struct mmc_card *card); | |
16 | +void mmc_remove_card(struct mmc_card *card); | |
17 | + | |
18 | +struct mmc_host *mmc_alloc_host_sysfs(int extra, struct device *dev); | |
19 | +int mmc_add_host_sysfs(struct mmc_host *host); | |
20 | +void mmc_remove_host_sysfs(struct mmc_host *host); | |
21 | +void mmc_free_host_sysfs(struct mmc_host *host); | |
22 | + | |
23 | +int mmc_schedule_work(struct work_struct *work); | |
24 | +int mmc_schedule_delayed_work(struct delayed_work *work, unsigned long delay); | |
25 | +void mmc_flush_scheduled_work(void); | |
26 | + | |
27 | +#endif |
include/linux/mmc/core.h
... | ... | @@ -101,7 +101,7 @@ |
101 | 101 | |
102 | 102 | extern int mmc_wait_for_req(struct mmc_host *, struct mmc_request *); |
103 | 103 | extern int mmc_wait_for_cmd(struct mmc_host *, struct mmc_command *, int); |
104 | -extern int mmc_wait_for_app_cmd(struct mmc_host *, unsigned int, | |
104 | +extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *, | |
105 | 105 | struct mmc_command *, int); |
106 | 106 | |
107 | 107 | extern void mmc_set_data_timeout(struct mmc_data *, const struct mmc_card *, int); |
include/linux/mmc/mmc.h
1 | +/* | |
2 | + * Header for MultiMediaCard (MMC) | |
3 | + * | |
4 | + * Copyright 2002 Hewlett-Packard Company | |
5 | + * | |
6 | + * Use consistent with the GNU GPL is permitted, | |
7 | + * provided that this copyright notice is | |
8 | + * preserved in its entirety in all copies and derived works. | |
9 | + * | |
10 | + * HEWLETT-PACKARD COMPANY MAKES NO WARRANTIES, EXPRESSED OR IMPLIED, | |
11 | + * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS | |
12 | + * FITNESS FOR ANY PARTICULAR PURPOSE. | |
13 | + * | |
14 | + * Many thanks to Alessandro Rubini and Jonathan Corbet! | |
15 | + * | |
16 | + * Based strongly on code by: | |
17 | + * | |
18 | + * Author: Yong-iL Joh <tolkien@mizi.com> | |
19 | + * Date : $Date: 2002/06/18 12:37:30 $ | |
20 | + * | |
21 | + * Author: Andrew Christian | |
22 | + * 15 May 2002 | |
23 | + */ | |
24 | + | |
25 | +#ifndef MMC_MMC_H | |
26 | +#define MMC_MMC_H | |
27 | + | |
28 | +/* Standard MMC commands (4.1) type argument response */ | |
29 | + /* class 1 */ | |
30 | +#define MMC_GO_IDLE_STATE 0 /* bc */ | |
31 | +#define MMC_SEND_OP_COND 1 /* bcr [31:0] OCR R3 */ | |
32 | +#define MMC_ALL_SEND_CID 2 /* bcr R2 */ | |
33 | +#define MMC_SET_RELATIVE_ADDR 3 /* ac [31:16] RCA R1 */ | |
34 | +#define MMC_SET_DSR 4 /* bc [31:16] RCA */ | |
35 | +#define MMC_SWITCH 6 /* ac [31:0] See below R1b */ | |
36 | +#define MMC_SELECT_CARD 7 /* ac [31:16] RCA R1 */ | |
37 | +#define MMC_SEND_EXT_CSD 8 /* adtc R1 */ | |
38 | +#define MMC_SEND_CSD 9 /* ac [31:16] RCA R2 */ | |
39 | +#define MMC_SEND_CID 10 /* ac [31:16] RCA R2 */ | |
40 | +#define MMC_READ_DAT_UNTIL_STOP 11 /* adtc [31:0] dadr R1 */ | |
41 | +#define MMC_STOP_TRANSMISSION 12 /* ac R1b */ | |
42 | +#define MMC_SEND_STATUS 13 /* ac [31:16] RCA R1 */ | |
43 | +#define MMC_GO_INACTIVE_STATE 15 /* ac [31:16] RCA */ | |
44 | + | |
45 | + /* class 2 */ | |
46 | +#define MMC_SET_BLOCKLEN 16 /* ac [31:0] block len R1 */ | |
47 | +#define MMC_READ_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 */ | |
48 | +#define MMC_READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 */ | |
49 | + | |
50 | + /* class 3 */ | |
51 | +#define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */ | |
52 | + | |
53 | + /* class 4 */ | |
54 | +#define MMC_SET_BLOCK_COUNT 23 /* adtc [31:0] data addr R1 */ | |
55 | +#define MMC_WRITE_BLOCK 24 /* adtc [31:0] data addr R1 */ | |
56 | +#define MMC_WRITE_MULTIPLE_BLOCK 25 /* adtc R1 */ | |
57 | +#define MMC_PROGRAM_CID 26 /* adtc R1 */ | |
58 | +#define MMC_PROGRAM_CSD 27 /* adtc R1 */ | |
59 | + | |
60 | + /* class 6 */ | |
61 | +#define MMC_SET_WRITE_PROT 28 /* ac [31:0] data addr R1b */ | |
62 | +#define MMC_CLR_WRITE_PROT 29 /* ac [31:0] data addr R1b */ | |
63 | +#define MMC_SEND_WRITE_PROT 30 /* adtc [31:0] wpdata addr R1 */ | |
64 | + | |
65 | + /* class 5 */ | |
66 | +#define MMC_ERASE_GROUP_START 35 /* ac [31:0] data addr R1 */ | |
67 | +#define MMC_ERASE_GROUP_END 36 /* ac [31:0] data addr R1 */ | |
68 | +#define MMC_ERASE 38 /* ac R1b */ | |
69 | + | |
70 | + /* class 9 */ | |
71 | +#define MMC_FAST_IO 39 /* ac <Complex> R4 */ | |
72 | +#define MMC_GO_IRQ_STATE 40 /* bcr R5 */ | |
73 | + | |
74 | + /* class 7 */ | |
75 | +#define MMC_LOCK_UNLOCK 42 /* adtc R1b */ | |
76 | + | |
77 | + /* class 8 */ | |
78 | +#define MMC_APP_CMD 55 /* ac [31:16] RCA R1 */ | |
79 | +#define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1 */ | |
80 | + | |
81 | +/* | |
82 | + * MMC_SWITCH argument format: | |
83 | + * | |
84 | + * [31:26] Always 0 | |
85 | + * [25:24] Access Mode | |
86 | + * [23:16] Location of target Byte in EXT_CSD | |
87 | + * [15:08] Value Byte | |
88 | + * [07:03] Always 0 | |
89 | + * [02:00] Command Set | |
90 | + */ | |
91 | + | |
92 | +/* | |
93 | + MMC status in R1 | |
94 | + Type | |
95 | + e : error bit | |
96 | + s : status bit | |
97 | + r : detected and set for the actual command response | |
98 | + x : detected and set during command execution. the host must poll | |
99 | + the card by sending status command in order to read these bits. | |
100 | + Clear condition | |
101 | + a : according to the card state | |
102 | + b : always related to the previous command. Reception of | |
103 | + a valid command will clear it (with a delay of one command) | |
104 | + c : clear by read | |
105 | + */ | |
106 | + | |
107 | +#define R1_OUT_OF_RANGE (1 << 31) /* er, c */ | |
108 | +#define R1_ADDRESS_ERROR (1 << 30) /* erx, c */ | |
109 | +#define R1_BLOCK_LEN_ERROR (1 << 29) /* er, c */ | |
110 | +#define R1_ERASE_SEQ_ERROR (1 << 28) /* er, c */ | |
111 | +#define R1_ERASE_PARAM (1 << 27) /* ex, c */ | |
112 | +#define R1_WP_VIOLATION (1 << 26) /* erx, c */ | |
113 | +#define R1_CARD_IS_LOCKED (1 << 25) /* sx, a */ | |
114 | +#define R1_LOCK_UNLOCK_FAILED (1 << 24) /* erx, c */ | |
115 | +#define R1_COM_CRC_ERROR (1 << 23) /* er, b */ | |
116 | +#define R1_ILLEGAL_COMMAND (1 << 22) /* er, b */ | |
117 | +#define R1_CARD_ECC_FAILED (1 << 21) /* ex, c */ | |
118 | +#define R1_CC_ERROR (1 << 20) /* erx, c */ | |
119 | +#define R1_ERROR (1 << 19) /* erx, c */ | |
120 | +#define R1_UNDERRUN (1 << 18) /* ex, c */ | |
121 | +#define R1_OVERRUN (1 << 17) /* ex, c */ | |
122 | +#define R1_CID_CSD_OVERWRITE (1 << 16) /* erx, c, CID/CSD overwrite */ | |
123 | +#define R1_WP_ERASE_SKIP (1 << 15) /* sx, c */ | |
124 | +#define R1_CARD_ECC_DISABLED (1 << 14) /* sx, a */ | |
125 | +#define R1_ERASE_RESET (1 << 13) /* sr, c */ | |
126 | +#define R1_STATUS(x) (x & 0xFFFFE000) | |
127 | +#define R1_CURRENT_STATE(x) ((x & 0x00001E00) >> 9) /* sx, b (4 bits) */ | |
128 | +#define R1_READY_FOR_DATA (1 << 8) /* sx, a */ | |
129 | +#define R1_APP_CMD (1 << 5) /* sr, c */ | |
130 | + | |
131 | +/* These are unpacked versions of the actual responses */ | |
132 | + | |
133 | +struct _mmc_csd { | |
134 | + u8 csd_structure; | |
135 | + u8 spec_vers; | |
136 | + u8 taac; | |
137 | + u8 nsac; | |
138 | + u8 tran_speed; | |
139 | + u16 ccc; | |
140 | + u8 read_bl_len; | |
141 | + u8 read_bl_partial; | |
142 | + u8 write_blk_misalign; | |
143 | + u8 read_blk_misalign; | |
144 | + u8 dsr_imp; | |
145 | + u16 c_size; | |
146 | + u8 vdd_r_curr_min; | |
147 | + u8 vdd_r_curr_max; | |
148 | + u8 vdd_w_curr_min; | |
149 | + u8 vdd_w_curr_max; | |
150 | + u8 c_size_mult; | |
151 | + union { | |
152 | + struct { /* MMC system specification version 3.1 */ | |
153 | + u8 erase_grp_size; | |
154 | + u8 erase_grp_mult; | |
155 | + } v31; | |
156 | + struct { /* MMC system specification version 2.2 */ | |
157 | + u8 sector_size; | |
158 | + u8 erase_grp_size; | |
159 | + } v22; | |
160 | + } erase; | |
161 | + u8 wp_grp_size; | |
162 | + u8 wp_grp_enable; | |
163 | + u8 default_ecc; | |
164 | + u8 r2w_factor; | |
165 | + u8 write_bl_len; | |
166 | + u8 write_bl_partial; | |
167 | + u8 file_format_grp; | |
168 | + u8 copy; | |
169 | + u8 perm_write_protect; | |
170 | + u8 tmp_write_protect; | |
171 | + u8 file_format; | |
172 | + u8 ecc; | |
173 | +}; | |
174 | + | |
175 | +/* | |
176 | + * OCR bits are mostly in host.h | |
177 | + */ | |
178 | +#define MMC_CARD_BUSY 0x80000000 /* Card Power up status bit */ | |
179 | + | |
180 | +/* | |
181 | + * Card Command Classes (CCC) | |
182 | + */ | |
183 | +#define CCC_BASIC (1<<0) /* (0) Basic protocol functions */ | |
184 | + /* (CMD0,1,2,3,4,7,9,10,12,13,15) */ | |
185 | +#define CCC_STREAM_READ (1<<1) /* (1) Stream read commands */ | |
186 | + /* (CMD11) */ | |
187 | +#define CCC_BLOCK_READ (1<<2) /* (2) Block read commands */ | |
188 | + /* (CMD16,17,18) */ | |
189 | +#define CCC_STREAM_WRITE (1<<3) /* (3) Stream write commands */ | |
190 | + /* (CMD20) */ | |
191 | +#define CCC_BLOCK_WRITE (1<<4) /* (4) Block write commands */ | |
192 | + /* (CMD16,24,25,26,27) */ | |
193 | +#define CCC_ERASE (1<<5) /* (5) Ability to erase blocks */ | |
194 | + /* (CMD32,33,34,35,36,37,38,39) */ | |
195 | +#define CCC_WRITE_PROT (1<<6) /* (6) Able to write protect blocks */ | |
196 | + /* (CMD28,29,30) */ | |
197 | +#define CCC_LOCK_CARD (1<<7) /* (7) Able to lock down card */ | |
198 | + /* (CMD16,CMD42) */ | |
199 | +#define CCC_APP_SPEC (1<<8) /* (8) Application specific */ | |
200 | + /* (CMD55,56,57,ACMD*) */ | |
201 | +#define CCC_IO_MODE (1<<9) /* (9) I/O mode */ | |
202 | + /* (CMD5,39,40,52,53) */ | |
203 | +#define CCC_SWITCH (1<<10) /* (10) High speed switch */ | |
204 | + /* (CMD6,34,35,36,37,50) */ | |
205 | + /* (11) Reserved */ | |
206 | + /* (CMD?) */ | |
207 | + | |
208 | +/* | |
209 | + * CSD field definitions | |
210 | + */ | |
211 | + | |
212 | +#define CSD_STRUCT_VER_1_0 0 /* Valid for system specification 1.0 - 1.2 */ | |
213 | +#define CSD_STRUCT_VER_1_1 1 /* Valid for system specification 1.4 - 2.2 */ | |
214 | +#define CSD_STRUCT_VER_1_2 2 /* Valid for system specification 3.1 - 3.2 - 3.31 - 4.0 - 4.1 */ | |
215 | +#define CSD_STRUCT_EXT_CSD 3 /* Version is coded in CSD_STRUCTURE in EXT_CSD */ | |
216 | + | |
217 | +#define CSD_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.2 */ | |
218 | +#define CSD_SPEC_VER_1 1 /* Implements system specification 1.4 */ | |
219 | +#define CSD_SPEC_VER_2 2 /* Implements system specification 2.0 - 2.2 */ | |
220 | +#define CSD_SPEC_VER_3 3 /* Implements system specification 3.1 - 3.2 - 3.31 */ | |
221 | +#define CSD_SPEC_VER_4 4 /* Implements system specification 4.0 - 4.1 */ | |
222 | + | |
223 | +/* | |
224 | + * EXT_CSD fields | |
225 | + */ | |
226 | + | |
227 | +#define EXT_CSD_BUS_WIDTH 183 /* R/W */ | |
228 | +#define EXT_CSD_HS_TIMING 185 /* R/W */ | |
229 | +#define EXT_CSD_CARD_TYPE 196 /* RO */ | |
230 | +#define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */ | |
231 | + | |
232 | +/* | |
233 | + * EXT_CSD field definitions | |
234 | + */ | |
235 | + | |
236 | +#define EXT_CSD_CMD_SET_NORMAL (1<<0) | |
237 | +#define EXT_CSD_CMD_SET_SECURE (1<<1) | |
238 | +#define EXT_CSD_CMD_SET_CPSECURE (1<<2) | |
239 | + | |
240 | +#define EXT_CSD_CARD_TYPE_26 (1<<0) /* Card can run at 26MHz */ | |
241 | +#define EXT_CSD_CARD_TYPE_52 (1<<1) /* Card can run at 52MHz */ | |
242 | + | |
243 | +#define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */ | |
244 | +#define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */ | |
245 | +#define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */ | |
246 | + | |
247 | +/* | |
248 | + * MMC_SWITCH access modes | |
249 | + */ | |
250 | + | |
251 | +#define MMC_SWITCH_MODE_CMD_SET 0x00 /* Change the command set */ | |
252 | +#define MMC_SWITCH_MODE_SET_BITS 0x01 /* Set bits which are 1 in value */ | |
253 | +#define MMC_SWITCH_MODE_CLEAR_BITS 0x02 /* Clear bits which are 1 in value */ | |
254 | +#define MMC_SWITCH_MODE_WRITE_BYTE 0x03 /* Set target to value */ | |
255 | + | |
256 | +#endif /* MMC_MMC_PROTOCOL_H */ |
include/linux/mmc/protocol.h
1 | -/* | |
2 | - * Header for MultiMediaCard (MMC) | |
3 | - * | |
4 | - * Copyright 2002 Hewlett-Packard Company | |
5 | - * | |
6 | - * Use consistent with the GNU GPL is permitted, | |
7 | - * provided that this copyright notice is | |
8 | - * preserved in its entirety in all copies and derived works. | |
9 | - * | |
10 | - * HEWLETT-PACKARD COMPANY MAKES NO WARRANTIES, EXPRESSED OR IMPLIED, | |
11 | - * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS | |
12 | - * FITNESS FOR ANY PARTICULAR PURPOSE. | |
13 | - * | |
14 | - * Many thanks to Alessandro Rubini and Jonathan Corbet! | |
15 | - * | |
16 | - * Based strongly on code by: | |
17 | - * | |
18 | - * Author: Yong-iL Joh <tolkien@mizi.com> | |
19 | - * Date : $Date: 2002/06/18 12:37:30 $ | |
20 | - * | |
21 | - * Author: Andrew Christian | |
22 | - * 15 May 2002 | |
23 | - */ | |
24 | - | |
25 | -#ifndef MMC_MMC_PROTOCOL_H | |
26 | -#define MMC_MMC_PROTOCOL_H | |
27 | - | |
28 | -/* Standard MMC commands (4.1) type argument response */ | |
29 | - /* class 1 */ | |
30 | -#define MMC_GO_IDLE_STATE 0 /* bc */ | |
31 | -#define MMC_SEND_OP_COND 1 /* bcr [31:0] OCR R3 */ | |
32 | -#define MMC_ALL_SEND_CID 2 /* bcr R2 */ | |
33 | -#define MMC_SET_RELATIVE_ADDR 3 /* ac [31:16] RCA R1 */ | |
34 | -#define MMC_SET_DSR 4 /* bc [31:16] RCA */ | |
35 | -#define MMC_SWITCH 6 /* ac [31:0] See below R1b */ | |
36 | -#define MMC_SELECT_CARD 7 /* ac [31:16] RCA R1 */ | |
37 | -#define MMC_SEND_EXT_CSD 8 /* adtc R1 */ | |
38 | -#define MMC_SEND_CSD 9 /* ac [31:16] RCA R2 */ | |
39 | -#define MMC_SEND_CID 10 /* ac [31:16] RCA R2 */ | |
40 | -#define MMC_READ_DAT_UNTIL_STOP 11 /* adtc [31:0] dadr R1 */ | |
41 | -#define MMC_STOP_TRANSMISSION 12 /* ac R1b */ | |
42 | -#define MMC_SEND_STATUS 13 /* ac [31:16] RCA R1 */ | |
43 | -#define MMC_GO_INACTIVE_STATE 15 /* ac [31:16] RCA */ | |
44 | - | |
45 | - /* class 2 */ | |
46 | -#define MMC_SET_BLOCKLEN 16 /* ac [31:0] block len R1 */ | |
47 | -#define MMC_READ_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 */ | |
48 | -#define MMC_READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 */ | |
49 | - | |
50 | - /* class 3 */ | |
51 | -#define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */ | |
52 | - | |
53 | - /* class 4 */ | |
54 | -#define MMC_SET_BLOCK_COUNT 23 /* adtc [31:0] data addr R1 */ | |
55 | -#define MMC_WRITE_BLOCK 24 /* adtc [31:0] data addr R1 */ | |
56 | -#define MMC_WRITE_MULTIPLE_BLOCK 25 /* adtc R1 */ | |
57 | -#define MMC_PROGRAM_CID 26 /* adtc R1 */ | |
58 | -#define MMC_PROGRAM_CSD 27 /* adtc R1 */ | |
59 | - | |
60 | - /* class 6 */ | |
61 | -#define MMC_SET_WRITE_PROT 28 /* ac [31:0] data addr R1b */ | |
62 | -#define MMC_CLR_WRITE_PROT 29 /* ac [31:0] data addr R1b */ | |
63 | -#define MMC_SEND_WRITE_PROT 30 /* adtc [31:0] wpdata addr R1 */ | |
64 | - | |
65 | - /* class 5 */ | |
66 | -#define MMC_ERASE_GROUP_START 35 /* ac [31:0] data addr R1 */ | |
67 | -#define MMC_ERASE_GROUP_END 36 /* ac [31:0] data addr R1 */ | |
68 | -#define MMC_ERASE 38 /* ac R1b */ | |
69 | - | |
70 | - /* class 9 */ | |
71 | -#define MMC_FAST_IO 39 /* ac <Complex> R4 */ | |
72 | -#define MMC_GO_IRQ_STATE 40 /* bcr R5 */ | |
73 | - | |
74 | - /* class 7 */ | |
75 | -#define MMC_LOCK_UNLOCK 42 /* adtc R1b */ | |
76 | - | |
77 | - /* class 8 */ | |
78 | -#define MMC_APP_CMD 55 /* ac [31:16] RCA R1 */ | |
79 | -#define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1 */ | |
80 | - | |
81 | -/* SD commands type argument response */ | |
82 | - /* class 0 */ | |
83 | -/* This is basically the same command as for MMC with some quirks. */ | |
84 | -#define SD_SEND_RELATIVE_ADDR 3 /* bcr R6 */ | |
85 | -#define SD_SEND_IF_COND 8 /* bcr [11:0] See below R7 */ | |
86 | - | |
87 | - /* class 10 */ | |
88 | -#define SD_SWITCH 6 /* adtc [31:0] See below R1 */ | |
89 | - | |
90 | - /* Application commands */ | |
91 | -#define SD_APP_SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */ | |
92 | -#define SD_APP_SEND_NUM_WR_BLKS 22 /* adtc R1 */ | |
93 | -#define SD_APP_OP_COND 41 /* bcr [31:0] OCR R3 */ | |
94 | -#define SD_APP_SEND_SCR 51 /* adtc R1 */ | |
95 | - | |
96 | -/* | |
97 | - * MMC_SWITCH argument format: | |
98 | - * | |
99 | - * [31:26] Always 0 | |
100 | - * [25:24] Access Mode | |
101 | - * [23:16] Location of target Byte in EXT_CSD | |
102 | - * [15:08] Value Byte | |
103 | - * [07:03] Always 0 | |
104 | - * [02:00] Command Set | |
105 | - */ | |
106 | - | |
107 | -/* | |
108 | - * SD_SWITCH argument format: | |
109 | - * | |
110 | - * [31] Check (0) or switch (1) | |
111 | - * [30:24] Reserved (0) | |
112 | - * [23:20] Function group 6 | |
113 | - * [19:16] Function group 5 | |
114 | - * [15:12] Function group 4 | |
115 | - * [11:8] Function group 3 | |
116 | - * [7:4] Function group 2 | |
117 | - * [3:0] Function group 1 | |
118 | - */ | |
119 | - | |
120 | -/* | |
121 | - * SD_SEND_IF_COND argument format: | |
122 | - * | |
123 | - * [31:12] Reserved (0) | |
124 | - * [11:8] Host Voltage Supply Flags | |
125 | - * [7:0] Check Pattern (0xAA) | |
126 | - */ | |
127 | - | |
128 | -/* | |
129 | - MMC status in R1 | |
130 | - Type | |
131 | - e : error bit | |
132 | - s : status bit | |
133 | - r : detected and set for the actual command response | |
134 | - x : detected and set during command execution. the host must poll | |
135 | - the card by sending status command in order to read these bits. | |
136 | - Clear condition | |
137 | - a : according to the card state | |
138 | - b : always related to the previous command. Reception of | |
139 | - a valid command will clear it (with a delay of one command) | |
140 | - c : clear by read | |
141 | - */ | |
142 | - | |
143 | -#define R1_OUT_OF_RANGE (1 << 31) /* er, c */ | |
144 | -#define R1_ADDRESS_ERROR (1 << 30) /* erx, c */ | |
145 | -#define R1_BLOCK_LEN_ERROR (1 << 29) /* er, c */ | |
146 | -#define R1_ERASE_SEQ_ERROR (1 << 28) /* er, c */ | |
147 | -#define R1_ERASE_PARAM (1 << 27) /* ex, c */ | |
148 | -#define R1_WP_VIOLATION (1 << 26) /* erx, c */ | |
149 | -#define R1_CARD_IS_LOCKED (1 << 25) /* sx, a */ | |
150 | -#define R1_LOCK_UNLOCK_FAILED (1 << 24) /* erx, c */ | |
151 | -#define R1_COM_CRC_ERROR (1 << 23) /* er, b */ | |
152 | -#define R1_ILLEGAL_COMMAND (1 << 22) /* er, b */ | |
153 | -#define R1_CARD_ECC_FAILED (1 << 21) /* ex, c */ | |
154 | -#define R1_CC_ERROR (1 << 20) /* erx, c */ | |
155 | -#define R1_ERROR (1 << 19) /* erx, c */ | |
156 | -#define R1_UNDERRUN (1 << 18) /* ex, c */ | |
157 | -#define R1_OVERRUN (1 << 17) /* ex, c */ | |
158 | -#define R1_CID_CSD_OVERWRITE (1 << 16) /* erx, c, CID/CSD overwrite */ | |
159 | -#define R1_WP_ERASE_SKIP (1 << 15) /* sx, c */ | |
160 | -#define R1_CARD_ECC_DISABLED (1 << 14) /* sx, a */ | |
161 | -#define R1_ERASE_RESET (1 << 13) /* sr, c */ | |
162 | -#define R1_STATUS(x) (x & 0xFFFFE000) | |
163 | -#define R1_CURRENT_STATE(x) ((x & 0x00001E00) >> 9) /* sx, b (4 bits) */ | |
164 | -#define R1_READY_FOR_DATA (1 << 8) /* sx, a */ | |
165 | -#define R1_APP_CMD (1 << 5) /* sr, c */ | |
166 | - | |
167 | -/* These are unpacked versions of the actual responses */ | |
168 | - | |
169 | -struct _mmc_csd { | |
170 | - u8 csd_structure; | |
171 | - u8 spec_vers; | |
172 | - u8 taac; | |
173 | - u8 nsac; | |
174 | - u8 tran_speed; | |
175 | - u16 ccc; | |
176 | - u8 read_bl_len; | |
177 | - u8 read_bl_partial; | |
178 | - u8 write_blk_misalign; | |
179 | - u8 read_blk_misalign; | |
180 | - u8 dsr_imp; | |
181 | - u16 c_size; | |
182 | - u8 vdd_r_curr_min; | |
183 | - u8 vdd_r_curr_max; | |
184 | - u8 vdd_w_curr_min; | |
185 | - u8 vdd_w_curr_max; | |
186 | - u8 c_size_mult; | |
187 | - union { | |
188 | - struct { /* MMC system specification version 3.1 */ | |
189 | - u8 erase_grp_size; | |
190 | - u8 erase_grp_mult; | |
191 | - } v31; | |
192 | - struct { /* MMC system specification version 2.2 */ | |
193 | - u8 sector_size; | |
194 | - u8 erase_grp_size; | |
195 | - } v22; | |
196 | - } erase; | |
197 | - u8 wp_grp_size; | |
198 | - u8 wp_grp_enable; | |
199 | - u8 default_ecc; | |
200 | - u8 r2w_factor; | |
201 | - u8 write_bl_len; | |
202 | - u8 write_bl_partial; | |
203 | - u8 file_format_grp; | |
204 | - u8 copy; | |
205 | - u8 perm_write_protect; | |
206 | - u8 tmp_write_protect; | |
207 | - u8 file_format; | |
208 | - u8 ecc; | |
209 | -}; | |
210 | - | |
211 | -/* | |
212 | - * OCR bits are mostly in host.h | |
213 | - */ | |
214 | -#define MMC_CARD_BUSY 0x80000000 /* Card Power up status bit */ | |
215 | - | |
216 | -/* | |
217 | - * Card Command Classes (CCC) | |
218 | - */ | |
219 | -#define CCC_BASIC (1<<0) /* (0) Basic protocol functions */ | |
220 | - /* (CMD0,1,2,3,4,7,9,10,12,13,15) */ | |
221 | -#define CCC_STREAM_READ (1<<1) /* (1) Stream read commands */ | |
222 | - /* (CMD11) */ | |
223 | -#define CCC_BLOCK_READ (1<<2) /* (2) Block read commands */ | |
224 | - /* (CMD16,17,18) */ | |
225 | -#define CCC_STREAM_WRITE (1<<3) /* (3) Stream write commands */ | |
226 | - /* (CMD20) */ | |
227 | -#define CCC_BLOCK_WRITE (1<<4) /* (4) Block write commands */ | |
228 | - /* (CMD16,24,25,26,27) */ | |
229 | -#define CCC_ERASE (1<<5) /* (5) Ability to erase blocks */ | |
230 | - /* (CMD32,33,34,35,36,37,38,39) */ | |
231 | -#define CCC_WRITE_PROT (1<<6) /* (6) Able to write protect blocks */ | |
232 | - /* (CMD28,29,30) */ | |
233 | -#define CCC_LOCK_CARD (1<<7) /* (7) Able to lock down card */ | |
234 | - /* (CMD16,CMD42) */ | |
235 | -#define CCC_APP_SPEC (1<<8) /* (8) Application specific */ | |
236 | - /* (CMD55,56,57,ACMD*) */ | |
237 | -#define CCC_IO_MODE (1<<9) /* (9) I/O mode */ | |
238 | - /* (CMD5,39,40,52,53) */ | |
239 | -#define CCC_SWITCH (1<<10) /* (10) High speed switch */ | |
240 | - /* (CMD6,34,35,36,37,50) */ | |
241 | - /* (11) Reserved */ | |
242 | - /* (CMD?) */ | |
243 | - | |
244 | -/* | |
245 | - * CSD field definitions | |
246 | - */ | |
247 | - | |
248 | -#define CSD_STRUCT_VER_1_0 0 /* Valid for system specification 1.0 - 1.2 */ | |
249 | -#define CSD_STRUCT_VER_1_1 1 /* Valid for system specification 1.4 - 2.2 */ | |
250 | -#define CSD_STRUCT_VER_1_2 2 /* Valid for system specification 3.1 - 3.2 - 3.31 - 4.0 - 4.1 */ | |
251 | -#define CSD_STRUCT_EXT_CSD 3 /* Version is coded in CSD_STRUCTURE in EXT_CSD */ | |
252 | - | |
253 | -#define CSD_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.2 */ | |
254 | -#define CSD_SPEC_VER_1 1 /* Implements system specification 1.4 */ | |
255 | -#define CSD_SPEC_VER_2 2 /* Implements system specification 2.0 - 2.2 */ | |
256 | -#define CSD_SPEC_VER_3 3 /* Implements system specification 3.1 - 3.2 - 3.31 */ | |
257 | -#define CSD_SPEC_VER_4 4 /* Implements system specification 4.0 - 4.1 */ | |
258 | - | |
259 | -/* | |
260 | - * EXT_CSD fields | |
261 | - */ | |
262 | - | |
263 | -#define EXT_CSD_BUS_WIDTH 183 /* R/W */ | |
264 | -#define EXT_CSD_HS_TIMING 185 /* R/W */ | |
265 | -#define EXT_CSD_CARD_TYPE 196 /* RO */ | |
266 | -#define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */ | |
267 | - | |
268 | -/* | |
269 | - * EXT_CSD field definitions | |
270 | - */ | |
271 | - | |
272 | -#define EXT_CSD_CMD_SET_NORMAL (1<<0) | |
273 | -#define EXT_CSD_CMD_SET_SECURE (1<<1) | |
274 | -#define EXT_CSD_CMD_SET_CPSECURE (1<<2) | |
275 | - | |
276 | -#define EXT_CSD_CARD_TYPE_26 (1<<0) /* Card can run at 26MHz */ | |
277 | -#define EXT_CSD_CARD_TYPE_52 (1<<1) /* Card can run at 52MHz */ | |
278 | - | |
279 | -#define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */ | |
280 | -#define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */ | |
281 | -#define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */ | |
282 | - | |
283 | -/* | |
284 | - * MMC_SWITCH access modes | |
285 | - */ | |
286 | - | |
287 | -#define MMC_SWITCH_MODE_CMD_SET 0x00 /* Change the command set */ | |
288 | -#define MMC_SWITCH_MODE_SET_BITS 0x01 /* Set bits which are 1 in value */ | |
289 | -#define MMC_SWITCH_MODE_CLEAR_BITS 0x02 /* Clear bits which are 1 in value */ | |
290 | -#define MMC_SWITCH_MODE_WRITE_BYTE 0x03 /* Set target to value */ | |
291 | - | |
292 | -/* | |
293 | - * SCR field definitions | |
294 | - */ | |
295 | - | |
296 | -#define SCR_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.01 */ | |
297 | -#define SCR_SPEC_VER_1 1 /* Implements system specification 1.10 */ | |
298 | -#define SCR_SPEC_VER_2 2 /* Implements system specification 2.00 */ | |
299 | - | |
300 | -/* | |
301 | - * SD bus widths | |
302 | - */ | |
303 | -#define SD_BUS_WIDTH_1 0 | |
304 | -#define SD_BUS_WIDTH_4 2 | |
305 | - | |
306 | -#endif /* MMC_MMC_PROTOCOL_H */ |
include/linux/mmc/sd.h
1 | +/* | |
2 | + * include/linux/mmc/sd.h | |
3 | + * | |
4 | + * Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved. | |
5 | + * | |
6 | + * This program is free software; you can redistribute it and/or modify | |
7 | + * it under the terms of the GNU General Public License as published by | |
8 | + * the Free Software Foundation; either version 2 of the License, or (at | |
9 | + * your option) any later version. | |
10 | + */ | |
11 | + | |
12 | +#ifndef MMC_SD_H | |
13 | +#define MMC_SD_H | |
14 | + | |
15 | +/* SD commands type argument response */ | |
16 | + /* class 0 */ | |
17 | +/* This is basically the same command as for MMC with some quirks. */ | |
18 | +#define SD_SEND_RELATIVE_ADDR 3 /* bcr R6 */ | |
19 | +#define SD_SEND_IF_COND 8 /* bcr [11:0] See below R7 */ | |
20 | + | |
21 | + /* class 10 */ | |
22 | +#define SD_SWITCH 6 /* adtc [31:0] See below R1 */ | |
23 | + | |
24 | + /* Application commands */ | |
25 | +#define SD_APP_SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */ | |
26 | +#define SD_APP_SEND_NUM_WR_BLKS 22 /* adtc R1 */ | |
27 | +#define SD_APP_OP_COND 41 /* bcr [31:0] OCR R3 */ | |
28 | +#define SD_APP_SEND_SCR 51 /* adtc R1 */ | |
29 | + | |
30 | +/* | |
31 | + * SD_SWITCH argument format: | |
32 | + * | |
33 | + * [31] Check (0) or switch (1) | |
34 | + * [30:24] Reserved (0) | |
35 | + * [23:20] Function group 6 | |
36 | + * [19:16] Function group 5 | |
37 | + * [15:12] Function group 4 | |
38 | + * [11:8] Function group 3 | |
39 | + * [7:4] Function group 2 | |
40 | + * [3:0] Function group 1 | |
41 | + */ | |
42 | + | |
43 | +/* | |
44 | + * SD_SEND_IF_COND argument format: | |
45 | + * | |
46 | + * [31:12] Reserved (0) | |
47 | + * [11:8] Host Voltage Supply Flags | |
48 | + * [7:0] Check Pattern (0xAA) | |
49 | + */ | |
50 | + | |
51 | +/* | |
52 | + * SCR field definitions | |
53 | + */ | |
54 | + | |
55 | +#define SCR_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.01 */ | |
56 | +#define SCR_SPEC_VER_1 1 /* Implements system specification 1.10 */ | |
57 | +#define SCR_SPEC_VER_2 2 /* Implements system specification 2.00 */ | |
58 | + | |
59 | +/* | |
60 | + * SD bus widths | |
61 | + */ | |
62 | +#define SD_BUS_WIDTH_1 0 | |
63 | +#define SD_BUS_WIDTH_4 2 | |
64 | + | |
65 | +/* | |
66 | + * SD_SWITCH mode | |
67 | + */ | |
68 | +#define SD_SWITCH_CHECK 0 | |
69 | +#define SD_SWITCH_SET 1 | |
70 | + | |
71 | +/* | |
72 | + * SD_SWITCH function groups | |
73 | + */ | |
74 | +#define SD_SWITCH_GRP_ACCESS 0 | |
75 | + | |
76 | +/* | |
77 | + * SD_SWITCH access modes | |
78 | + */ | |
79 | +#define SD_SWITCH_ACCESS_DEF 0 | |
80 | +#define SD_SWITCH_ACCESS_HS 1 | |
81 | + | |
82 | +#endif |