Motorola SD/MMC驱动源码分析

 今天重新看了一下Motorola的SD/MMC驱动源码,并结合以前的分析记录,做一个总结。

以E680为例,按照初始化的过程进行分析。

模块初始化函数
module_init(e680_mmc_init);

在函数e680_mmc_init里初始化定时器,定时器的function函数为e680_detect_handler,当卡插入或取出时调用该函数。
init_timer(&e680_detection);
e680_detection.function = e680_detect_handler;

e680_mmc_slot_init完成进一步初始化。
retval = mmc_register_slot_driver(&e680_dops, 1);
static struct mmc_slot_driver e680_dops = {
    owner:        THIS_MODULE,
    name:        "Motorola E680 MMC/SD",
    ocr:        1 << 19,  /* Mainstone voltage is 3.15V */
    flags:        MMC_SDFLAG_MMC_MODE | MMC_SDFLAG_SD_MODE | MMC_SDFLAG_SPI_MODE,
    init:        e680_mmc_slot_init,
    cleanup:    e680_mmc_slot_cleanup,
    is_empty:    e680_mmc_slot_is_empty,
    is_wp:        e680_mmc_slot_is_wp,
    send_cmd:    bvd_mmc_send_command,
    set_clock:    bvd_mmc_set_clock,
};


设置检测是否有卡的管脚的中断属性,并申请中断。
set_GPIO_IRQ_edge( GPIO_MMC_DETECT, GPIO_FALLING_EDGE | GPIO_RISING_EDGE);

        /* Request card detect interrupt */
retval = request_irq(IRQ_GPIO(GPIO_MMC_DETECT), e680_detect_int,
            SA_INTERRUPT | SA_SAMPLE_RANDOM,
            "MMC/SD card detect", (void*)1);


中断处理函数e680_detect_int如下:
static void e680_detect_int(int irq, void *dev, struct pt_regs *regs)
{
    DEBUG(2, "card detect IRQ/n");

    mod_timer(&e680_detection, jiffies + HZ);
}
更新定时器,到达时间点(jiffies + HZ)时执行前面所说的e680_detect_handler。

检测卡是否存在。
e680_mmc_slot_is_empty(0);

通过e680_mmc_slot_up(0)调用bvd_mmc_slot_up()
在bvd_mmc_slot_up()完成时钟和GPIO的设置,移植的时候按自己的板子做对应的修改。
CKEN |= CKEN12_MMC;
    DEBUG(3, " ...core MMC clock OK/n");
   
    /* Configure MMCLK bus clock output signal
       ([2], 15.3, 24.4.2) */
    set_GPIO_mode(GPIO_MMC_CLK | GPIO_ALT_FN_2_OUT);
    DEBUG(3, " ...MMCLK signal OK/n");

    /* Configure MMCMD command/response bidirectional signal
       ([2], 15.3, 24.4.2) */
    set_GPIO_mode(GPIO_MMC_CMD | GPIO_ALT_FN_1_IN | GPIO_ALT_FN_1_OUT);
    DEBUG(3, " ...MMCMD signal OK/n");

    /* Configure MMDAT[0123] data bidirectional signals
       ([2], 15.3, 24.4.2) */
    set_GPIO_mode(GPIO_MMC_DATA0  | GPIO_ALT_FN_1_IN | GPIO_ALT_FN_1_OUT);
    // for dat3 used to detect card insert and remove on A780,
    // so we only use 1 bit transfer mode ---zq
#ifndef CONFIG_ARCH_EZX_A780
    //from Barbados P3, we will use 4 bit mode --jll
     set_GPIO_mode(GPIO_MMC_DATA1 | GPIO_ALT_FN_1_IN | GPIO_ALT_FN_1_OUT);
    set_GPIO_mode(GPIO_MMC_DATA2 | GPIO_ALT_FN_1_IN | GPIO_ALT_FN_1_OUT);
    set_GPIO_mode(GPIO_MMC_DATA3 | GPIO_ALT_FN_1_IN | GPIO_ALT_FN_1_OUT);
#endif    
    DEBUG(3, " ...MMDATx signals OK/n");

至此,跟底层相关的初始化完成。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值