From b2bcc798bbb482b2909801280f3c4aff8cbbf5be Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Tue, 22 May 2007 20:25:21 +0200 Subject: mmc: implement SDIO IO_RW_DIRECT operation Signed-off-by: Pierre Ossman --- drivers/mmc/core/sdio_ops.c | 37 +++++++++++++++++++++++++++++++++++++ drivers/mmc/core/sdio_ops.h | 2 ++ 2 files changed, 39 insertions(+) (limited to 'drivers/mmc/core') diff --git a/drivers/mmc/core/sdio_ops.c b/drivers/mmc/core/sdio_ops.c index d6f9f9d8517..31233f7b55c 100644 --- a/drivers/mmc/core/sdio_ops.c +++ b/drivers/mmc/core/sdio_ops.c @@ -10,6 +10,7 @@ */ #include +#include #include #include @@ -47,3 +48,39 @@ int mmc_send_io_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) return err; } +int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn, + unsigned addr, u8 in, u8* out) +{ + struct mmc_command cmd; + int err; + + BUG_ON(!card); + BUG_ON(fn > 7); + + memset(&cmd, 0, sizeof(struct mmc_command)); + + cmd.opcode = SD_IO_RW_DIRECT; + cmd.arg = write ? 0x80000000 : 0x00000000; + cmd.arg |= fn << 28; + cmd.arg |= (write && out) ? 0x08000000 : 0x00000000; + cmd.arg |= addr << 9; + cmd.arg |= in; + cmd.flags = MMC_RSP_R5 | MMC_CMD_AC; + + err = mmc_wait_for_cmd(card->host, &cmd, 0); + if (err) + return err; + + if (cmd.resp[0] & R5_ERROR) + return -EIO; + if (cmd.resp[0] & R5_FUNCTION_NUMBER) + return -EINVAL; + if (cmd.resp[0] & R5_OUT_OF_RANGE) + return -ERANGE; + + if (out) + *out = cmd.resp[0] & 0xFF; + + return 0; +} + diff --git a/drivers/mmc/core/sdio_ops.h b/drivers/mmc/core/sdio_ops.h index d8c982976f1..f0e9d69e5ce 100644 --- a/drivers/mmc/core/sdio_ops.h +++ b/drivers/mmc/core/sdio_ops.h @@ -13,6 +13,8 @@ #define _MMC_SDIO_OPS_H int mmc_send_io_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr); +int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn, + unsigned addr, u8 in, u8* out); #endif -- cgit v1.2.3