当前位置: 技术问答>linux和unix
linux SD卡驱动移植问题
来源: 互联网 发布时间:2017-01-17
本文导语: 本帖最后由 prettyboybaoxiaopeng 于 2011-05-17 14:41:39 编辑 我想在博创的平台移植SD卡驱动 Linux-2.6.29的SD卡platform_driver在drivers/mmc/host/sdhci-s3c.c下,在arch/arm/plat-s3c/dev-hsmmc.c中,在arch/arm/mach-s3c6410/mach-smdk6410.c中对&s3c_device_hsmmc0...
Linux-2.6.29的SD卡platform_driver在drivers/mmc/host/sdhci-s3c.c下,在arch/arm/plat-s3c/dev-hsmmc.c中,在arch/arm/mach-s3c6410/mach-smdk6410.c中对&s3c_device_hsmmc0进行platform_device的注册。
我查看原理图发现SD卡座的CLK接GPG0,CMD接GPG1,DATA0-DATA3接GPG2-GPG5,您说的CD中断信号线接GPG6,于是我的resource为默认
static struct resource s3c_hsmmc_resource[] = {
[0] = {
.start = S3C_PA_HSMMC0,
.end = S3C_PA_HSMMC0 + S3C_SZ_HSMMC - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_HSMMC0,
.end = IRQ_HSMMC0,
.flags = IORESOURCE_IRQ,
}
};
另外WP引脚接的是GPN9,我认为没有作用,所以没有管它。
内核启动之后显示
sdhci: Secure Digital Host Controller Interface driver
sdhci: Copyright(c) Pierre Ossman
s3c-sdhci s3c-sdhci.0: clock source 0: hsmmc (133000000 Hz)
s3c-sdhci s3c-sdhci.0: clock source 1: hsmmc (133000000 Hz)
s3c-sdhci s3c-sdhci.0: clock source 2: mmc_bus (24000000 Hz)
s3c6410_setup_sdhci0_cfg_card: CTRL 2=c0004100, 3=80808080
mmc0: SDHCI controller on samsung-hsmmc [s3c-sdhci.0] using ADMA
s3c6410_setup_sdhci0_cfg_card: CTRL 2=c0004100, 3=80808080
s3c6410_setup_sdhci0_cfg_card: CTRL 2=c0004100, 3=80808080
插入SD卡后显示
s3c6410_setup_sdhci0_cfg_card: CTRL 2=c0004100, 3=80808080
s3c6410_setup_sdhci0_cfg_card: CTRL 2=c0004100, 3=80808080
s3c6410_setup_sdhci0_cfg_card: CTRL 2=c0004100, 3=80808080
s3c6410_setup_sdhci0_cfg_card: CTRL 2=c0004100, 3=80808080
进入了中断,但没有正确识别SD卡
比较博创linux-2.6.21内核代码,以为是时钟不对。
SD卡的时钟部分我发现在启动时会调用s3c6410_map_io,它又会调用s3c6410_default_sdhci0();
其中s3c6410_hsmmc_clksrcs,s3c6410_setup_sdhci0_cfg_gpio,s3c6410_setup_sdhci0_cfg_card;都在定义在arch/arm/mach-s3c6410/setup-sdhci.c中,s3c6410_hsmmc_clksrcs就给出了时钟源。
static inline void s3c6410_default_sdhci0(void)
{
s3c_hsmmc0_def_platdata.clocks = s3c6410_hsmmc_clksrcs;
s3c_hsmmc0_def_platdata.cfg_gpio = s3c6410_setup_sdhci0_cfg_gpio;
s3c_hsmmc0_def_platdata.cfg_card = s3c6410_setup_sdhci0_cfg_card;
}
于是将博创linux-2.6.21内核arch/arm/mach-s3c6410/clock.c文件中的
static struct clk clk_hsmmc_DOUTmpll_mmc0 = {
.name = "sclk_DOUTmpll_mmc0",
.id = -1,
.parent = &clk_mpll_uart,
.enable = s3c_clkcon_enable,
.ctrlbit = S3C_CLKCON_SCLK_MMC0,
.get_rate = s3c6410_getrate_DOUTmpll_hsmmc_clk,
.usage = 0,
};
结构体经过一番努力的修改移植到了linux-2.6.29中,后指定s3c6410_hsmmc_clksrc时钟name为sclk_DOUTmpll_mmc0,重新启动后依旧进入中断,但无法识别真确SD卡。
无奈在sdhci-s3c.c的sdhci_s3c_probe()中加入调试代码,
printk(KERN_INFO "[in_probe]: %s.%d: at 0x%p with irq %d. clk src:",pdev->name, pdev->id, host->ioaddr, host->irq);
for (i=0; iclk_bus[i]))
printk(" %s", (sc->clk_bus[i])->name);
}
printk("n");
在drivers/mmc/host/sdhci.c的irqreturn_t sdhci_irq函数中加入
printk(KERN_ALERT "in sdhci_irqn");
printk(KERN_ALERT "*** %s got interrupt: 0x%08xn",mmc_hostname(host->mmc), intmask);
调试输出
[in_probe]: s3c-sdhci.0: at 0xc887e000 with irq 88. clk src: hsmmc sclk_DOUTmpll_mmc0
……
插入SD后显示
s3c6410_setup_sdhci0_cfg_card: CTRL 2=c0004100, 3=80808080
in sdhci_irq
*** mmc0 got interrupt: 0x00000001
s3c6410_setup_sdhci0_cfg_card: CTRL 2=c0004100, 3=80808080
in sdhci_irq
*** mmc0 got interrupt: 0x00018001
in sdhci_irq
*** mmc0 got interrupt: 0x00018001
in sdhci_irq
*** mmc0 got interrupt: 0x00018001
in sdhci_irq
*** mmc0 got interrupt: 0x00018001
in sdhci_irq
……
查阅s3c6410数据手册,NORINTSTS0的定义
0x8001的第15位为1,说明发生了错误,但我不知道错误在哪里?
注:后来我将driver下mmc整个文件夹删除,从linux-2.6.21下的mmc拷贝过来,将有关的的头文件,一并拷贝过来,经过一番修改,加入调试代码,驱动顺利加载,但却出现了同样的现象,能进入中断,但读取NORINTSTS0时的第15位都为1。
|
内核中的sdhci-s3c.c很强壮的。
可能的原因:如果是6410,GPG6不能同时做为MMC0与MMC1的CD线的。如果你板子中使用的s3c_device_hsmmc1,那GPG6是配置成MMC1的CD线的。
可能的原因:如果是6410,GPG6不能同时做为MMC0与MMC1的CD线的。如果你板子中使用的s3c_device_hsmmc1,那GPG6是配置成MMC1的CD线的。
|
崩提了,我调了两个星期,一张SD卡可以正常启动,两张就不行了,也就是只添加一个设备可以,你试试删掉一个试备。