mmc.c 15.9 KB
Newer Older
W
weety 已提交
1
/*
2
 * Copyright (c) 2006-2021, RT-Thread Development Team
W
weety 已提交
3
 *
4
 * SPDX-License-Identifier: Apache-2.0
W
weety 已提交
5 6
 *
 * Change Logs:
7 8
 * Date           Author       Notes
 * 2015-06-15     hichard      first version
W
weety 已提交
9 10 11 12 13
 */

#include <drivers/mmcsd_core.h>
#include <drivers/mmc.h>

14
#define DBG_TAG               "SDIO"
15
#ifdef RT_SDIO_DEBUG
16
#define DBG_LVL               DBG_LOG
17
#else
18
#define DBG_LVL               DBG_INFO
19 20 21
#endif /* RT_SDIO_DEBUG */
#include <rtdbg.h>

W
weety 已提交
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
static const rt_uint32_t tran_unit[] =
{
    10000, 100000, 1000000, 10000000,
    0,     0,      0,       0
};

static const rt_uint8_t tran_value[] =
{
    0,  10, 12, 13, 15, 20, 25, 30,
    35, 40, 45, 50, 55, 60, 70, 80,
};

static const rt_uint32_t tacc_uint[] =
{
    1, 10, 100, 1000, 10000, 100000, 1000000, 10000000,
};

static const rt_uint8_t tacc_value[] =
{
    0,  10, 12, 13, 15, 20, 25, 30,
    35, 40, 45, 50, 55, 60, 70, 80,
};

rt_inline rt_uint32_t GET_BITS(rt_uint32_t *resp,
                               rt_uint32_t  start,
                               rt_uint32_t  size)
48
{
W
weety 已提交
49
        const rt_int32_t __size = size;
50
        const rt_uint32_t __mask = (__size < 32 ? 1 << __size : 0) - 1;
W
weety 已提交
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
        const rt_int32_t __off = 3 - ((start) / 32);
        const rt_int32_t __shft = (start) & 31;
        rt_uint32_t __res;

        __res = resp[__off] >> __shft;
        if (__size + __shft > 32)
            __res |= resp[__off-1] << ((32 - __shft) % 32);

        return __res & __mask;
}

/*
 * Given a 128-bit response, decode to our card CSD structure.
 */
static rt_int32_t mmcsd_parse_csd(struct rt_mmcsd_card *card)
{
      rt_uint32_t a, b;
      struct rt_mmcsd_csd *csd = &card->csd;
      rt_uint32_t *resp = card->resp_csd;
70

W
weety 已提交
71 72 73 74 75 76 77
      /*
      * We only understand CSD structure v1.1 and v1.2.
      * v1.2 has extra information in bits 15, 11 and 10.
      * We also support eMMC v4.4 & v4.41.
      */
      csd->csd_structure = GET_BITS(resp, 126, 2);
      if (csd->csd_structure == 0) {
78
        LOG_E("unrecognised CSD structure version %d!", csd->csd_structure);
79

W
weety 已提交
80 81
        return -RT_ERROR;
      }
82

W
weety 已提交
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
      csd->taac = GET_BITS(resp, 112, 8);
      csd->nsac = GET_BITS(resp, 104, 8);
      csd->tran_speed = GET_BITS(resp, 96, 8);
      csd->card_cmd_class = GET_BITS(resp, 84, 12);
      csd->rd_blk_len = GET_BITS(resp, 80, 4);
      csd->rd_blk_part = GET_BITS(resp, 79, 1);
      csd->wr_blk_misalign = GET_BITS(resp, 78, 1);
      csd->rd_blk_misalign = GET_BITS(resp, 77, 1);
      csd->dsr_imp = GET_BITS(resp, 76, 1);
      csd->c_size = GET_BITS(resp, 62, 12);
      csd->c_size_mult = GET_BITS(resp, 47, 3);
      csd->r2w_factor = GET_BITS(resp, 26, 3);
      csd->wr_blk_len = GET_BITS(resp, 22, 4);
      csd->wr_blk_partial = GET_BITS(resp, 21, 1);
      csd->csd_crc = GET_BITS(resp, 1, 7);
98

W
weety 已提交
99 100 101 102 103 104 105 106 107 108
      card->card_blksize = 1 << csd->rd_blk_len;
      card->tacc_clks = csd->nsac * 100;
      card->tacc_ns = (tacc_uint[csd->taac&0x07] * tacc_value[(csd->taac&0x78)>>3] + 9) / 10;
      card->max_data_rate = tran_unit[csd->tran_speed&0x07] * tran_value[(csd->tran_speed&0x78)>>3];
      if (csd->wr_blk_len >= 9) {
        a = GET_BITS(resp, 42, 5);
        b = GET_BITS(resp, 37, 5);
        card->erase_size = (a + 1) * (b + 1);
        card->erase_size <<= csd->wr_blk_len - 9;
      }
109

W
weety 已提交
110 111 112 113 114 115 116 117 118 119 120 121
      return 0;
}

