分类: LINUX
2012-02-10 15:45:37
一、基于S3C2440的MMC/SD内寄存器介绍
1. SDICON:控制寄存器,完成SD卡基础配置,包括大小端,中断允许,模式选择,时钟使能等。
2. SDIPRE:波特率预定标器寄存器,对SDCLK的配置。
3. SDICmdArg:指令参数寄存器,指令的参数存放在这里。
4. SDICCON:控制指令形式的寄存器,配置SPI还是SDI指令,指令的反馈长度,是否等待反馈,是否运行指令,指令的索引等。
5. SDICmdSta:指令状态寄存器,指令是否超时,传送,结束,CRC是否正确等。
6. SDIRSP0-3:反映SD的状态。
7. SDIDTimer:设置超时时间。
8. SDIBSize:模块大小寄存器。
9. SDIDatCon:数据控制寄存器,配置是几线传输,数据发送方向,数据传送方式等。
10. SDIDatSta:数据状态寄存器,数据是否发送完,CRC效验,超时等。
11. SDIFSTA:FIFO状态寄存器,DMA传输是否判断FIFO。
12. SDIIntMsk:中断屏蔽寄存器。
13. SDIDAT:SDI数据寄存器。
二、MMC/SD协议
根据协议,MMC/SD卡的驱动被分为:卡识别阶段和数据传输阶段。在卡识别阶段通过命令使MMC/SD处于:空闲(idle)、准备(ready)、识别(ident)、等待(stby)、不活动(ina)几种不同的状态;而在数据传输阶段通过命令使MMC/SD处于:发送(data)、传输(tran)、接收(rcv)、程序(prg)、断开连接(dis)几种不同的状态。所以可以总结MMC/SD在工作的整个过程中分为两个阶段和十种状态。下面使用图形来描述一下在两个阶段中这十种状态之间的转换关系。
三、Mini2440开发板的MMC/SD硬件接口电路原路图
从电路原理图上可以看出,SD分别使用S3C2440的复用IO端口GPE7-10作为4根数据信号线、使用GPE6作命令信号线、使用GPE5作时钟信号线,使用复用端口GPG8的外部中断功能来作SD卡的插拔检测,使用GPH8端口来判断SD卡是否写有保护。
四、重要结构体
struct mmc_host
{
struct device *parent;
struct device class_dev;
int index;
const struct mmc_host_ops *ops;
unsigned int f_min;
unsigned int f_max;
u32 ocr_avail;
#define MMC_VDD_165_195 0x00000080 /* VDD voltage 1.65 - 1.95 */
#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 */
unsigned long caps; /* Host capabilities */
#define MMC_CAP_4_BIT_DATA (1 << 0)/* Can the host do 4 bit transfers */
#define MMC_CAP_MMC_HIGHSPEED (1 << 1)/* Can do MMC high-speed timing */
#define MMC_CAP_SD_HIGHSPEED (1 << 2)/* Can do SD high-speed timing */
#define MMC_CAP_SDIO_IRQ (1 << 3)/* Can signal pending SDIO IRQs */
#define MMC_CAP_SPI (1 << 4)/* Talks only SPI protocols */
#define MMC_CAP_NEEDS_POLL (1 << 5)/* Needs polling for card-detection */
#define MMC_CAP_8_BIT_DATA (1 << 6)/* Can the host do 8 bit transfers */
/* host specific block data */
unsigned int max_seg_size; /* see blk_queue_max_segment_size */
unsigned short max_hw_segs; /* see blk_queue_max_hw_segments */
unsigned short max_phys_segs; /* see blk_queue_max_phys_segments */
unsigned short unused;
unsigned int max_req_size; /* maximum number of bytes in one req */
unsigned int max_blk_size; /* maximum size of one mmc block */
unsigned int max_blk_count; /* maximum number of blocks in one req */
/* private data */
spinlock_t lock; /* lock for claim and bus ops */
struct mmc_ios ios; /* current io bus settings */
u32 ocr; /* the current OCR setting */
/* group bitfields together to minimize padding */
unsigned int use_spi_crc:1;
unsigned int claimed:1; /* host exclusively claimed */
unsigned int bus_dead:1; /* bus has been released */
#ifdef CONFIG_MMC_DEBUG
unsigned int removed:1; /* host is being removed */
#endif
struct mmc_card *card; /* device attached to this host */
wait_queue_head_t wq;
struct delayed_work detect;
const struct mmc_bus_ops *bus_ops; /* current bus driver */
unsigned int bus_refs; /* reference counter */
unsigned int sdio_irqs;
struct task_struct *sdio_irq_thread;
atomic_t sdio_irq_thread_abort;
#ifdef CONFIG_LEDS_TRIGGERS
struct led_trigger *led; /* activity led */
#endif
struct dentry *debugfs_root;
unsigned long private[0] ____cacheline_aligned;
};
该结构体定义在/include/linux/mmc/host.h中,主要用于核心层与主机驱动层的数据交换处理。
struct s3cmci_host
{
struct platform_device *pdev;
struct s3c24xx_mci_pdata *pdata;
struct mmc_host *mmc;
struct resource *mem;
struct clk *clk;
void __iomem *base;
int irq;
int irq_cd;
int dma;
unsigned long clk_rate;
unsigned long clk_div;
unsigned long real_rate;
u8 prescaler;
unsigned sdiimsk;
unsigned sdidata;
int dodma;
int dmatogo;
struct mmc_request *mrq;
int cmd_is_stop;
spinlock_t complete_lock;
enum s3cmci_waitfor complete_what;
int dma_complete;
u32 pio_sgptr;
u32 pio_bytes;
u32 pio_count;
u32 *pio_ptr;
#define XFER_NONE 0
#define XFER_READ 1
#define XFER_WRITE 2
u32 pio_active;
int bus_width;
char dbgmsg_cmd[301];
char dbgmsg_dat[301];
char *status;
unsigned int ccnt, dcnt;
struct tasklet_struct pio_tasklet;
#ifdef CONFIG_CPU_FREQ
struct notifier_block freq_transition;
#endif
};