diff options
| author | Phani Kumar Uppalapati <phaniu@codeaurora.org> | 2015-11-17 15:00:47 -0800 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 21:13:48 -0700 |
| commit | ed642a40cde3bc96a1f5d6f45e28580be3786cd7 (patch) | |
| tree | 9436f072d0832706b9adf7e5aff1f94eb0759f57 | |
| parent | d6a51f8080a05866d970f5cdee21ec942616ded1 (diff) | |
ASoC: wcd-mbhc: Fix unbalanced irq enable/disable
Fix unbalanced mbhc electrial irq enable/disable to
avoid detection failures when headset or headphone
is inserted into an extension cable at the other
end.
Change-Id: I2eb9096f1cb45957a3d511af86cb630348581e0b
Signed-off-by: Phani Kumar Uppalapati <phaniu@codeaurora.org>
| -rw-r--r-- | sound/soc/codecs/wcd-mbhc-v2.c | 75 | ||||
| -rw-r--r-- | sound/soc/codecs/wcd-mbhc-v2.h | 7 |
2 files changed, 56 insertions, 26 deletions
diff --git a/sound/soc/codecs/wcd-mbhc-v2.c b/sound/soc/codecs/wcd-mbhc-v2.c index 8bcd24fee5e8..445b7e8a2345 100644 --- a/sound/soc/codecs/wcd-mbhc-v2.c +++ b/sound/soc/codecs/wcd-mbhc-v2.c @@ -512,6 +512,34 @@ int wcd_mbhc_get_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, return -EINVAL; } +static void wcd_mbhc_hs_elec_irq(struct wcd_mbhc *mbhc, int irq_type, + bool enable) +{ + int irq; + + WCD_MBHC_RSC_ASSERT_LOCKED(mbhc); + + if (irq_type == WCD_MBHC_ELEC_HS_INS) + irq = mbhc->intr_ids->mbhc_hs_ins_intr; + else if (irq_type == WCD_MBHC_ELEC_HS_REM) + irq = mbhc->intr_ids->mbhc_hs_rem_intr; + else { + pr_debug("%s: irq_type: %d, enable: %d\n", + __func__, irq_type, enable); + return; + } + + pr_debug("%s: irq: %d, enable: %d, intr_status:%lu\n", + __func__, irq, enable, mbhc->intr_status); + if ((test_bit(irq_type, &mbhc->intr_status)) != enable) { + mbhc->mbhc_cb->irq_control(mbhc->codec, irq, enable); + if (enable) + set_bit(irq_type, &mbhc->intr_status); + else + clear_bit(irq_type, &mbhc->intr_status); + } +} + static void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion, enum snd_jack_types jack_type) { @@ -599,9 +627,9 @@ static void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion, WCD_MBHC_ELECT_DETECTION_TYPE, 0); usleep_range(200, 210); - mbhc->mbhc_cb->irq_control(mbhc->codec, - mbhc->intr_ids->mbhc_hs_rem_intr, - true); + wcd_mbhc_hs_elec_irq(mbhc, + WCD_MBHC_ELEC_HS_REM, + true); } mbhc->hph_status &= ~(SND_JACK_HEADSET | SND_JACK_LINEOUT | @@ -712,9 +740,8 @@ static void wcd_mbhc_find_plug_and_report(struct wcd_mbhc *mbhc, */ WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_SCHMT_ISRC, 3); - mbhc->mbhc_cb->irq_control(mbhc->codec, - mbhc->intr_ids->mbhc_hs_ins_intr, - true); + wcd_mbhc_hs_elec_irq(mbhc, WCD_MBHC_ELEC_HS_INS, + true); } else { wcd_mbhc_report_plug(mbhc, 1, SND_JACK_LINEOUT); } @@ -1304,24 +1331,20 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc) /* Pulldown micbias */ WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_PULLDOWN_CTRL, 1); - mbhc->mbhc_cb->irq_control(codec, - mbhc->intr_ids->mbhc_hs_rem_intr, - false); - mbhc->mbhc_cb->irq_control(codec, - mbhc->intr_ids->mbhc_hs_ins_intr, - false); + wcd_mbhc_hs_elec_irq(mbhc, WCD_MBHC_ELEC_HS_REM, + false); + wcd_mbhc_hs_elec_irq(mbhc, WCD_MBHC_ELEC_HS_INS, + false); WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_DETECTION_TYPE, 1); WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_SCHMT_ISRC, 0); wcd_mbhc_report_plug(mbhc, 0, SND_JACK_HEADSET); } else if (mbhc->current_plug == MBHC_PLUG_TYPE_HIGH_HPH) { mbhc->is_extn_cable = false; - mbhc->mbhc_cb->irq_control(codec, - mbhc->intr_ids->mbhc_hs_rem_intr, - false); - mbhc->mbhc_cb->irq_control(codec, - mbhc->intr_ids->mbhc_hs_ins_intr, - false); + wcd_mbhc_hs_elec_irq(mbhc, WCD_MBHC_ELEC_HS_REM, + false); + wcd_mbhc_hs_elec_irq(mbhc, WCD_MBHC_ELEC_HS_INS, + false); WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_DETECTION_TYPE, 1); WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_SCHMT_ISRC, 0); @@ -1459,9 +1482,8 @@ determine_plug: * Setup for insertion detection. */ pr_debug("%s: Disable insertion interrupt\n", __func__); - mbhc->mbhc_cb->irq_control(mbhc->codec, - mbhc->intr_ids->mbhc_hs_ins_intr, - false); + wcd_mbhc_hs_elec_irq(mbhc, WCD_MBHC_ELEC_HS_INS, + false); WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_SCHMT_ISRC, 0); hphl_trigerred = 0; @@ -1566,9 +1588,8 @@ report_unplug: * Disable HPHL trigger and MIC Schmitt triggers. * Setup for insertion detection. */ - mbhc->mbhc_cb->irq_control(mbhc->codec, - mbhc->intr_ids->mbhc_hs_rem_intr, - false); + wcd_mbhc_hs_elec_irq(mbhc, WCD_MBHC_ELEC_HS_REM, + false); wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_NONE); /* Disable HW FSM */ WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 0); @@ -1576,8 +1597,8 @@ report_unplug: /* Set the detection type appropriately */ WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_DETECTION_TYPE, 1); - mbhc->mbhc_cb->irq_control(mbhc->codec, - mbhc->intr_ids->mbhc_hs_ins_intr, true); + wcd_mbhc_hs_elec_irq(mbhc, WCD_MBHC_ELEC_HS_INS, + true); hphl_trigerred = 0; mic_trigerred = 0; WCD_MBHC_RSC_UNLOCK(mbhc); @@ -2210,6 +2231,7 @@ int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec, } mbhc->mbhc_cb->irq_control(codec, mbhc->intr_ids->mbhc_hs_ins_intr, false); + clear_bit(WCD_MBHC_ELEC_HS_INS, &mbhc->intr_status); ret = mbhc->mbhc_cb->request_irq(codec, mbhc->intr_ids->mbhc_hs_rem_intr, @@ -2222,6 +2244,7 @@ int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec, } mbhc->mbhc_cb->irq_control(codec, mbhc->intr_ids->mbhc_hs_rem_intr, false); + clear_bit(WCD_MBHC_ELEC_HS_REM, &mbhc->intr_status); ret = mbhc->mbhc_cb->request_irq(codec, mbhc->intr_ids->hph_left_ocp, wcd_mbhc_hphl_ocp_irq, "HPH_L OCP detect", diff --git a/sound/soc/codecs/wcd-mbhc-v2.h b/sound/soc/codecs/wcd-mbhc-v2.h index 767a05c80fa1..f6cc238ec6e5 100644 --- a/sound/soc/codecs/wcd-mbhc-v2.h +++ b/sound/soc/codecs/wcd-mbhc-v2.h @@ -26,6 +26,11 @@ #define WCD_MONO_HS_MIN_THR 2 #define WCD_MBHC_STRINGIFY(s) __stringify(s) +enum { + WCD_MBHC_ELEC_HS_INS, + WCD_MBHC_ELEC_HS_REM, +}; + struct wcd_mbhc; enum wcd_mbhc_register_function { WCD_MBHC_L_DET_EN, @@ -414,6 +419,8 @@ struct wcd_mbhc { struct completion btn_press_compl; struct mutex hphl_pa_lock; struct mutex hphr_pa_lock; + + unsigned long intr_status; }; #define WCD_MBHC_CAL_SIZE(buttons, rload) ( \ sizeof(struct wcd_mbhc_general_cfg) + \ |
