www.pudn.com > s3c2440_kernel2.4.18_module_mmc.rar > mmc.h


/*
 * drivers/mmc/mmc.h
 *
 * header file for MMC device driver
 *
 * Copyright (C) 2001-2003 MIZI Research, Inc.
 *
 * Author: Yong-iL Joh 
 * $Id: mmc.h,v 1.1.1.1 2004/01/19 13:24:45 laputa Exp $
 *
 * Revision History:
 *
 * 2001-XX-XX Yong-iL Joh 
 * - initial release
 *
 * 2002-07-25 Chan Gyun Jeong 
 * - code cleanup 
 * 
 * 2002-12-07 Chan Gyun Jeong 
 * - rough restructuring for S3C2410 SD Controller
 *
 * 2003-01-17 Chan Gyun Jeong 
 * - add slot mutex
 *
 */

#ifndef MMC_MMC_H
#define MMC_MMC_H

#include 
#include 

/*
 * MMC Legends
 */
/*
  PP		PushPull, output driver type with
  		low impedance driver capability for 0 and 1
  OD		OpenDrain, output driver type with
  		low impedance driver capability for 0 and
		high impedance driver capability for 1

  bc		broadcast commands
  bcr		broadcase commands with response
  ac		addressed (point-to-point) commands (with resp.)
  adtc		addressed (point-to-point) data transfer commands (with resp.)

  CSD		CardSpecific data, MultiMediaCard register
  		to store operating parameters
  CID		Card IDentification Data, MultiMediaCard register
		for ther card initialization procedure
  RCA		Ralative Card Address, MultiMediaCard register
		which contains the current card address of
		an initialized MultiMediaCard
  OCR		Operation Condition Register, MultiMediaCard register
		which contains the voltage window
		witch is supported by the MultiMediaCard
  DSR		Driver Stage Register, control register
  		for the programmable driver tge driver (PDS)
  PDS		Porgrammable Driver Stage driver, is a tristate output driver
  		which has is programmable to adapt
		the driver capabilities to the bus design

  CMD	send command (48bit)
  		47	0		start bit
		46	1		host
		45:40	bit5   .. bit0	command
		39:8	bit31  .. bit0	argument
		7:1	bit6   .. bit0	CRC7
		0	1		end bit
  R1		reponse command (48bit)
  		47	0		start bit
		46	0		card
		45:40	bit5   .. bit0	command
		39:8	bit31  .. bit0	status
		7:1	bit6   .. bit0	CRC7
		0	1		end bit
  R1b		identical to R1 with the additional busy signaling via the data
  R2		CID, CSD register (136bit)
  		135	0		start bit
		134	0		card
		133:128	bit5   .. bit0	reserved
		127:1	bit127 .. bit1	CID or CSD register
					including internal CRC
		0	1		end bit
  R3		OCR register (48bit)
  		47	0		start bit
		46	0		card
		45:40	bit5   .. bit0	reserved
		39:8	bit31  .. bit0	OCR
		7:1	bit6   .. bit0	reserved
		0	1		end bit
		0	1		end bit

  dadr		Data Address
  wadr		Write protect data Address

  7-bit CRC	CRC7 (warning!!! it's a polynomical arithmetic mod 2)
		G(x) = x^7 + x^3 + 1
  		M(x) = (start bit)*x^39 + (host bit)*x^38 + ... +
		       (last bit before CRC)*x^0
		CRC[6..0] = Remainder[M(x)*x^7 / G(x)]
*/

/*
 * MMC Commands
 */

/* class 1, basic commands */
#define	MMC_CMD0	0x40	/* bc, , , GO_IDLE_STATE */
#define MMC_CMD1	0x41	/* bcr, 31:0 OCR, R3, SEND_OP_COND */
#define MMC_CMD2	0x42	/* bcr, , R2, ALL_SEND_CID */
#define MMC_CMD3	0x43	/* ac, 31:16 RCA, R1, SET_RELATIVE_ADDR */
#define MMC_CMD4	0x44	/* bc, 31:16 RCA, , SET_DSR */
#define MMC_CMD7	0x47	/* ac, 31:16 RCA, R1, SEELECT/DESELECT CARD */
#define MMC_CMD9	0x49	/* ac, 31:16 RCA, R2, SEND_CSD */
#define MMC_CMD10	0x4a	/* ac, 31:16 RCA, R2, SEND_CID */
#define MMC_CMD11	0x4b	/* adtc, 31:0 dadr, R1, READ_DAT_UNTIL_STOP */
#define MMC_CMD12	0x4c	/* ac, , R1b, STOP_TRANSMISSION */
#define MMC_CMD13	0x4d	/* ac, 31:16 RCA, R1, SEND_STATUS */
#define MMC_CMD15	0x4f	/* ac, 31:16 RCA, , GO_INACTIVE_SATE */

