linux/android sdcard framwork


0.层次关系


# 1.各平台 mmc host controler 驱动  qcom/freescale/atmel  

/*---------------------------------------------------------------------------------*/ 

# 2.mmc控制器驱动相关接口函数,有些平台的控制器驱动不需要, 比如freescale、atmle  
#drivers/mmc/host/sdhci.c     (Secure Digital Host Controller Interface support)    

 /*--------------------------------------------------------------------------------*/ 
# 3.核心层 
    #drivers/mmc/core/mmc.c     // mmc
    #drivers/mmc/core/sdio.c    // sdio
    #drivers/mmc/core/sd.c      // sdcard 
/*-----------------------------------------*/
    #drivers/mmc/core/core.c  
    #drivers/mmc/core/host.c

 /*---------------------------------------------------------------------------------*/ 

1.framwork层核心函数 mmc_rescan

sdcard热插拔逻辑都在此函数中

#(drivers/mmc/core/core.c) 

mmc_rescan   
     mmc_rescan_try_freq

 /*
     将依次尝试给sdio、sdcard、mmc上电
     — 如果上电失败则表示不是此设备插入,继续尝试下一个设备的attach
     - 如果上电成功
       1. 注册SD总线上的操作函数 - struct mmc_bus_ops mmc_sd_ops
       2. 设置主控制器的时钟和总线方式 - 通过回调函数host->ops->set_ios();
       3. 启动SD卡 - 根据协议,完成SD卡启动的各个步骤
  */
         if (!mmc_attach_sdio(host))    //sdio.c
            return 0;

         if (!mmc_attach_sd(host))     // sd.c
            return 0;

        if (!mmc_attach_mmc(host))     // mmc.c 
            return 0;

1.1 继续追踪 mmc_attach_sd 函数

mmc_attach_sd
    mmc_send_app_op_cond   // 尝试上电,上电不成功直接return
    mmc_sd_attach_bus_ops  // 注册sd总线上的操作函数 (sd.c 中的总线相关操作函数)
    mmc_sd_init_card
            mmc_set_clock(host, mmc_sd_get_max_clock(card));  // 根据卡的类型自动获取最大的时钟速率
               ...
                host->ops->set_ios(host, ios);     // 调用host->ops->set_ios设置bus时钟


1.各平台 mmc host controler 驱动

# drivers/mmc/host/msm_sdcc.c   Qualcomm SDCC Controller Support
# drivers/mmc/host/mxs-mmc.c    Freescale MXS Multimedia Card Interface support
# drivers/mmc/host/atmel-mci.c  Atmel SD/MMC Driver  Multimedia Card Interface

1.1 关于两个中断

一个为SD主控制器芯片内电路固有的内部中断,另一个为探测引脚的探测到外部有SD卡插拔引起的中断。

(1) 控制器内部中断
当调用(*request),即host->ops->request(host, mrq) (2.2节重要结构),即上文中的 sdhci_request() 后,控制器与SD卡之间开始进行一次指令或数据传输,
通信完毕后,主控芯片将产生一个内部中断,以告知此次指令或数据传输完毕。这个中断的具体值将保存在一个名为MMC_I_REG的中断寄存器中以供读取,


(2) 探测sdcard插拔引脚中断
检测sdcard的插拔,中断处理函数调用 core.c中的 mmc_detect_change -> mmc_rescan检测状态变化。

    mmc_detect_change
                mmc_schedule_delayed_work(&host->detect, delay);     -》   INIT_DELAYED_WORK(&host->detect, mmc_rescan); // host.c
                    mmc_rescan

2.mmc控制器驱动相关接口函数

有些平台的控制器驱动不需要, 比如freescale、atmle

# drivers/mmc/host/sdhci.c     (Secure Digital Host Controller Interface support)    

