mmc: mmc_spi: Re-write driver using DM framework
authorBhargav Shah <bhargavshah1988@gmail.com>
Mon, 8 Jul 2019 04:10:48 +0000 (04:10 +0000)
committerPeng Fan <peng.fan@nxp.com>
Mon, 15 Jul 2019 02:16:49 +0000 (10:16 +0800)
This patch rewrites MMC SPI driver using U-Boot DM
framework and get it's working on SiFive Unleashed
board.

Signed-off-by: Bhargav Shah <bhargavshah1988@gmail.com>
Signed-off-by: Anup Patel <anup.patel@wdc.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>
drivers/mmc/Kconfig
drivers/mmc/mmc_spi.c
scripts/config_whitelist.txt

index b5180ea4a0682740b8d6db8c4b369c16ee5dc20c..a4a6a6c085d7f459aa94d3b930f0517aefadfd15 100644 (file)
@@ -46,6 +46,24 @@ config SPL_DM_MMC
 
 if MMC
 
+config MMC_SPI
+       bool "Support for SPI-based MMC controller"
+       depends on DM_MMC && DM_SPI
+       help
+         This selects SPI-based MMC controllers.
+         If you have an MMC controller on a SPI bus, say Y here.
+
+         If unsure, say N.
+
+config MMC_SPI_CRC_ON
+       bool "Support CRC for SPI-based MMC controller"
+       depends on MMC_SPI
+       default y
+       help
+         This enables CRC for SPI-based MMC controllers.
+
+         If unsure, say N.
+
 config ARM_PL180_MMCI
        bool "ARM AMBA Multimedia Card Interface and compatible support"
        depends on DM_MMC && OF_CONTROL
index 4f57990d9c4e5bd7426bc2726bd8c3fc8e0d4074..f3d687ae806f6aded5f9f6f210e7b93e39f78c44 100644 (file)
@@ -2,6 +2,8 @@
  * generic mmc spi driver
  *
  * Copyright (C) 2010 Thomas Chou <thomas@wytron.com.tw>
+ * Copyright 2019 Bhargav Shah <bhargavshah1988@gmail.com>
+ *
  * Licensed under the GPL-2 or later.
  */
 #include <common.h>
 #include <malloc.h>
 #include <part.h>
 #include <mmc.h>
-#include <spi.h>
+#include <stdlib.h>
 #include <u-boot/crc.h>
 #include <linux/crc7.h>
 #include <asm/byteorder.h>
+#include <dm.h>
+#include <spi.h>
 
 /* MMC/SD in SPI mode reports R1 status always */
-#define R1_SPI_IDLE            (1 << 0)
-#define R1_SPI_ERASE_RESET     (1 << 1)
-#define R1_SPI_ILLEGAL_COMMAND (1 << 2)
-#define R1_SPI_COM_CRC         (1 << 3)
-#define R1_SPI_ERASE_SEQ       (1 << 4)
-#define R1_SPI_ADDRESS         (1 << 5)
-#define R1_SPI_PARAMETER       (1 << 6)
+#define R1_SPI_IDLE                    BIT(0)
+#define R1_SPI_ERASE_RESET             BIT(1)
+#define R1_SPI_ILLEGAL_COMMAND         BIT(2)
+#define R1_SPI_COM_CRC                 BIT(3)
+#define R1_SPI_ERASE_SEQ               BIT(4)
+#define R1_SPI_ADDRESS                 BIT(5)
+#define R1_SPI_PARAMETER               BIT(6)
 /* R1 bit 7 is always zero, reuse this bit for error */
-#define R1_SPI_ERROR           (1 << 7)
+#define R1_SPI_ERROR                   BIT(7)
 
 /* Response tokens used to ack each block written: */
 #define SPI_MMC_RESPONSE_CODE(x)       ((x) & 0x1f)
 /* Read and write blocks start with these tokens and end with crc;
  * on error, read tokens act like a subset of R2_SPI_* values.
  */