/* class 2, block oriented read commands */
#define MMC_CMD16	0x50	/* ac, 31:0 blk len, R1, SET_BLOCKLEN */
#define MMC_CMD17	0x51	/* adtc, 31:0 dadr, R1, READ_SINGLE_BLOCK */
#define MMC_CMD18	0x52	/* adtc, 31:0 dadr, R1, READ_MULTIPLE_BLOCK */

/* class 3 */
#define MMC_CMD20	0x54	/* adtc, 31:0 dadr, R1, WRITE_DAT_UNTIL_STOP */

/* class 4, block oriented write commands */
#define MMC_CMD24	0x58	/* adtc, 31:0 dadr, R1, WRITE_BLOCK */
#define MMC_CMD25	0x59	/* adtc, 31:0 dadr, R1, WRITE_MULTIPLE_BLOCK */
#define MMC_CMD26	0x5a	/* adtc, , R1, PROGRAM_CID */
#define MMC_CMD27	0x5b	/* adtc, , R1, PROGRAM_CSD */

/* class 6, block oriented write protection commands */
#define MMC_CMD28	0x5c	/* ac, 31:0 dadr, R1b, SET_WRITE_PROT */
#define MMC_CMD29	0x5d	/* ac, 31:0 dadr, R1b, CLR_WRITE_PROT */
#define MMC_CMD30	0x5e	/* adtc, 31:0 wadr, R1, SEND_WRITE_PROT */

/* class 5, erase commands */
#define MMC_CMD32	0x60	/* ac, 31:0 dadr, R1, TAG_SECTOR_START */
#define MMC_CMD33	0x61	/* ac, 31:0 dadr, R1, TAG_SECTOR_END */
#define MMC_CMD34	0x62	/* ac, 31:0 dadr, R1, UNTAG_SECTOR */
#define MMC_CMD35	0x63	/* ac, 31:0 dadr, R1, TAG_ERASE_GROUP_START */
#define MMC_CMD36	0x64	/* ac, 31:0 dadr, R1, TAG_ERASE_GROUP_END */
#define MMC_CMD37	0x65	/* ac, 31:0 dadr, R1, UNTAG_ERASE_GROUP */
#define MMC_CMD38	0x66	/* ac, , R1b, ERASE */

/* class 7, lock card */
#define MMC_CMD42	0x6a	/* adtc, , R1b, LOCK_UNLOCK */

/* class 8, applicatin specific commands */
#define MMC_CMD55	0x77	/* ac, 31:16 RCA, R1, APP_CMD */
#define MMC_CMD56	0x78	/* adtc, 0 RD/WR, R1, GEN_CMD  */

/* Command size */
#define MMC_CMD_SIZE	6

/* Command timings */
#define	MMC_TIME_NCR_MIN	2	/* min. of Number of cycles
					   between command and response */
#define MMC_TIME_NCR_MAX	64	/* max. of Number of cycles
					   between command and response */
#define MMC_TIME_NID_MIN	5	/* min. of Number of cycles
					   between card identification or
					   card operation conditions command
					   and the corresponding response */
#define MMC_TIME_NID_MAX	10	/* max. of Number of cycles
					   between card identification or
					   card operation conditions command
					   and the corresponding response */
#define MMC_TIME_NAC_MIN	2	/* min. of Number of cycles
					   between command and 
					   the start of a related data block */
#define MMC_TIME_NRC_MIN	8	/* min. of Number of cycles
					   between the last reponse and
					   a new command */
#define MMC_TIME_NCC_MIN	8	/* min. of Number of cycles
					   between two commands, if no reponse
					   will be send after the first command
					   (e.g. broadcast) */
#define MMC_TIME_NWR_MIN	2	/* min. of Number of cycles
					   between a write command and
					   the start of a related data block */

/* 
 * CID(Card IDentification) Register 
 */
typedef struct {
	__u8  mid;	/* Manufacturer ID */
	__u16 oid;	/* OEM/Application ID */
	__u8  pnm[7];	/* Product Name + '\0', MMC only */
	__u8  prv;	/* Product Version */
	__u32 psn;	/* Product Serial Number */
	__u8  mdt;	/* Manufacturing date, MMC only */
} CID_regs;

