mmc_spi.c
字号:
/* * mmc_spi.c - Access SD/MMC cards through SPI master controllers * * (C) Copyright 2005, Intec Automation, * Mike Lavender (mike@steroidmicros) * (C) Copyright 2006-2007, David Brownell * (C) Copyright 2007, Axis Communications, * Hans-Peter Nilsson (hp@axis.com) * (C) Copyright 2007, ATRON electronic GmbH, * Jan Nikitenko <jan.nikitenko@gmail.com> * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include <linux/hrtimer.h>#include <linux/delay.h>#include <linux/bio.h>#include <linux/dma-mapping.h>#include <linux/crc7.h>#include <linux/crc-itu-t.h>#include <linux/scatterlist.h>#include <linux/mmc/host.h>#include <linux/mmc/mmc.h> /* for R1_SPI_* bit values */#include <linux/spi/spi.h>#include <linux/spi/mmc_spi.h>#include <asm/unaligned.h>/* NOTES: * * - For now, we won't try to interoperate with a real mmc/sd/sdio * controller, although some of them do have hardware support for * SPI protocol. The main reason for such configs would be mmc-ish * cards like DataFlash, which don't support that "native" protocol. * * We don't have a "DataFlash/MMC/SD/SDIO card slot" abstraction to * switch between driver stacks, and in any case if "native" mode * is available, it will be faster and hence preferable. * * - MMC depends on a different chipselect management policy than the * SPI interface currently supports for shared bus segments: it needs * to issue multiple spi_message requests with the chipselect active, * using the results of one message to decide the next one to issue. * * Pending updates to the programming interface, this driver expects * that it not share the bus with other drivers (precluding conflicts). * * - We tell the controller to keep the chipselect active from the * beginning of an mmc_host_ops.request until the end. So beware * of SPI controller drivers that mis-handle the cs_change flag! * * However, many cards seem OK with chipselect flapping up/down * during that time ... at least on unshared bus segments. *//* * Local protocol constants, internal to data block protocols. *//* Response tokens used to ack each block written: */#define SPI_MMC_RESPONSE_CODE(x) ((x) & 0x1f)#define SPI_RESPONSE_ACCEPTED ((2 << 1)|1)#define SPI_RESPONSE_CRC_ERR ((5 << 1)|1)#define SPI_RESPONSE_WRITE_ERR ((6 << 1)|1)/* 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 */#define MMC_SPI_BLOCKSIZE 512/* These fixed timeouts come from the latest SD specs, which say to ignore * the CSD values. The R1B value is for card erase (e.g. the "I forgot the * card's password" scenario); it's mostly applied to STOP_TRANSMISSION after * reads which takes nowhere near that long. Older cards may be able to use * shorter timeouts ... but why bother? */#define readblock_timeout ktime_set(0, 100 * 1000 * 1000)#define writeblock_timeout ktime_set(0, 250 * 1000 * 1000)#define r1b_timeout ktime_set(3, 0)/****************************************************************************//* * Local Data Structures *//* "scratch" is per-{command,block} data exchanged with the card */struct scratch { u8 status[29]; u8 data_token; __be16 crc_val;};struct mmc_spi_host { struct mmc_host *mmc; struct spi_device *spi; unsigned char power_mode; u16 powerup_msecs; struct mmc_spi_platform_data *pdata; /* for bulk data transfers */ struct spi_transfer token, t, crc, early_status; struct spi_message m; /* for status readback */ struct spi_transfer status; struct spi_message readback; /* underlying DMA-aware controller, or null */ struct device *dma_dev; /* buffer used for commands and for message "overhead" */ struct scratch *data; dma_addr_t data_dma; /* Specs say to write ones most of the time, even when the card * has no need to read its input data; and many cards won't care. * This is our source of those ones. */ void *ones; dma_addr_t ones_dma;};/****************************************************************************//* * MMC-over-SPI protocol glue, used by the MMC stack interface */static inline int mmc_cs_off(struct mmc_spi_host *host){ /* chipselect will always be inactive after setup() */ return spi_setup(host->spi);}static intmmc_spi_readbytes(struct mmc_spi_host *host, unsigned len){ int status; if (len > sizeof(*host->data)) { WARN_ON(1); return -EIO; } host->status.len = len; if (host->dma_dev) dma_sync_single_for_device(host->dma_dev, host->data_dma, sizeof(*host->data), DMA_FROM_DEVICE); status = spi_sync(host->spi, &host->readback); if (host->dma_dev) dma_sync_single_for_cpu(host->dma_dev, host->data_dma, sizeof(*host->data), DMA_FROM_DEVICE); return status;}static intmmc_spi_skip(struct mmc_spi_host *host, ktime_t timeout, unsigned n, u8 byte){ u8 *cp = host->data->status; timeout = ktime_add(timeout, ktime_get()); while (1) { int status; unsigned i; status = mmc_spi_readbytes(host, n); if (status < 0) return status; for (i = 0; i < n; i++) { if (cp[i] != byte) return cp[i]; } /* REVISIT investigate msleep() to avoid busy-wait I/O * in at least some cases. */ if (ktime_to_ns(ktime_sub(ktime_get(), timeout)) > 0) break; } return -ETIMEDOUT;}static inline intmmc_spi_wait_unbusy(struct mmc_spi_host *host, ktime_t timeout){ return mmc_spi_skip(host, timeout, sizeof(host->data->status), 0);}static int mmc_spi_readtoken(struct mmc_spi_host *host){ return mmc_spi_skip(host, readblock_timeout, 1, 0xff);}/* * Note that for SPI, cmd->resp[0] is not the same data as "native" protocol * hosts return! The low byte holds R1_SPI bits. The next byte may hold * R2_SPI bits ... for SEND_STATUS, or after data read errors. * * cmd->resp[1] holds any four-byte response, for R3 (READ_OCR) and on * newer cards R7 (IF_COND). */static char *maptype(struct mmc_command *cmd){ switch (mmc_spi_resp_type(cmd)) { case MMC_RSP_SPI_R1: return "R1"; case MMC_RSP_SPI_R1B: return "R1B"; case MMC_RSP_SPI_R2: return "R2/R5"; case MMC_RSP_SPI_R3: return "R3/R4/R7"; default: return "?"; }}/* return zero, else negative errno after setting cmd->error */static int mmc_spi_response_get(struct mmc_spi_host *host, struct mmc_command *cmd, int cs_on){ u8 *cp = host->data->status; u8 *end = cp + host->t.len; int value = 0; char tag[32]; snprintf(tag, sizeof(tag), " ... CMD%d response SPI_%s", cmd->opcode, maptype(cmd)); /* Except for data block reads, the whole response will already * be stored in the scratch buffer. It's somewhere after the * command and the first byte we read after it. We ignore that * first byte. After STOP_TRANSMISSION command it may include * two data bits, but otherwise it's all ones. */ cp += 8; while (cp < end && *cp == 0xff) cp++; /* Data block reads (R1 response types) may need more data... */ if (cp == end) { unsigned i; cp = host->data->status; /* Card sends N(CR) (== 1..8) bytes of all-ones then one * status byte ... and we already scanned 2 bytes. * * REVISIT block read paths use nasty byte-at-a-time I/O * so it can always DMA directly into the target buffer. * It'd probably be better to memcpy() the first chunk and * avoid extra i/o calls... */ for (i = 2; i < 9; i++) { value = mmc_spi_readbytes(host, 1); if (value < 0) goto done; if (*cp != 0xff) goto checkstatus; } value = -ETIMEDOUT; goto done; }checkstatus: if (*cp & 0x80) { dev_dbg(&host->spi->dev, "%s: INVALID RESPONSE, %02x\n", tag, *cp); value = -EBADR; goto done; } cmd->resp[0] = *cp++; cmd->error = 0; /* Status byte: the entire seven-bit R1 response. */ if (cmd->resp[0] != 0) { if ((R1_SPI_PARAMETER | R1_SPI_ADDRESS | R1_SPI_ILLEGAL_COMMAND) & cmd->resp[0]) value = -EINVAL; else if (R1_SPI_COM_CRC & cmd->resp[0]) value = -EILSEQ; else if ((R1_SPI_ERASE_SEQ | R1_SPI_ERASE_RESET) & cmd->resp[0]) value = -EIO; /* else R1_SPI_IDLE, "it's resetting" */ } switch (mmc_spi_resp_type(cmd)) { /* SPI R1B == R1 + busy; STOP_TRANSMISSION (for multiblock reads) * and less-common stuff like various erase operations. */ case MMC_RSP_SPI_R1B: /* maybe we read all the busy tokens already */ while (cp < end && *cp == 0) cp++; if (cp == end) mmc_spi_wait_unbusy(host, r1b_timeout); break; /* SPI R2 == R1 + second status byte; SEND_STATUS * SPI R5 == R1 + data byte; IO_RW_DIRECT */ case MMC_RSP_SPI_R2: cmd->resp[0] |= *cp << 8; break; /* SPI R3, R4, or R7 == R1 + 4 bytes */ case MMC_RSP_SPI_R3: cmd->resp[1] = be32_to_cpu(get_unaligned((u32 *)cp)); break; /* SPI R1 == just one status byte */ case MMC_RSP_SPI_R1: break; default: dev_dbg(&host->spi->dev, "bad response type %04x\n", mmc_spi_resp_type(cmd)); if (value >= 0) value = -EINVAL; goto done; } if (value < 0) dev_dbg(&host->spi->dev, "%s: resp %04x %08x\n", tag, cmd->resp[0], cmd->resp[1]); /* disable chipselect on errors and some success cases */ if (value >= 0 && cs_on) return value;done: if (value < 0) cmd->error = value; mmc_cs_off(host); return value;}/* Issue command and read its response. * Returns zero on success, negative for error. * * On error, caller must cope with mmc core retry mechanism. That * means immediate low-level resubmit, which affects the bus lock... */static intmmc_spi_command_send(struct mmc_spi_host *host, struct mmc_request *mrq, struct mmc_command *cmd, int cs_on){ struct scratch *data = host->data; u8 *cp = data->status; u32 arg = cmd->arg; int status; struct spi_transfer *t; /* We can handle most commands (except block reads) in one full * duplex I/O operation before either starting the next transfer * (data block or command) or else deselecting the card. * * First, write 7 bytes: * - an all-ones byte to ensure the card is ready * - opcode byte (plus start and transmission bits) * - four bytes of big-endian argument * - crc7 (plus end bit) ... always computed, it's cheap * * We init the whole buffer to all-ones, which is what we need * to write while we're reading (later) response data. */ memset(cp++, 0xff, sizeof(data->status)); *cp++ = 0x40 | cmd->opcode; *cp++ = (u8)(arg >> 24); *cp++ = (u8)(arg >> 16); *cp++ = (u8)(arg >> 8); *cp++ = (u8)arg; *cp++ = (crc7(0, &data->status[1], 5) << 1) | 0x01; /* Then, read up to 13 bytes (while writing all-ones): * - N(CR) (== 1..8) bytes of all-ones * - status byte (for all response types) * - the rest of the response, either: * + nothing, for R1 or R1B responses * + second status byte, for R2 responses * + four data bytes, for R3 and R7 responses * * Finally, read some more bytes ... in the nice cases we know in * advance how many, and reading 1 more is always OK: * - N(EC) (== 0..N) bytes of all-ones, before deselect/finish * - N(RC) (== 1..N) bytes of all-ones, before next command * - N(WR) (== 1..N) bytes of all-ones, before data write * * So in those cases one full duplex I/O of at most 21 bytes will * handle the whole command, leaving the card ready to receive a * data block or new command. We do that whenever we can, shaving * CPU and IRQ costs (especially when using DMA or FIFOs). * * There are two other cases, where it's not generally practical * to rely on a single I/O: * * - R1B responses need at least N(EC) bytes of all-zeroes. * * In this case we can *try* to fit it into one I/O, then * maybe read more data later. * * - Data block reads are more troublesome, since a variable * number of padding bytes precede the token and data. * + N(CX) (== 0..8) bytes of all-ones, before CSD or CID * + N(AC) (== 1..many) bytes of all-ones * * In this case we currently only have minimal speedups here: * when N(CR) == 1 we can avoid I/O in response_get(). */ if (cs_on && (mrq->data->flags & MMC_DATA_READ)) { cp += 2; /* min(N(CR)) + status */ /* R1 */ } else { cp += 10; /* max(N(CR)) + status + min(N(RC),N(WR)) */ if (cmd->flags & MMC_RSP_SPI_S2) /* R2/R5 */ cp++; else if (cmd->flags & MMC_RSP_SPI_B4) /* R3/R4/R7 */ cp += 4; else if (cmd->flags & MMC_RSP_BUSY) /* R1B */ cp = data->status + sizeof(data->status); /* else: R1 (most commands) */ } dev_dbg(&host->spi->dev, " mmc_spi: CMD%d, resp %s\n", cmd->opcode, maptype(cmd)); /* send command, leaving chipselect active */ spi_message_init(&host->m); t = &host->t; memset(t, 0, sizeof(*t)); t->tx_buf = t->rx_buf = data->status; t->tx_dma = t->rx_dma = host->data_dma; t->len = cp - data->status; t->cs_change = 1; spi_message_add_tail(t, &host->m);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -