2. MTK6737 7.0Accdetドライバー分析の要約
2 Mtk6737 7 0 Accdet Driver Analysis Summary
注:この記事は多くの場所で複製されており、ソースを見つけるのは困難です
1.関連する概念の紹介
1. EINT + ACCDET検出割り込み
EINT割り込み:主にヘッドセットのプラグインとプラグインの検出、つまりプラグインとプラグアウトに使用されます
ACCDET割り込み:主に、PLUG_OUT、PLUG_IN、MIC_BIAS(ヘッドセットのマイク)、HOOK_SWITCH(ヘッドセットボタン)など、ヘッドセットのイベントタイプを検出するために使用されます。
この方法を使用する場合は、マクロCONFIG_EINT_INT_IRQを開く必要があります
2.ヘッドセットボタンの検出
ヘッドセットボタンの原理図は以下のとおりです:
PMICには、さまざまなヘッドフォン電圧を読み取ることができる内部ADCチャネルがあります。さまざまなイベントタイプに対応する電圧は次のとおりです。
プラグアウト:1.77<=voltage<=1.9
マイクバイアス:0.5v<=voltage<1.77v
フックスイッチ:0v<=voltage<=0.5v
上記の3つの状態は、2ビットA = bit1、B = bit0によって判断されるACCDET_STATE_RGレジスタを介して取得され、上記の対応するイベントは次のとおりです。
プラグアウト:1.77<=voltage<=1.9 A=1,B=1,AB=3,
マイクバイアス:0.5v<=voltage<1.77v A=0,B=1,AB=1,
フックスイッチ:0v<=voltage<=0.5v A=0,B=0,AB=0,
その中で、フックスイッチには上、中、下のボタンがあり、対応する電圧は次のとおりです。
0v<=middle<=0.09v<=up<=0.24v<=down<=0.5v
第二に、ヘッドセットプラグインプロセス分析
ヘッドセットボタンを挿入すると、最初にEINT割り込みがトリガーされ、次にACCDET割り込みがトリガーされます。これらの2つの割り込みは、PMIC機能に登録され、PMIC終了割り込みに属します。
前述の2つの割り込み関数は、プローブ初期化関数に登録されています。これは割り込みの上部です:
- pmic_register_interrupt_callback(12、accdet_int_handler)
- pmic_register_interrupt_callback(13、accdet_eint_int_handler)
次に、上記の2つの割り込みの下半分に対応する、accdet_workとaccdet_eint_workの2つの作業キューが初期化されました。
1.全体的な一般的なプロセスは次のとおりです。特定のヘッドセットイベントの詰まりの検出は、次のフローチャートで紹介されます。
2.ここでは、MIC_BIASとHOOKSWITCHの2つの主要なイヤホンモードを紹介します。
A、MIC_BIASモード、つまりヘッドセットを接続した後のデフォルトモード、ステータスはPLUG_OUT -----> MIC_BIASから、メインコードは次のとおりです。
[cpp] プレーンビュー コピー
- 場合PLUG_OUT:
- #ifdef CONFIG_ACCDET_PIN_RECOGNIZATION
- pmic_pwrap_write(ACCDET_DEBOUNCE1、cust_headset_settings-> debounce1)
- #endif
- もし(current_status == 0){
- #ifdef CONFIG_ACCDET_PIN_RECOGNIZATION
- / *検出されたPIN認識中は常にmicbiasがオンになります* /
- pmic_pwrap_write(ACCDET_PWM_WIDTH、cust_headset_settings-> pwm_width)
- pmic_pwrap_write(ACCDET_PWM_THRESH、cust_headset_settings-> pwm_width)
- ACCDET_DEBUG('[Accdet] PIN認識micbiasは常にオンです! n')。
- ACCDET_DEBUG('[Accdet] adc読み取り前、pin_adc_value =%d mv! n'、pin_adc_value)
- msleep(500)
- current_status =((pmic_pwrap_read(ACCDET_STATE_RG)&0xc0)>> 6)/ * A = bit1 B = bit0 * /
- もし(current_status == 0 && show_icon_delay!= 0){
- / * accdet_auxadc_switch(1)auxadc読み取り電圧を使用する必要がある場合はオンに切り替えます* /
- pin_adc_value = Accdet_PMIC_IMM_GetOneChannelValue(1)
- ACCDET_DEBUG('[Accdet] pin_adc_value =%d mv! n'、pin_adc_value)
- / * accdet_auxadc_switch(0)* /
- もし(180> pin_adc_value && pin_adc_value> 90){/ * 90mvの違法ヘッドセット* /
- / * mt_set_gpio_out(GPIO_CAMERA_2_CMRST_PIN、GPIO_OUT_ONE)* /
- / * ACCDET_DEBUG( '[Accdet] PIN認識の変更GPIO_OUT! n')* /
- mutex_lock(&accdet_eint_irq_sync_mutex)
- もし(1 == eint_accdet_sync_flag){
- cable_type = HEADSET_NO_MIC
- accdet_status = HOOK_SWITCH
- cable_pin_recognition = 1
- ACCDET_DEBUG('[Accdet] cable_pin_recognition =%d n'、
- cable_pin_recognition)
- }そうしないと{{
- ACCDET_DEBUG('[Accdet]ヘッドセットがプラグアウトされました n')。
- }
- mutex_unlock(&accdet_eint_irq_sync_mutex)
- }そうしないと{{
- mutex_lock(&accdet_eint_irq_sync_mutex)
- もし(1 == eint_accdet_sync_flag){
- cable_type = HEADSET_NO_MIC
- accdet_status = HOOK_SWITCH
- }そうしないと{{
- ACCDET_DEBUG('[Accdet]ヘッドセットがプラグアウトされました n')。
- }
- mutex_unlock(&accdet_eint_irq_sync_mutex)
- }
- }
- #そうしないと
- mutex_lock(&accdet_eint_irq_sync_mutex)
- もし(1 == eint_accdet_sync_flag){
- cable_type = HEADSET_NO_MIC
- accdet_status = HOOK_SWITCH
- }そうしないと{{
- ACCDET_DEBUG('[Accdet]ヘッドセットがプラグアウトされました n')。
- }
- mutex_unlock(&accdet_eint_irq_sync_mutex)
- #endif
- }そうしないと もし(current_status == 1){
- mutex_lock(&accdet_eint_irq_sync_mutex)
- もし(1 == eint_accdet_sync_flag){
- accdet_status = MIC_BIAS
- cable_type = HEADSET_MIC
- #ifdef CONFIG_HEADSET_SUPPORT_FIVE_POLE
- msleep(20)
- もし(pmic_pwrap_read(0x0F46)&0x01){
- / * 5極ヘッドセットを確認* /
- ACCDET_DEBUG('[Accdet] 5極ヘッドセットを確認してください:はい n')。
- cable_type = HEADSET_FIVE_POLE
- }
- #endif
- / * AB = 11デバウンス= 30ms * /
- pmic_pwrap_write(ACCDET_DEBOUNCE3、cust_headset_settings-> debounce3 * 30)
- }そうしないと{{
- ACCDET_DEBUG('[Accdet]ヘッドセットがプラグアウトされました n')。
- }
- mutex_unlock(&accdet_eint_irq_sync_mutex)
- pmic_pwrap_write(ACCDET_DEBOUNCE0、button_press_debounce)
- / *ポーリングセットAB00-01を回復します* /
- #ifdef CONFIG_ACCDET_PIN_RECOGNIZATION
- pmic_pwrap_write(ACCDET_PWM_WIDTH、REGISTER_VALUE(cust_headset_settings-> pwm_width))
- pmic_pwrap_write(ACCDET_PWM_THRESH、REGISTER_VALUE(cust_headset_settings-> pwm_thresh))
- #endif
- }そうしないと もし(current_status == 3){
- ACCDET_DEBUG('[Accdet] PLUG_OUT状態は変更されません! n')。
- #ifdef CONFIG_ACCDET_EINT
- ACCDET_DEBUG('[Accdet]プラグアウトイベントをプラグアウトで送信しません n')。
- #そうしないと
- mutex_lock(&accdet_eint_irq_sync_mutex)
- もし(1 == eint_accdet_sync_flag){
- accdet_status = PLUG_OUT
- cable_type = NO_DEVICE
- }そうしないと{{
- ACCDET_DEBUG('[Accdet]ヘッドセットがプラグアウトされました n')。
- }
- mutex_unlock(&accdet_eint_irq_sync_mutex)
- #endif
- }そうしないと{{
- ACCDET_DEBUG('[Accdet] PLUG_OUTはこの状態に変更できません! n')。
- }
- ブレーク
b。 HOOK_SWITCHモード、つまり、ヘッドセットボタンが押された状態、ボタンを離したときの状態はMIC_BIAS -----> HOOK_SWITCHからです。HOOK_SWITCH -----> MIC_BIAS、主なコードは次のとおりです。
[cpp] プレーンビュー コピー
- 場合MIC_BIAS:
- / *解決策:フックスイッチのデバウンス時間を再開します* /
- pmic_pwrap_write(ACCDET_DEBOUNCE0、cust_headset_settings-> debounce0)
- もし(current_status == 0){
- mutex_lock(&accdet_eint_irq_sync_mutex)
- もし(1 == eint_accdet_sync_flag){
- 一方((pmic_pwrap_read(ACCDET_IRQ_STS)&IRQ_STATUS_BIT)
- &&(wait_clear_irq_times<3)) {
- ACCDET_DEBUG('[Accdet] check_cable_type:MIC BIAS clear IRQ on-going1 .... n')。
- wait_clear_irq_times ++
- msleep(20)
- }
- irq_temp = pmic_pwrap_read(ACCDET_IRQ_STS)
- irq_temp = irq_temp&(〜IRQ_CLR_BIT)
- pmic_pwrap_write(ACCDET_IRQ_STS、irq_temp)
- IRQ_CLR_FLAG =true
- accdet_status = HOOK_SWITCH
- }そうしないと{{
- ACCDET_DEBUG('[Accdet]ヘッドセットがプラグアウトされました n')。
- }
- mutex_unlock(&accdet_eint_irq_sync_mutex)
- button_status = 1
- もし(button_status){
- mutex_lock(&accdet_eint_irq_sync_mutex)
- もし(1 == eint_accdet_sync_flag)
- multi_key_detection(current_status)
- そうしないと
- ACCDET_DEBUG('[Accdet] multi_key_detection:ヘッドセットがプラグアウトされました n')。
- mutex_unlock(&accdet_eint_irq_sync_mutex)
- / * accdet_auxadc_switch(0)* /
- / * pwmの周波数とデューティを回復します* /
- pmic_pwrap_write(ACCDET_PWM_WIDTH、REGISTER_VALUE(cust_headset_settings-> pwm_width))
- pmic_pwrap_write(ACCDET_PWM_THRESH、REGISTER_VALUE(cust_headset_settings-> pwm_thresh))
- }
- }そうしないと もし(current_status == 1){
- mutex_lock(&accdet_eint_irq_sync_mutex)
- もし(1 == eint_accdet_sync_flag){
- accdet_status = MIC_BIAS
- cable_type = HEADSET_MIC
- ACCDET_DEBUG('[Accdet] MIC_BIASの状態は変更されません! n')。
- }そうしないと{{
- ACCDET_DEBUG('[Accdet]ヘッドセットがプラグアウトされました n')。
- }
- mutex_unlock(&accdet_eint_irq_sync_mutex)
- }そうしないと もし(current_status == 3){
- #if定義されたCONFIG_ACCDET_EINT ||定義されたCONFIG_ACCDET_EINT_IRQ
- ACCDET_DEBUG('[Accdet] micbiastでプラグouを送信しないでください n')。
- mutex_lock(&accdet_eint_irq_sync_mutex)
- もし(1 == eint_accdet_sync_flag)
- accdet_status = PLUG_OUT
- そうしないと
- ACCDET_DEBUG('[Accdet]ヘッドセットがプラグアウトされました n')。
- mutex_unlock(&accdet_eint_irq_sync_mutex)
- #そうしないと
- mutex_lock(&accdet_eint_irq_sync_mutex)
- もし(1 == eint_accdet_sync_flag){
- accdet_status = PLUG_OUT
- cable_type = NO_DEVICE
- }そうしないと{{
- ACCDET_DEBUG('[Accdet]ヘッドセットがプラグアウトされました n')。
- }
- mutex_unlock(&accdet_eint_irq_sync_mutex)
- #endif
- }そうしないと{{
- ACCDET_DEBUG('[Accdet] MIC_BIASはこの状態に変更できません! n')。
- }
- ブレーク
- 場合HOOK_SWITCH://ボタンを離した後
- もし(current_status == 0){
- mutex_lock(&accdet_eint_irq_sync_mutex)
- もし(1 == eint_accdet_sync_flag){
- / *ヘッドセットの01-> 00フレームワークを回避するために、オーディオのプレスキー情報が報告されます* /
- / * cable_type = HEADSET_NO_MIC * /
- / * accdet_status = HOOK_SWITCH * /
- ACCDET_DEBUG('[Accdet] HOOK_SWITCHの状態は変更されません! n')。
- }そうしないと{{
- ACCDET_DEBUG('[Accdet]ヘッドセットがプラグアウトされました n')。
- }
- mutex_unlock(&accdet_eint_irq_sync_mutex)
- }そうしないと もし(current_status == 1){
- mutex_lock(&accdet_eint_irq_sync_mutex)
- もし(1 == eint_accdet_sync_flag){
- multi_key_detection(current_status)
- accdet_status = MIC_BIAS
- cable_type = HEADSET_MIC
- }そうしないと{{
- ACCDET_DEBUG('[Accdet]ヘッドセットがプラグアウトされました n')。
- }
- mutex_unlock(&accdet_eint_irq_sync_mutex)
- / * accdet_auxadc_switch(0)* /
- #ifdef CONFIG_ACCDET_PIN_RECOGNIZATION
- cable_pin_recognition = 0
- ACCDET_DEBUG('[Accdet] cable_pin_recognition =%d n'、cable_pin_recognition)
- pmic_pwrap_write(ACCDET_PWM_WIDTH、REGISTER_VALUE(cust_headset_settings-> pwm_width))
- pmic_pwrap_write(ACCDET_PWM_THRESH、REGISTER_VALUE(cust_headset_settings-> pwm_thresh))
- #endif
- / *解決策:フックスイッチのデバウンス時間を0x400に短縮* /
- pmic_pwrap_write(ACCDET_DEBOUNCE0、button_press_debounce)
- }そうしないと もし(current_status == 3){
- #ifdef CONFIG_ACCDET_PIN_RECOGNIZATION
- cable_pin_recognition = 0
- ACCDET_DEBUG('[Accdet] cable_pin_recognition =%d n'、cable_pin_recognition)
- mutex_lock(&accdet_eint_irq_sync_mutex)
- もし(1 == eint_accdet_sync_flag)
- accdet_status = PLUG_OUT
- そうしないと
- ACCDET_DEBUG('[Accdet]ヘッドセットがプラグアウトされました n')。
- mutex_unlock(&accdet_eint_irq_sync_mutex)
- #endif
- #if定義されたCONFIG_ACCDET_EINT ||定義されたCONFIG_ACCDET_EINT_IRQ
- ACCDET_DEBUG('[Accdet]フックスイッチでプラグアウトイベントを送信しません n')。
- mutex_lock(&accdet_eint_irq_sync_mutex)
- もし(1 == eint_accdet_sync_flag)
- accdet_status = PLUG_OUT
- そうしないと
- ACCDET_DEBUG('[Accdet]ヘッドセットがプラグアウトされました n')。
- mutex_unlock(&accdet_eint_irq_sync_mutex)
- #そうしないと
- mutex_lock(&accdet_eint_irq_sync_mutex)
- もし(1 == eint_accdet_sync_flag){
- accdet_status = PLUG_OUT
- cable_type = NO_DEVICE
- }そうしないと{{
- ACCDET_DEBUG('[Accdet]ヘッドセットがプラグアウトされました n')。
- }
- mutex_unlock(&accdet_eint_irq_sync_mutex)
- #endif
- }そうしないと{{
- ACCDET_DEBUG('[Accdet] HOOK_SWITCHはこの状態に変更できません! n')。
- }
- ブレーク
コードに対応するヘッドホンキーの処理フローは以下のとおりです。
3.まとめ
ヘッドセットのキー処理は主に2つの割り込みEINT + ACCDETに依存し、キー検出は内部ADC検出に依存します。重要なイベントを報告する場合、プレスとリリースはsend_key_eventを介して報告する必要があります。