#define MMC_CID_SIZE	16

/* 
 * OCR (Operation Condition Register)
 */
typedef __u32 OCR_regs;

#define MMC_OCR_SIZE	4

#define MMC_VDD_20_36	0x00ffff00	/* VDD voltage 2.0 ~ 3.6 */
#define MMC_VDD_27_36	0x00ff8000	/* VDD voltage 2.0 ~ 3.6 */
#define MMC_VDD_20_21	0x00000100	/* VDD voltage 2.0 ~ 2.1 */
#define MMC_VDD_21_22	0x00000200	/* VDD voltage 2.1 ~ 2.2 */
#define MMC_VDD_22_23	0x00000400	/* VDD voltage 2.2 ~ 2.3 */
#define MMC_VDD_23_24	0x00000800	/* VDD voltage 2.3 ~ 2.4 */
#define MMC_VDD_24_25	0x00001000	/* VDD voltage 2.4 ~ 2.5 */
#define MMC_VDD_25_26	0x00002000	/* VDD voltage 2.5 ~ 2.6 */
#define MMC_VDD_26_27	0x00004000	/* VDD voltage 2.6 ~ 2.7 */
#define MMC_VDD_27_28	0x00008000	/* VDD voltage 2.7 ~ 2.8 */
#define MMC_VDD_28_29	0x00010000	/* VDD voltage 2.8 ~ 2.9 */
#define MMC_VDD_29_30	0x00020000	/* VDD voltage 2.9 ~ 3.0 */
#define MMC_VDD_30_31	0x00040000	/* VDD voltage 3.0 ~ 3.1 */
#define MMC_VDD_31_32	0x00080000	/* VDD voltage 3.1 ~ 3.2 */
#define MMC_VDD_32_33	0x00100000	/* VDD voltage 3.2 ~ 3.3 */
#define MMC_VDD_33_34	0x00200000	/* VDD voltage 3.3 ~ 3.4 */
#define MMC_VDD_34_35	0x00400000	/* VDD voltage 3.4 ~ 3.5 */
#define MMC_VDD_35_36	0x00800000	/* VDD voltage 3.5 ~ 3.6 */
#define MMC_nCARD_BUSY	0x80000000	/* Card Power up status bit */

/* 
 * Relative Card Address 
 */
typedef __u16 RCA_regs;

#define MMC_RCA_SIZE	2

/* 
 * CSD register, rwe == read/write/erase 
 */
typedef struct {
	__u8 csd;		/* CSD structure */
	__u8 spec_vers;		/* Spec version, MMC only */
	struct {
		__u8 man;	/* time mantissa */
		__u8 exp;	/* time exponent */
	} taac;			/* Data read access-time-1 */
	__u8 nsac;		/* Data read access-time-2 in CLK cycle */
	struct {
		__u8 man;	/* rate mantissa */
		__u8 exp;	/* rate exponent */
	} tran_speed;		/* Max. data transfer rate */
	__u16 ccc;		/* Card command classes */
	__u8 read_len;		/* Max. read data block length */
	__u8 read_part;		/* Partial blocks for read allowed */
	__u8 write_mis;		/* write block misalignment */
	__u8 read_mis;		/* read block misalignment */
	__u8 dsr;		/* DSR implemented */
	__u16 c_size;		/* Device size */
	__u8 vcc_r_min;		/* Max. read current at Vcc min */
	__u8 vcc_r_max;		/* Max. read current at Vcc max */
	__u8 vcc_w_min;		/* Max. write current at Vcc min */
	__u8 vcc_w_max;		/* Max. write current at Vcc max */
	__u8 c_size_mult;	/* Device size multiplier */
	__u8 er_size;		/* Erase sector size, MMC only */
	__u8 er_grp_size;	/* Erase group size, MMC only */
	__u8 wp_grp_size;	/* Write protect group size */
	__u8 wp_grp_en;		/* Write protect group enable */
	__u8 dflt_ecc;		/* Manufacturer default ECC, MMC only */
	__u8 r2w_factor;	/* Write speed factor */
	__u8 write_len;		/* Max. write data block length */
	__u8 write_part;	/* Partial blocks for write allowed */
	__u8 ffmt_grp;		/* File format group, rw */
	__u8 copy;		/* Copy flag (OTP), rw */
	__u8 perm_wp;		/* Permanent write protection, rw */
	__u8 tmp_wp;		/* temporary write protection, rwe */
	__u8 ffmt;		/* file format, rw */
	__u8 ecc;		/* ECC, rwe, MMC only */
} CSD_regs;

