Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mmc: implement SDIO IO_RW_DIRECT operation

Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>

+74
+37
drivers/mmc/core/sdio_ops.c
··· 10 10 */ 11 11 12 12 #include <linux/mmc/host.h> 13 + #include <linux/mmc/card.h> 13 14 #include <linux/mmc/mmc.h> 14 15 #include <linux/mmc/sdio.h> 15 16 ··· 46 45 *rocr = cmd.resp[0]; 47 46 48 47 return err; 48 + } 49 + 50 + int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn, 51 + unsigned addr, u8 in, u8* out) 52 + { 53 + struct mmc_command cmd; 54 + int err; 55 + 56 + BUG_ON(!card); 57 + BUG_ON(fn > 7); 58 + 59 + memset(&cmd, 0, sizeof(struct mmc_command)); 60 + 61 + cmd.opcode = SD_IO_RW_DIRECT; 62 + cmd.arg = write ? 0x80000000 : 0x00000000; 63 + cmd.arg |= fn << 28; 64 + cmd.arg |= (write && out) ? 0x08000000 : 0x00000000; 65 + cmd.arg |= addr << 9; 66 + cmd.arg |= in; 67 + cmd.flags = MMC_RSP_R5 | MMC_CMD_AC; 68 + 69 + err = mmc_wait_for_cmd(card->host, &cmd, 0); 70 + if (err) 71 + return err; 72 + 73 + if (cmd.resp[0] & R5_ERROR) 74 + return -EIO; 75 + if (cmd.resp[0] & R5_FUNCTION_NUMBER) 76 + return -EINVAL; 77 + if (cmd.resp[0] & R5_OUT_OF_RANGE) 78 + return -ERANGE; 79 + 80 + if (out) 81 + *out = cmd.resp[0] & 0xFF; 82 + 83 + return 0; 49 84 } 50 85
+2
drivers/mmc/core/sdio_ops.h
··· 13 13 #define _MMC_SDIO_OPS_H 14 14 15 15 int mmc_send_io_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr); 16 + int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn, 17 + unsigned addr, u8 in, u8* out); 16 18 17 19 #endif 18 20
+1
include/linux/mmc/core.h
··· 42 42 #define MMC_RSP_R2 (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC) 43 43 #define MMC_RSP_R3 (MMC_RSP_PRESENT) 44 44 #define MMC_RSP_R4 (MMC_RSP_PRESENT) 45 + #define MMC_RSP_R5 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE) 45 46 #define MMC_RSP_R6 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE) 46 47 #define MMC_RSP_R7 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE) 47 48
+34
include/linux/mmc/sdio.h
··· 14 14 15 15 /* SDIO commands type argument response */ 16 16 #define SD_IO_SEND_OP_COND 5 /* bcr [23:0] OCR R4 */ 17 + #define SD_IO_RW_DIRECT 52 /* ac [31:0] See below R5 */ 18 + 19 + /* 20 + * SD_IO_RW_DIRECT argument format: 21 + * 22 + * [31] R/W flag 23 + * [30:28] Function number 24 + * [27] RAW flag 25 + * [25:9] Register address 26 + * [7:0] Data 27 + */ 28 + 29 + /* 30 + SDIO status in R5 31 + Type 32 + e : error bit 33 + s : status bit 34 + r : detected and set for the actual command response 35 + x : detected and set during command execution. the host must poll 36 + the card by sending status command in order to read these bits. 37 + Clear condition 38 + a : according to the card state 39 + b : always related to the previous command. Reception of 40 + a valid command will clear it (with a delay of one command) 41 + c : clear by read 42 + */ 43 + 44 + #define R5_COM_CRC_ERROR (1 << 15) /* er, b */ 45 + #define R5_ILLEGAL_COMMAND (1 << 14) /* er, b */ 46 + #define R5_ERROR (1 << 11) /* erx, c */ 47 + #define R5_FUNCTION_NUMBER (1 << 9) /* er, c */ 48 + #define R5_OUT_OF_RANGE (1 << 8) /* er, c */ 49 + #define R5_STATUS(x) (x & 0xCB00) 50 + #define R5_IO_CURRENT_STATE(x) ((x & 0x3000) >> 12) /* s, b */ 17 51 18 52 #endif 19 53