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つの割り込み関数は、プローブ初期化関数に登録されています。これは割り込みの上部です:

[cpp] プレーンビュー コピー
  1. pmic_register_interrupt_callback(12、accdet_int_handler)
  2. 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] プレーンビュー コピー
  1. 場合PLUG_OUT:
  2. #ifdef CONFIG_ACCDET_PIN_RECOGNIZATION
  3. pmic_pwrap_write(ACCDET_DEBOUNCE1、cust_headset_settings-> debounce1)
  4. #endif
  5. もし(current_status == 0){
  6. #ifdef CONFIG_ACCDET_PIN_RECOGNIZATION
  7. / *検出されたPIN認識中は常にmicbiasがオンになります* /
  8. pmic_pwrap_write(ACCDET_PWM_WIDTH、cust_headset_settings-> pwm_width)
  9. pmic_pwrap_write(ACCDET_PWM_THRESH、cust_headset_settings-> pwm_width)
  10. ACCDET_DEBUG('[Accdet] PIN認識micbiasは常にオンです! n')。
  11. ACCDET_DEBUG('[Accdet] adc読み取り前、pin_adc_value =%d mv! n'、pin_adc_value)
  12. msleep(500)
  13. current_status =((pmic_pwrap_read(ACCDET_STATE_RG)&0xc0)>> 6)/ * A = bit1 B = bit0 * /
  14. もし(current_status == 0 && show_icon_delay!= 0){
  15. / * accdet_auxadc_switch(1)auxadc読み取り電圧を使用する必要がある場合はオンに切り替えます* /
  16. pin_adc_value = Accdet_PMIC_IMM_GetOneChannelValue(1)
  17. ACCDET_DEBUG('[Accdet] pin_adc_value =%d mv! n'、pin_adc_value)
  18. / * accdet_auxadc_switch(0)* /
  19. もし(180> pin_adc_value && pin_adc_value> 90){/ * 90mvの違法ヘッドセット* /
  20. / * mt_set_gpio_out(GPIO_CAMERA_2_CMRST_PIN、GPIO_OUT_ONE)* /
  21. / * ACCDET_DEBUG( '[Accdet] PIN認識の変更GPIO_OUT! n')* /
  22. mutex_lock(&accdet_eint_irq_sync_mutex)
  23. もし(1 == eint_accdet_sync_flag){
  24. cable_type = HEADSET_NO_MIC
  25. accdet_status = HOOK_SWITCH
  26. cable_pin_recognition = 1
  27. ACCDET_DEBUG('[Accdet] cable_pin_recognition =%d n'
  28. cable_pin_recognition)
  29. }そうしないと{{
  30. ACCDET_DEBUG('[Accdet]ヘッドセットがプラグアウトされました n')。
  31. }
  32. mutex_unlock(&accdet_eint_irq_sync_mutex)
  33. }そうしないと{{
  34. mutex_lock(&accdet_eint_irq_sync_mutex)
  35. もし(1 == eint_accdet_sync_flag){
  36. cable_type = HEADSET_NO_MIC
  37. accdet_status = HOOK_SWITCH
  38. }そうしないと{{
  39. ACCDET_DEBUG('[Accdet]ヘッドセットがプラグアウトされました n')。
  40. }
  41. mutex_unlock(&accdet_eint_irq_sync_mutex)
  42. }
  43. }
  44. #そうしないと
  45. mutex_lock(&accdet_eint_irq_sync_mutex)
  46. もし(1 == eint_accdet_sync_flag){
  47. cable_type = HEADSET_NO_MIC
  48. accdet_status = HOOK_SWITCH
  49. }そうしないと{{
  50. ACCDET_DEBUG('[Accdet]ヘッドセットがプラグアウトされました n')。
  51. }
  52. mutex_unlock(&accdet_eint_irq_sync_mutex)
  53. #endif
  54. }そうしないと もし(current_status == 1){
  55. mutex_lock(&accdet_eint_irq_sync_mutex)
  56. もし(1 == eint_accdet_sync_flag){
  57. accdet_status = MIC_BIAS
  58. cable_type = HEADSET_MIC
  59. #ifdef CONFIG_HEADSET_SUPPORT_FIVE_POLE
  60. msleep(20)
  61. もし(pmic_pwrap_read(0x0F46)&0x01){
  62. / * 5極ヘッドセットを確認* /
  63. ACCDET_DEBUG('[Accdet] 5極ヘッドセットを確認してください:はい n')。
  64. cable_type = HEADSET_FIVE_POLE
  65. }
  66. #endif
  67. / * AB = 11デバウンス= 30ms * /
  68. pmic_pwrap_write(ACCDET_DEBOUNCE3、cust_headset_settings-> debounce3 * 30)
  69. }そうしないと{{
  70. ACCDET_DEBUG('[Accdet]ヘッドセットがプラグアウトされました n')。
  71. }
  72. mutex_unlock(&accdet_eint_irq_sync_mutex)
  73. pmic_pwrap_write(ACCDET_DEBOUNCE0、button_press_debounce)
  74. / *ポーリングセットAB00-01を回復します* /
  75. #ifdef CONFIG_ACCDET_PIN_RECOGNIZATION
  76. pmic_pwrap_write(ACCDET_PWM_WIDTH、REGISTER_VALUE(cust_headset_settings-> pwm_width))
  77. pmic_pwrap_write(ACCDET_PWM_THRESH、REGISTER_VALUE(cust_headset_settings-> pwm_thresh))
  78. #endif
  79. }そうしないと もし(current_status == 3){
  80. ACCDET_DEBUG('[Accdet] PLUG_OUT状態は変更されません! n')。
  81. #ifdef CONFIG_ACCDET_EINT
  82. ACCDET_DEBUG('[Accdet]プラグアウトイベントをプラグアウトで送信しません n')。
  83. #そうしないと
  84. mutex_lock(&accdet_eint_irq_sync_mutex)
  85. もし(1 == eint_accdet_sync_flag){
  86. accdet_status = PLUG_OUT
  87. cable_type = NO_DEVICE
  88. }そうしないと{{
  89. ACCDET_DEBUG('[Accdet]ヘッドセットがプラグアウトされました n')。
  90. }
  91. mutex_unlock(&accdet_eint_irq_sync_mutex)
  92. #endif
  93. }そうしないと{{
  94. ACCDET_DEBUG('[Accdet] PLUG_OUTはこの状態に変更できません! n')。
  95. }
  96. ブレーク

b。 HOOK_SWITCHモード、つまり、ヘッドセットボタンが押された状態、ボタンを離したときの状態はMIC_BIAS -----> HOOK_SWITCHからです。HOOK_SWITCH -----> MIC_BIAS、主なコードは次のとおりです。
[cpp] プレーンビュー コピー
  1. 場合MIC_BIAS:
  2. / *解決策:フックスイッチのデバウンス時間を再開します* /
  3. pmic_pwrap_write(ACCDET_DEBOUNCE0、cust_headset_settings-> debounce0)
  4. もし(current_status == 0){
  5. mutex_lock(&accdet_eint_irq_sync_mutex)
  6. もし(1 == eint_accdet_sync_flag){
  7. 一方((pmic_pwrap_read(ACCDET_IRQ_STS)&IRQ_STATUS_BIT)
  8. &&(wait_clear_irq_times<3)) {
  9. ACCDET_DEBUG('[Accdet] check_cable_type:MIC BIAS clear IRQ on-going1 .... n')。
  10. wait_clear_irq_times ++
  11. msleep(20)
  12. }
  13. irq_temp = pmic_pwrap_read(ACCDET_IRQ_STS)
  14. irq_temp = irq_temp&(〜IRQ_CLR_BIT)
  15. pmic_pwrap_write(ACCDET_IRQ_STS、irq_temp)
  16. IRQ_CLR_FLAG =true
  17. accdet_status = HOOK_SWITCH
  18. }そうしないと{{
  19. ACCDET_DEBUG('[Accdet]ヘッドセットがプラグアウトされました n')。
  20. }
  21. mutex_unlock(&accdet_eint_irq_sync_mutex)
  22. button_status = 1
  23. もし(button_status){
  24. mutex_lock(&accdet_eint_irq_sync_mutex)
  25. もし(1 == eint_accdet_sync_flag)
  26. multi_key_detection(current_status)
  27. そうしないと
  28. ACCDET_DEBUG('[Accdet] multi_key_detection:ヘッドセットがプラグアウトされました n')。
  29. mutex_unlock(&accdet_eint_irq_sync_mutex)
  30. / * accdet_auxadc_switch(0)* /
  31. / * pwmの周波数とデューティを回復します* /
  32. pmic_pwrap_write(ACCDET_PWM_WIDTH、REGISTER_VALUE(cust_headset_settings-> pwm_width))
  33. pmic_pwrap_write(ACCDET_PWM_THRESH、REGISTER_VALUE(cust_headset_settings-> pwm_thresh))
  34. }
  35. }そうしないと もし(current_status == 1){
  36. mutex_lock(&accdet_eint_irq_sync_mutex)
  37. もし(1 == eint_accdet_sync_flag){
  38. accdet_status = MIC_BIAS
  39. cable_type = HEADSET_MIC
  40. ACCDET_DEBUG('[Accdet] MIC_BIASの状態は変更されません! n')。
  41. }そうしないと{{
  42. ACCDET_DEBUG('[Accdet]ヘッドセットがプラグアウトされました n')。
  43. }
  44. mutex_unlock(&accdet_eint_irq_sync_mutex)
  45. }そうしないと もし(current_status == 3){
  46. #if定義されたCONFIG_ACCDET_EINT ||定義されたCONFIG_ACCDET_EINT_IRQ
  47. ACCDET_DEBUG('[Accdet] micbiastでプラグouを送信しないでください n')。
  48. mutex_lock(&accdet_eint_irq_sync_mutex)
  49. もし(1 == eint_accdet_sync_flag)
  50. accdet_status = PLUG_OUT
  51. そうしないと
  52. ACCDET_DEBUG('[Accdet]ヘッドセットがプラグアウトされました n')。
  53. mutex_unlock(&accdet_eint_irq_sync_mutex)
  54. #そうしないと
  55. mutex_lock(&accdet_eint_irq_sync_mutex)
  56. もし(1 == eint_accdet_sync_flag){
  57. accdet_status = PLUG_OUT
  58. cable_type = NO_DEVICE
  59. }そうしないと{{
  60. ACCDET_DEBUG('[Accdet]ヘッドセットがプラグアウトされました n')。
  61. }
  62. mutex_unlock(&accdet_eint_irq_sync_mutex)
  63. #endif
  64. }そうしないと{{
  65. ACCDET_DEBUG('[Accdet] MIC_BIASはこの状態に変更できません! n')。
  66. }
  67. ブレーク
  68. 場合HOOK_SWITCH://ボタンを離した後
  69. もし(current_status == 0){
  70. mutex_lock(&accdet_eint_irq_sync_mutex)
  71. もし(1 == eint_accdet_sync_flag){
  72. / *ヘッドセットの01-> 00フレームワークを回避するために、オーディオのプレスキー情報が報告されます* /
  73. / * cable_type = HEADSET_NO_MIC * /
  74. / * accdet_status = HOOK_SWITCH * /
  75. ACCDET_DEBUG('[Accdet] HOOK_SWITCHの状態は変更されません! n')。
  76. }そうしないと{{
  77. ACCDET_DEBUG('[Accdet]ヘッドセットがプラグアウトされました n')。
  78. }
  79. mutex_unlock(&accdet_eint_irq_sync_mutex)
  80. }そうしないと もし(current_status == 1){
  81. mutex_lock(&accdet_eint_irq_sync_mutex)
  82. もし(1 == eint_accdet_sync_flag){
  83. multi_key_detection(current_status)
  84. accdet_status = MIC_BIAS
  85. cable_type = HEADSET_MIC
  86. }そうしないと{{
  87. ACCDET_DEBUG('[Accdet]ヘッドセットがプラグアウトされました n')。
  88. }
  89. mutex_unlock(&accdet_eint_irq_sync_mutex)
  90. / * accdet_auxadc_switch(0)* /
  91. #ifdef CONFIG_ACCDET_PIN_RECOGNIZATION
  92. cable_pin_recognition = 0
  93. ACCDET_DEBUG('[Accdet] cable_pin_recognition =%d n'、cable_pin_recognition)
  94. pmic_pwrap_write(ACCDET_PWM_WIDTH、REGISTER_VALUE(cust_headset_settings-> pwm_width))
  95. pmic_pwrap_write(ACCDET_PWM_THRESH、REGISTER_VALUE(cust_headset_settings-> pwm_thresh))
  96. #endif
  97. / *解決策:フックスイッチのデバウンス時間を0x400に短縮* /
  98. pmic_pwrap_write(ACCDET_DEBOUNCE0、button_press_debounce)
  99. }そうしないと もし(current_status == 3){
  100. #ifdef CONFIG_ACCDET_PIN_RECOGNIZATION
  101. cable_pin_recognition = 0
  102. ACCDET_DEBUG('[Accdet] cable_pin_recognition =%d n'、cable_pin_recognition)
  103. mutex_lock(&accdet_eint_irq_sync_mutex)
  104. もし(1 == eint_accdet_sync_flag)
  105. accdet_status = PLUG_OUT
  106. そうしないと
  107. ACCDET_DEBUG('[Accdet]ヘッドセットがプラグアウトされました n')。
  108. mutex_unlock(&accdet_eint_irq_sync_mutex)
  109. #endif
  110. #if定義されたCONFIG_ACCDET_EINT ||定義されたCONFIG_ACCDET_EINT_IRQ
  111. ACCDET_DEBUG('[Accdet]フックスイッチでプラグアウトイベントを送信しません n')。
  112. mutex_lock(&accdet_eint_irq_sync_mutex)
  113. もし(1 == eint_accdet_sync_flag)
  114. accdet_status = PLUG_OUT
  115. そうしないと
  116. ACCDET_DEBUG('[Accdet]ヘッドセットがプラグアウトされました n')。
  117. mutex_unlock(&accdet_eint_irq_sync_mutex)
  118. #そうしないと
  119. mutex_lock(&accdet_eint_irq_sync_mutex)
  120. もし(1 == eint_accdet_sync_flag){
  121. accdet_status = PLUG_OUT
  122. cable_type = NO_DEVICE
  123. }そうしないと{{
  124. ACCDET_DEBUG('[Accdet]ヘッドセットがプラグアウトされました n')。
  125. }
  126. mutex_unlock(&accdet_eint_irq_sync_mutex)
  127. #endif
  128. }そうしないと{{
  129. ACCDET_DEBUG('[Accdet] HOOK_SWITCHはこの状態に変更できません! n')。
  130. }
  131. ブレーク

コードに対応するヘッドホンキーの処理フローは以下のとおりです。


3.まとめ

ヘッドセットのキー処理は主に2つの割り込みEINT + ACCDETに依存し、キー検出は内部ADC検出に依存します。重要なイベントを報告する場合、プレスとリリースはsend_key_eventを介して報告する必要があります