SD/MMC子系统之一——插卡、检测
一、SDHCI與控制器驅動
SDHC:Secure Digital(SD) Host Controller,是指一套sd host控制器的設計標準,其寄存器偏移以及意義都有一定的規范,并且提供了對應的驅動程序,方便vendor進行host controller的開發。
廠商按照這套標準設計host controller之后,可以直接使用sdhci driver來實現host controller的使用,(qcom和samsung都使用了這套標準)。而vendor只需要實現平臺相關的部分、如clock、pinctrl、power等等的部分即可。
關于這個標準,可以參考《SDHC_Ver3.00_Final_110225》。
注意,強調一下,這是一種mmc host controller的設計標準,其本質上還是屬于mmc host。并且,其兼容mmc type card,而不是說只能使用于sd type card。
SDHCI:Secure Digital(SD) Host Controller Interface,是針對SDHC標準的驅動接口。
其常見接口如:
sdhci_pltfm_init:平臺設備SDHCI初始化,主要是分配、設置sdhci_host,最終關聯到platform_device的device
sdhci_alloc_host:分配sdhci_host
mmc_alloc_host:分配、設置mmc_host(卡檢測的掃描工作隊列)
sdhci_add_host:設置sdhci_host,關聯到mmc_host,并注冊mmc_host
sdhci_setup_host:設置sdhci_host
二、卡檢測的初始化:
自定義SDHC驅動初始化調用platform_driver_register平臺注冊用戶platform_driver。
其中自定義SDHC驅動的probe會分配sdhci_host、sdhci_pltfm_host內存,并對sdhci_host進行設置
然后進行關聯mmc_host、sdhci_host、sdhci_pltfm_host。
然后調用SDHCI接口sdhci_add_host,將得到的sdhci_host注冊到sdhci core中。
SDHCI接口sdhci_add_host會設置sdhci_host,并調用下級__sdhci_add_host。
SDHCI接口__sdhci_add_host:
設置請求處理完成時調用的任務隊列處理函數sdhci_tasklet_finish
設置當前請求命令的響應定時處理函數sdhci_timeout_timer
設置當前數據交互的響應定時sdhci_timeout_data_timer
設置等待隊列的緩沖區讀準備中斷
設置sdhci_host
設置外部中斷
注冊LE燈
調用mmc_add_host
使能卡檢測sdhci_enable_card_detection
其中mmc_add_host會添加設備類,調用mmc_start_host開啟主機,并注冊電源管理通知。
其中mmc_claim_host聲明獨占主機,設置電源,使用host->slot.handler_priv->cd_gpio注冊線程化中斷,執行一次卡檢測_mmc_detect_change。
注意:其中SD插拔經常出現一個打印問題“mmcblk1: error -110 sending status command, aborting”
其實問題原因:
二、卡檢測的執行:
因為在啟動主機時會執行卡檢測,但是這里也不一定會檢測成功,因為有可能沒插卡。
除了SDHC驅動以外,還會編寫一份控制器驅動,比如海思的himci。
自定義控制器驅動初始化調用platform_driver_register平臺注冊用戶platform_driver。
其中自定義SDHC驅動的probe會分配、設置自定義主機屬性,其中卡檢測函數有三種使用情況:
1)自定義主機屬性的mmc_host_ops的get_cd函數
2)自定義主機屬性的card_status函數
3)自定義主機屬性的定時器
其中通常插卡檢測是由定時器的處理函數檢測到的,定時器處理函數的流程為:
1)通過卡檢測寄存器或者IO,連續檢查5次SD卡狀態,相同則繼續,否則重復100次。(次數均為自定義)
2)如果5次相同則判斷其值是否為插入,如果是插入則軟復位,初始化自定義主機屬性,調用MMC子系統API的mmc_detect_change。
mmc_detect_change調用_mmc_detect_change,兩者的區別為電源管理是否喚醒事件,默認為有
_mmc_detect_change會判斷如果設備被配置為喚醒,我們將防止新的休眠5秒,以便為用戶提供使用事件的空間。
然后設置mmc_host->detect_change為1,檢測更改
然后調用mmc_schedule_delayed_work調度工作隊列
mmc_schedule_delayed_work會調用queue_delayed_work執行system_freezable_wq的工作隊列,其中使用system_freezable_wq的原因有2個:
1)它允許同時執行多個工作(不是相同的工作項)。
2)當用戶空間在系統PM期間凍結時,隊列將凍結。
而此處的工作任務為mmc_alloc_host中設置的INIT_DELAYED_WORK(&host->detect, mmc_rescan);
所以,這里跳轉到mmc_rescan
mmc_rescan:
根據mmc_host->rescan_disable判斷是否允許掃描,如果為真則不允許直接退出。
根據mmc_host->cap判斷是否為不可移動的已注冊卡只掃描一次還是可以繼續掃描。
設置mmc_host->rescan_entered=1,表示進入掃描
調用mmc_bus_get遞增總線操作計數
調用mmc_rescan_try_freq,以四種頻率進行初始化SDIO SD EMMC
mmc_rescan_try_freq:
設置mmc_host->f_init,根據mmc_recan函數傳進來的頻率參數,一般mmc/sd/sdio的初始化時鐘采用的是400kHZ.
調用mmc_power_up,進行上電。在mmc_add_host時,會調用mmc_start_host,而那里首先是將host掉電的,所以這里上電。
調用mmc_hw_reset_for_init,有些emmc (VCCQ總是開著的)可能在通電后無法復位,所以如果可能的話,可以進行硬件復位。
根據不同卡做不同的操作:
1)純SD卡,則目標卡不會應答,一般主機host的寄存器會報錯,但是這個無關緊要,可以不理它。
2)純SDIO卡,那么這里就是復位SDIO卡,通過發送命令CMD52來實現的。
3)SD卡和SDIO卡的組合卡,則需要先發送CMD52來復位SDIO卡,再復位SD卡,因為CMD52要先于CMD0發送。
調用mmc_go_idle,發送CMD0,復位SD卡,進入IDLE模式
調用mmc_send_if_cond,如果是SD卡,則發送CMD8 獲取支持的電壓值
根據不同卡做不同的卡檢測操作:
1)SDIO卡,調用mmc_attach_sdio
2)SD卡,調用mmc_attach_sd
3)MMC卡,調用mmc_attach_mmc
4)都不是,則調用mmc_power_off進行下電
此處以SD卡為例,所以只看mmc_attach_sd
總結
以上是生活随笔為你收集整理的SD/MMC子系统之一——插卡、检测的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PCA的原理及MATLAB实现
- 下一篇: 《数据结构》08-图7 公路村村通(最小