summaryrefslogtreecommitdiff
path: root/sound/soc/codecs/wcd-mbhc-v2.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wcd-mbhc-v2.c')
-rw-r--r--sound/soc/codecs/wcd-mbhc-v2.c45
1 files changed, 40 insertions, 5 deletions
diff --git a/sound/soc/codecs/wcd-mbhc-v2.c b/sound/soc/codecs/wcd-mbhc-v2.c
index 36ab897b8dc0..63ffacad61e1 100644
--- a/sound/soc/codecs/wcd-mbhc-v2.c
+++ b/sound/soc/codecs/wcd-mbhc-v2.c
@@ -315,12 +315,17 @@ out_micb_en:
mbhc->is_hs_recording);
break;
case WCD_EVENT_POST_MICBIAS_2_OFF:
+ if (!mbhc->mbhc_cb->mbhc_micbias_control)
+ mbhc->is_hs_recording = false;
+ if (mbhc->micbias_enable) {
+ wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_MB);
+ break;
+ }
+
if (mbhc->mbhc_cb->set_auto_zeroing)
mbhc->mbhc_cb->set_auto_zeroing(codec, false);
- if (mbhc->mbhc_cb->set_micbias_value)
+ if (mbhc->mbhc_cb->set_micbias_value && !mbhc->micbias_enable)
mbhc->mbhc_cb->set_micbias_value(codec);
- if (!mbhc->mbhc_cb->mbhc_micbias_control)
- mbhc->is_hs_recording = false;
/* Enable PULL UP if PA's are enabled */
if ((test_bit(WCD_MBHC_EVENT_PA_HPHL, &mbhc->event_state)) ||
(test_bit(WCD_MBHC_EVENT_PA_HPHR,
@@ -578,6 +583,10 @@ static void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion,
mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic(
mbhc->codec,
MIC_BIAS_2, false);
+ if (mbhc->mbhc_cb->set_micbias_value) {
+ mbhc->mbhc_cb->set_micbias_value(mbhc->codec);
+ WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_MICB_CTRL, 0);
+ }
mbhc->micbias_enable = false;
}
@@ -611,6 +620,12 @@ static void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion,
mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic(
mbhc->codec,
MIC_BIAS_2, false);
+ if (mbhc->mbhc_cb->set_micbias_value) {
+ mbhc->mbhc_cb->set_micbias_value(
+ mbhc->codec);
+ WCD_MBHC_REG_UPDATE_BITS(
+ WCD_MBHC_MICB_CTRL, 0);
+ }
mbhc->micbias_enable = false;
}
mbhc->hph_type = WCD_MBHC_HPH_NONE;
@@ -979,7 +994,7 @@ static bool wcd_is_special_headset(struct wcd_mbhc *mbhc)
mbhc->mbhc_cb->mbhc_common_micb_ctrl(codec,
MBHC_COMMON_MICB_PRECHARGE,
false);
- if (mbhc->mbhc_cb->set_micbias_value)
+ if (mbhc->mbhc_cb->set_micbias_value && !mbhc->micbias_enable)
mbhc->mbhc_cb->set_micbias_value(codec);
if (mbhc->mbhc_cb->set_auto_zeroing)
mbhc->mbhc_cb->set_auto_zeroing(codec, false);
@@ -1039,7 +1054,7 @@ static void wcd_enable_mbhc_supply(struct wcd_mbhc *mbhc,
wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_MB);
} else {
if (plug_type == MBHC_PLUG_TYPE_HEADSET) {
- if (mbhc->is_hs_recording)
+ if (mbhc->is_hs_recording || mbhc->micbias_enable)
wcd_enable_curr_micbias(mbhc,
WCD_MBHC_EN_MB);
else if ((test_bit(WCD_MBHC_EVENT_PA_HPHL,
@@ -1192,6 +1207,9 @@ correct_plug_type:
if (mbhc->micbias_enable) {
mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic(
mbhc->codec, MIC_BIAS_2, false);
+ if (mbhc->mbhc_cb->set_micbias_value)
+ mbhc->mbhc_cb->set_micbias_value(
+ mbhc->codec);
mbhc->micbias_enable = false;
}
goto exit;
@@ -1214,6 +1232,9 @@ correct_plug_type:
if (mbhc->micbias_enable) {
mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic(
mbhc->codec, MIC_BIAS_2, false);
+ if (mbhc->mbhc_cb->set_micbias_value)
+ mbhc->mbhc_cb->set_micbias_value(
+ mbhc->codec);
mbhc->micbias_enable = false;
}
goto exit;
@@ -1382,6 +1403,15 @@ exit:
micbias2 = mbhc->mbhc_cb->micbias_enable_status(mbhc,
MIC_BIAS_2);
}
+
+ if (mbhc->mbhc_cfg->detect_extn_cable &&
+ ((plug_type == MBHC_PLUG_TYPE_HEADPHONE) ||
+ (plug_type == MBHC_PLUG_TYPE_HEADSET)) &&
+ !mbhc->hs_detect_work_stop) {
+ WCD_MBHC_RSC_LOCK(mbhc);
+ wcd_mbhc_hs_elec_irq(mbhc, WCD_MBHC_ELEC_HS_REM, true);
+ WCD_MBHC_RSC_UNLOCK(mbhc);
+ }
if (mbhc->mbhc_cb->set_cap_mode)
mbhc->mbhc_cb->set_cap_mode(codec, micbias1, micbias2);
@@ -1734,6 +1764,10 @@ static irqreturn_t wcd_mbhc_hs_rem_irq(int irq, void *data)
}
} while (!time_after(jiffies, timeout));
+ if (wcd_swch_level_remove(mbhc)) {
+ pr_debug("%s: Switch level is low ", __func__);
+ goto exit;
+ }
pr_debug("%s: headset %s actually removed\n", __func__,
removed ? "" : "not ");
@@ -1768,6 +1802,7 @@ static irqreturn_t wcd_mbhc_hs_rem_irq(int irq, void *data)
}
}
}
+exit:
WCD_MBHC_RSC_UNLOCK(mbhc);
pr_debug("%s: leave\n", __func__);
return IRQ_HANDLED;