linux设置sd卡密码,(续)linux SD卡初始化---mmc_sd_init_card函数

mmc_sd_init_card剩下的关于UHS-I的分支结构。linux

uhs-I的初始化流程图如图:app

0b3b36195a991f0c3a342d61c2f1581f.png

红线标出的部分是已经作了的事,与上一篇那个流程图是一致的,以后就是if分支中作的事。函数

if分支中的函数mmc_sd_init_uhs_card:ui

/** UHS-I specific initialization procedure*/

static int mmc_sd_init_uhs_card(struct mmc_card *card)

{interr;

u8*status;if (!card->scr.sda_spec3)//sd卡3.0版本才加入的UHS-I

return 0;if (!(card->csd.cmdclass & CCC_SWITCH))//判断是否支持class10命令,CMD6属于该类

return 0;

status= kmalloc(64, GFP_KERNEL);//CMD6的应答

if (!status) {

pr_err("%s: could not allocate a buffer for"

"switch capabilities.\n", mmc_hostname(card->host));return -ENOMEM;

}/*Set 4-bit bus width*/

if ((card->host->caps & MMC_CAP_4_BIT_DATA) &&//host是否支持4位数据线宽度

(card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) {//卡是否支持4位数据线宽度模式

err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4);//发送ACMD6切换.

if(err)goto out;

mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4);//host端的设置.

}/** Select the bus speed mode depending on host

* and card capability.*/sd_update_bus_speed_mode(card);/*这个函数是找一个card和host都支持的速度,相似上面对数据线宽度的操做,spec上有定义:

Bus Speed Mode (using 4 parallel data lines)

(1) Default Speed mode: 3.3V signaling, Frequency up to 25 MHz, up to 12.5 MB/sec

(2) High Speed mode: 3.3V signaling, Frequency up to 50 MHz, up to 25 MB/sec

(3) SDR12: UHS-I 1.8V signaling, Frequency up to 25 MHz, up to 12.5MB/sec

(4) SDR25: UHS-I 1.8V signaling, Frequency up to 50 MHz, up to 25MB/sec

(5) SDR50: UHS-I 1.8V signaling, Frequency up to 100 MHz, up to 50MB/sec

(6) SDR104: UHS-I 1.8V signaling, Frequency up to 208 MHz, up to 104MB/sec

(7) DDR50: UHS-I 1.8V signaling, Frequency up to 50 MHz, sampled on both clock edges, up to 50MB/sec

指望找到一个host和card支持的最快的速度.*/

/*Set the driver strength for the card*/err= sd_select_driver_type(card, status);/*driver strength在spec中没找到详细的说明,

spec中流程图里有这个步骤.这个也是3.0才增长的,sd卡这边切换用的是CMD6, driver strength属于CMD6的function group 3*/

if(err)goto out;/*Set current limit for the card*/err= sd_set_current_limit(card, status);/*这个函数里面注释比较清楚了,根据电压和速度模式,设置卡的最大功率,属于CMD6的function group 4*/

if(err)goto out;/*Set bus speed mode of the card*/err= sd_set_bus_speed_mode(card, status);/*设置速度,属于CMD6的function group 1*/

if(err)goto out;/*SPI mode doesn't define CMD19*/

if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning) {

mmc_host_clk_hold(card->host);

err= card->host->ops->execute_tuning(card->host,

MMC_SEND_TUNING_BLOCK);

mmc_host_clk_release(card->host);

}out:

kfree(status);returnerr;

}

linux并无发送CMD42,spec上原话:spa

“When entering tran state, CARD_IS_LOCKED status in the R1 response should be checked (it is indicated in the response of CMD7). If the card is locked, CMD42 is required to unlock the card. If the card is unlocked, CMD42 can be skipped.”3d

但linux好像并无检查,CMD7的返回值。没有搞懂,望知道的朋友指点一下。code

还有最后发送CMD19的步骤,Tuning,我简单理解为调整时钟让时序稳定。blog

if分支中还有几条语句,都是主机或驱动的操做,没有涉及到卡的操做。ip

关于UHS-I,linux中的初始化就到这里。ci

下面说说CMD6。这些内容都是spec中的,这里只是按个人理解简单整理。

在3.0以后的协议中,该命令功能增长了不少。CMD6是这个样子的:

b74bb1647d01b9dd9e3aa2c2812b660a.png

共有6组function group ,须要操做哪一个功能就把相应goup 的相应 bit置1。 各个group的bit定义以下:

0ba8631f4dd004101a9634908b6347bd.png

例如上面函数,要设置driver strenth

static int sd_select_driver_type(struct mmc_card *card, u8 *status)

{

。。。。。。

。。。。。。

err= mmc_sd_switch(card, 1, 2, drive_strength, status);if(err)returnerr;if ((status[15] & 0xF) !=drive_strength) {

pr_warning("%s: Problem setting drive strength!\n",

mmc_hostname(card->host));return mmc_set_driver_type(card->host, drive_strength);0;

}return 0;

}

调用mmc_sd_switch(card, 1, 2, drive_strength, status)函数,传入参数mode=1 group=2与表中相符(group参数从0开始),drive_strength就表示group 3的值,与表中相对应。

而后检查返回值,判断是否设置成功。 CMD6命令会从数据线而不是命令先接受一个512bit的应答值,这个值的具体定义在spec

Table 4-13: Status Data Structure。 这个表太大就不贴了。 须要注意的是表中定义与linux中收的数据字节顺序相反。status[0]是spec中的第504~511位。

mode 0和 mode 1

CMD6第31位表示该命令的两种模式,mode 0用来检查卡支持那些function group。 mode 1用来设置具体的function group的值。

发送mode 0 CMD6 ,可参考linux中mmc_read_switch()函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值