-#define SPI_TOKEN_SINGLE       0xfe    /* single block r/w, multiblock read */
-#define SPI_TOKEN_MULTI_WRITE  0xfc    /* multiblock write */
-#define SPI_TOKEN_STOP_TRAN    0xfd    /* terminate multiblock write */
+/* single block write multiblock read */
+#define SPI_TOKEN_SINGLE               0xfe
+/* multiblock write */
+#define SPI_TOKEN_MULTI_WRITE          0xfc
+/* terminate multiblock write */
+#define SPI_TOKEN_STOP_TRAN            0xfd
 
 /* MMC SPI commands start with a start bit "0" and a transmit bit "1" */
-#define MMC_SPI_CMD(x) (0x40 | (x & 0x3f))
+#define MMC_SPI_CMD(x) (0x40 | (x))
 
 /* bus capability */
-#define MMC_SPI_VOLTAGE (MMC_VDD_32_33 | MMC_VDD_33_34)
-#define MMC_SPI_MIN_CLOCK 400000 /* 400KHz to meet MMC spec */
+#define MMC_SPI_VOLTAGE                        (MMC_VDD_32_33 | MMC_VDD_33_34)
+#define MMC_SPI_MIN_CLOCK              400000  /* 400KHz to meet MMC spec */
+#define MMC_SPI_MAX_CLOCK              25000000 /* SD/MMC legacy speed */
 
 /* timeout value */
-#define CTOUT 8
-#define RTOUT 3000000 /* 1 sec */
-#define WTOUT 3000000 /* 1 sec */
+#define CMD_TIMEOUT                    8
+#define READ_TIMEOUT                   3000000 /* 1 sec */
+#define WRITE_TIMEOUT                  3000000 /* 1 sec */
 