2.1 主要函数

    (1)sdhci_add_host       // 核心函数 :对 struct mmc_host *mmc->ops 进行了赋值
         request_irq(host->irq, sdhci_irq, IRQF_SHARED,mmc_hostname(mmc), host);  // mmc控制器内部中断,数据或指令传输完成会产生一个中断(中断名以host名字命名)

    (2)sdhci_irq   //    host内部中断数据或指令传输完成函数

            // 读取中断状态寄存器
            intmask = sdhci_readl(host, SDHCI_INT_STATUS);

            // cmd 传输完毕
            if (intmask & SDHCI_INT_CMD_MASK) 
            {
                sdhci_writel(host, intmask & SDHCI_INT_CMD_MASK,SDHCI_INT_STATUS);
                sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK);
            }

            // data 传输完毕
            if (intmask & SDHCI_INT_DATA_MASK) 
            {
                sdhci_writel(host, intmask & SDHCI_INT_DATA_MASK,
                SDHCI_INT_STATUS);
                sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK);
            }

2.2 主要结构

host 驱动的驱动能力 struct mmc_host_ops

    static const struct mmc_host_ops sdhci_ops = {
        .pre_req    = sdhci_pre_req,
        .post_req   = sdhci_post_req,

        /*以上通过pxamci_request()实现了主控制器的通信功能,之后只须通过host->ops->request(host, mrq);回调函数即可。
        协议层里,每条指令都会通过mmc_wait_for_req(host, &mrq)调用到host->ops->request(host, mrq)来发送指令和数据。*/
        .request    = sdhci_request,                // 它是整个SD主控制器驱动的核心,实现了SD主控制器能与SD卡进行通信的能力 ☆

        .set_ios    = sdhci_set_ios,                // ☆ 为主控制器设置总线和时钟等配置
        .get_ro     = sdhci_get_ro,                 // 得到只读属性
        .hw_reset   = sdhci_hw_reset,
        .enable_sdio_irq = sdhci_enable_sdio_irq,   //开启sdio中断
        .start_signal_voltage_switch    = sdhci_start_signal_voltage_switch,
        .execute_tuning         = sdhci_execute_tuning,
        .enable_preset_value        = sdhci_enable_preset_value,
        .enable     = sdhci_enable,
        .disable    = sdhci_disable,
        .stop_request = sdhci_stop_request,
        .get_xfer_remain = sdhci_get_xfer_remain,
        .notify_load    = sdhci_notify_load,
    };      

3.框架层

drivers/mmc/core/core.c


3.1 核心函数

// mmc、sdcard scanf、add、remove工作
    mmc_rescan      


----------


// 中断检测到sdcard变化调用  mmc_rescan 进行add/remove 操作;第二个参数是防抖操作,考虑到插入SD卡需要一个短时间的过程                                                    
    mmc_detect_change(struct mmc_host *host, unsigned long delay)   



----------


// 调用host->ops->request 完成和sdcard的通讯。   
    mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq)    

drivers/mmc/core/host.c


4.结构体和层次关系


4.1 主控制器 mmc host controler

—— SD卡的控制器芯片,可以看成CPU的代言人,它为CPU分担了完成与SD卡数据通信的任务
—— struct mmc_host *mmc,此mmc指针指向不同平台芯片SD卡控制器的一个具体化对象


4.2 mmc_host 的具体化对象列举



# msm_sdcc.c   Qualcomm SDCC Controller Support

   struct msmsdcc_host {
    struct mmc_host     *mmc;
    struct resource     *cmd_irqres;
    struct resource     *memres;
    struct resource     *dmares;
    void __iomem        *base;
    int         pdev_id;
    unsigned int        stat_irq;
    struct msmsdcc_curr_req curr;
    ...
    ...

    }


----------


# mxs-mmc.c   Freescale MXS Multimedia Card Interface support
    struct mxs_mmc_host {
    struct mxs_ssp          ssp;

    struct mmc_host         *mmc;
    struct mmc_request      *mrq;
    struct mmc_command      *cmd;
    struct mmc_data         *data;
    ...
    ...
    }


----------


# atmel-mci.c  Atmel SD/MMC Driver  Multimedia Card Interface
    struct atmel_mci_slot {
    struct mmc_host     *mmc;
    struct atmel_mci    *host;

    u32         sdc_reg;
    u32         sdio_irq;

    struct mmc_request  *mrq;
    struct list_head    queue_node; 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值