楼上莫非是李总?
我周末特地查了查代码。而且编译内核做了实验。
在linux中,MMC的检测方式有几种:
linux/arch/arm/plat-s3c/include/plat/sdhci.h
enum cd_types {
S3C_SDHCI_CD_INTERNAL, /* use mmc internal CD line */
S3C_SDHCI_CD_EXTERNAL, /* use external callback */
S3C_SDHCI_CD_GPIO, /* use external gpio pin for CD line */
S3C_SDHCI_CD_NONE, /* no CD line, use polling to detect card */
S3C_SDHCI_CD_PERMANENT, /* no CD line, card permanently wired to host */
};
从这个觅类型的定义,我初步认为,nCD0管脚,是没有外部输入信号出触发的。应该是内部或者其他方式。然后我跟踪到了
linux/arch/arm/plat-s3c64xx/setup-sdhci-gpio.c
void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
{
struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
unsigned int gpio;
unsigned int end;
end = S3C64XX_GPG(2 + width);
/* Set all the necessary GPG pins to special-function 0 */
for (gpio = S3C64XX_GPG(0); gpio < end; gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) { //就是这里,根据检测类型设置cd线的寄存器值
s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP);
s3c_gpio_cfgpin(S3C64XX_GPG(6), S3C_GPIO_SFN(2));
}
}
再往后面跟踪,设备初始化是在
linux/arch/arm/mach-s3c64xx/mach-mini6410.c
static struct platform_device *mini6410_devices[] __initdata = {
#ifdef CONFIG_MINI6410_SD_CH0
&s3c_device_hsmmc0,
#endif
#ifdef CONFIG_MINI6410_SD_CH1
&s3c_device_hsmmc1,
#endif
……
};
static void __init mini6410_machine_init(void)
{
….
platform_add_devices(mini6410_devices, ARRAY_SIZE(mini6410_devices));
}
在这里定义了设备数组,并且在启动的时候逐个加入到系统中。我在其中做了跟踪,MMC0的cd_type是S3C_SDHCI_CD_INTERNAL,MMC1的cd_type是S3C_SDHCI_CD_PERMANENT。
后面我又在driver的probe中跟踪了cd_type,还是如此。就我粗浅的分析看,6410的nCD线路应该不是外部触发,而是通过某种机制转换之后,在其内部引发了中断。
如果我理解有误,还希望有人指点。
