Teaching the MMC/SD block card driver about SPI.

 - Provide the SPI response type flags with each request issued.  The
   model is that if no such flags are provided, it will be rejected 
   by the MMC-over-SPI host.

 - Understand that multiblock SPI writes don't use STOP_TRANSMISSION.

 - Correct check for APP_CMD failure.

Signed-off-by: David Brownell <[EMAIL PROTECTED]>
---
 drivers/mmc/card/block.c |   26 +++++++++++++++++---------
 1 files changed, 17 insertions(+), 9 deletions(-)

--- g26.orig/drivers/mmc/card/block.c   2007-07-14 14:47:12.000000000 -0700
+++ g26/drivers/mmc/card/block.c        2007-07-14 14:47:55.000000000 -0700
@@ -151,17 +151,19 @@ static u32 mmc_sd_num_wr_blocks(struct m
 
        cmd.opcode = MMC_APP_CMD;
        cmd.arg = card->rca << 16;
-       cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
+       cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
 
        err = mmc_wait_for_cmd(card->host, &cmd, 0);
-       if ((err != MMC_ERR_NONE) || !(cmd.resp[0] & R1_APP_CMD))
+       if (err != MMC_ERR_NONE)
+               return (u32)-1;
+       if (!mmc_host_is_spi(card->host) && !(cmd.resp[0] & R1_APP_CMD))
                return (u32)-1;
 
        memset(&cmd, 0, sizeof(struct mmc_command));
 
        cmd.opcode = SD_APP_SEND_NUM_WR_BLKS;
        cmd.arg = 0;
-       cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
+       cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
 
        memset(&data, 0, sizeof(struct mmc_data));
 
@@ -220,11 +222,11 @@ static int mmc_blk_issue_rq(struct mmc_q
                brq.cmd.arg = req->sector;
                if (!mmc_card_blockaddr(card))
                        brq.cmd.arg <<= 9;
-               brq.cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
+               brq.cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
                brq.data.blksz = 1 << md->block_bits;
                brq.stop.opcode = MMC_STOP_TRANSMISSION;
                brq.stop.arg = 0;
-               brq.stop.flags = MMC_RSP_R1B | MMC_CMD_AC;
+               brq.stop.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;
                brq.data.blocks = req->nr_sectors >> (md->block_bits - 9);
                if (brq.data.blocks > card->host->max_blk_count)
                        brq.data.blocks = card->host->max_blk_count;
@@ -244,7 +246,12 @@ static int mmc_blk_issue_rq(struct mmc_q
 
                if (brq.data.blocks > 1) {
                        brq.data.flags |= MMC_DATA_MULTI;
-                       brq.mrq.stop = &brq.stop;
+                       /* SPI multiblock writes terminate using a special
+                        * token, not a STOP_TRANSMISSION request.
+                        */
+                       if (!mmc_host_is_spi(card->host)
+                                       || rq_data_dir(req) == READ)
+                               brq.mrq.stop = &brq.stop;
                        readcmd = MMC_READ_MULTIPLE_BLOCK;
                        writecmd = MMC_WRITE_MULTIPLE_BLOCK;
                } else {
@@ -302,13 +309,14 @@ static int mmc_blk_issue_rq(struct mmc_q
                        goto cmd_err;
                }
 
-               if (rq_data_dir(req) != READ) {
+               if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) {
                        do {
                                int err;
 
                                cmd.opcode = MMC_SEND_STATUS;
                                cmd.arg = card->rca << 16;
-                               cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
+                               cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1
+                                               | MMC_CMD_AC;
                                err = mmc_wait_for_cmd(card->host, &cmd, 5);
                                if (err) {
                                        printk(KERN_ERR "%s: error %d 
requesting status\n",
@@ -511,7 +519,7 @@ mmc_blk_set_blksize(struct mmc_blk_data 
        mmc_claim_host(card->host);
        cmd.opcode = MMC_SET_BLOCKLEN;
        cmd.arg = 1 << md->block_bits;
-       cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
+       cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
        err = mmc_wait_for_cmd(card->host, &cmd, 5);
        mmc_release_host(card->host);
 

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
spi-devel-general mailing list
spi-devel-general@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/spi-devel-general

Reply via email to