static int mmc_spi_request(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data) { struct mmc_spi_host *host = to_spi_host(mci); uint8_t r1; int i; int ret = 0; dev_dbg(host->dev, "%s : CMD%02d, RESP %s, ARG 0x%X\n", __func__, cmd->cmdidx, maptype(cmd), cmd->cmdarg); r1 = mmc_spi_command_send(host, cmd); cmd->response[0] = r1; if (r1 == 0xff) { /* no response */ ret = -ETIME; goto done; } else if (r1 & R1_SPI_COM_CRC) { ret = -ECOMM; goto done; } else if (r1 & ~R1_SPI_IDLE) { /* other errors */ ret = -ETIME; goto done; } else if (cmd->resp_type == MMC_RSP_R2) { r1 = mmc_spi_readdata(host, cmd->response, 1, 16); for (i = 0; i < 4; i++) cmd->response[i] = be32_to_cpu(cmd->response[i]); dev_dbg(host->dev, "MMC_RSP_R2 -> %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_SEND_IF_COND: case MMC_CMD_SPI_READ_OCR: mmc_spi_readbytes(host, 4, cmd->response); cmd->response[0] = be32_to_cpu(cmd->response[0]); break; } } else { if (data->flags == MMC_DATA_READ) { dev_dbg(host->dev, "%s : DATA READ, %x blocks, bsize = 0x%X\n", __func__, data->blocks, data->blocksize); r1 = mmc_spi_readdata(host, data->dest, data->blocks, data->blocksize); } else if (data->flags == MMC_DATA_WRITE) { dev_dbg(host->dev, "%s : DATA WRITE, %x blocks, bsize = 0x%X\n", __func__, data->blocks, data->blocksize); r1 = mmc_spi_writedata(host, data->src, data->blocks, data->blocksize, (cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK)); } if (r1 & R1_SPI_COM_CRC) ret = -ECOMM; else if (r1) ret = -ETIME; } done: mmc_cs_off(host); return ret; return 0; }
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 = NO_CARD_ERR; goto done; } else if (r1 & R1_SPI_COM_CRC) { ret = COMM_ERR; goto done; } else if (r1 & ~R1_SPI_IDLE) { /* other errors */ ret = TIMEOUT; goto done; } else if (cmd->resp_type == MMC_RSP_R2) { r1 = mmc_spi_readdata(mmc, cmd->response, 1, 16); 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); if (data->flags == MMC_DATA_READ) r1 = mmc_spi_readdata(mmc, 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 = COMM_ERR; else if (r1) /* other errors */ ret = TIMEOUT; } done: spi_cs_deactivate(spi); spi_release_bus(spi); return ret; }