linux-SD驱动

发布于 2022-10-15 06:47:44 字数 6940 浏览 15 评论 0

我想在博创的6410上移植android,一基本完成,剩SD卡驱动和音频驱动,
用的飞凌改好的内核和文件系统
Linux-2.6.29SD卡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为默认

   1. static struct resource s3c_hsmmc_resource[] = {
   2.         [0] = {
   3.                 .start = S3C_PA_HSMMC0,
   4.                 .end = S3C_PA_HSMMC0 + S3C_SZ_HSMMC - 1,
   5.                 .flags = IORESOURCE_MEM,
   6.         },
   7.         [1] = {
   8.                 .start = IRQ_HSMMC0,
   9.                 .end   = IRQ_HSMMC0,
  10.                 .flags = IORESOURCE_IRQ,
  11.         }
  12. };

复制代码
另外WP引脚接的是GPN9,我认为没有作用,所以没有管它。

内核启动之后显示

   1. sdhci: Secure Digital Host Controller Interface driver
   2. sdhci: Copyright(c) Pierre Ossman
   3. s3c-sdhci s3c-sdhci.0: clock source 0: hsmmc (133000000 Hz)
   4. s3c-sdhci s3c-sdhci.0: clock source 1: hsmmc (133000000 Hz)
   5. s3c-sdhci s3c-sdhci.0: clock source 2: mmc_bus (24000000 Hz)
   6. s3c6410_setup_sdhci0_cfg_card: CTRL 2=c0004100, 3=80808080
   7. mmc0: SDHCI controller on samsung-hsmmc [s3c-sdhci.0] using ADMA
   8. s3c6410_setup_sdhci0_cfg_card: CTRL 2=c0004100, 3=80808080
   9. s3c6410_setup_sdhci0_cfg_card: CTRL 2=c0004100, 3=80808080

复制代码
插入SD卡后显示

   1. s3c6410_setup_sdhci0_cfg_card: CTRL 2=c0004100, 3=80808080
   2. s3c6410_setup_sdhci0_cfg_card: CTRL 2=c0004100, 3=80808080
   3. s3c6410_setup_sdhci0_cfg_card: CTRL 2=c0004100, 3=80808080
   4. s3c6410_setup_sdhci0_cfg_card: CTRL 2=c0004100, 3=80808080

复制代码
进入了中断,但没有正确识别SD卡

比较博创linux-2.6.21内核代码,以为是时钟不对。
SD卡的时钟部分我发现在启动时会调用s3c6410_map_io,它又会调用s3c6410_default_sdhci0();

   1. static inline void s3c6410_default_sdhci0(void)
   2. {
   3.         s3c_hsmmc0_def_platdata.clocks = s3c6410_hsmmc_clksrcs;
   4.         s3c_hsmmc0_def_platdata.cfg_gpio = s3c6410_setup_sdhci0_cfg_gpio;
   5.         s3c_hsmmc0_def_platdata.cfg_card = s3c6410_setup_sdhci0_cfg_card;
   6. }

复制代码
其中 s3c6410_hsmmc_clksrcs,s3c6410_setup_sdhci0_cfg_gpio,s3c6410_setup_sdhci0_cfg_card; 都在定义在arch/arm/mach-s3c6410/setup-sdhci.c中,s3c6410_hsmmc_clksrcs就给出了时钟源。

于是将博创linux-2.6.21内核arch/arm/mach-s3c6410/clock.c文件中的

   1. static struct clk clk_hsmmc_DOUTmpll_mmc0 = {
   2.         .name            = "sclk_DOUTmpll_mmc0",
   3.         .id                   = -1,
   4.         .parent          = &clk_mpll_uart,
   5.         .enable          = s3c_clkcon_enable,
   6.         .ctrlbit         = S3C_CLKCON_SCLK_MMC0,
   7.         .get_rate         = s3c6410_getrate_DOUTmpll_hsmmc_clk,
   8.         .usage           = 0,
   9. };

复制代码
结构体经过一番努力的修改移植到了linux-2.6.29中,后指定s3c6410_hsmmc_clksrc时钟name为sclk_DOUTmpll_mmc0,重新启动后依旧进入中断,但无法识别真确SD卡。

无奈在sdhci-s3c.c的sdhci_s3c_probe()中加入调试代码,

   1. printk(KERN_INFO "[in_probe]: %s.%d: at 0x%p with irq %d. clk src:",pdev->name, pdev->id, host->ioaddr, host->irq);
   2.         for (i=0; i<2; i++) {
   3.                 if (!IS_ERR(sc->clk_bus[i]))
   4.                         printk(" %s", (sc->clk_bus[i])->name);
   5.         }
   6.         printk("\n");

复制代码
在drivers/mmc/host/sdhci.c的irqreturn_t sdhci_irq函数中加入

   1. printk(KERN_ALERT "in sdhci_irq\n");
   2. printk(KERN_ALERT "*** %s got interrupt: 0x%08x\n",mmc_hostname(host->mmc), intmask);

复制代码
调试输出

   1. [in_probe]: s3c-sdhci.0: at 0xc887e000 with irq 88. clk src: hsmmc sclk_DOUTmpll_mmc0
   2. ……
   3. 插入SD后显示
   4. s3c6410_setup_sdhci0_cfg_card: CTRL 2=c0004100, 3=80808080
   5. in sdhci_irq
   6. *** mmc0 got interrupt: 0x00000001
   7. s3c6410_setup_sdhci0_cfg_card: CTRL 2=c0004100, 3=80808080
   8. in sdhci_irq
   9. *** mmc0 got interrupt: 0x00018001
  10. in sdhci_irq
  11. *** mmc0 got interrupt: 0x00018001
  12. in sdhci_irq
  13. *** mmc0 got interrupt: 0x00018001
  14. in sdhci_irq
  15. *** mmc0 got interrupt: 0x00018001
  16. in sdhci_irq
  17. ……

复制代码
查阅s3c6410数据手册,NORINTSTS0的定义
123.jpg
下载 (27.25 KB)
35 秒前

0x8001的第15位为1,说明发生了错误,但我不知道错误在哪里?

注:后来我将driver下mmc整个文件夹删除,从linux-2.6.21下的mmc拷贝过来,将有关的的头文件,一并拷贝过来,经过一番修改,加入调试代码,驱动顺利加载,但却出现了同样的现象,能进入中断,但读取NORINTSTS0时的第15位都为1。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文