/*
 * Read extended CSD.
 */
static int mmc_get_ext_csd(struct rt_mmcsd_card *card, rt_uint8_t **new_ext_csd)
{
  void *ext_csd;
  struct rt_mmcsd_req req;
  struct rt_mmcsd_cmd cmd;
  struct rt_mmcsd_data data;
122

W
weety 已提交
123
  *new_ext_csd = RT_NULL;
124

W
weety 已提交
125 126
  if (GET_BITS(card->resp_cid, 122, 4) < 4)
     return 0;
127

W
weety 已提交
128 129 130 131 132 133
  /*
  * As the ext_csd is so large and mostly unused, we don't store the
  * raw block in mmc_card.
  */
  ext_csd = rt_malloc(512);
  if (!ext_csd) {
134
    LOG_E("alloc memory failed when get ext csd!");
W
weety 已提交
135 136
    return -RT_ENOMEM;
  }
137

W
weety 已提交
138 139 140
  rt_memset(&req, 0, sizeof(struct rt_mmcsd_req));
  rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd));
  rt_memset(&data, 0, sizeof(struct rt_mmcsd_data));
141

W
weety 已提交
142 143
  req.cmd = &cmd;
  req.data = &data;
144

W
weety 已提交
145 146
  cmd.cmd_code = SEND_EXT_CSD;
  cmd.arg = 0;
147

W
weety 已提交
148 149 150 151 152 153
  /* NOTE HACK:  the RESP_SPI_R1 is always correct here, but we
  * rely on callers to never use this with "native" calls for reading
  * CSD or CID.  Native versions of those commands use the R2 type,
  * not R1 plus a data block.
  */
  cmd.flags = RESP_SPI_R1 | RESP_R1 | CMD_ADTC;
154

W
weety 已提交
155 156 157 158
  data.blksize = 512;
  data.blks = 1;
  data.flags = DATA_DIR_READ;
  data.buf = ext_csd;
159

W
weety 已提交
160 161 162 163 164 165 166 167
  /*
  * Some cards require longer data read timeout than indicated in CSD.
  * Address this by setting the read timeout to a "reasonably high"
  * value. For the cards tested, 300ms has proven enough. If necessary,
  * this value can be increased if other problematic cards require this.
  */
  data.timeout_ns = 300000000;
  data.timeout_clks = 0;
168

W
weety 已提交
169
  mmcsd_send_request(card->host, &req);
170

W
weety 已提交
171 172 173 174
  if (cmd.err)
    return cmd.err;
  if (data.err)
    return data.err;
175

W
weety 已提交
176 177 178 179 180 181 182 183 184
  *new_ext_csd = ext_csd;
  return 0;
}

/*
 * Decode extended CSD.
 */
static int mmc_parse_ext_csd(struct rt_mmcsd_card *card, rt_uint8_t *ext_csd)
{
185 186
  rt_uint64_t card_capacity = 0;

187
  if(card == RT_NULL || ext_csd == RT_NULL)
188 189 190 191
  {
    LOG_E("emmc parse ext csd fail, invaild args");
    return -1;
  }
192

W
weety 已提交
193
  card->flags |=  CARD_FLAG_HIGHSPEED;
194
  card->hs_max_data_rate = 52000000;
195

196 197 198 199
  card_capacity = *((rt_uint32_t *)&ext_csd[EXT_CSD_SEC_CNT]);
  card_capacity *= card->card_blksize;
  card_capacity >>= 10; /* unit:KB */
  card->card_capacity = card_capacity;
200
  LOG_I("emmc card capacity %d KB.", card->card_capacity);
201

W
weety 已提交
202 203 204 205 206 207 208 209 210 211 212 213
  return 0;
}

