当前位置:操作系统 > 安卓/Android >>

Android OS MTK6573 SD卡驱动浅析

首次出关于MTK方面的驱动文章,网上也很少有这方面的文章,所以我立志要写几篇这样的文章来引导刚出道的朋友们,咱们一起努力!

大家都说MTK简单,但我个人做过高通平台一年时间,然后转而做MTK平台,感觉还是能学到东西的,代码并不比所谓的高通简单,只是它做的好,封装的好,所以做这块驱动可能开发者做的事情没高通多,所以大家觉得容易,学不到东西。但只要自己对技术执着,深入到架构的实现,还是能学到很多的。我要让大家有这样一个思想,我们做MTK平台的不比做其他任何平台的差。

一. SD卡的基本知识:

 SD卡有9个pin脚(micro-SD为8个,少一个接地pin脚),如图所示,

 

\\




SD的数据传输方式有两种,普通SD模式和SPI模式,以SD模式为例,9个pin脚分别是VDD,VSS,CLK,以及我们需要关注的一根指令线CMD,4根数据线DAT0~DAT3。

分类:
按存储大小,普通SD卡(<=2GB,支持FAT12/FAT16),HCSD卡(>2GB,<=32GB,支持FAT32)
按体积大小,普通SD卡,mini-SD卡,micro-SD卡(TF卡)
速度
默认模式: 12.5MB/s
高速模式: 25MB/s
二. SD卡在MTK6573中的架构
       涉及到的文件有:mediatek/platform/mt6573/kernel/drivers/mmc-host/sd.c

                                       mediatek/platform/mt6573/kernel/drivers/mmc-host/mt6573_sdc.c

        下面就整个驱动的流程过一下:

         系统起来的时候执行 static int __init mt6573_sd_init(void) 在这个函数里最重要的是执行platform_driver_register(&mt6573_sd_driver),即注册到内核的虚拟总线上,注册的原则是把驱动mt6573_sd_driver各参数进行初始化。

          下面进入变量mt6573_sd_driver各成员的初始化。其中最重要的成员是mt6573_sd_probe的执行。当在虚拟platform总线上driver和device的名字"mt6573-sd"相匹配时即执行probe函数。

下面先看看文件mt6573_sdc.c中的static struct platform_device mt6573_device_sd[] =
{
    {
        .name           = "mt6573-sd",
        .id             = 0,
        .num_resources  = ARRAY_SIZE(mt6573_resource_sd0),
        .resource       = mt6573_resource_sd0,
        .dev = {
            .platform_data = &mt6573_sd0_hw,
        },
    },

从这个结构体可以得出platform_device和platform_driver的name是相同的,所以会遍历到执行probe函数,这个结构体中有个重要的参数mt6573_sd0_hw,这个成员即是SD卡的初始状态值:

struct mt6573_sd_host_hw mt6573_sd0_hw = {
    .clk_src        = MSDC_CLKSRC_98MHZ,
    .cmd_edge       = EDGE_RISING,
    .data_edge      = EDGE_RISING,
    .cmd_odc        = MSDC_ODC_8MA,
    .data_odc       = MSDC_ODC_8MA,
    .cmd_slew_rate  = MSDC_ODC_SLEW_SLOW,
    .data_slew_rate = MSDC_ODC_SLEW_SLOW,
    .cmd_pull_res   = MSDC_PULL_RES_23K,
    .dat_pull_res   = MSDC_PULL_RES_23K,
    .clk_pull_res   = MSDC_PULL_RES_23K,
    .rst_wp_pull_res= MSDC_PULL_RES_23K,
    .data_pins      = 4,
    .data_offset    = 0,
    .flags          = MSDC_SYS_SUSPEND | MSDC_HIGHSPEED | MSDC_CD_PIN_EN,
};

这个相当于SD卡的私有数据。

来分析下mt6573_sd_probe(struct platform_device *pdev)

hw   = (struct mt6573_sd_host_hw*)pdev->dev.platform_data; //这个函数相当于hw =mt6573_sd0_hw 红色字体的变量是等价的

    reg  = platform_get_resource(pdev, IORESOURCE_MEM, 0);       //申请驱动的内存
    dma  = platform_get_resource(pdev, IORESOURCE_DMA, 0);     //申请驱动的DMA空间
    irq  = platform_get_irq(pdev, 0);                                                            //中断申请
    cirq = platform_get_irq(pdev, 1);                                                           //插卡外部中断申请
    mmc->ops        = &mt6573_sd_ops;                                                      //SD卡的处理函数,这个也是重点,等下再进入分析 www.zzzyk.com

    mmc->f_min      = HOST_MIN_SCLK;
    mmc->f_max      = HOST_MAX_SCLK;                                                //SD卡的工作时钟

    ................
    tasklet_init(&host->card_tasklet, mt6573_sd_tasklet_card, (ulong)host);
    tasklet_init(&host->fifo_tasklet, mt6573_sd_tasklet_fifo, (ulong)host);
    tasklet_init(&host->dma_tasklet, mt6573_sd_tasklet_dma, (ulong)host);

    这三个函数是中断处理下半部分别是处理识别卡/卡传输数据的buffer/卡传输数据的DMA通道。
    mt6573_sd_init_hw(host, dma);                                                        //具体SD卡的硬件寄存器参数的设置

        if (hw->flags & MSDC_CD_PIN_EN) {
        if (hw->request_cd_eirq) {                   
            hw->request_cd_eirq(mt6573_sd_cd_eirq, (void*)host)

补充:移动开发 , Android ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,