-static uint mmc_spi_sendcmd(struct mmc *mmc, ushort cmdidx, u32 cmdarg)
+struct mmc_spi_priv {
+       struct spi_slave *spi;
+       struct mmc_config cfg;
+       struct mmc mmc;
+};
+
+static int mmc_spi_sendcmd(struct udevice *dev,
+                          ushort cmdidx, u32 cmdarg, u32 resp_type,
+                          u8 *resp, u32 resp_size,
+                          bool resp_match, u8 resp_match_value)
 {
-       struct spi_slave *spi = mmc->priv;
-       u8 cmdo[7];
-       u8 r1;
-       int i;
+       int i, rpos = 0, ret = 0;
+       u8 cmdo[7], r;
+
+       debug("%s: cmd%d cmdarg=0x%x resp_type=0x%x "
+             "resp_size=%d resp_match=%d resp_match_value=0x%x\n",
+             __func__, cmdidx, cmdarg, resp_type,
+             resp_size, resp_match, resp_match_value);
+
        cmdo[0] = 0xff;
        cmdo[1] = MMC_SPI_CMD(cmdidx);
        cmdo[2] = cmdarg >> 24;
@@ -63,37 +84,79 @@ static uint mmc_spi_sendcmd(struct mmc *mmc, ushort cmdidx, u32 cmdarg)
        cmdo[4] = cmdarg >> 8;
        cmdo[5] = cmdarg;
        cmdo[6] = (crc7(0, &cmdo[1], 5) << 1) | 0x01;
-       spi_xfer(spi, sizeof(cmdo) * 8, cmdo, NULL, 0);
-       for (i = 0; i < CTOUT; i++) {
-               spi_xfer(spi, 1 * 8, NULL, &r1, 0);
-               if (i && (r1 & 0x80) == 0) /* r1 response */
-                       break;
+       ret = dm_spi_xfer(dev, sizeof(cmdo) * 8, cmdo, NULL, 0);
+       if (ret)
+               return ret;
+
+       ret = dm_spi_xfer(dev, 1 * 8, NULL, &r, 0);
+       if (ret)
+               return ret;
+
+       if (!resp || !resp_size)
+               return 0;
+
+       debug("%s: cmd%d", __func__, cmdidx);
+
+       if (resp_match) {
+               r = ~resp_match_value;
+               i = CMD_TIMEOUT;
+               while (i--) {
+                       ret = dm_spi_xfer(dev, 1 * 8, NULL, &r, 0);
+                       if (ret)
+                               return ret;
+                       debug(" resp%d=0x%x", rpos, r);
+                       rpos++;
+                       if (r == resp_match_value)
+                               break;
+               }
+               if (!i && (r != resp_match_value))
+                       return -ETIMEDOUT;
+       }
+
+       for (i = 0; i < resp_size; i++) {
+               if (i == 0 && resp_match) {
+                       resp[i] = resp_match_value;
+                       continue;
+               }
+               ret = dm_spi_xfer(dev, 1 * 8, NULL, &r, 0);
+               if (ret)
+                       return ret;
+               debug(" resp%d=0x%x", rpos, r);
+               rpos++;
+               resp[i] = r;
        }
-       debug("%s:cmd%d resp%d %x\n", __func__, cmdidx, i, r1);
-       return r1;
+
+       debug("\n");
+
+       return 0;
 }
 
-static uint mmc_spi_readdata(struct mmc *mmc, void *xbuf,
-                               u32 bcnt, u32 bsize)
+static int mmc_spi_readdata(struct udevice *dev,
+                           void *xbuf, u32 bcnt, u32 bsize)
 {
-       struct spi_slave *spi = mmc->priv;
-       u8 *buf = xbuf;
-       u8 r1;
        u16 crc;
-       int i;
+       u8 *buf = xbuf, r1;
+       int i, ret = 0;
+
        while (bcnt--) {
-               for (i = 0; i < RTOUT; i++) {
-                       spi_xfer(spi, 1 * 8, NULL, &r1, 0);
-                       if (r1 != 0xff) /* data token */
+               for (i = 0; i < READ_TIMEOUT; i++) {
+                       ret = dm_spi_xfer(dev, 1 * 8, NULL, &r1, 0);
+                       if (ret)
+                               return ret;
+                       if (r1 == SPI_TOKEN_SINGLE)
                                break;
                }
-               debug("%s:tok%d %x\n", __func__, i, r1);
+               debug("%s: data tok%d 0x%x\n", __func__, i, r1);
                if (r1 == SPI_TOKEN_SINGLE) {
-                       spi_xfer(spi, bsize * 8, NULL, buf, 0);
-                       spi_xfer(spi, 2 * 8, NULL, &crc, 0);
+                       ret = dm_spi_xfer(dev, bsize * 8, NULL, buf, 0);
+                       if (ret)
+                               return ret;
+                       ret = dm_spi_xfer(dev, 2 * 8, NULL, &crc, 0);
+                       if (ret)
+                               return ret;
 #ifdef CONFIG_MMC_SPI_CRC_ON
-                       if (be_to_cpu16(crc16_ccitt(0, buf, bsize)) != crc) {
-                               debug("%s: CRC error\n", mmc->cfg->name);
+                       if (be16_to_cpu(crc16_ccitt(0, buf, bsize)) != crc) {
+                               debug("%s: data crc error\n", __func__);
                                r1 = R1_SPI_COM_CRC;
                                break;
                        }
@@ -105,48 +168,56 @@ static uint mmc_spi_readdata(struct mmc *mmc, void *xbuf,
                }
                buf += bsize;
        }
-       return r1;
+
+       if (r1 & R1_SPI_COM_CRC)
+               ret = -ECOMM;
+       else if (r1) /* other errors */
+               ret = -ETIMEDOUT;
+
+       return ret;
 }
 
-static uint mmc_spi_writedata(struct mmc *mmc, const void *xbuf,
-                             u32 bcnt, u32 bsize, int multi)
+static int mmc_spi_writedata(struct udevice *dev, const void *xbuf,
+                            u32 bcnt, u32 bsize, int multi)
 {
-       struct spi_slave *spi = mmc->priv;
        const u8 *buf = xbuf;
-       u8 r1;
+       u8 r1, tok[2];
        u16 crc;
-       u8 tok[2];
-       int i;
+       int i, ret = 0;
+
        tok[0] = 0xff;
        tok[1] = multi ? SPI_TOKEN_MULTI_WRITE : SPI_TOKEN_SINGLE;
+
        while (bcnt--) {
 #ifdef CONFIG_MMC_SPI_CRC_ON
                crc = cpu_to_be16(crc16_ccitt(0, (u8 *)buf, bsize));
 #endif
-               spi_xfer(spi, 2 * 8, tok, NULL, 0);
-               spi_xfer(spi, bsize * 8, buf, NULL, 0);
-               spi_xfer(spi, 2 * 8, &crc, NULL, 0);
-               for (i = 0; i < CTOUT; i++) {
-                       spi_xfer(spi, 1 * 8, NULL, &r1, 0);
+               dm_spi_xfer(dev, 2 * 8, tok, NULL, 0);
+               dm_spi_xfer(dev, bsize * 8, buf, NULL, 0);
+               dm_spi_xfer(dev, 2 * 8, &crc, NULL, 0);
+               for (i = 0; i < CMD_TIMEOUT; i++) {
+                       dm_spi_xfer(dev, 1 * 8, NULL, &r1, 0);
                        if ((r1 & 0x10) == 0) /* response token */
                                break;
                }
-               debug("%s:tok%d %x\n", __func__, i, r1);
+               debug("%s: data tok%d 0x%x\n", __func__, i, r1);
                if (SPI_MMC_RESPONSE_CODE(r1) == SPI_RESPONSE_ACCEPTED) {
-                       for (i = 0; i < WTOUT; i++) { /* wait busy */
-                               spi_xfer(spi, 1 * 8, NULL, &r1, 0);
+                       debug("%s: data accepted\n", __func__);
+                       for (i = 0; i < WRITE_TIMEOUT; i++) { /* wait busy */
+                               dm_spi_xfer(dev, 1 * 8, NULL, &r1, 0);
                                if (i && r1 == 0xff) {
                                        r1 = 0;
                                        break;
                                }
                        }
-                       if (i == WTOUT) {
-                               debug("%s:wtout %x\n", __func__, r1);
+                       if (i == WRITE_TIMEOUT) {
+                               debug("%s: data write timeout 0x%x\n",
+                                     __func__, r1);
                                r1 = R1_SPI_ERROR;
                                break;
                        }
                } else {
-                       debug("%s: err %x\n", __func__, r1);
+                       debug("%s: data error 0x%x\n", __func__, r1);
                        r1 = R1_SPI_COM_CRC;
                        break;
                }
@@ -154,140 +225,204 @@ static uint mmc_spi_writedata(struct mmc *mmc, const void *xbuf,
        }
        if (multi && bcnt == -1) { /* stop multi write */
                tok[1] = SPI_TOKEN_STOP_TRAN;
-               spi_xfer(spi, 2 * 8, tok, NULL, 0);
-               for (i = 0; i < WTOUT; i++) { /* wait busy */
-                       spi_xfer(spi, 1 * 8, NULL, &r1, 0);
+               dm_spi_xfer(dev, 2 * 8, tok, NULL, 0);
+               for (i = 0; i < WRITE_TIMEOUT; i++) { /* wait busy */
+                       dm_spi_xfer(dev, 1 * 8, NULL, &r1, 0);
                        if (i && r1 == 0xff) {
                                r1 = 0;
                                break;
                        }
                }
-               if (i == WTOUT) {
-                       debug("%s:wstop %x\n", __func__, r1);
+               if (i == WRITE_TIMEOUT) {
+                       debug("%s: data write timeout 0x%x\n", __func__, r1);
                        r1 = R1_SPI_ERROR;
                }
        }
-       return r1;
-}
 
-static int mmc_spi_request(struct mmc *mmc, struct mmc_cmd *cmd,
-               struct mmc_data *data)
-{
-       struct spi_slave *spi = mmc->priv;
-       u8 r1;
-       int i;
-       int ret = 0;
-       debug("%s:cmd%d %x %x\n", __func__,
-             cmd->cmdidx, cmd->resp_type, cmd->cmdarg);
-       spi_claim_bus(spi);
-       spi_cs_activate(spi);
-       r1 = mmc_spi_sendcmd(mmc, cmd->cmdidx, cmd->cmdarg);
-       if (r1 == 0xff) { /* no response */
-               ret = -ENOMEDIUM;
-               goto done;
-       } else if (r1 & R1_SPI_COM_CRC) {
+       if (r1 & R1_SPI_COM_CRC)
                ret = -ECOMM;
-               goto done;
-       } else if (r1 & ~R1_SPI_IDLE) { /* other errors */
+       else if (r1) /* other errors */
                ret = -ETIMEDOUT;
+
+       return ret;
+}
+
+static int dm_mmc_spi_set_ios(struct udevice *dev)
+{
+       return 0;
+}
+
+static int dm_mmc_spi_request(struct udevice *dev, struct mmc_cmd *cmd,
+                             struct mmc_data *data)
+{
+       int i, multi, ret = 0;
+       u8 *resp = NULL;
+       u32 resp_size = 0;
+       bool resp_match = false;
+       u8 resp8 = 0, resp40[5] = { 0 }, resp_match_value = 0;
+
+       dm_spi_claim_bus(dev);
+
+       for (i = 0; i < 4; i++)
+               cmd->response[i] = 0;
+
+       switch (cmd->cmdidx) {
+       case SD_CMD_APP_SEND_OP_COND:
+       case MMC_CMD_SEND_OP_COND:
+               resp = &resp8;
+               resp_size = sizeof(resp8);
+               cmd->cmdarg = 0x40000000;
+               break;
+       case SD_CMD_SEND_IF_COND:
+               resp = (u8 *)&resp40[0];
+               resp_size = sizeof(resp40);
+               resp_match = true;
+               resp_match_value = R1_SPI_IDLE;
+               break;
+       case MMC_CMD_SPI_READ_OCR:
+               resp = (u8 *)&resp40[0];
+               resp_size = sizeof(resp40);
+               break;
+       case MMC_CMD_SEND_STATUS:
+       case MMC_CMD_SET_BLOCKLEN:
+       case MMC_CMD_SPI_CRC_ON_OFF:
+       case MMC_CMD_STOP_TRANSMISSION:
+               resp = &resp8;
+               resp_size = sizeof(resp8);
+               resp_match = true;
+               resp_match_value = 0x0;
+               break;
+       case MMC_CMD_SEND_CSD:
+       case MMC_CMD_SEND_CID:
+       case MMC_CMD_READ_SINGLE_BLOCK:
+       case MMC_CMD_READ_MULTIPLE_BLOCK:
+       case MMC_CMD_WRITE_SINGLE_BLOCK:
+       case MMC_CMD_WRITE_MULTIPLE_BLOCK:
+               break;
+       default:
+               resp = &resp8;
+               resp_size = sizeof(resp8);
+               resp_match = true;
+               resp_match_value = R1_SPI_IDLE;
+               break;
+       };
+
+       ret = mmc_spi_sendcmd(dev, cmd->cmdidx, cmd->cmdarg, cmd->resp_type,
+                             resp, resp_size, resp_match, resp_match_value);
+       if (ret)
                goto done;
-       } else if (cmd->resp_type == MMC_RSP_R2) {
-               r1 = mmc_spi_readdata(mmc, cmd->response, 1, 16);
+
+       switch (cmd->cmdidx) {
+       case SD_CMD_APP_SEND_OP_COND:
+       case MMC_CMD_SEND_OP_COND:
+               cmd->response[0] = (resp8 & R1_SPI_IDLE) ? 0 : OCR_BUSY;
+               break;
+       case SD_CMD_SEND_IF_COND:
+       case MMC_CMD_SPI_READ_OCR:
+               cmd->response[0] = resp40[4];
+               cmd->response[0] |= (uint)resp40[3] << 8;
+               cmd->response[0] |= (uint)resp40[2] << 16;
+               cmd->response[0] |= (uint)resp40[1] << 24;
+               break;
+       case MMC_CMD_SEND_STATUS:
+               cmd->response[0] = (resp8 & 0xff) ?
+                       MMC_STATUS_ERROR : MMC_STATUS_RDY_FOR_DATA;
+               break;
+       case MMC_CMD_SEND_CID:
+       case MMC_CMD_SEND_CSD:
+               ret = mmc_spi_readdata(dev, cmd->response, 1, 16);
+               if (ret)
+                       return ret;
                for (i = 0; i < 4; i++)
-                       cmd->response[i] = be32_to_cpu(cmd->response[i]);
-               debug("r128 %x %x %x %x\n", cmd->response[0], cmd->response[1],
-                     cmd->response[2], cmd->response[3]);
-       } else if (!data) {
-               switch (cmd->cmdidx) {
-               case SD_CMD_APP_SEND_OP_COND:
-               case MMC_CMD_SEND_OP_COND:
-                       cmd->response[0] = (r1 & R1_SPI_IDLE) ? 0 : OCR_BUSY;
-                       break;
-               case SD_CMD_SEND_IF_COND:
-               case MMC_CMD_SPI_READ_OCR:
-                       spi_xfer(spi, 4 * 8, NULL, cmd->response, 0);
-                       cmd->response[0] = be32_to_cpu(cmd->response[0]);
-                       debug("r32 %x\n", cmd->response[0]);
-                       break;
-               case MMC_CMD_SEND_STATUS:
-                       spi_xfer(spi, 1 * 8, NULL, cmd->response, 0);
-                       cmd->response[0] = (cmd->response[0] & 0xff) ?
-                               MMC_STATUS_ERROR : MMC_STATUS_RDY_FOR_DATA;
-                       break;
-               }
-       } else {
-               debug("%s:data %x %x %x\n", __func__,
-                     data->flags, data->blocks, data->blocksize);
+                       cmd->response[i] =
+                               cpu_to_be32(cmd->response[i]);
+               break;
+       default:
+               cmd->response[0] = resp8;
+               break;
+       }
+
+       debug("%s: cmd%d resp0=0x%x resp1=0x%x resp2=0x%x resp3=0x%x\n",
+             __func__, cmd->cmdidx, cmd->response[0], cmd->response[1],
+             cmd->response[2], cmd->response[3]);
+
+       if (data) {
+               debug("%s: data flags=0x%x blocks=%d block_size=%d\n",
+                     __func__, data->flags, data->blocks, data->blocksize);
+               multi = (cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK);
                if (data->flags == MMC_DATA_READ)
-                       r1 = mmc_spi_readdata(mmc, data->dest,
-                               data->blocks, data->blocksize);
+                       ret = mmc_spi_readdata(dev, data->dest,
+                                              data->blocks, data->blocksize);
                else if  (data->flags == MMC_DATA_WRITE)
-                       r1 = mmc_spi_writedata(mmc, data->src,
-                               data->blocks, data->blocksize,
-                               (cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK));
-               if (r1 & R1_SPI_COM_CRC)
-                       ret = -ECOMM;
-               else if (r1) /* other errors */
-                       ret = -ETIMEDOUT;
+                       ret = mmc_spi_writedata(dev, data->src,
+                                               data->blocks, data->blocksize,
+                                               multi);
        }
+
 done:
-       spi_cs_deactivate(spi);
-       spi_release_bus(spi);
+       dm_spi_release_bus(dev);
+
        return ret;
 }
 
-static int mmc_spi_set_ios(struct mmc *mmc)
+static int mmc_spi_probe(struct udevice *dev)
 {
-       struct spi_slave *spi = mmc->priv;
+       struct mmc_spi_priv *priv = dev_get_priv(dev);
+       struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+       char *name;
+
+       priv->spi = dev_get_parent_priv(dev);
+       if (!priv->spi->max_hz)
+               priv->spi->max_hz = MMC_SPI_MAX_CLOCK;
+       priv->spi->speed = 0;
+       priv->spi->mode = SPI_MODE_0;
+       priv->spi->wordlen = 8;
+
+       name = malloc(strlen(dev->parent->name) + strlen(dev->name) + 4);
+       if (!name)
+               return -ENOMEM;
+       sprintf(name, "%s:%s", dev->parent->name, dev->name);
+
+       priv->cfg.name = name;
+       priv->cfg.host_caps = MMC_MODE_SPI;
+       priv->cfg.voltages = MMC_SPI_VOLTAGE;
+       priv->cfg.f_min = MMC_SPI_MIN_CLOCK;
+       priv->cfg.f_max = priv->spi->max_hz;
+       priv->cfg.part_type = PART_TYPE_DOS;
+       priv->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
+
+       priv->mmc.cfg = &priv->cfg;
+       priv->mmc.priv = priv;
+       priv->mmc.dev = dev;
+
+       upriv->mmc = &priv->mmc;
 
-       debug("%s: clock %u\n", __func__, mmc->clock);
-       if (mmc->clock)
-               spi_set_speed(spi, mmc->clock);
        return 0;
 }
 
-static int mmc_spi_init_p(struct mmc *mmc)
+static int mmc_spi_bind(struct udevice *dev)
 {
-       struct spi_slave *spi = mmc->priv;
-       spi_set_speed(spi, MMC_SPI_MIN_CLOCK);
-       spi_claim_bus(spi);
-       /* cs deactivated for 100+ clock */
-       spi_xfer(spi, 18 * 8, NULL, NULL, 0);
-       spi_release_bus(spi);
-       return 0;
+       struct mmc_spi_priv *priv = dev_get_priv(dev);
+
+       return mmc_bind(dev, &priv->mmc, &priv->cfg);
 }
 
-static const struct mmc_ops mmc_spi_ops = {
-       .send_cmd       = mmc_spi_request,
-       .set_ios        = mmc_spi_set_ios,
-       .init           = mmc_spi_init_p,
+static const struct dm_mmc_ops mmc_spi_ops = {
+       .send_cmd       = dm_mmc_spi_request,
+       .set_ios        = dm_mmc_spi_set_ios,
 };
 
-static struct mmc_config mmc_spi_cfg = {
-       .name           = "MMC_SPI",
-       .ops            = &mmc_spi_ops,
-       .host_caps      = MMC_MODE_SPI,
-       .voltages       = MMC_SPI_VOLTAGE,
-       .f_min          = MMC_SPI_MIN_CLOCK,
-       .part_type      = PART_TYPE_DOS,
-       .b_max          = CONFIG_SYS_MMC_MAX_BLK_COUNT,
+static const struct udevice_id dm_mmc_spi_match[] = {
+       { .compatible = "mmc-spi-slot" },
+       { /* sentinel */ }
 };
 
-struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode)
-{
-       struct mmc *mmc;
-       struct spi_slave *spi;
-
-       spi = spi_setup_slave(bus, cs, speed, mode);
-       if (spi == NULL)
-               return NULL;
-
-       mmc_spi_cfg.f_max = speed;
-
-       mmc = mmc_create(&mmc_spi_cfg, spi);
-       if (mmc == NULL) {
-               spi_free_slave(spi);
-               return NULL;
-       }
-       return mmc;
-}
+U_BOOT_DRIVER(mmc_spi) = {
+       .name = "mmc_spi",
+       .id = UCLASS_MMC,
+       .of_match = dm_mmc_spi_match,
+       .ops = &mmc_spi_ops,
+       .probe = mmc_spi_probe,
+       .bind = mmc_spi_bind,
+       .priv_auto_alloc_size = sizeof(struct mmc_spi_priv),
+};
index 2c9cfb450d09a5b1e7dd3e88be0d952c1a77ae5a..44c03968307a2a1183fe420ba3743de6ed567802 100644 (file)
@@ -1165,12 +1165,6 @@ CONFIG_MMCBOOTCOMMAND
 CONFIG_MMCROOT
 CONFIG_MMC_DEFAULT_DEV
 CONFIG_MMC_RPMB_TRACE
-CONFIG_MMC_SPI
-CONFIG_MMC_SPI_BUS
-CONFIG_MMC_SPI_CRC_ON
-CONFIG_MMC_SPI_CS
-CONFIG_MMC_SPI_MODE
-CONFIG_MMC_SPI_SPEED
 CONFIG_MMC_SUNXI_SLOT
 CONFIG_MMU
 CONFIG_MONITOR_IS_IN_RAM