/**
 *   mmc_switch - modify EXT_CSD register
 *   @card: the MMC card associated with the data transfer
 *   @set: cmd set values
 *   @index: EXT_CSD register index
 *   @value: value to program into EXT_CSD register
 *
 *   Modifies the EXT_CSD register for selected card.
 */
214
static int mmc_switch(struct rt_mmcsd_card *card, rt_uint8_t set,
W
weety 已提交
215 216 217 218 219
                      rt_uint8_t index, rt_uint8_t value)
{
  int err;
  struct rt_mmcsd_host *host = card->host;
  struct rt_mmcsd_cmd cmd = {0};
220

W
weety 已提交
221 222 223 224
  cmd.cmd_code = SWITCH;
  cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
    (index << 16) | (value << 8) | set;
  cmd.flags = RESP_SPI_R1 | RESP_R1 | CMD_AC;
225

W
weety 已提交
226 227 228
  err = mmcsd_send_cmd(host, &cmd, 3);
  if (err)
    return err;
229

W
weety 已提交
230 231 232
  return 0;
}

233
static int mmc_compare_ext_csds(struct rt_mmcsd_card *card,
W
weety 已提交
234 235 236 237
                                rt_uint8_t *ext_csd, rt_uint32_t bus_width)
{
  rt_uint8_t *bw_ext_csd;
  int err;
238

W
weety 已提交
239 240
  if (bus_width == MMCSD_BUS_WIDTH_1)
    return 0;
241

W
weety 已提交
242
  err = mmc_get_ext_csd(card, &bw_ext_csd);
243

W
weety 已提交
244 245 246 247
  if (err || bw_ext_csd == RT_NULL) {
    err = -RT_ERROR;
    goto out;
  }
248

W
weety 已提交
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275
  /* only compare read only fields */
  err = !((ext_csd[EXT_CSD_PARTITION_SUPPORT] == bw_ext_csd[EXT_CSD_PARTITION_SUPPORT]) &&
          (ext_csd[EXT_CSD_ERASED_MEM_CONT] == bw_ext_csd[EXT_CSD_ERASED_MEM_CONT]) &&
          (ext_csd[EXT_CSD_REV] == bw_ext_csd[EXT_CSD_REV]) &&
          (ext_csd[EXT_CSD_STRUCTURE] == bw_ext_csd[EXT_CSD_STRUCTURE]) &&
          (ext_csd[EXT_CSD_CARD_TYPE] == bw_ext_csd[EXT_CSD_CARD_TYPE]) &&
          (ext_csd[EXT_CSD_S_A_TIMEOUT] == bw_ext_csd[EXT_CSD_S_A_TIMEOUT]) &&
          (ext_csd[EXT_CSD_HC_WP_GRP_SIZE] == bw_ext_csd[EXT_CSD_HC_WP_GRP_SIZE]) &&
          (ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT] == bw_ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT]) &&
          (ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] == bw_ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]) &&
          (ext_csd[EXT_CSD_SEC_TRIM_MULT] == bw_ext_csd[EXT_CSD_SEC_TRIM_MULT]) &&
          (ext_csd[EXT_CSD_SEC_ERASE_MULT] == bw_ext_csd[EXT_CSD_SEC_ERASE_MULT]) &&
          (ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT] == bw_ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT]) &&
          (ext_csd[EXT_CSD_TRIM_MULT] == bw_ext_csd[EXT_CSD_TRIM_MULT]) &&
          (ext_csd[EXT_CSD_SEC_CNT + 0] == bw_ext_csd[EXT_CSD_SEC_CNT + 0]) &&
          (ext_csd[EXT_CSD_SEC_CNT + 1] == bw_ext_csd[EXT_CSD_SEC_CNT + 1]) &&
          (ext_csd[EXT_CSD_SEC_CNT + 2] == bw_ext_csd[EXT_CSD_SEC_CNT + 2]) &&
          (ext_csd[EXT_CSD_SEC_CNT + 3] == bw_ext_csd[EXT_CSD_SEC_CNT + 3]) &&
          (ext_csd[EXT_CSD_PWR_CL_52_195] == bw_ext_csd[EXT_CSD_PWR_CL_52_195]) &&
          (ext_csd[EXT_CSD_PWR_CL_26_195] == bw_ext_csd[EXT_CSD_PWR_CL_26_195]) &&
          (ext_csd[EXT_CSD_PWR_CL_52_360] == bw_ext_csd[EXT_CSD_PWR_CL_52_360]) &&
          (ext_csd[EXT_CSD_PWR_CL_26_360] == bw_ext_csd[EXT_CSD_PWR_CL_26_360]) &&
          (ext_csd[EXT_CSD_PWR_CL_200_195] == bw_ext_csd[EXT_CSD_PWR_CL_200_195]) &&
          (ext_csd[EXT_CSD_PWR_CL_200_360] == bw_ext_csd[EXT_CSD_PWR_CL_200_360]) &&
          (ext_csd[EXT_CSD_PWR_CL_DDR_52_195] == bw_ext_csd[EXT_CSD_PWR_CL_DDR_52_195]) &&
          (ext_csd[EXT_CSD_PWR_CL_DDR_52_360] == bw_ext_csd[EXT_CSD_PWR_CL_DDR_52_360]) &&
          (ext_csd[EXT_CSD_PWR_CL_DDR_200_360] == bw_ext_csd[EXT_CSD_PWR_CL_DDR_200_360]));
