/*
* 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/sched.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/module.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/mmc/slot-gpio.h>
#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 r1b_timeout (HZ * 3)
/* One of the critical speed parameters is the amount of data which may
* be transferred in one command. If this value is too low, the SD card
* controller has to do multiple partial block writes (argggh!). With
* today (2008) SD cards there is little speed gain if we transfer more
* than 64 KBytes at a time. So use this value until there is any indication
* that we should do more here.
*/
#define MMC_SPI_BLOCKSATONCE 128
/****************************************************************************/
/*
* 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 int
mmc_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_locked(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 int mmc_spi_skip(struct mmc_spi_host *host, unsigned long timeout,
unsigned n, u8 byte)
{
u8 *cp = host->data->status;
unsigned long start = jiffies;
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];
}
if (time_is_before_jiffies(start + timeout))
break;
/* If we need long timeouts, we may release the CPU.
* We use jiffies here because we want to have a relation
* between elapsed time and the blocking of th
|