#define MMC_CSD_SIZE	16

#define CSD_VERSION_10	0
#define CSD_VERSION_11	1

#define MMC_PROT_10	0	/* MMC protocol version 1.0 - 1.2 */
#define MMC_PROT_14	1	/* MMC protocol version 1.4 */

#define TAAC_EXP_1NS	0	/* 1ns */
#define TAAC_EXP_10NS	1	/* 10ns */
#define TAAC_EXP_100NS	2	/* 100ns */
#define TAAC_EXP_1UMS	3	/* 1 u-ms */
#define TAAC_EXP_10UMS	4	/* 10 u-ms */
#define TAAC_EXP_100UMS	5	/* 100 u-ms */
#define TAAC_EXP_1MS	6	/* 1ms */
#define TAAC_EXP_10MS	7	/* 10ms */

#define TIME_MAN_NONE	0	/* reserved */
#define TIME_MAN_10	1	/* 1.0 */
#define TIME_MAN_12	2	/* 1.2 */
#define TIME_MAN_13	3	/* 1.3 */
#define TIME_MAN_15	4	/* 1.5 */
#define TIME_MAN_20	5	/* 2.0 */
#define TIME_MAN_25	6	/* 2.5 */
#define TIME_MAN_30	7	/* 3.0 */
#define TIME_MAN_35	8	/* 3.5 */
#define TIME_MAN_40	9	/* 4.0 */
#define TIME_MAN_45	A	/* 4.5 */
#define TIME_MAN_50	B	/* 5.0 */
#define TIME_MAN_55	C	/* 5.5 */
#define TIME_MAN_60	D	/* 6.0 */
#define TIME_MAN_70	E	/* 7.0 */
#define TIME_MAN_80	F	/* 8.0 */

#define TRAN_EXP_100K	0	/* 100kbit/s */
#define TRAN_EXP_1M	1	/* 1Mbit/s */
#define TRAN_EXP_10M	2	/* 10Mbit/s */
#define TRAN_EXP_100M	3	/* 100Mbit/s */

#define CCC_CLASS_0	0x001	/* Card Command Class 0 */
#define CCC_CLASS_1	0x002	/* Card Command Class 1 */
#define CCC_CLASS_2	0x004	/* Card Command Class 2 */
#define CCC_CLASS_3	0x008	/* Card Command Class 3 */
#define CCC_CLASS_4	0x010	/* Card Command Class 4 */
#define CCC_CLASS_5	0x020	/* Card Command Class 5 */
#define CCC_CLASS_6	0x040	/* Card Command Class 6 */
#define CCC_CLASS_7	0x080	/* Card Command Class 7 */
#define CCC_CLASS_8	0x100	/* Card Command Class 8 */
#define CCC_CLASS_9	0x200	/* Card Command Class 9 */
#define CCC_CLASS_10	0x400	/* Card Command Class 10 */
#define CCC_CLASS_11	0x800	/* Card Command Class 11 */

#define BLK_LEN_1	0	/* 2^0 = 1 byte */
#define BLK_LEN_2	1	/* 2^1 = 2 bytes */
#define BLK_LEN_4	2	/* 2^2 = 4 bytes */
#define BLK_LEN_8	3	/* 2^3 = 8 bytes */
#define BLK_LEN_16	4	/* 2^4 = 16 bytes */
#define BLK_LEN_32	5	/* 2^5 = 32 bytes */
#define BLK_LEN_64	6	/* 2^6 = 64 bytes */
#define BLK_LEN_128	7	/* 2^7 = 128 bytes */
#define BLK_LEN_256	8	/* 2^8 = 256 bytes */
#define BLK_LEN_512	9	/* 2^9 = 512 bytes */
#define BLK_LEN_1024	10	/* 2^10 = 1024 bytes */
#define BLK_LEN_2048	11	/* 2^11 = 2048 bytes */
#define MAX_MMC_BLK_LEN	2048

/*
	Memory Capacity = BLOCKNR * BLOCK_LEN
	where
	BLOCKNR = (C_SIZE + 1) * MULT
	MULT = 2^(c_size_mult+2) ( c_size_mult < 8)
	BLOCK_LEN = 2^read_len	( read_len < 12)
 */

#define VCC_MIN_05	0	/* 0.5mA */
#define VCC_MIN_1	1	/* 1mA */
#define VCC_MIN_5	2	/* 5mA */
#define VCC_MIN_10	3	/* 10mA */
#define VCC_MIN_25	4	/* 25mA */
#define VCC_MIN_35	5	/* 35mA */
#define VCC_MIN_60	6	/* 60mA */
#define VCC_MIN_100	7	/* 100mA */

