最近遇到sdio设备无法识别问题,一直解决不掉很痛苦,好在最终解决,分享下
用的是有WIFI和BT功能的芯片,WIFI采用sdio接口,由WL_EN控制上电;BT是UART接口,由BT_EN控制上电;
首先sdio属于mmc子系统中设备,mmc子系统包括:sdio,sd,mmc
sdio设备在加载driver之前,首先得被mmc子系统识别到,才能进行后续操作
static const unsigned freqs[] = { 400000, 300000, 200000, 100000 };
void mmc_rescan(struct work_struct *work)
{
......
for (i = 0; i < ARRAY_SIZE(freqs); i++) {
if (!mmc_rescan_try_freq(host, max(freqs[i], host->f_min))) {
extend_wakelock = true;
break;
}
if (freqs[i] <= host->f_min)
break;
}
......
}
之后按照sdio(CMD5),sd,mmc的顺序扫描,一旦扫到立即返回
static int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq)
{
......
/*
* sdio_reset sends CMD52 to reset card. Since we do not know
* if the card is being re-initialized, just send it. CMD52
* should be ignored by SD/eMMC cards.
*/
sdio_reset(host);
mmc_go_idle(host);
mmc_send_if_cond(host, host->ocr_avail);
/* Order's important: probe SDIO, then SD, then MMC */
if (!mmc_attach_sdio(host))
return 0;
if (!mmc_attach_sd(host))
return 0;
if (!mmc_attach_mmc(host))
return 0;
mmc_power_off(host);
return -EIO;
}
如果成功检测到设备,便会进行后续的mmc_sdio_init_card和mmc_add_card,进行建立设备节点等操作
检测到设备的check方式:
以上都check过后,sdio设备依然对CMD52和CMD没有response,于是做了下面的实验
用示波器量开机时候的波形,确认是否有信号出来;结果是发现开机过程中是有信号的,正常开完机就没有了
(黄色SDIO_CLK,蓝色SDIO_CMD),所以猜测这个信号可能是host端发给sdio设备的检测信号,但sdio是否有回复呢?
可以用逻辑分析仪看一下结果,逻辑分析仪用法可以参考上篇博文https://blog.csdn.net/miss_lazygoat/article/details/84105304
截取一段逻辑分析仪的结果来看,全是从host端发出的cmd,没有slave的回应,CMD52也是符合预期的
Time [s] | Value |
1.96874275 | START |
1.9687453 | DIR:from Host |
1.9687478 | CMD:52 |
1.968763 | ARG:0x00 |
1.9688441 | CRC:0x1C |
1.96886185 | STOP |
1.9696981 | START |
1.96970065 | DIR:from Host |
1.96970315 | CMD:52 |
1.96971835 | ARG:0x08 |
1.96979945 | CRC:0x4F |
1.9698172 | STOP |
1.9719129 | START |
1.9719154 | DIR:from Host |
既然能确认host端已发送检测命令,没有response就是slave端的问题了,给芯片供应商去排查就好了。
最后发现问题所在:WL_EN和BT_EN需同时拉高模组才能正常工作(由于模块bug),之后sdio便能正常被识别了
<7>[ 8.261000] mmc0: req failed (CMD5): -110, retrying...
<7>[ 8.261000] dwmmc_balong 900ae000.dwmmc1: start command: ARGR=0x00000000 CMDR=0x20000045 CMD(5)
<6>[ 8.261000] ftyreset module initialized.
<6>[ 8.261000] [HWLOCK] drv verify simlock init ok!
<7>[ 8.262000] mmc0: req done (CMD5): -110: 00000000 00000000 00000000 00000000
<7>[ 8.262000] mmc0: starting CMD55 arg 00000000 flags 000000f5
<7>[ 8.262000] dwmmc_balong 900ae000.dwmmc1: start command: ARGR=0x00000000 CMDR=0x20000177 CMD(55)
<6>[ 8.263000] SIO data mode[0], clk mode[1], clk rate[2048000]
<7>[ 8.263000] mmc0: req done (CMD55): -110: 00000000 00000000 00000000 00000000
<7>[ 8.410000] mmc0: starting CMD52 arg 00227800 flags 00000195
<7>[ 8.410000] dwmmc_balong 900ae000.dwmmc1: start command: ARGR=0x00227800 CMDR=0x20000174 CMD(52)
<7>[ 8.410000] mmc0: req done (CMD52): 0: 00001082 00000000 00000000 00000000
<7>[ 8.410000] mmc0: starting CMD52 arg 00227a00 flags 00000195
<7>[ 8.410000] dwmmc_balong 900ae000.dwmmc1: start command: ARGR=0x00227a00 CMDR=0x20000174 CMD(52)
<7>[ 8.410000] mmc0: req done (CMD52): 0: 00001001 00000000 00000000 00000000
<7>[ 8.410000] mmc0: starting CMD52 arg 00227c00 flags 00000195
<7>[ 8.410000] dwmmc_balong 900ae000.dwmmc1: start command: ARGR=0x00227c00 CMDR=0x20000174 CMD(52)
<7>[ 8.410000] mmc0: req done (CMD52): 0: 000010df 00000000 00000000 00000000
<4>[ 8.410000] mmc0: queuing unknown CIS tuple 0x82 (1 bytes)
<7>[ 8.410000] mmc0: starting CMD52 arg 00227e00 flags 00000195
<7>[ 8.410000] dwmmc_balong 900ae000.dwmmc1: start command: ARGR=0x00227e00 CMDR=0x20000174 CMD(52)
<7>[ 8.410000] mmc0: req done (CMD52): 0: 000010ff 00000000 00000000 00000000
<6>[ 8.410000] mmc0: new SDIO card at address 0001