276

W
weety 已提交
277 278
  if (err)
     err = -RT_ERROR;
279

W
weety 已提交
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304
out:
  rt_free(bw_ext_csd);
  return err;
}

/*
 * Select the bus width amoung 4-bit and 8-bit(SDR).
 * If the bus width is changed successfully, return the selected width value.
 * Zero is returned instead of error value if the wide width is not supported.
 */
static int mmc_select_bus_width(struct rt_mmcsd_card *card, rt_uint8_t *ext_csd)
{
  rt_uint32_t ext_csd_bits[] = {
    EXT_CSD_BUS_WIDTH_8,
    EXT_CSD_BUS_WIDTH_4,
    EXT_CSD_BUS_WIDTH_1
  };
  rt_uint32_t bus_widths[] = {
    MMCSD_BUS_WIDTH_8,
    MMCSD_BUS_WIDTH_4,
    MMCSD_BUS_WIDTH_1
  };
  struct rt_mmcsd_host *host = card->host;
  unsigned idx, bus_width = 0;
  int err = 0;
305

W
weety 已提交
306 307
  if (GET_BITS(card->resp_cid, 122, 4) < 4)
     return 0;
308

W
weety 已提交
309 310 311 312 313 314 315 316 317 318 319 320
  /*
  * Unlike SD, MMC cards dont have a configuration register to notify
  * supported bus width. So bus test command should be run to identify
  * the supported bus width or compare the ext csd values of current
  * bus width and ext csd values of 1 bit mode read earlier.
  */
  for (idx = 0; idx < sizeof(bus_widths)/sizeof(rt_uint32_t); idx++) {
    /*
    * Host is capable of 8bit transfer, then switch
    * the device to work in 8bit transfer mode. If the
    * mmc switch command returns error then switch to
    * 4bit transfer mode. On success set the corresponding
321 322 323
    * bus width on the host. Meanwhile, mmc core would
    * bail out early if corresponding bus capable wasn't
    * set by drivers.
W
weety 已提交
324
    */
325
     if ((!(host->flags & MMCSD_BUSWIDTH_8) &&
326
      ext_csd_bits[idx] == EXT_CSD_BUS_WIDTH_8) ||
327
         (!(host->flags & MMCSD_BUSWIDTH_4) &&
328 329 330
      (ext_csd_bits[idx] == EXT_CSD_BUS_WIDTH_4 ||
      ext_csd_bits[idx] == EXT_CSD_BUS_WIDTH_8)))
         continue;
331

W
weety 已提交
332 333 334 335 336
    err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
                     EXT_CSD_BUS_WIDTH,
                     ext_csd_bits[idx]);
    if (err)
      continue;
337

W
weety 已提交
338 339 340 341 342 343 344 345 346 347
    bus_width = bus_widths[idx];
    mmcsd_set_bus_width(host, bus_width);
    mmcsd_delay_ms(20); //delay 10ms
    err = mmc_compare_ext_csds(card, ext_csd, bus_width);
    if (!err) {
      err = bus_width;
      break;
    } else {
      switch(ext_csd_bits[idx]){
          case 0:
348
            LOG_E("switch to bus width 1 bit failed!");
W
weety 已提交
349 350
            break;
          case 1:
351
            LOG_E("switch to bus width 4 bit failed!");
W
weety 已提交
352 353
            break;
          case 2:
354
            LOG_E("switch to bus width 8 bit failed!");
W
weety 已提交
355 356 357 358 359 360
            break;
          default:
            break;
      }
    }
  }
