static void mmcsd_power_up(struct rt_mmcsd_host *host) { int bit = fls(host->valid_ocr) - 1; host->io_cfg.vdd = bit; if (controller_is_spi(host)) { host->io_cfg.chip_select = MMCSD_CS_HIGH; host->io_cfg.bus_mode = MMCSD_BUSMODE_PUSHPULL; } else { host->io_cfg.chip_select = MMCSD_CS_IGNORE; host->io_cfg.bus_mode = MMCSD_BUSMODE_OPENDRAIN; } host->io_cfg.power_mode = MMCSD_POWER_UP; host->io_cfg.bus_width = MMCSD_BUS_WIDTH_1; mmcsd_set_iocfg(host); /* * This delay should be sufficient to allow the power supply * to reach the minimum voltage. */ mmcsd_delay_ms(10); host->io_cfg.clock = host->freq_min; host->io_cfg.power_mode = MMCSD_POWER_ON; mmcsd_set_iocfg(host); /* * This delay must be at least 74 clock sizes, or 1 ms, or the * time required to reach a stable voltage. */ mmcsd_delay_ms(10); }
rt_int32_t mmcsd_go_idle(struct rt_mmcsd_host *host) { rt_int32_t err; struct rt_mmcsd_cmd cmd; if (!controller_is_spi(host)) { mmcsd_set_chip_select(host, MMCSD_CS_HIGH); mmcsd_delay_ms(1); } rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd)); cmd.cmd_code = GO_IDLE_STATE; cmd.arg = 0; cmd.flags = RESP_SPI_R1 | RESP_NONE | CMD_BC; err = mmcsd_send_cmd(host, &cmd, 0); mmcsd_delay_ms(1); if (!controller_is_spi(host)) { mmcsd_set_chip_select(host, MMCSD_CS_IGNORE); mmcsd_delay_ms(1); } return err; }
rt_int32_t sdio_io_send_op_cond(struct rt_mmcsd_host *host, rt_uint32_t ocr, rt_uint32_t *cmd5_resp) { struct rt_mmcsd_cmd cmd; rt_int32_t i, err = 0; RT_ASSERT(host != RT_NULL); rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd)); cmd.cmd_code = SD_IO_SEND_OP_COND; cmd.arg = ocr; cmd.flags = RESP_SPI_R4 | RESP_R4 | CMD_BCR; for (i = 100; i; i--) { err = mmcsd_send_cmd(host, &cmd, 0); if (err) break; /* if we're just probing, do a single pass */ if (ocr == 0) break; /* otherwise wait until reset completes */ if (controller_is_spi(host)) { /* * Both R1_SPI_IDLE and MMC_CARD_BUSY indicate * an initialized card under SPI, but some cards * (Marvell's) only behave when looking at this * one. */ if (cmd.resp[1] & CARD_BUSY) break; } else { if (cmd.resp[0] & CARD_BUSY) break; } err = -RT_ETIMEOUT; mmcsd_delay_ms(10); } if (cmd5_resp) *cmd5_resp = cmd.resp[controller_is_spi(host) ? 1 : 0]; return err; }
rt_err_t mmcsd_send_app_op_cond(struct rt_mmcsd_host *host, 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)); cmd.cmd_code = SD_APP_OP_COND; if (controller_is_spi(host)) cmd.arg = ocr & (1 << 30); /* SPI only defines one bit */ else cmd.arg = ocr; cmd.flags = RESP_SPI_R1 | RESP_R3 | CMD_BCR; for (i = 100; i; i--) { err = mmcsd_send_app_cmd(host, RT_NULL, &cmd, 3); if (err) break; /* if we're just probing, do a single pass */ if (ocr == 0) break; /* 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; } err = -RT_ETIMEOUT; mmcsd_delay_ms(10); //delay 10ms } if (rocr && !controller_is_spi(host)) *rocr = cmd.resp[0]; return err; }