MX25上SD卡的插拨检测机制
飞思卡尔开发板留有可插拨的SD卡卡槽,BSP包中提供了热插拨的检测机制。在sdhci_probe_slot函数中,gpio_sdhc_active函数初始化SD卡相关的GPIO口,包括SD卡检测脚的初始化。下面的程序实现SD卡检测中断号的申请,以及中断的触发方式:
host->detect_irq = platform_get_irq(pdev, 1);//申请卡检测中断号
if (!host->detect_irq)
{
host->flags &= ~SDHCI_CD_PRESENT;
if ((pdev->id >= 0) && (pdev->id < MXC_SDHCI_NUM))
mxc_fix_chips[pdev->id] = chip;
goto no_detect_irq;
}
do
{
ret = host->plat_data->status(host->mmc->parent);//获取SD卡的存在状态
if (ret)//根据当前SD卡存在状态设置卡检测中断触发类型
set_irq_type(host->detect_irq, IRQF_TRIGGER_FALLING);
else
set_irq_type(host->detect_irq, IRQF_TRIGGER_RISING);
} while (ret != host->plat_data->status(host->mmc->parent));
ret = host->plat_data->status(host->mmc->parent);
程序首先使用platform_get_irq函数申请一个中断号,然后读取SD卡的存在状态,如果SD卡不在卡槽内,则设置为下降沿触发,反之则设置为上升沿触发。这一点需要与硬件接口对应起来,开发板的SD卡硬件电路如下图所示:
SD1_DET脚即为SD卡检测脚,在没有卡存在的情况下,该脚被硬件上拉为高电平,插入卡后,该脚被卡槽直连到地。因此,在没有卡存在时,需要设置为下降沿触发,反之设置为上升沿触发。其实如果CPU支持双边沿触发,可以设置为双边沿触发,然后在中断处理函数中通过检测脚的电平判断是插入还是拨出。
紧接着程序通过下面的函数初始化自旋锁:
spin_lock_init(&host->lock);
使用INIT_WORK函数初始化卡检测函数的工作队列:
INIT_WORK(&host->cd_wq, esdhc_cd_callback);
使用request_irq函数申请卡检测中断:
if (host->detect_irq)//lqm changed
{
ret = request_irq(host->detect_irq, sdhci_cd_irq, 0,pdev->name, host);//响应检测SD卡中断
if (ret)//失败
goto out4;
}
sdhci_cd_irq函数为中断顶半部:
static irqreturn_t sdhci_cd_irq(int irq, void *dev_id)
{
struct sdhci_host *host = dev_id;
schedule_work(&host->cd_wq);
return IRQ_HANDLED;
}
当卡检测中断产生后,中断顶半部调用schedule_work函数调度工作队列执行。这里的传入参数host->cd_wq和前面工作队列初始化的第一个传入参数必须一致。工作队列初始化的第二个参数esdhc_cd_callback为卡检测中断的底半部,产生中断后需要做的工作全在这个函数里面。schedule_work执行后该函数马上会执行:
static void esdhc_cd_callback(struct work_struct *work)
{
unsigned long flags;
unsigned int cd_status = 0;
struct sdhci_host *host = container_of(work, struct sdhci_host, cd_wq);
do
{
if (host->detect_irq == 0)
break;
cd_status = host->plat_data->status(host->mmc->parent);//读取SD卡状态
if (cd_status)//如果卡槽内没有卡,则设置为下降沿触发,否则为上升沿触发
set_irq_type(host->detect_irq, IRQF_TRIGGER_FALLING);
else
set_irq_type(host->detect_irq, IRQF_TRIGGER_RISING);
} while (cd_status != host->plat_data->status(host->mmc->parent));
cd_status = host->plat_data->status(host->mmc->parent);//获得卡状态
printk(KERN_INFO"cd_status=%d %s/n",cd_status, cd_status ? "removed" : "inserted");//lqm added.
/* If there is no card, call the card detection func immediately. */
if (!cd_status) // 当没卡时插入卡,开启定时器
{
if (host->flags & SDHCI_CD_TIMEOUT)
host->flags &= ~SDHCI_CD_TIMEOUT;
else
{
mod_timer(&host->cd_timer, jiffies + HZ / 4);
return;
}
}
cd_status = host->plat_data->status(host->mmc->parent);
if (cd_status)//cd_status=1表示没有卡
host->flags &= ~SDHCI_CD_PRESENT;
else
host->flags |= SDHCI_CD_PRESENT;
/* Detect there is a card in slot or not */
spin_lock_irqsave(&host->lock, flags);//自旋锁第三步:获得自旋锁,保护临界区
if (!(host->flags & SDHCI_CD_PRESENT)) //当卡拨出时执行下面程序
{
printk(KERN_INFO"%s: Card removed and resetting controller./n",mmc_hostname(host->mmc));
if (host->mrq)
{
struct mmc_data *data;
data = host->data;
host->data = NULL;
printk(KERN_ERR"%s: Card removed during transfer!/n",mmc_hostname(host->mmc));
printk(KERN_ERR"%s: Resetting controller./n",mmc_hostname(host->mmc));
if ((host->flags & SDHCI_USE_EXTERNAL_DMA) && (data != NULL))
{
dma_unmap_sg(mmc_dev(host->mmc), data->sg,
host->dma_len, host->dma_dir);
host->dma_size = 0;
}
sdhci_reset(host, SDHCI_RESET_CMD);
sdhci_reset(host, SDHCI_RESET_DATA);
host->mrq->cmd->error = -ENOMEDIUM;
tasklet_schedule(&host->finish_tasklet);
}
if (host->init_flag > 0)
host->init_flag--;
else
sdhci_init(host);
}
spin_unlock_irqrestore(&host->lock, flags);//自旋锁第四步:解锁
if (host->flags & SDHCI_CD_PRESENT)
{
printk(KERN_ERR"SDHCI_CD_PRESENT.../n");// lqm added.
del_timer(&host->cd_timer);
mmc_detect_change(host->mmc, msecs_to_jiffies(100));// lqm masked for test.
}
else
{
printk(KERN_ERR"no SDHCI_CD_PRESENT.../n");
mmc_detect_change(host->mmc, 0);
}
}
由于卡状态发生了改变,因此函数的第一步即先读取卡状态,根据不同的状态设置对应的卡中断方式。如果是卡插入造成的中断,则打开定时器,进而执行卡挂载等操作,如果是卡拨出造成的中断,则复位SD卡模块。注意在卡拨出执行的代码段添加了自旋锁,正因为它,前面才使用了spin_lock_init函数初始化自旋锁。
MX25上SD卡的插拨检测机制相关推荐
- SD卡结构、检测方式
SD卡检测方式 方法之一,使用DAT3(pin1)作为卡在位检测信号:DAT3在sd 卡内部有90k的上拉电阻.Host与sd card之间对DAT3做外部下拉.这样卡没插入时host读DAT为低,卡 ...
- sd卡linux错误检测,android系统正在准备SD卡正在检测是否有错误且SD卡无法读取解决办法...
手机android系统,也许您会碰到这样的情况. 错误提示:正在准备SD卡 正在检测是否有错误.这时sd卡(即内存卡)不能正常使用,不管手机自带的程序,还是通过usb口连接到电脑都无法识别sd卡. 这 ...
- 索尼android sd卡上,SD卡各个文件夹功能详解 入手必看经验!!!!
对于初次使用Android系统的新手来说,当打开SD开一看,里面那些林林总总的文件夹总会让自己不知所措,有些看文件夹名称,还能猜到点作用来,但是大部分的都不知道是做什么的 1..android_sec ...
- 读卡器(8年前的)插上SD卡提示未插入修复教程,仅适用于放置较久的读卡器。
前提:SD能够正常使用 1.插入SD卡的读卡器,在电脑中弹出如下提示: 2.此时排除了SD损坏的原因,直接对读卡器下手了,拆解图如下,构造还是比较简单的. 3.由于放置时间较长可能是电路板上发生了氧化 ...
- 三星android sd卡,神乎其技:大神让三星S7 Edge同时用上SD卡和双SIM卡
IT之家讯 3月22日消息 三星在今年的S7/S7 Edge手机上增加了支持microSD卡扩展的功能,对于那些手机重度用户而言无疑是一项福音,不过三星S7的microSD卡功能有个尴尬的地方,就是和 ...
- cube sdio fatfs 初始化sd卡_SD卡读卡器检测——硬盘检测软件Hard Disk Sentinel Pro介绍
在本教程中,将介绍如何使用硬盘检测软件Hard Disk Sentinel Pro查看相应的行业标准(微型)SD卡,USB设备的完整状态. 尽管大多数SD / microSD卡不提供状态信息,并且只能 ...
- SD卡与SD卡座电路以及TF卡(Micro SD Card,原名Trans-flash Card(TF卡))插拔式卡座和自弹出的卡座的引脚定义详细
Micro SD Card,原名Trans-flash Card(TF卡),2004年正式更名为Micro SD Card,由SanDisk(闪迪)公司发明,主要用于移动电话. 在Micro SD面市 ...
- 苹果电脑更改sd卡只读_SD卡变为只读系统
2.使用用fsck – y 来修复文件系统 转自:http://blog.chinaunix.net/uid-20753645-id-1877931.html 问题: 将上述这些存储设备插入USB端口 ...
- android u盘自动挂载点,Android2.3实现SD卡与U盘自动挂载的方法
本文实例讲述了Android2.3实现SD卡与U盘自动挂载的方法.分享给大家供大家参考,具体如下: 在 s3c6410平台上移植android2.3 过程中SD卡总是不能自动挂载. 查阅相关资料,知道 ...
最新文章
- GIt本地相关操作(一)
- Java中JRE、JDK和JVM的区别
- Angularjs 开始之Hello world
- java中elements_Java中的提供程序elements()方法
- 内部简单二进制编码(SBE)
- 将字符串中的字符按Z字形排列,按行输出
- mysql Innodb参数配置
- Bokeh 使用Basic Glyphs做图
- android library使用,Android:Library module的使用
- 20200217:下一个排列(leetcode31)
- ubuntu-16.04安装程序报错 you might want to run 'apt-get -f install' to correct these
- oracle xtts 测试,XTTS 跨平台表空间迁移测试
- TensorFlow 训练单特征和多特征的线性回归
- TransposonPSI——转座子分析的入门自学
- 【情感分析】基于Aspect的情感分析模型总结(PART IV)
- VMware vSphere 5.x 与 vSphere 6.0各版本功能特性对比
- NMDS非度量多维尺度分析
- centos 7.6安装WeADMIN ITOSS步骤
- 守望先锋地图英文和英雄英文
- Flexsim Rack设置最底层Level不放货物