361

W
weety 已提交
362 363
  return err;
}
364
rt_err_t mmc_send_op_cond(struct rt_mmcsd_host *host,
W
weety 已提交
365 366 367 368 369 370 371
                          rt_uint32_t ocr, rt_uint32_t *rocr)
{
    struct rt_mmcsd_cmd cmd;
    rt_uint32_t i;
    rt_err_t err = RT_EOK;

    rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd));
372

W
weety 已提交
373 374 375
    cmd.cmd_code = SEND_OP_COND;
    cmd.arg = controller_is_spi(host) ? 0 : ocr;
    cmd.flags = RESP_SPI_R1 | RESP_R3 | CMD_BCR;
376

W
weety 已提交
377 378 379 380
    for (i = 100; i; i--) {
      err = mmcsd_send_cmd(host, &cmd, 3);
      if (err)
        break;
381

W
weety 已提交
382 383 384
      /* if we're just probing, do a single pass */
      if (ocr == 0)
        break;
385

W
weety 已提交
386 387 388 389 390 391 392 393
      /* otherwise wait until reset completes */
      if (controller_is_spi(host)) {
        if (!(cmd.resp[0] & R1_SPI_IDLE))
          break;
      } else {
        if (cmd.resp[0] & CARD_BUSY)
          break;
      }
394

W
weety 已提交
395
      err = -RT_ETIMEOUT;
396

W
weety 已提交
397 398
      mmcsd_delay_ms(10); //delay 10ms
    }
399

W
weety 已提交
400 401
  if (rocr && !controller_is_spi(host))
    *rocr = cmd.resp[0];
402

W
weety 已提交
403 404 405 406 407 408 409
  return err;
}

static rt_err_t mmc_set_card_addr(struct rt_mmcsd_host *host, rt_uint32_t rca)
{
  rt_err_t err;
  struct rt_mmcsd_cmd cmd;
410

W
weety 已提交
411
  rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd));
412

W
weety 已提交
413 414 415
  cmd.cmd_code = SET_RELATIVE_ADDR;
  cmd.arg = rca << 16;
  cmd.flags = RESP_R1 | CMD_AC;
416

W
weety 已提交
417 418 419
  err = mmcsd_send_cmd(host, &cmd, 3);
  if (err)
    return err;
420

W
weety 已提交
421 422 423 424 425 426 427 428
  return 0;
}

