diff options
-rw-r--r-- | sound/soc/codecs/wcd9xxx-mbhc.c | 132 | ||||
-rw-r--r-- | sound/soc/codecs/wcd9xxx-mbhc.h | 1 | ||||
-rw-r--r-- | sound/soc/msm/msm8226.c | 3 | ||||
-rw-r--r-- | sound/soc/msm/msm8974.c | 3 |
4 files changed, 93 insertions, 46 deletions
diff --git a/sound/soc/codecs/wcd9xxx-mbhc.c b/sound/soc/codecs/wcd9xxx-mbhc.c index bf0a93dec57d..91505514fb47 100644 --- a/sound/soc/codecs/wcd9xxx-mbhc.c +++ b/sound/soc/codecs/wcd9xxx-mbhc.c @@ -1704,10 +1704,10 @@ static int wcd9xxx_pull_down_micbias(struct wcd9xxx_mbhc *mbhc, int us) return 0; } -void wcd9xxx_turn_onoff_current_source(struct wcd9xxx_mbhc *mbhc, bool on, - bool highhph) +void wcd9xxx_turn_onoff_current_source(struct wcd9xxx_mbhc *mbhc, + struct mbhc_micbias_regs *mbhc_micb_regs, + bool on, bool highhph) { - struct snd_soc_codec *codec; struct wcd9xxx_mbhc_btn_detect_cfg *btn_det; const struct wcd9xxx_mbhc_plug_detect_cfg *plug_det = @@ -1722,7 +1722,7 @@ void wcd9xxx_turn_onoff_current_source(struct wcd9xxx_mbhc *mbhc, bool on, snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_B1_CTL, 0x78, 0x48); /* pull down diode bit to 0 */ - snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.mbhc_reg, + snd_soc_update_bits(codec, mbhc_micb_regs->mbhc_reg, 0x01, 0x00); /* * Keep the low power insertion/removal @@ -1737,7 +1737,7 @@ void wcd9xxx_turn_onoff_current_source(struct wcd9xxx_mbhc *mbhc, bool on, * (INS_DET_ISRC_EN__ENABLE) * MICB_2_MBHC__SCHT_TRIG_EN to 1 */ - snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.mbhc_reg, + snd_soc_update_bits(codec, mbhc_micb_regs->mbhc_reg, 0xF0, 0xF0); /* Disconnect MBHC Override from MicBias and LDOH */ snd_soc_update_bits(codec, WCD9XXX_A_MAD_ANA_CTRL, 0x10, 0x00); @@ -1746,16 +1746,16 @@ void wcd9xxx_turn_onoff_current_source(struct wcd9xxx_mbhc *mbhc, bool on, /* Connect MBHC Override from MicBias and LDOH */ snd_soc_update_bits(codec, WCD9XXX_A_MAD_ANA_CTRL, 0x10, 0x10); /* INS_DET_ISRC_CTL to acdb value */ - snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.mbhc_reg, + snd_soc_update_bits(codec, mbhc_micb_regs->mbhc_reg, 0x60, plug_det->mic_current << 5); if (!highhph) { /* INS_DET_ISRC_EN__ENABLE to 0 */ snd_soc_update_bits(codec, - mbhc->mbhc_bias_regs.mbhc_reg, + mbhc_micb_regs->mbhc_reg, 0x80, 0x00); /* MICB_2_MBHC__SCHT_TRIG_EN to 0 */ snd_soc_update_bits(codec, - mbhc->mbhc_bias_regs.mbhc_reg, + mbhc_micb_regs->mbhc_reg, 0x10, 0x00); } /* Nsc to acdb value */ @@ -1795,11 +1795,15 @@ wcd9xxx_codec_cs_get_plug_type(struct wcd9xxx_mbhc *mbhc, bool highhph) wcd9xxx_codec_hphr_gnd_switch(codec, true); if (rt[i].mic_bias) - wcd9xxx_turn_onoff_current_source(mbhc, false, false); + wcd9xxx_turn_onoff_current_source(mbhc, + &mbhc->mbhc_bias_regs, + false, false); rt[i].dce = __wcd9xxx_codec_sta_dce(mbhc, 1, !highhph, true); if (rt[i].mic_bias) - wcd9xxx_turn_onoff_current_source(mbhc, true, false); + wcd9xxx_turn_onoff_current_source(mbhc, + &mbhc->mbhc_bias_regs, + true, false); if (rt[i].swap_gnd) wcd9xxx_codec_hphr_gnd_switch(codec, false); } @@ -2054,15 +2058,16 @@ static bool wcd9xxx_detect_anc_plug_type(struct wcd9xxx_mbhc *mbhc) { struct wcd9xxx_mbhc_detect rt[NUM_DCE_PLUG_INS_DETECT - 1]; bool anc_mic_found = true; - int i; + int i, mb_mv; const struct wcd9xxx_mbhc_plug_type_cfg *plug_type = WCD9XXX_MBHC_CAL_PLUG_TYPE_PTR(mbhc->mbhc_cfg->calibration); - const s16 hs_max = plug_type->v_hs_max; - const s16 no_mic = plug_type->v_no_mic; + s16 hs_max, dce_z; + s16 no_mic; bool override_en; bool timedout; unsigned long timeout, retry = 0; enum wcd9xxx_mbhc_plug_type type; + bool cs_enable; if (mbhc->mbhc_cfg->anc_micbias != MBHC_MICBIAS3 && mbhc->mbhc_cfg->anc_micbias != MBHC_MICBIAS2) @@ -2072,17 +2077,40 @@ static bool wcd9xxx_detect_anc_plug_type(struct wcd9xxx_mbhc *mbhc) override_en = (snd_soc_read(mbhc->codec, WCD9XXX_A_CDC_MBHC_B1_CTL) & 0x04) ? true : false; + cs_enable = ((mbhc->mbhc_cfg->cs_enable_flags & + (1 << MBHC_CS_ENABLE_DET_ANC)) != 0) && + (!(snd_soc_read(mbhc->codec, + mbhc->mbhc_anc_bias_regs.ctl_reg) & 0x80)) && + (mbhc->mbhc_cfg->micbias != mbhc->mbhc_cfg->anc_micbias); - if (mbhc->mbhc_cfg->anc_micbias == MBHC_MICBIAS3) { - if (mbhc->micbias_enable_cb) - mbhc->micbias_enable_cb(mbhc->codec, true, + if (cs_enable) { + wcd9xxx_turn_onoff_current_source(mbhc, + &mbhc->mbhc_anc_bias_regs, + true, false); + } else { + if (mbhc->mbhc_cfg->anc_micbias == MBHC_MICBIAS3) { + if (mbhc->micbias_enable_cb) + mbhc->micbias_enable_cb(mbhc->codec, true, mbhc->mbhc_cfg->anc_micbias); - else - return false; + else + return false; + } else { + /* Enable override */ + if (!override_en) + wcd9xxx_turn_onoff_override(mbhc, true); + } + } + + if (!cs_enable) { + hs_max = plug_type->v_hs_max; + no_mic = plug_type->v_no_mic; + dce_z = mbhc->mbhc_data.dce_z; + mb_mv = mbhc->mbhc_data.micb_mv; } else { - /* Enable override */ - if (!override_en) - wcd9xxx_turn_onoff_override(mbhc, true); + hs_max = WCD9XXX_V_CS_HS_MAX; + no_mic = WCD9XXX_V_CS_NO_MIC; + mb_mv = VDDIO_MICBIAS_MV; + dce_z = mbhc->mbhc_data.dce_nsc_cs_z; } wcd9xxx_mbhc_ctrl_clk_bandgap(mbhc, true); @@ -2104,8 +2132,9 @@ static bool wcd9xxx_detect_anc_plug_type(struct wcd9xxx_mbhc *mbhc) rt[0].hphl_status = wcd9xxx_hphl_status(mbhc); rt[0].dce = wcd9xxx_mbhc_setup_hs_polling(mbhc, &mbhc->mbhc_anc_bias_regs, - false); - rt[0]._vdces = wcd9xxx_codec_sta_dce_v(mbhc, true, rt[0].dce); + cs_enable); + rt[0]._vdces = __wcd9xxx_codec_sta_dce_v(mbhc, true, rt[0].dce, + dce_z, (u32)mb_mv); if (rt[0]._vdces >= no_mic && rt[0]._vdces < hs_max) rt[0]._type = PLUG_TYPE_HEADSET; @@ -2122,8 +2151,9 @@ static bool wcd9xxx_detect_anc_plug_type(struct wcd9xxx_mbhc *mbhc) for (i = 1; i < NUM_DCE_PLUG_INS_DETECT - 1; i++) { rt[i].dce = __wcd9xxx_codec_sta_dce(mbhc, 1, true, true); - rt[i]._vdces = wcd9xxx_codec_sta_dce_v(mbhc, - true, rt[i].dce); + rt[i]._vdces = __wcd9xxx_codec_sta_dce_v(mbhc, true, + rt[i].dce, dce_z, + (u32) mb_mv); if (rt[i]._vdces >= no_mic && rt[i]._vdces < hs_max) rt[i]._type = PLUG_TYPE_HEADSET; @@ -2156,6 +2186,7 @@ static bool wcd9xxx_detect_anc_plug_type(struct wcd9xxx_mbhc *mbhc) pr_debug("%s: Plug type found in ANC detection :%d", __func__, type); + if (type != PLUG_TYPE_HEADSET) anc_mic_found = false; if (anc_mic_found || (type == PLUG_TYPE_HEADPHONE && @@ -2166,16 +2197,21 @@ static bool wcd9xxx_detect_anc_plug_type(struct wcd9xxx_mbhc *mbhc) } wcd9xxx_mbhc_ctrl_clk_bandgap(mbhc, false); - if (mbhc->mbhc_cfg->anc_micbias == MBHC_MICBIAS3) { - if (mbhc->micbias_enable_cb) - mbhc->micbias_enable_cb(mbhc->codec, false, - mbhc->mbhc_cfg->anc_micbias); + if (cs_enable) { + wcd9xxx_turn_onoff_current_source(mbhc, + &mbhc->mbhc_anc_bias_regs, + false, false); } else { - /* Disable override */ - if (!override_en) - wcd9xxx_turn_onoff_override(mbhc, false); + if (mbhc->mbhc_cfg->anc_micbias == MBHC_MICBIAS3) { + if (mbhc->micbias_enable_cb) + mbhc->micbias_enable_cb(mbhc->codec, false, + mbhc->mbhc_cfg->anc_micbias); + } else { + /* Disable override */ + if (!override_en) + wcd9xxx_turn_onoff_override(mbhc, false); + } } - pr_debug("%s: leave\n", __func__); return anc_mic_found; } @@ -2304,9 +2340,11 @@ static void wcd9xxx_mbhc_decide_swch_plug(struct wcd9xxx_mbhc *mbhc) mbhc->scaling_mux_in = 0x04; if (current_source_enable) { - wcd9xxx_turn_onoff_current_source(mbhc, true, false); + wcd9xxx_turn_onoff_current_source(mbhc, &mbhc->mbhc_bias_regs, + true, false); plug_type = wcd9xxx_codec_cs_get_plug_type(mbhc, false); - wcd9xxx_turn_onoff_current_source(mbhc, false, false); + wcd9xxx_turn_onoff_current_source(mbhc, &mbhc->mbhc_bias_regs, + false, false); } else { wcd9xxx_turn_onoff_override(mbhc, true); plug_type = wcd9xxx_codec_get_plug_type(mbhc, true); @@ -2437,7 +2475,8 @@ static bool wcd9xxx_hs_remove_settle(struct wcd9xxx_mbhc *mbhc) (!(snd_soc_read(mbhc->codec, mbhc->mbhc_bias_regs.ctl_reg) & 0x80))); if (cs_enable) - wcd9xxx_turn_onoff_current_source(mbhc, true, false); + wcd9xxx_turn_onoff_current_source(mbhc, &mbhc->mbhc_bias_regs, + true, false); timeout = jiffies + msecs_to_jiffies(HS_DETECT_PLUG_TIME_MS); while (!(timedout = time_after(jiffies, timeout))) { @@ -2505,7 +2544,8 @@ static bool wcd9xxx_hs_remove_settle(struct wcd9xxx_mbhc *mbhc) } if (cs_enable) - wcd9xxx_turn_onoff_current_source(mbhc, false, false); + wcd9xxx_turn_onoff_current_source(mbhc, &mbhc->mbhc_bias_regs, + false, false); if (timedout) pr_debug("%s: Microphone did not settle in %d seconds\n", @@ -2553,7 +2593,8 @@ static void wcd9xxx_hs_remove_irq_noswch(struct wcd9xxx_mbhc *mbhc) (!(snd_soc_read(codec, mbhc->mbhc_bias_regs.ctl_reg) & 0x80))); if (cs_enable) - wcd9xxx_turn_onoff_current_source(mbhc, true, false); + wcd9xxx_turn_onoff_current_source(mbhc, &mbhc->mbhc_bias_regs, + true, false); timeout = jiffies + msecs_to_jiffies(FAKE_REMOVAL_MIN_PERIOD_MS); do { @@ -2584,7 +2625,8 @@ static void wcd9xxx_hs_remove_irq_noswch(struct wcd9xxx_mbhc *mbhc) removed ? "" : "not "); if (cs_enable) - wcd9xxx_turn_onoff_current_source(mbhc, false, false); + wcd9xxx_turn_onoff_current_source(mbhc, &mbhc->mbhc_bias_regs, + false, false); if (removed) { if (mbhc->mbhc_cfg->detect_extn_cable) { @@ -2966,8 +3008,8 @@ static void wcd9xxx_correct_swch_plug(struct work_struct *work) * headphone detection. */ if (current_source_enable) - wcd9xxx_turn_onoff_current_source(mbhc, true, - false); + wcd9xxx_turn_onoff_current_source(mbhc, &mbhc->mbhc_bias_regs, + true, false); else wcd9xxx_turn_onoff_override(mbhc, true); @@ -3059,8 +3101,9 @@ static void wcd9xxx_correct_swch_plug(struct work_struct *work) WCD9XXX_BCL_LOCK(mbhc->resmgr); /* Turn off override/current source */ if (current_source_enable) - wcd9xxx_turn_onoff_current_source(mbhc, false, - false); + wcd9xxx_turn_onoff_current_source(mbhc, + &mbhc->mbhc_bias_regs, + false, false); else wcd9xxx_turn_onoff_override(mbhc, false); /* @@ -3086,7 +3129,8 @@ static void wcd9xxx_correct_swch_plug(struct work_struct *work) } if (!correction && current_source_enable) - wcd9xxx_turn_onoff_current_source(mbhc, false, highhph); + wcd9xxx_turn_onoff_current_source(mbhc, &mbhc->mbhc_bias_regs, + false, highhph); else if (!correction) wcd9xxx_turn_onoff_override(mbhc, false); diff --git a/sound/soc/codecs/wcd9xxx-mbhc.h b/sound/soc/codecs/wcd9xxx-mbhc.h index 3fb59c8baf44..526b9e5a7324 100644 --- a/sound/soc/codecs/wcd9xxx-mbhc.h +++ b/sound/soc/codecs/wcd9xxx-mbhc.h @@ -109,6 +109,7 @@ enum wcd9xx_mbhc_cs_enable_bits { MBHC_CS_ENABLE_POLLING, MBHC_CS_ENABLE_INSERTION, MBHC_CS_ENABLE_REMOVAL, + MBHC_CS_ENABLE_DET_ANC, }; enum wcd9xxx_mbhc_state { diff --git a/sound/soc/msm/msm8226.c b/sound/soc/msm/msm8226.c index 44d40bb209a3..4affdbd996f4 100644 --- a/sound/soc/msm/msm8226.c +++ b/sound/soc/msm/msm8226.c @@ -93,7 +93,8 @@ static struct wcd9xxx_mbhc_config mbhc_cfg = { .swap_gnd_mic = NULL, .cs_enable_flags = (1 << MBHC_CS_ENABLE_POLLING | 1 << MBHC_CS_ENABLE_INSERTION | - 1 << MBHC_CS_ENABLE_REMOVAL), + 1 << MBHC_CS_ENABLE_REMOVAL | + 1 << MBHC_CS_ENABLE_DET_ANC), .do_recalibration = true, .use_vddio_meas = true, .enable_anc_mic_detect = false, diff --git a/sound/soc/msm/msm8974.c b/sound/soc/msm/msm8974.c index 79c15e87d08c..8854828591f5 100644 --- a/sound/soc/msm/msm8974.c +++ b/sound/soc/msm/msm8974.c @@ -128,7 +128,8 @@ static struct wcd9xxx_mbhc_config mbhc_cfg = { .swap_gnd_mic = NULL, .cs_enable_flags = (1 << MBHC_CS_ENABLE_POLLING | 1 << MBHC_CS_ENABLE_INSERTION | - 1 << MBHC_CS_ENABLE_REMOVAL), + 1 << MBHC_CS_ENABLE_REMOVAL | + 1 << MBHC_CS_ENABLE_DET_ANC), .do_recalibration = true, .use_vddio_meas = true, .enable_anc_mic_detect = false, |