Chinaunix首页 | 论坛 | 博客
  • 博客访问: 852180
  • 博文数量: 189
  • 博客积分: 4310
  • 博客等级: 上校
  • 技术积分: 1925
  • 用 户 组: 普通用户
  • 注册时间: 2009-11-27 08:56
文章分类

全部博文(189)

文章存档

2015年(1)

2013年(2)

2012年(1)

2011年(39)

2010年(98)

2009年(48)

分类: LINUX

2010-03-30 18:07:27

前面一些内容我就先不说了,后面有时间我再统一整理,谢谢我前面所转载的博文的作者,减少了我一大堆理解的时间。
 
现直接说s3cmci_probe这个函数吧,
mmc_alloc_host(sizeof(struct s3cmci_host), &pdev->dev)
进入上面这个函数
    dev_set_name(&host->class_dev, "mmc%d", host->index);
    host->parent = dev;
    host->class_dev.parent = dev;
    host->class_dev.class = &mmc_host_class;
    device_initialize(&host->class_dev);
这几句是将导致在/SYS/CLASS/mmc_host下出现mmc0目录,添加类设备
初始化延迟的工作队列INIT_DELAYED_WORK(&host->detect, mmc_rescan);
工作队列被调度后延时一段时间将执行mmc_rescan(这个会在mmc_add_host后被执行)
以下为mmc_rescan比较重要的部分
mmc_power_up(host);//这个函数实际上与前面的mmc_power_off类似,不过设置了启动时需要的ios
        mmc_go_idle(host);//让SD卡处于空闲状态
        //CMD0 ,from inactive to idle
        mmc_send_if_cond(host, host->ocr_avail);//发送SD_SEND_IF_COND,是使用SD2.0卡才需要设置的命令
/*suppot for 2.0 card*/
         * ...then normal SD...
         */
        err = mmc_send_app_op_cond(host, 0, &ocr); //注解一
        if (!err) {
            if (mmc_attach_sd(host, ocr))  //注解二
                mmc_power_off(host);
            goto out;
        }
注解一:实际上是要发送ACMD41命令,这条命令可以用来获取SDcard的允许电压范围值,由于这是一条应用命令,所有发送它之前需要发送CMD_55命令。执行完后card状态变为READY获取的电压范围保存在ocr中,再调用mmc_attach_sd(host,ocr)看这个电压范围是否满足主机的要求,不满足,则power_off主机。
注解二:mmc_attach_sd完成匹配,和初始化卡的功能host->ocr = mmc_select_voltage(host, ocr);看是否匹配,如果匹配则做下面初始化工作mmc_sd_init_card(host, host->ocr, NULL);我们分析该函数
(1)mmc_all_send_cid()这个函数发生CMD2,获取卡的身份信息,进入到身份状态
(2)card = mmc_alloc_card(host, &sd_type);分配一张SD类型的card结构
(3)接着调用mmc_send_relative_add,获取卡的相对地址,注意一前卡和主机通信都采用默认地址,现在有了自己的地址了,进入到stand_by状态
(4)通过发送SEND_CSD (CMD9) 获取CSD 寄存器的信息,包括block长度,卡容量等信息
(5) mmc_select_card(card)发送CMD7,选中目前RADD地址上的卡,任何时候总线上只有一张卡被选中,进入了传输状态,
(6)调用mmc_app_send_scr发送命令ACMD51获取SRC寄存器的内容,进入到SENDING-DATA状态
在函数中还将获得的各个卡寄存器的内容解码,并保存到cmd结构的相应成员中。
(7)if (host->ops->get_ro(host) > 0)
                mmc_card_set_readonly(card);
通过调用get_ro(host)函数,实际上就是s3cmci_get_ro函数了。我们判断是否写保护,如果是的,将card状态设置为只读状态
最后再mmc_attach_sd里,我们将card结构添加进去
mmc_add_card(host->card);
dev_set_name(&card->dev,
"%s:%04x", mmc_hostname(card->host),
card->rca);这里我们以host名+rca地址来命名卡我们可以看到在/sys/devices/platform/s3c2440-
sdi/mmc_host:mmc0/下出现mmc0:0002的目录,这个0002就是rca地址
 
到这s3cmci_probe的比较重要的功能算是结束了。
 
插入SD卡的检测过程为
1.当插入SD卡,会引发一个中断s3cmci_irq_cd
2.进入中断后调用mmc_detect_change
3.进入mmc_detect_change后会调度delay work
4.调度后变调用mmc_rescan,以后的过程就更上面的分析一样。


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