static rt_int32_t mmcsd_mmc_init_card(struct rt_mmcsd_host *host,
                                     rt_uint32_t           ocr)
{
    rt_int32_t err;
    rt_uint32_t resp[4];
429
    rt_uint32_t rocr = 0;
W
weety 已提交
430 431
    rt_uint32_t max_data_rate;
    rt_uint8_t *ext_csd = RT_NULL;
432
    struct rt_mmcsd_card *card = RT_NULL;
W
weety 已提交
433 434

    mmcsd_go_idle(host);
435

W
weety 已提交
436 437 438 439
    /* The extra bit indicates that we support high capacity */
    err = mmc_send_op_cond(host, ocr | (1 << 30), &rocr);
    if (err)
      goto err;
440 441

    if (controller_is_spi(host))
W
weety 已提交
442 443 444 445 446
    {
        err = mmcsd_spi_use_crc(host, 1);
        if (err)
            goto err1;
    }
447

W
weety 已提交
448 449 450 451 452 453 454 455
    if (controller_is_spi(host))
        err = mmcsd_get_cid(host, resp);
    else
        err = mmcsd_all_get_cid(host, resp);
    if (err)
        goto err;

    card = rt_malloc(sizeof(struct rt_mmcsd_card));
456
    if (!card)
W
weety 已提交
457
    {
458
        LOG_E("malloc card failed!");
W
weety 已提交
459 460 461 462 463 464 465 466 467 468 469 470 471
        err = -RT_ENOMEM;
        goto err;
    }
    rt_memset(card, 0, sizeof(struct rt_mmcsd_card));

    card->card_type = CARD_TYPE_MMC;
    card->host = host;
    card->rca = 1;
    rt_memcpy(card->resp_cid, resp, sizeof(card->resp_cid));

    /*
     * For native busses:  get card RCA and quit open drain mode.
     */
472
    if (!controller_is_spi(host))
W
weety 已提交
473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488
    {
        err = mmc_set_card_addr(host, card->rca);
        if (err)
            goto err1;

        mmcsd_set_bus_mode(host, MMCSD_BUSMODE_PUSHPULL);
    }

    err = mmcsd_get_csd(card, card->resp_csd);
    if (err)
        goto err1;

    err = mmcsd_parse_csd(card);
    if (err)
        goto err1;

489
    if (!controller_is_spi(host))
W
weety 已提交
490 491 492 493 494
    {
        err = mmcsd_select_card(card);
        if (err)
            goto err1;
    }
495

W
weety 已提交
496 497 498
    /*
    * Fetch and process extended CSD.
    */
499

W
weety 已提交
500 501 502 503 504 505
    err = mmc_get_ext_csd(card, &ext_csd);
    if (err)
      goto err1;
    err = mmc_parse_ext_csd(card, ext_csd);
    if (err)
      goto err1;
506

W
weety 已提交
507 508 509 510 511 512 513
    /* If doing byte addressing, check if required to do sector
    * addressing.  Handle the case of <2GB cards needing sector
    * addressing.  See section 8.1 JEDEC Standard JED84-A441;
    * ocr register has bit 30 set for sector addressing.
    */
    if (!(card->flags & CARD_FLAG_SDHC) && (rocr & (1<<30)))
        card->flags |= CARD_FLAG_SDHC;
514

W
weety 已提交
515
    /* set bus speed */
516
    if (card->flags & CARD_FLAG_HIGHSPEED)
517 518
        max_data_rate = card->hs_max_data_rate;
    else
W
weety 已提交
519 520 521 522 523 524
        max_data_rate = card->max_data_rate;

    mmcsd_set_clock(host, max_data_rate);

    /*switch bus width*/
    mmc_select_bus_width(card, ext_csd);
525

W
weety 已提交
526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588
    host->card = card;

    rt_free(ext_csd);
    return 0;

err1:
    rt_free(card);
err:

    return err;
}

/*
 * Starting point for mmc card init.
 */
rt_int32_t init_mmc(struct rt_mmcsd_host *host, rt_uint32_t ocr)
{
    rt_int32_t err;
    rt_uint32_t  current_ocr;
    /*
     * We need to get OCR a different way for SPI.
     */
    if (controller_is_spi(host))
    {
        err = mmcsd_spi_read_ocr(host, 0, &ocr);
        if (err)
            goto err;
    }

    current_ocr = mmcsd_select_voltage(host, ocr);

    /*
     * Can we support the voltage(s) of the card(s)?
     */
    if (!current_ocr)
    {
        err = -RT_ERROR;
        goto err;
    }

    /*
     * Detect and init the card.
     */
    err = mmcsd_mmc_init_card(host, current_ocr);
    if (err)
        goto err;

    mmcsd_host_unlock(host);

    err = rt_mmcsd_blk_probe(host->card);
    if (err)
        goto remove_card;
    mmcsd_host_lock(host);

    return 0;

remove_card:
    mmcsd_host_lock(host);
    rt_mmcsd_blk_remove(host->card);
    rt_free(host->card);
    host->card = RT_NULL;
err:

589
    LOG_E("init MMC card failed!");
W
weety 已提交
590 591 592

    return err;
}