#define VCC_MAX_1	0	/* 1mA */
#define VCC_MAX_5	1	/* 5mA */
#define VCC_MAX_10	2	/* 10mA */
#define VCC_MAX_25	3	/* 25mA */
#define VCC_MAX_35	4	/* 35mA */
#define VCC_MAX_45	5	/* 45mA */
#define VCC_MAX_80	6	/* 80mA */
#define VCC_MAX_200	7	/* 200mA */

				/* the typical block program time is */
#define R2W_FACTOR_1	0	/*   1 Multiples of Read Access Time */
#define R2W_FACTOR_2	1	/*   2 Multiples of Read Access Time */
#define R2W_FACTOR_4	2	/*   4 Multiples of Read Access Time */
#define R2W_FACTOR_8	3	/*   8 Multiples of Read Access Time */
#define R2W_FACTOR_16	4	/*  16 Multiples of Read Access Time */
#define R2W_FACTOR_32	5	/*  32 Multiples of Read Access Time */

#define ECC_NONE	0	/* none. Max.No.ofCorrectable bit/block=0 */
#define ECC_BCH		1	/* 542,512. Max.No.ofCorrectable bit/block=3 */

/*
 * R1 status: card status
 * Type
 *	e : error bit
 *	s : status bit
 *	r : detected and set for the actual command response
 *	x : detected and set during command execution. the host must poll
 *	    the card by sending status command in order to read these bits.
 * Clear condition
 *	a : according to the card state
 *	b : always related to the previous command. Reception of
 *	    a valid command will clear it (with a delay of one command)
 *	c : clear by read
 */
typedef __u32 R1_status;
#define R1_out_of_range		0x80000000	/* er, c */
#define R1_address_err		0x40000000	/* erx, c */
#define R1_block_len_err	0x20000000	/* er, c */
#define R1_erase_seq_err	0x10000000	/* er, c */
#define R1_erase_param		0x08000000	/* ex, c */
#define R1_wp_violation		0x04000000	/* erx, c */
#define R1_card_is_locked	0x02000000	/* sx, a */
#define R1_lock_unlock_fail	0x01000000	/* erx, c */
#define R1_com_crc_err		0x00800000	/* er, b */
#define R1_illegal_command	0x00400000	/* er, b */
#define R1_ecc_fail		0x00200000	/* ex, c */
#define R1_cc_err		0x00100000	/* erx, c */
#define R1_err			0x00080000	/* erx, c */
#define R1_underrun		0x00040000	/* ex, c */
#define R1_overrun		0x00020000	/* ex, c */
#define R1_overwrite		0x00010000	/* erx, c, CID/CSD overwrite */
#define R1_wp_erase_skip	0x00008000	/* sx, c */
#define R1_ecc_disable		0x00004000	/* sx, a */
#define R1_erase_reset		0x00002000	/* sr, c */
#define R1_state		0x00001E00	/* sx, b */
#define R1_buf_empty		0x00000100	/* sx, a */
#define R1_app_cmd		0x00000020	/* sr, c */
#define R1_ERR			0xFDFF0000	/* R1 error mask */

/* KAILAS added next line */
#define SD_CARD                 0x00000111      /* SD Card Identification */
                                                                                
/* card state flags of R1 */
#define STATE_IDLE	0x00000000	/* 0 */
#define STATE_READY	0x00000200	/* 1 */
#define STATE_IDENT	0x00000400	/* 2 */
#define STATE_STBY	0x00000600	/* 3 */
#define STATE_TRAN	0x00000800	/* 4 */
#define STATE_DATA	0x00000A00	/* 5 */
#define STATE_RCV	0x00000C00	/* 6 */
#define STATE_PRG	0x00000E00	/* 7 */
#define STATE_DIS	0x00001000	/* 8 */

/* flags for stat field of the mmc_slot structure */
#define MMC_WP_GRP_EN		0x00000010
#define MMC_PERM_WP		0x00000020
#define MMC_TMP_WP		0x00000040
#define MMC_READ_PART		0x00000100
#define MMC_WRITE_PART		0x00000200

/*
 * MMC
 */
#define MMC_MMC_CLOCK_HIGH		20000000
#define MMC_MMC_CLOCK_LOW		400000

/*
 * MMC command/response structure
 */

