fba68bd2da
Thanks to the generous donation of an SDHC card by John Gilmore, and the surprisingly enlightened decision by the SD Card Association to publish useful specs, I've been able to bash out support for SDHC. The changes are not too profound: i) Add a card flag indicating the card uses block level addressing and check it in the block driver. As we never took advantage of byte-level addressing, this simply involves skipping the block -> byte translation when sending commands. ii) The layout of the CSD is changed - a set of fields are discarded to make space for a larger C_SIZE. We did not reference any of the discarded fields except those related to the C_SIZE. iii) Read and write timeouts are fixed values and not calculated from CSD values. iv) Before invoking SEND_APP_OP_COND, we must invoke the new SEND_IF_COND to inform the card we support SDHC. Signed-off-by: Philipl Langdale <philipl@overt.org> Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
120 lines
3.5 KiB
C
120 lines
3.5 KiB
C
/*
|
|
* linux/include/linux/mmc/mmc.h
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*/
|
|
#ifndef MMC_H
|
|
#define MMC_H
|
|
|
|
#include <linux/list.h>
|
|
#include <linux/interrupt.h>
|
|
#include <linux/device.h>
|
|
|
|
struct request;
|
|
struct mmc_data;
|
|
struct mmc_request;
|
|
|
|
struct mmc_command {
|
|
u32 opcode;
|
|
u32 arg;
|
|
u32 resp[4];
|
|
unsigned int flags; /* expected response type */
|
|
#define MMC_RSP_PRESENT (1 << 0)
|
|
#define MMC_RSP_136 (1 << 1) /* 136 bit response */
|
|
#define MMC_RSP_CRC (1 << 2) /* expect valid crc */
|
|
#define MMC_RSP_BUSY (1 << 3) /* card may send busy */
|
|
#define MMC_RSP_OPCODE (1 << 4) /* response contains opcode */
|
|
#define MMC_CMD_MASK (3 << 5) /* command type */
|
|
#define MMC_CMD_AC (0 << 5)
|
|
#define MMC_CMD_ADTC (1 << 5)
|
|
#define MMC_CMD_BC (2 << 5)
|
|
#define MMC_CMD_BCR (3 << 5)
|
|
|
|
/*
|
|
* These are the response types, and correspond to valid bit
|
|
* patterns of the above flags. One additional valid pattern
|
|
* is all zeros, which means we don't expect a response.
|
|
*/
|
|
#define MMC_RSP_NONE (0)
|
|
#define MMC_RSP_R1 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
|
|
#define MMC_RSP_R1B (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE|MMC_RSP_BUSY)
|
|
#define MMC_RSP_R2 (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC)
|
|
#define MMC_RSP_R3 (MMC_RSP_PRESENT)
|
|
#define MMC_RSP_R6 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
|
|
#define MMC_RSP_R7 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
|
|
|
|
#define mmc_resp_type(cmd) ((cmd)->flags & (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC|MMC_RSP_BUSY|MMC_RSP_OPCODE))
|
|
|
|
/*
|
|
* These are the command types.
|
|
*/
|
|
#define mmc_cmd_type(cmd) ((cmd)->flags & MMC_CMD_MASK)
|
|
|
|
unsigned int retries; /* max number of retries */
|
|
unsigned int error; /* command error */
|
|
|
|
#define MMC_ERR_NONE 0
|
|
#define MMC_ERR_TIMEOUT 1
|
|
#define MMC_ERR_BADCRC 2
|
|
#define MMC_ERR_FIFO 3
|
|
#define MMC_ERR_FAILED 4
|
|
#define MMC_ERR_INVALID 5
|
|
|
|
struct mmc_data *data; /* data segment associated with cmd */
|
|
struct mmc_request *mrq; /* associated request */
|
|
};
|
|
|
|
struct mmc_data {
|
|
unsigned int timeout_ns; /* data timeout (in ns, max 80ms) */
|
|
unsigned int timeout_clks; /* data timeout (in clocks) */
|
|
unsigned int blksz; /* data block size */
|
|
unsigned int blocks; /* number of blocks */
|
|
unsigned int error; /* data error */
|
|
unsigned int flags;
|
|
|
|
#define MMC_DATA_WRITE (1 << 8)
|
|
#define MMC_DATA_READ (1 << 9)
|
|
#define MMC_DATA_STREAM (1 << 10)
|
|
#define MMC_DATA_MULTI (1 << 11)
|
|
|
|
unsigned int bytes_xfered;
|
|
|
|
struct mmc_command *stop; /* stop command */
|
|
struct mmc_request *mrq; /* associated request */
|
|
|
|
unsigned int sg_len; /* size of scatter list */
|
|
struct scatterlist *sg; /* I/O scatter list */
|
|
};
|
|
|
|
struct mmc_request {
|
|
struct mmc_command *cmd;
|
|
struct mmc_data *data;
|
|
struct mmc_command *stop;
|
|
|
|
void *done_data; /* completion data */
|
|
void (*done)(struct mmc_request *);/* completion function */
|
|
};
|
|
|
|
struct mmc_host;
|
|
struct mmc_card;
|
|
|
|
extern int mmc_wait_for_req(struct mmc_host *, struct mmc_request *);
|
|
extern int mmc_wait_for_cmd(struct mmc_host *, struct mmc_command *, int);
|
|
extern int mmc_wait_for_app_cmd(struct mmc_host *, unsigned int,
|
|
struct mmc_command *, int);
|
|
|
|
extern void mmc_set_data_timeout(struct mmc_data *, const struct mmc_card *, int);
|
|
|
|
extern int __mmc_claim_host(struct mmc_host *host, struct mmc_card *card);
|
|
|
|
static inline void mmc_claim_host(struct mmc_host *host)
|
|
{
|
|
__mmc_claim_host(host, (struct mmc_card *)-1);
|
|
}
|
|
|
|
extern void mmc_release_host(struct mmc_host *host);
|
|
|
|
#endif
|