SD卡概率性不识别

当遇到一些质量不是很好的sdcard,可能多次suspend & resume的操作后,某一次resume可能会失败,看到的现象就是当手机唤醒后会看到sdcard移除或者重新插入sdcard的提示,一般处理方式都是先加强下SD的pin脚驱动能力,如下

	msdc1_pins_default: msdc1@default {
		pins_cmd {
			drive-strength = /bits/ 8 <3>;
		};
		pins_dat {
			drive-strength = /bits/ 8 <3>;
		};
		pins_clk {
			drive-strength = /bits/ 8 <4>;
		};
	};

现在主要介绍的是另外一个解决思路,在resume失败后,重新再给卡power off -> power on-> reinit

/kernel-3.10/drivers/mmc/core/core.c 添加函数mmc_power_cycle_special()

void mmc_power_cycle(struct mmc_host *host)
{
        mmc_power_off(host);

        /* Wait at least 1 ms according to SD spec */

        mmc_delay(1);

        mmc_power_up(host);
}

void mmc_power_cycle_special(struct mmc_host *host)
{

        mmc_power_off(host);

        /* Wait at least 1 ms according to SD spec */

        mmc_delay(20);

        mmc_power_up(host);

        mmc_delay(20);
}

/kernel-3.10/drivers/mmc/core/sd.c mmc_sd_resume 函数err时调用mmc_power_cycle_special重新初始化

extern void mmc_power_cycle_special(struct mmc_host *host);
static int mmc_sd_resume(struct mmc_host *host)
{

    int err;

#ifdef CONFIG_MMC_PARANOID_SD_INIT

    int retries;

#endif

    BUG_ON(!host);

    BUG_ON(!host->card);

    mmc_claim_host(host);

#ifdef 1

 retries = 3;//modify by blogger

 while (retries) {
         err = mmc_sd_init_card(host, host->ocr, host->card);

      if (err) {
                  printk(KERN_ERR "%s: Re-init card rc = %d (retries = %d)\n",

                      mmc_hostname(host), err, retries);

                 mdelay(5);

                  retries--;

                       mmc_power_cycle_special(host);//add  by blogger

                continue;
          }
       break;
   }

#else
   err = mmc_sd_init_card(host, host->ocr, host->card);
#endif

 mmc_release_host(host);

return err;
}

现在kernel-4.4 MTK平台有个专门针对此类的问题的宏控处理,CONFIG_MMC_PARANOID_SD_INIT, 请搜索该关键字宏控,参考代码如下,

static int _mmc_sd_resume(struct mmc_host *host)
{
	int err = 0;
#ifdef CONFIG_MMC_PARANOID_SD_INIT
	int retries;
#endif

	BUG_ON(!host);
	BUG_ON(!host->card);

	mmc_claim_host(host);

	if (!mmc_card_suspended(host->card))
		goto out;

	mmc_power_up(host, host->card->ocr);
#ifdef CONFIG_MMC_PARANOID_SD_INIT
	retries = 5;
	while (retries) {
		err = mmc_sd_init_card(host, host->card->ocr, host->card);

		if (err) {
			printk(KERN_ERR "%s: Re-init card rc = %d (retries = %d)\n",
			       mmc_hostname(host), err, retries);
			mdelay(5);
			retries--;
			continue;
		}
		break;
	}
#else
	err = mmc_sd_init_card(host, host->card->ocr, host->card);
#endif
	mmc_card_clr_suspended(host->card);

out:
	mmc_release_host(host);
	return err;
}
static void mmc_sd_detect(struct mmc_host *host)
{
	int err = 0;
#ifdef CONFIG_MMC_PARANOID_SD_INIT
	int retries = 5;
#endif

	BUG_ON(!host);
	BUG_ON(!host->card);

	mmc_get_card(host->card);

	/*
	 * Just check if our card has been removed.
	 */
#ifdef CONFIG_MMC_PARANOID_SD_INIT
	while(retries) {
		err = mmc_send_status(host->card, NULL);
		if (err) {
			retries--;
			udelay(5);
			continue;
		}
		break;
	}
	if (!retries) {
		printk(KERN_ERR "%s(%s): Unable to re-detect card (%d)\n",
		       __func__, mmc_hostname(host), err);
	}
#else
	err = _mmc_detect_card_removed(host);
#endif

	mmc_put_card(host->card);

	if (err) {
		mmc_sd_remove(host);

		mmc_claim_host(host);
		mmc_detach_bus(host);
		mmc_power_off(host);
		mmc_release_host(host);
	}
}
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值