/* MMC Response type */
enum {
	MMC_RES_TYPE_NONE = 0,
	MMC_RES_TYPE_R1,
	MMC_RES_TYPE_R1B,
	MMC_RES_TYPE_R2,
	MMC_RES_TYPE_R3,
	MMC_RES_TYPE_R4,
	MMC_RES_TYPE_R5,
	MMC_RES_TYPE_R6,
};

/* MMC Response length */
#define MMC_RES_LEN_SHORT		6
#define MMC_RES_LEN_LONG		17

/* MMC Response flag */
#define MMC_RES_FLAG_DATALINE		0x01 /* transferred on dataline */
#define MMC_RES_FLAG_NOCRC		0x02 /* no crc check */
#define MMC_RES_FLAG_RDATA		0x04 /* data read */
#define MMC_RES_FLAG_WDATA		0x08 /* data write */

/* MMC Command request type */
struct mmc_cmd {
	__u8 cmd; /* command */
	__u32 arg; /* command argument */
	__u8 res_type; /* response type */
	__u8 res_flag; /* response flag */
	__u8 res[MMC_RES_LEN_LONG]; /* response buffer */
	__u8 *data; /* pointer to data buffer */
	__u32 data_len; /* data length */
	__u32 t_res; /* timing between command and response */
	__u32 t_fin; /* timing after response */
};

/*
 * MMC slot interface
 */

#define MAX_MMC_SLOTS		2

struct mmc_slot {
	/* power up */
	void (*power_up)(struct mmc_slot *slot);

	/* power down */
	void (*power_down)(struct mmc_slot *slot);

	/* wait for reset */
	void (*wait_for_reset)(struct mmc_slot *slot);

	/* set clock rate */
	void (*set_clock)(struct mmc_slot *slot, int rate);

	/* send command and receive response */
	int (*send_cmd)(struct mmc_slot *slot, struct mmc_cmd *cmd);

	/* transfer 1 block for Memory Card */
	int (*transfer1b)(struct mmc_slot *slot, int rd, u_long from, 
			  u_char *buf);


	struct semaphore mutex; /* for exclusive I/O */

	__u8 id;	/* slot id(begins at 0) assigned by slot driver */
	__u8 narrow_bus; /* if true, support only narrow bus */

	/* MMC card information */
	unsigned int read_len;	/* read block length */
	unsigned int write_len;	/* write block length */
	u_long size;	/* total size of card in bytes */
	u_long stat;	/* card status */
	__u8 readonly;	/* If true, it's readonly */

	/* Temporary registers */
	RCA_regs rca;
	CID_regs cid;
	OCR_regs ocr;
	CSD_regs csd;
	R1_status r1;

	void *priv;
};

/*
 * MMC device notifier structure
 */
struct mmc_notifier
{
	void (*add)(struct mmc_slot *slot);
        void (*remove)(struct mmc_slot *slot);
        struct mmc_notifier *next;
};

/*
 * Function prototypes
 */

/* Data Conversion functions */
static inline void mmc_str2r1(R1_status *r1, __u8 *buff)
{
	*r1 = (buff[0] << 24) | (buff[1] << 16) | (buff[2] << 8) | buff[3];
}

static inline void mmc_str2ocr(OCR_regs *regs, __u8 *buff)
{
	*regs = (buff[0] << 24) | (buff[1] << 16) | (buff[2] << 8) | buff[3];
}

static inline void mmc_str2rca(RCA_regs *regs, __u8 *buff)
{
	*regs = (buff[0] << 8) | buff[1];
}

extern void mmc_str2cid(CID_regs *regs, __u8 *buff);
extern void mmc_str2csd(CSD_regs *regs, __u8 *buff);

/* Information Collecting functions */
extern void mmc_get_CSD_info(struct mmc_slot *slot, CSD_regs *csd);

extern const int mmc_res_len[];
static inline int mmc_get_res_len(int res_type)
{
	return mmc_res_len[res_type];
}

/* Slot and User functions */
extern int add_mmc_device(struct mmc_slot *slot);
extern int del_mmc_device(struct mmc_slot *slot);
extern int reidentify_mmc_device(struct mmc_slot *slot);
extern void register_mmc_user(struct mmc_notifier *new);
extern int unregister_mmc_user(struct mmc_notifier *old);


#ifdef CONFIG_MMC_DEBUG
#define DEBUG2(n, args...)	\
	if (n <= CONFIG_MMC_DEBUG_VERBOSE) {	\
		printk(args);	\
	}
#else
#define DEBUG2(n, args...)
#endif

#endif /* ! MMC_MMC_H */