在ALSA架構中,ASOC是由3個部分組成:Platform、CODEC & Machine。而耳機檢測一般是在Machine driver里實現,當然也可以在CODEC driver里實現。耳機插拔接口Jack的結構圖如圖1所示(iPhone和Nokia耳機MIC & GROUND正好相反)。
圖1.Jack結構圖
耳機檢測信號HP_DET#可以通過以下有兩種方式傳遞到SOC端:
1.直接將HP_DET#信號接到SOC端;
2.將HP_DET#信號先接到CODEC端,再有CODEC端GPIO/IRQ引腳將信號傳送到SOC端;
若要實現方法2,需要在CODEC driver端進行一系列的配置,比如給COEDC端耳機檢測引腳JD#上電、GPIO/IRQ輸出用做JD#狀態檢測 & IRQ Debounce Clock選擇Interal Clock等,這樣才能開啟CODEC端HP_DET#信號的接收和中斷信號的上報。
同樣的,在Machine driver中也要做以下3個操作:
1.定義一個類型為“snd_soc_jack_gpios”的結構體變量hs_gpio,該變量是用來配置用於耳機檢測的gpio。hs_gpio結構體中初始化該gpio的name、report、debounce_time、jack_status_check & irq_flags等結構體變量,其中name表示gpio的名字;report表示會上報的狀態種類,一共有HEADSET、HEADPHONE & BUTTON;debounce_time表示防抖動時延;jack_status_check表示中中處理函數;irq_flags表示中斷處理函數是上升沿觸發還是下降沿觸發。
1 static struct snd_soc_jack_gpio hs_gpio[] = { 2 [HSDET] = { 3 .name = "AUDIOCODEC_INT", 4 .report = SND_JACK_HEADSET | SND_JACK_HEADPHONE | SND_JACK_BTN_0, 5 .debounce_time = 100, 6 .jack_status_check = jack_gpio_detect_bp, 7 .irq_flags = IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, 8 }, 9 };
2.通過snd_soc_jack_new()函數新建一個新的jack,將該jack指向Machine對應的CODEC,使該jack與CODEC建立聯系。
3.通過snd_soc_jack_add_gpios()函數將定義好的GPIO pins與ASoC jack聯系起來,並實現GPIO pins的中斷申請irq_request & 通過snd_jack_report上報jack_status。
總結,實現kernel層耳機檢測,主要是通過系統release出來的函數接口實現GPIO pins的配置、GPIO pins與CODEC建立聯系 & GPIO pins與ASoC建立聯系這3部分組成。
【參考文章:http://blog.csdn.net/piaozhiye/article/details/25101891】