summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhani Kumar Uppalapati <phaniu@codeaurora.org>2015-11-17 15:00:47 -0800
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 21:13:48 -0700
commited642a40cde3bc96a1f5d6f45e28580be3786cd7 (patch)
tree9436f072d0832706b9adf7e5aff1f94eb0759f57
parentd6a51f8080a05866d970f5cdee21ec942616ded1 (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.c75
-rw-r--r--sound/soc/codecs/wcd-mbhc-v2.h7
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) + \