Chinaunix首页 | 论坛 | 博客
  • 博客访问: 637331
  • 博文数量: 121
  • 博客积分: 8469
  • 博客等级: 中将
  • 技术积分: 1065
  • 用 户 组: 普通用户
  • 注册时间: 2008-07-03 10:32
文章分类

全部博文(121)

文章存档

2013年(1)

2012年(15)

2010年(2)

2009年(8)

2008年(95)

我的朋友

分类: LINUX

2008-07-21 11:53:52

今天重新看了一下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");

至此,跟底层相关的初始化完成。

驱动移植过程


阅读(1868) | 评论(0) | 转发(2) |
给主人留下些什么吧!~~