耳機插拔/線控按鍵識別流程
1.文檔概述
本文以msm8909平臺,android N爲例,介紹了通用情況下,耳機插拔的流程步驟,以及對耳機類型的識別邏輯。以方便在項目工作中經常會遇到耳機不被識別,或者識別後不能正常工作等情況,都可以參考此文檔檢測判斷邏輯,確定問題根本,理解底層框架。
2.耳機的類型
從主觀來看,耳機分三段耳機和四段耳機,而四段耳機又分爲歐標和美標兩種。通常,四段耳機被寫作headset,而三段耳機寫作headphones。具體的區別如下圖:
- 三段耳機:線序分別爲,L、R、G,沒有MIC端,所以三段耳機無法使用mic,只能接受聲音,另外,三段耳機L,R線序長度正常,G端比較長
- 四段-美標(CTIA)耳機:線序分別爲L,R,G,M,第三階爲GND
- 四段-歐標(OMTP)耳機:線序分別爲L,R,M,G,第四段爲GND
如想兼容兩種不同類型的耳機:
有以下方式可以選擇:
- 增加硬件兼容支持兩種耳機
- 使用轉接線
在軟件上,除了上述情況以外,還有一些外設設備會鏈接到耳機接孔,比如:自拍杆,外接音箱,TTY設備或者AUX延長線等,在軟件上,對這些額外的設備進行了一個分類,如下枚舉:
enum wcd_mbhc_plug_type { MBHC_PLUG_TYPE_INVALID = -1, // ——無效設備 MBHC_PLUG_TYPE_NONE, // ——未接入設備 MBHC_PLUG_TYPE_HEADSET, // ——四段耳機 MBHC_PLUG_TYPE_HEADPHONE, // ——三段耳機 MBHC_PLUG_TYPE_HIGH_HPH, // ——高阻抗耳機 MBHC_PLUG_TYPE_GND_MIC_SWAP, //——歐美標標誌位 };
可以在log中檢索如下樣例,確認目前MBHC耳機狀態類型
wcd_mbhc_find_plug_and_report: entercurrent_plug(1) new_plug(2)
除了上述以外,還有一種LINE_OUT設備,如AUX延長線,以上幾種情況都是一些本身比較特別的耳機接口,當然LINE_OUT本身也屬於一種特殊的HIGH_HPH設備,其中比較普遍的如iphone的耳機屬於HIGH_HPH設備。
個人經驗,在插入自拍杆和編寫音箱球的時候,從LOG上看,是被識別成headset處理的。但音箱球是個很特殊的設備,電阻超過我們閥值很多,歐標配置的手機可能適用這個設備。在PIXI445TF上插入音箱球后有圖標,但卻無法正常使用。這樣的情況的原因是,爲們增大了識別的閥值,但平臺卻不支持這樣的設備造成。
2.1 如何區分歐標和美標耳機
通常在國內有一些簡單的區分方式,比如依照中間的橡膠圈來區分,白色是美標,黑色素歐標(國內大部分廠商都使用歐標,所以也有把OMTP叫做國標)。PS:這種說法僅作參考,因爲黑色橡膠圈的美標耳機也有很多
區分美標或者歐標,可以簡單的用萬能表來測量耳機電阻,確定線序中的GND是在第三段或者第四段,具體方法不再贅述。喇叭單元(第一二節)到地電阻通常是16~32歐姆,找到哪一節是地線就知道是什麼耳機。
2.2 對耳機的檢測
Qcom對耳機的檢測是在wcd_mbhc_v2.c中進行,在耳機接孔中存在一個detced引腳,用於檢測是否有設備接入,具體接入的設備,會根據對micbias的電壓等參數來做判斷,下面會做詳細介紹。
目前市面上耳機的阻抗不同,大都在32歐姆左右,driver會根據不同電阻來配置不同響度,在void wcd_imped_config()
函數中會有這樣的邏輯。
從目前來看,這個閥值需要調節至36,因爲如果以32作爲臨界值,會有很多客戶發現部分耳機使用起來音量大小差異較大(差了4.5db)。
以iphone的耳機,接入設備有執行以下流程,如下流程圖:
以上步驟分別註釋:
- 耳機插入後會產生中斷,確認事件,但在接入時候可能會由GND接觸MIC端造成硬件短路等情況,所以需要在接入時候進行一個2s的延遲(qcom默認是0.5s)來確認是耳機插入事件,而不是btn事件。這點可以用於優化個別耳機接入後自動出現音量調節的問題。
- 中斷中進入第一次耳機類型檢測代碼:
static void wcd_mbhc_detect_plug_type(struct wcd_mbhc *mbhc)
- 第一次耳機類型檢測代碼處理:在50ms內反覆讀取0x1580x159的兩個寄存器的值,(注意這兩個寄存器的值是跟HS_VREF threshold 的設置有關)
- 第一次耳機類型檢測代碼處理:確認檢測出來0x158 0x159寄存器值是否等於(0 ,0)
- 如果0x158和0x159的值爲(0,0)說明是類型是耳機,直接上報給上層
- 若寄存器值是(0,1),說明是高阻態耳機類型
- 進入第二次耳機類型檢測代碼(
static void wcd_correct_swch_plug(struct work_struct *work)
)。 - 同時確認耳機不是歐標/美標,在
static int wcd_check_cross_conn(struct wcd_mbhc *mbhc)
中,如果確認不支持某款,可以在該函數開始直接return false
。 - 同時在3s內讀取0x159,0x158的寄存器的值,再進行判斷
- 如果讀取出來的數值仍然爲(0,1),說明結果仍然是高阻抗耳機
- 進入特殊耳機檢測(
static bool wcd_is_special_headset(struct wcd_mbhc *mbhc)
) - 特殊耳機檢測(
wcd_is_special_headset
)會在2S內反覆檢測0x158 0x159寄存器值,並且擡高mic bais相關電壓,正常情況電壓會在1.5V左右,此時進行擡高會將電壓增加到2.7V左右 - 將電壓擡到一定程度讀出0x158 0x159寄存器值繼續確認是否爲(0 ,0)
- 讀出0x158 0x159寄存器值是(0 ,1),說明是高阻態設備,會進行上報處理後上報
以上結果,如果以目前手機情況,插入一個iphone的高阻抗耳機,大約需要7s左右才能正常識別到耳機,請留意該情況。
2.3 LINE_OUT DEVICE ERROR
由於個別LINE_OUT設備電阻太大造成的不識別問題,可以通過修改v_hs_max的參考電壓來增加識別機率,qcom默認爲1.5V,通常會增加到1.7V。qcom默認支持設備的電阻範圍是在5k歐,但個別設備遠遠超過這個閥值,如AUX cable達到了2W+歐,移動音箱球達到了0.6M歐,可以修改linein_th的閥值來增加識別範圍,建議最大設置爲3W,否則會造成很多額外設備能夠被識別成耳機,但卻無法使用的問題。
3.耳機線控按鍵
通常耳機上的線控按鈕會有一個或者三個,如果HOOK,音量+,音量-(音量調節的按鈕只在部分耳機上會有,如TF運營商目前的標準僅支持一個HOOK按鍵)
HOOK的作用是由上層負責,底層只需要確保上報了對應的HOOK event給上層。
線控按鈕的按鍵檢測,在驅動中,會在如下的static void* def_msm8x16_wcd_mbhc_cal
函數中進行閥值的設置:
/* * In SW we are maintaining two sets of threshold register * one for current source and another for Micbias. * all btn_low corresponds to threshold for current source * all bt_high corresponds to threshold for Micbias * Below thresholds are based on following resistances * 0-70 == Button 0 * 110-180 == Button 1 * 210-290 == Button 2 * 360-680 == Button 3 */
值得注意到是,其中btn_low和btn_high的設定是對不同供電而言,Low對應Current Source的分壓,High對應Mic Bias的分壓,而這兩種供電方式取決於應用場景的不同,採取不同的供電,分壓值對應做不同的設置,如下代碼中判斷
btn_voltage =((is_micbias) ? btn_high : btn_low);
按鍵識別與耳機上btn[4]的閥值設置有關。由於我們的標配耳機mic阻值(300mV電壓偏置下等效阻抗1.2Kohm)較小,current模式的時候vmic上電壓較低,和btn[4]的範圍有重疊,所以按Hook key的時候容易產生btn[4]的事件,雖然btn[4]沒有用到,但是會影響到hook key的狀態
軟件的具體改動是把除了要用的兩個鍵,其他的閥值都設成了300, 保證不會誤按鍵產生,另外,鑑於很多自拍杆在按鍵都是觸發btn2的情況,btn2需要適配自拍杆。
耳機按鍵硬件原理
上圖是耳機MIc線控板的原理簡化圖,圖中方框內是耳機內線控板mic和按鍵的等效電路,右側是手機內的Mic接口偏置電路。
3.1.1 MIC的工作原理
在分壓電阻R和MIC兩端加DC偏置電壓V,MOS管與MIC_BIAS電阻R(推薦2.2Kohm)分壓,Mic電容振膜在接收聲波振動時兩端會產生微弱的電壓變化,經過MOS管的放大腳放大後,Pin4與Pin3兩端分的電壓也會相應變化,此時採集到的交變信號就是音頻的信號Output到手機Mic in端。
MIC2_P 爲MIC輸入及耳機按鍵功能檢測,按鍵檢測用於監測 耳機線控板按鍵,通過ADC檢測電壓範圍(根據上面5主btn閥值)來識別是哪一種按鍵事件,實現對應的功能。關於按鍵識別ADC電壓檢測,可以參考Idol 4上的設置(高通平臺):
值得注意到是:
推薦手機端 V_mic bias爲DC 2.8V,R_mic bias爲2.2K ohm,調整系統內部btn(MIC2_P端)檢測的電壓範圍閥值與 實際耳機一致;
其中,如果針對每個按鈕去做計算,btn後的值計算公式如下:
因爲高通平臺在MIC未工作時,會降低V_micbias的電壓值到幾百mV級,經過偏置電阻R(2.2K)和MIC分壓輸入到 HS_DET端的電壓如果不在 hook範圍,會導致觸發音量+/-等其它事件。
高通有一片文檔,專門講這個分區應該如何調試,文檔名:application_note__multibutton_headset_control.pdf