ASoC: wcd-mbhc: update electrical removal detection logic
when moisture is in jack, removing of the plug result in electrical removal interrupt. So, update electrical interrupt handler to handle mechanical removal based on moisture status. CRs-Fixed: 2058106 Change-Id: I9cfbfbaf04783f0edcadb14d7828759020745289 Signed-off-by: Meng Wang <mwang@codeaurora.org>
This commit is contained in:
parent
7cc0186011
commit
6f90162f22
6 changed files with 148 additions and 29 deletions
|
@ -895,6 +895,8 @@ static irqreturn_t wcd_mbhc_adc_hs_rem_irq(int irq, void *data)
|
|||
struct wcd_mbhc *mbhc = data;
|
||||
unsigned long timeout;
|
||||
int adc_threshold, output_mv, retry = 0;
|
||||
bool hphpa_on = false;
|
||||
u8 moisture_status = 0;
|
||||
|
||||
pr_debug("%s: enter\n", __func__);
|
||||
WCD_MBHC_RSC_LOCK(mbhc);
|
||||
|
@ -928,17 +930,59 @@ static irqreturn_t wcd_mbhc_adc_hs_rem_irq(int irq, void *data)
|
|||
goto exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* ADC COMPLETE and ELEC_REM interrupts are both enabled for HEADPHONE,
|
||||
* need to reject the ADC COMPLETE interrupt which follows ELEC_REM one
|
||||
* when HEADPHONE is removed.
|
||||
*/
|
||||
if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADPHONE)
|
||||
mbhc->extn_cable_hph_rem = true;
|
||||
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_DETECTION_DONE, 0);
|
||||
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_MODE, 0);
|
||||
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_EN, 0);
|
||||
wcd_mbhc_elec_hs_report_unplug(mbhc);
|
||||
if (mbhc->mbhc_cfg->moisture_en) {
|
||||
if (mbhc->mbhc_cb->hph_pa_on_status)
|
||||
if (mbhc->mbhc_cb->hph_pa_on_status(mbhc->codec)) {
|
||||
hphpa_on = true;
|
||||
WCD_MBHC_REG_UPDATE_BITS(
|
||||
WCD_MBHC_HPHL_PA_EN, 0);
|
||||
WCD_MBHC_REG_UPDATE_BITS(
|
||||
WCD_MBHC_HPH_PA_EN, 0);
|
||||
}
|
||||
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPHR_GND, 1);
|
||||
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPHL_GND, 1);
|
||||
/* wait for 50ms to get moisture status */
|
||||
usleep_range(50000, 50100);
|
||||
|
||||
WCD_MBHC_REG_READ(WCD_MBHC_MOISTURE_STATUS, moisture_status);
|
||||
}
|
||||
|
||||
if (mbhc->mbhc_cfg->moisture_en && !moisture_status) {
|
||||
pr_debug("%s: moisture present in jack\n", __func__);
|
||||
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_L_DET_EN, 0);
|
||||
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_MECH_DETECTION_TYPE, 1);
|
||||
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_L_DET_EN, 1);
|
||||
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 0);
|
||||
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_BTN_ISRC_CTL, 0);
|
||||
mbhc->btn_press_intr = false;
|
||||
mbhc->is_btn_press = false;
|
||||
if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADSET)
|
||||
wcd_mbhc_report_plug(mbhc, 0, SND_JACK_HEADSET);
|
||||
else if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADPHONE)
|
||||
wcd_mbhc_report_plug(mbhc, 0, SND_JACK_HEADPHONE);
|
||||
else if (mbhc->current_plug == MBHC_PLUG_TYPE_GND_MIC_SWAP)
|
||||
wcd_mbhc_report_plug(mbhc, 0, SND_JACK_UNSUPPORTED);
|
||||
else if (mbhc->current_plug == MBHC_PLUG_TYPE_HIGH_HPH)
|
||||
wcd_mbhc_report_plug(mbhc, 0, SND_JACK_LINEOUT);
|
||||
} else {
|
||||
/*
|
||||
* ADC COMPLETE and ELEC_REM interrupts are both enabled for
|
||||
* HEADPHONE, need to reject the ADC COMPLETE interrupt which
|
||||
* follows ELEC_REM one when HEADPHONE is removed.
|
||||
*/
|
||||
if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADPHONE)
|
||||
mbhc->extn_cable_hph_rem = true;
|
||||
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_DETECTION_DONE, 0);
|
||||
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_MODE, 0);
|
||||
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_EN, 0);
|
||||
wcd_mbhc_elec_hs_report_unplug(mbhc);
|
||||
|
||||
if (hphpa_on) {
|
||||
hphpa_on = false;
|
||||
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPHL_PA_EN, 1);
|
||||
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPH_PA_EN, 1);
|
||||
}
|
||||
}
|
||||
exit:
|
||||
WCD_MBHC_RSC_UNLOCK(mbhc);
|
||||
pr_debug("%s: leave\n", __func__);
|
||||
|
|
|
@ -794,6 +794,8 @@ static irqreturn_t wcd_mbhc_hs_rem_irq(int irq, void *data)
|
|||
unsigned long timeout;
|
||||
bool removed = true;
|
||||
int retry = 0;
|
||||
bool hphpa_on = false;
|
||||
u8 moisture_status = 0;
|
||||
|
||||
pr_debug("%s: enter\n", __func__);
|
||||
|
||||
|
@ -830,29 +832,78 @@ static irqreturn_t wcd_mbhc_hs_rem_irq(int irq, void *data)
|
|||
WCD_MBHC_REG_READ(WCD_MBHC_HS_COMP_RESULT, hs_comp_result);
|
||||
|
||||
if (removed) {
|
||||
if (!(hphl_sch && mic_sch && hs_comp_result)) {
|
||||
/*
|
||||
* extension cable is still plugged in
|
||||
* report it as LINEOUT device
|
||||
*/
|
||||
goto report_unplug;
|
||||
if (mbhc->mbhc_cfg->moisture_en) {
|
||||
if (mbhc->mbhc_cb->hph_pa_on_status)
|
||||
if (
|
||||
mbhc->mbhc_cb->hph_pa_on_status(mbhc->codec)) {
|
||||
hphpa_on = true;
|
||||
WCD_MBHC_REG_UPDATE_BITS(
|
||||
WCD_MBHC_HPHL_PA_EN, 0);
|
||||
WCD_MBHC_REG_UPDATE_BITS(
|
||||
WCD_MBHC_HPH_PA_EN, 0);
|
||||
}
|
||||
|
||||
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPHR_GND, 1);
|
||||
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPHL_GND, 1);
|
||||
/* wait for 50ms to get moisture status */
|
||||
usleep_range(50000, 50100);
|
||||
|
||||
WCD_MBHC_REG_READ(
|
||||
WCD_MBHC_MOISTURE_STATUS, moisture_status);
|
||||
}
|
||||
|
||||
if (mbhc->mbhc_cfg->moisture_en && !moisture_status) {
|
||||
pr_debug("%s: moisture present in jack\n", __func__);
|
||||
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_L_DET_EN, 0);
|
||||
WCD_MBHC_REG_UPDATE_BITS(
|
||||
WCD_MBHC_MECH_DETECTION_TYPE, 1);
|
||||
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_L_DET_EN, 1);
|
||||
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 0);
|
||||
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_BTN_ISRC_CTL, 0);
|
||||
mbhc->btn_press_intr = false;
|
||||
mbhc->is_btn_press = false;
|
||||
if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADSET)
|
||||
wcd_mbhc_report_plug(
|
||||
mbhc, 0, SND_JACK_HEADSET);
|
||||
else if (mbhc->current_plug ==
|
||||
MBHC_PLUG_TYPE_HEADPHONE)
|
||||
wcd_mbhc_report_plug(
|
||||
mbhc, 0, SND_JACK_HEADPHONE);
|
||||
else if (mbhc->current_plug ==
|
||||
MBHC_PLUG_TYPE_GND_MIC_SWAP)
|
||||
wcd_mbhc_report_plug(
|
||||
mbhc, 0, SND_JACK_UNSUPPORTED);
|
||||
else if (mbhc->current_plug ==
|
||||
MBHC_PLUG_TYPE_HIGH_HPH)
|
||||
wcd_mbhc_report_plug(
|
||||
mbhc, 0, SND_JACK_LINEOUT);
|
||||
} else {
|
||||
if (!mic_sch) {
|
||||
mic_trigerred++;
|
||||
pr_debug("%s: Removal MIC trigerred %d\n",
|
||||
__func__, mic_trigerred);
|
||||
}
|
||||
if (!hphl_sch) {
|
||||
hphl_trigerred++;
|
||||
pr_debug("%s: Removal HPHL trigerred %d\n",
|
||||
__func__, hphl_trigerred);
|
||||
}
|
||||
if (mic_trigerred && hphl_trigerred) {
|
||||
if (!(hphl_sch && mic_sch && hs_comp_result)) {
|
||||
/*
|
||||
* extension cable is still plugged in
|
||||
* report it as LINEOUT device
|
||||
*/
|
||||
goto report_unplug;
|
||||
} else {
|
||||
if (!mic_sch) {
|
||||
mic_trigerred++;
|
||||
pr_debug(
|
||||
"%s: Removal MIC trigerred %d\n",
|
||||
__func__, mic_trigerred);
|
||||
}
|
||||
if (!hphl_sch) {
|
||||
hphl_trigerred++;
|
||||
pr_debug(
|
||||
"%s: Removal HPHL trigerred %d\n",
|
||||
__func__, hphl_trigerred);
|
||||
}
|
||||
if (mic_trigerred && hphl_trigerred) {
|
||||
/*
|
||||
* extension cable is still plugged in
|
||||
* report it as LINEOUT device
|
||||
*/
|
||||
goto report_unplug;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -863,6 +914,11 @@ static irqreturn_t wcd_mbhc_hs_rem_irq(int irq, void *data)
|
|||
|
||||
report_unplug:
|
||||
wcd_mbhc_elec_hs_report_unplug(mbhc);
|
||||
if (hphpa_on) {
|
||||
hphpa_on = false;
|
||||
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPHL_PA_EN, 1);
|
||||
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPH_PA_EN, 1);
|
||||
}
|
||||
hphl_trigerred = 0;
|
||||
mic_trigerred = 0;
|
||||
WCD_MBHC_RSC_UNLOCK(mbhc);
|
||||
|
|
|
@ -550,7 +550,7 @@ void wcd_mbhc_hs_elec_irq(struct wcd_mbhc *mbhc, int irq_type,
|
|||
}
|
||||
EXPORT_SYMBOL(wcd_mbhc_hs_elec_irq);
|
||||
|
||||
static void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion,
|
||||
void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion,
|
||||
enum snd_jack_types jack_type)
|
||||
{
|
||||
struct snd_soc_codec *codec = mbhc->codec;
|
||||
|
@ -725,6 +725,7 @@ static void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion,
|
|||
}
|
||||
pr_debug("%s: leave hph_status %x\n", __func__, mbhc->hph_status);
|
||||
}
|
||||
EXPORT_SYMBOL(wcd_mbhc_report_plug);
|
||||
|
||||
void wcd_mbhc_elec_hs_report_unplug(struct wcd_mbhc *mbhc)
|
||||
{
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <linux/stringify.h>
|
||||
#include <linux/power_supply.h>
|
||||
#include "wcdcal-hwdep.h"
|
||||
#include <sound/jack.h>
|
||||
|
||||
#define TOMBAK_MBHC_NC 0
|
||||
#define TOMBAK_MBHC_NO 1
|
||||
|
@ -204,6 +205,9 @@ enum wcd_mbhc_register_function {
|
|||
WCD_MBHC_ANC_DET_EN,
|
||||
WCD_MBHC_FSM_STATUS,
|
||||
WCD_MBHC_MUX_CTL,
|
||||
WCD_MBHC_MOISTURE_STATUS,
|
||||
WCD_MBHC_HPHR_GND,
|
||||
WCD_MBHC_HPHL_GND,
|
||||
WCD_MBHC_HPHL_OCP_DET_EN,
|
||||
WCD_MBHC_HPHR_OCP_DET_EN,
|
||||
WCD_MBHC_HPHL_OCP_STATUS,
|
||||
|
@ -594,5 +598,7 @@ void wcd_mbhc_jack_report(struct wcd_mbhc *mbhc,
|
|||
struct snd_soc_jack *jack, int status, int mask);
|
||||
int wcd_cancel_btn_work(struct wcd_mbhc *mbhc);
|
||||
int wcd_mbhc_get_button_mask(struct wcd_mbhc *mbhc);
|
||||
void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion,
|
||||
enum snd_jack_types jack_type);
|
||||
|
||||
#endif /* __WCD_MBHC_V2_H__ */
|
||||
|
|
|
@ -650,6 +650,12 @@ static struct wcd_mbhc_register
|
|||
0, 0, 0, 0),
|
||||
WCD_MBHC_REGISTER("WCD_MBHC_MUX_CTL",
|
||||
WCD9335_MBHC_CTL_2, 0x70, 4, 0),
|
||||
WCD_MBHC_REGISTER("WCD_MBHC_MOISTURE_STATUS",
|
||||
WCD9335_MBHC_FSM_STATUS, 0X20, 5, 0),
|
||||
WCD_MBHC_REGISTER("WCD_MBHC_HPHR_GND",
|
||||
WCD9335_HPH_PA_CTL2, 0x40, 6, 0),
|
||||
WCD_MBHC_REGISTER("WCD_MBHC_HPHL_GND",
|
||||
WCD9335_HPH_PA_CTL2, 0x10, 4, 0),
|
||||
};
|
||||
|
||||
static const struct wcd_mbhc_intr intr_ids = {
|
||||
|
|
|
@ -120,6 +120,12 @@ static struct wcd_mbhc_register
|
|||
WCD934X_MBHC_STATUS_SPARE_1, 0x01, 0, 0),
|
||||
WCD_MBHC_REGISTER("WCD_MBHC_MUX_CTL",
|
||||
WCD934X_MBHC_NEW_CTL_2, 0x70, 4, 0),
|
||||
WCD_MBHC_REGISTER("WCD_MBHC_MOISTURE_STATUS",
|
||||
WCD934X_MBHC_NEW_FSM_STATUS, 0x20, 5, 0),
|
||||
WCD_MBHC_REGISTER("WCD_MBHC_HPHR_GND",
|
||||
WCD934X_HPH_PA_CTL2, 0x40, 6, 0),
|
||||
WCD_MBHC_REGISTER("WCD_MBHC_HPHL_GND",
|
||||
WCD934X_HPH_PA_CTL2, 0x10, 4, 0),
|
||||
WCD_MBHC_REGISTER("WCD_MBHC_HPHL_OCP_DET_EN",
|
||||
WCD934X_HPH_L_TEST, 0x01, 0, 0),
|
||||
WCD_MBHC_REGISTER("WCD_MBHC_HPHR_OCP_DET_EN",
|
||||
|
|
Loading…
Add table
Reference in a new issue