Linux MMC/SD/SDIO体系结构

有关MMC/SD/SDIO相关的知识这里就不多讲了,请参考相关资料。这里主要涉及Linux下MMC相关内容。

内核版本(2.6.36)

首先说一下Linux相关MMC的代码分布,主要有两个目录,一个头文件目录和一个源代码目录。

分别位置如下:

include/linux/mmc

drivers/mmc

要阅读MMC相关代码就必须要看这两个目录。在drivers/mmc目录下分别有三个子目录,其将对应接下来要讲的MMC的体系结构。这三个子目录分别为:

 card
 core
 host

它们的内容后面讲到体系结构时自然就明了了。
 现在来说说MMC的体系结构,其分为三层

        /dev下设备文件访问MMC/SD/SDIO
用户空间             |
---------------------|-----------------------------------------------------
内核空间            \ /
         MMC Card层(对应具体的设备驱动,如MMC/SD卡块设备驱动,SDIO UART)
                     |
                    \ /
          MMC core层(为上次设备驱动实现提供操作接口,和下层host注册提供机制)
                     |
                    \ /
           Host层(具体MMC/SD/SDIO控制器驱动层。如S3C2440 MMC/SD控制器驱动)
                     |
                    \ /
-----------------------------------------------------------------------------
                    硬件层

对于我们来说,编写MMC/SD卡相关驱动主要涉及的就是Host层,其余层不用考虑。对于SDIO设备除了Host层以外,还有可能要编写MMC Card层的设备驱动。

编写Host层驱动,主要是填充mmc_host结构体相关内容和实现mmc_host_ops结构体中的函数。最后调用mmc_add_host向MMC core注册host驱动。可以参考S3C24XX的HOST驱动程序(drivers/mmc/host/s3cmci.c,s3cmci.h),上层MMC Core主要调用mmc_host_ops中的函数来实现与硬件交互。如下是mmc_host_ops结构体里面的函数:
  struct mmc_host_ops {
    /*使能和禁止HOST控制器*/
    int (*enable)(struct mmc_host *host);
    int (*disable)(struct mmc_host *host, int lazy);
   
        /*这个是关键的函数,所有对MMC/SD的操作,包括发命令和读数据,都通过该接口来实现,所以实现该接口时要处理是命令还是数据操作,另外要考虑是否使用DMA来进行数据传输。*/
    void    (*request)(struct mmc_host *host, struct mmc_request *req);

        /*用来设置MMC/SD的时钟,电压等操作*/
    void    (*set_ios)(struct mmc_host *host, struct mmc_ios *ios);

        /*检查MMC/SD是否写保护了*/
    int    (*get_ro)(struct mmc_host *host);

        /*检查mmc/sd的插入和拔出*/
    int    (*get_cd)(struct mmc_host *host);

    void    (*enable_sdio_irq)(struct mmc_host *host, int enable);

    /* optional callback for HC quirks */
    void    (*init_card)(struct mmc_host *host, struct mmc_card *card);
};