H、 mmc_select_card通过RCA选择sdio设备;
cmd,Arg:0x10000, Cmd:7 /* cmd7的参数只有[31:16]为RCA,其它无效 */
cmd resp, 0:0x1e00, 1:0x7 /* response为Status Register */
response bit[12:9]值为0Fh:CURRENT_STATE,
For an I/O only card, the current state shall be fixed at a value of 0Fh.
I、 sdio_read_cccr读取cccr、Card Capability寄存器:
cmd,Arg:0x0, Cmd:52 /* 读取寄存器cccr */
cmd resp, 0:0x1032, 1:0x34
response bit[13:12] IO_CURRENT_STATE: 0x01,cmd state
response bit[7:4] sdio version: 0x3,version 2.00
response bit[3:0] CCCR Format Version: 0x2 version 2.00
cmd,Arg:0x1000, Cmd:52 /* 读取Card Capability寄存器 */
cmd resp, 0:0x1002, 1:0x34
response bit[1] Support Multiple Block Transfer: 0x1 支持
根据CCCR Format Version >= 2.0,再读取12h(Power Control),13h(Bus Speed Select)寄存器;
cmd,Arg:0x2400, Cmd:52 /* 读取12h(Power Control) */
cmd resp, 0:0x1001, 1:0x34
response bit[0] Support Master Power Control:
The total card power may exceed 720mW
cmd,Arg:0x2600, Cmd:52 /* 读取13h(Bus Speed Select) */
cmd resp, 0:0x1001, 1:0x34
response bit[0] Support High-Speed: 0x1,支持;
response bit[4:2] Bus Speed Select: 0x0,默认最高速率25MHz;
High-speed下速率值:
J、 sdio_read_common_cis读取CIS;
先读取Common CIS Pointer
cmd,Arg:0x1200, Cmd:52 /* 读寄存器9 */
cmd resp, 0:0x1070, 1:0x34
cmd,Arg:0x1400, Cmd:52 /* 读寄存器A */
cmd resp, 0:0x1010, 1:0x34
cmd,Arg:0x1600, Cmd:52 /* 读寄存器B */
cmd resp, 0:0x1000, 1:0x34
从3个response中得到Common CIS Pointer:0x1070;
接着从地址0x1070读取CIS数据。
内核代码只解析tuple code为0x15(cistpl_vers_1),0x20(cistpl_manfid), 0x22(cistpl_funce),其中0x22(cistpl_funce)中只解析type为0x0(cistpl_funce_common)、type为0x1(cistpl_funce_func)的数据。至于其它的CIS数据,在后续设备驱动代码中回重新再读一次,再由设备驱动使用。在这里只列出0x20(cistpl_manfid)的读取。
cmd,Arg:0x20e000, Cmd:52 /* 读取寄存器0x1070 */
cmd resp, 0:0x1020, 1:0x34 /* 返回tuple code:0x20 */
cmd,Arg:0x20e200, Cmd:52 /* 读取寄存器0x1071 */
cmd resp, 0:0x1004, 1:0x34 /* 返回tuple 长度:0x04 */
cmd,Arg:0x20e400, Cmd:52 /* 读取寄存器0x1072 */
cmd resp, 0:0x10d0, 1:0x34 /* 返回vendor id低8bit:0xd0 */
cmd,Arg:0x20e600, Cmd:52 /* 读取寄存器0x1073 */
cmd resp, 0:0x1002, 1:0x34 /* 返回vendor id高8bit:0x02 */
cmd,Arg:0x20e800, Cmd:52 /* 读取寄存器0x1074 */
cmd resp, 0:0x10a6, 1:0x34 /* 返回device id低8bit:0xa6 */
cmd,Arg:0x20ea00, Cmd:52 /* 读取寄存器0x1075 */
cmd resp, 0:0x10a9, 1:0x34 /* 返回device id高8bit:0xa9 */
从上面的读取值,vendor id:0x02d0, device id:0xa9a6;
接着读取function 0的cis.blksize,cis.max_dtr。
当读到tuple code为0x00时,表示没有tuple内容,继续往下读,当读到tuple code为0xFF时,表示整个CIS内容结束了。
K、 接着sdio_enable_hs切换到high-speed;
cmd,Arg:0x2600, Cmd:52 /* 读取寄存器0x13 */
cmd resp, 0:0x1001, 1:0x34 /* 支持high-speed */
cmd,Arg:0x80002603, Cmd:52 /* 设置寄存器0x13,最高速率50MHz */
cmd resp, 0:0x1003, 1:0x34
L、 设置控制器clock,调用sdio_enable_4bit_bus设置sdio设备bus width,再设置控制器的bus width;
cmd,Arg:0xe00, Cmd:52 /* 读取寄存器0x7 */
cmd resp, 0:0x1040, 1:0x34 /* 支持8bit模式,当前为1bit模式 */
cmd,Arg:0x80000e42, Cmd:52 /* 写寄存器0x7,设置为4bit模式 */
cmd resp, 0:0x1042, 1:0x34
到这里,mmc_sdio_init_card初始化完成,接下来进行sdio设备 function的初始化,function的初始化由sdio_init_func函数完成,每一个function调用一次。这里扫描的sdio设备有2个function,会调用2次sdio_init_func。
M、 sdio_init_func函数中先sdio_read_fbr,读取fbr;
cmd,Arg:0x20000, Cmd:52
/* 读取寄存器0x100,即function 1的fbr寄存器0 */
cmd resp, 0:0x1000, 1:0x34
response bit[6] 0x0:不支持CSA;
response bit[3:0] 0x0:
No SDIO standard interface supported by this function;
bit[3:0]各个值对应的含义;
N、 接着调用sdio_read_func_cis读取function的CIS;
读取function的CIS与前面sdio_read_common_cis读取CIS是一样的流程,只是读取CIS的地址不同,CIS的内容也不同而已。
其中一个很重要的参数是:func->max_blksize;
同时如果读到vendor id,device id,就保存在function的结构中,若没读到,就从card->cis.vendor、card->cis.device(sdio_read_common_cis读出来的)copy过来,
到这里,sdio设备的扫描就完成了,接着会调用mmc_add_card增加sdio设备,调用sdio_add_func增加function设备,这样整个扫描过程就完成了。