Loading sound/soc/codecs/wcd9xxx-mbhc.c +35 −22 Original line number Diff line number Diff line Loading @@ -1059,6 +1059,27 @@ static s32 wcd9xxx_codec_sta_dce_v(struct wcd9xxx_mbhc *mbhc, s8 dce, mbhc->mbhc_data.micb_mv); } /* To enable/disable bandgap and RC oscillator */ static void wcd9xxx_mbhc_ctrl_clk_bandgap(struct wcd9xxx_mbhc *mbhc, bool enable) { if (enable) { WCD9XXX_BG_CLK_LOCK(mbhc->resmgr); wcd9xxx_resmgr_get_bandgap(mbhc->resmgr, WCD9XXX_BANDGAP_AUDIO_MODE); wcd9xxx_resmgr_get_clk_block(mbhc->resmgr, WCD9XXX_CLK_RCO); WCD9XXX_BG_CLK_UNLOCK(mbhc->resmgr); } else { WCD9XXX_BG_CLK_LOCK(mbhc->resmgr); wcd9xxx_resmgr_put_clk_block(mbhc->resmgr, WCD9XXX_CLK_RCO); wcd9xxx_resmgr_put_bandgap(mbhc->resmgr, WCD9XXX_BANDGAP_AUDIO_MODE); WCD9XXX_BG_CLK_UNLOCK(mbhc->resmgr); } } /* called only from interrupt which is under codec_resource_lock acquisition */ static short wcd9xxx_mbhc_setup_hs_polling(struct wcd9xxx_mbhc *mbhc, bool is_cs_enable) Loading Loading @@ -1096,15 +1117,6 @@ static short wcd9xxx_mbhc_setup_hs_polling(struct wcd9xxx_mbhc *mbhc, __func__); } /* * Request BG and clock. * These will be released by wcd9xxx_cleanup_hs_polling */ WCD9XXX_BG_CLK_LOCK(mbhc->resmgr); wcd9xxx_resmgr_get_bandgap(mbhc->resmgr, WCD9XXX_BANDGAP_AUDIO_MODE); wcd9xxx_resmgr_get_clk_block(mbhc->resmgr, WCD9XXX_CLK_RCO); WCD9XXX_BG_CLK_UNLOCK(mbhc->resmgr); snd_soc_update_bits(codec, WCD9XXX_A_CLK_BUFF_EN1, 0x05, 0x01); /* Make sure CFILT is in fast mode, save current mode */ Loading Loading @@ -1215,11 +1227,6 @@ static void wcd9xxx_cleanup_hs_polling(struct wcd9xxx_mbhc *mbhc) wcd9xxx_shutdown_hs_removal_detect(mbhc); /* Release clock and BG requested by wcd9xxx_mbhc_setup_hs_polling */ WCD9XXX_BG_CLK_LOCK(mbhc->resmgr); wcd9xxx_resmgr_put_clk_block(mbhc->resmgr, WCD9XXX_CLK_RCO); wcd9xxx_resmgr_put_bandgap(mbhc->resmgr, WCD9XXX_BANDGAP_MBHC_MODE); WCD9XXX_BG_CLK_UNLOCK(mbhc->resmgr); /* Disable external voltage source to micbias if present */ if (mbhc->mbhc_cb && mbhc->mbhc_cb->enable_mb_source) Loading Loading @@ -1694,6 +1701,7 @@ wcd9xxx_codec_cs_get_plug_type(struct wcd9xxx_mbhc *mbhc, bool highhph) BUG_ON(NUM_DCE_PLUG_INS_DETECT < 4); wcd9xxx_mbhc_ctrl_clk_bandgap(mbhc, true); rt[0].swap_gnd = false; rt[0].vddio = false; rt[0].hwvalue = true; Loading Loading @@ -1722,6 +1730,7 @@ wcd9xxx_codec_cs_get_plug_type(struct wcd9xxx_mbhc *mbhc, bool highhph) type = wcd9xxx_cs_find_plug_type(mbhc, rt, ARRAY_SIZE(rt), highhph, mbhc->event_state); wcd9xxx_mbhc_ctrl_clk_bandgap(mbhc, false); pr_debug("%s: plug_type:%d\n", __func__, type); return type; Loading Loading @@ -1762,6 +1771,8 @@ wcd9xxx_codec_get_plug_type(struct wcd9xxx_mbhc *mbhc, bool highhph) */ (void) wcd9xxx_pull_down_micbias(mbhc, WCD9XXX_MICBIAS_PULLDOWN_SETTLE_US); wcd9xxx_mbhc_ctrl_clk_bandgap(mbhc, true); rt[0].hphl_status = wcd9xxx_hphl_status(mbhc); rt[0].dce = wcd9xxx_mbhc_setup_hs_polling(mbhc, false); rt[0].swap_gnd = false; Loading Loading @@ -1801,6 +1812,7 @@ wcd9xxx_codec_get_plug_type(struct wcd9xxx_mbhc *mbhc, bool highhph) type = wcd9xxx_find_plug_type(mbhc, rt, ARRAY_SIZE(rt), mbhc->event_state); wcd9xxx_mbhc_ctrl_clk_bandgap(mbhc, false); pr_debug("%s: leave\n", __func__); return type; } Loading Loading @@ -1989,6 +2001,8 @@ static void wcd9xxx_find_plug_and_report(struct wcd9xxx_mbhc *mbhc, * only report the mic line */ wcd9xxx_report_plug(mbhc, 1, SND_JACK_HEADSET); /* Button detection required RC oscillator */ wcd9xxx_mbhc_ctrl_clk_bandgap(mbhc, true); msleep(100); /* if PA is already on, switch micbias source to VDDIO */ Loading Loading @@ -2323,6 +2337,9 @@ static void wcd9xxx_hs_remove_irq_noswch(struct wcd9xxx_mbhc *mbhc) * extension cable is still plugged in * report it as LINEOUT device */ if (mbhc->hph_status == SND_JACK_HEADSET) wcd9xxx_mbhc_ctrl_clk_bandgap(mbhc, false); wcd9xxx_report_plug(mbhc, 1, SND_JACK_LINEOUT); wcd9xxx_cleanup_hs_polling(mbhc); wcd9xxx_enable_hs_detect(mbhc, 1, Loading @@ -2341,6 +2358,7 @@ static void wcd9xxx_hs_remove_irq_noswch(struct wcd9xxx_mbhc *mbhc) wcd9xxx_switch_micbias(mbhc, 0); wcd9xxx_report_plug(mbhc, 0, SND_JACK_HEADSET); wcd9xxx_mbhc_ctrl_clk_bandgap(mbhc, false); wcd9xxx_cleanup_hs_polling(mbhc); wcd9xxx_enable_hs_detect(mbhc, 1, MBHC_USE_MB_TRIGGER | MBHC_USE_HPHL_TRIGGER, Loading Loading @@ -2879,6 +2897,7 @@ static void wcd9xxx_swch_irq_handler(struct wcd9xxx_mbhc *mbhc) is_removed = true; } else if (mbhc->current_plug == PLUG_TYPE_HEADSET) { wcd9xxx_pause_hs_polling(mbhc); wcd9xxx_mbhc_ctrl_clk_bandgap(mbhc, false); wcd9xxx_cleanup_hs_polling(mbhc); wcd9xxx_report_plug(mbhc, 0, SND_JACK_HEADSET); is_removed = true; Loading Loading @@ -4351,16 +4370,13 @@ static int wcd9xxx_detect_impedance(struct wcd9xxx_mbhc *mbhc, uint32_t *zl, */ mutex_lock(&codec->mutex); WCD9XXX_BG_CLK_LOCK(mbhc->resmgr); /* * Fast(mbhc) mode bandagap doesn't need to be enabled explicitly * since fast mode is set by MBHC hardware when override is on. * Enable bandgap mode to avoid unnecessary RCO disable and enable * during clock source change. */ wcd9xxx_resmgr_get_bandgap(mbhc->resmgr, WCD9XXX_BANDGAP_AUDIO_MODE); wcd9xxx_resmgr_get_clk_block(mbhc->resmgr, WCD9XXX_CLK_RCO); WCD9XXX_BG_CLK_UNLOCK(mbhc->resmgr); wcd9xxx_mbhc_ctrl_clk_bandgap(mbhc, true); wcd9xxx_turn_onoff_override(mbhc, true); pr_debug("%s: Setting impedance detection\n", __func__); Loading Loading @@ -4408,10 +4424,7 @@ static int wcd9xxx_detect_impedance(struct wcd9xxx_mbhc *mbhc, uint32_t *zl, mutex_unlock(&codec->mutex); WCD9XXX_BG_CLK_LOCK(mbhc->resmgr); wcd9xxx_resmgr_put_bandgap(mbhc->resmgr, WCD9XXX_BANDGAP_AUDIO_MODE); wcd9xxx_resmgr_put_clk_block(mbhc->resmgr, WCD9XXX_CLK_RCO); WCD9XXX_BG_CLK_UNLOCK(mbhc->resmgr); wcd9xxx_mbhc_ctrl_clk_bandgap(mbhc, false); wcd9xxx_turn_onoff_override(mbhc, false); mbhc->mbhc_cb->compute_impedance(l, r, zl, zr); Loading Loading
sound/soc/codecs/wcd9xxx-mbhc.c +35 −22 Original line number Diff line number Diff line Loading @@ -1059,6 +1059,27 @@ static s32 wcd9xxx_codec_sta_dce_v(struct wcd9xxx_mbhc *mbhc, s8 dce, mbhc->mbhc_data.micb_mv); } /* To enable/disable bandgap and RC oscillator */ static void wcd9xxx_mbhc_ctrl_clk_bandgap(struct wcd9xxx_mbhc *mbhc, bool enable) { if (enable) { WCD9XXX_BG_CLK_LOCK(mbhc->resmgr); wcd9xxx_resmgr_get_bandgap(mbhc->resmgr, WCD9XXX_BANDGAP_AUDIO_MODE); wcd9xxx_resmgr_get_clk_block(mbhc->resmgr, WCD9XXX_CLK_RCO); WCD9XXX_BG_CLK_UNLOCK(mbhc->resmgr); } else { WCD9XXX_BG_CLK_LOCK(mbhc->resmgr); wcd9xxx_resmgr_put_clk_block(mbhc->resmgr, WCD9XXX_CLK_RCO); wcd9xxx_resmgr_put_bandgap(mbhc->resmgr, WCD9XXX_BANDGAP_AUDIO_MODE); WCD9XXX_BG_CLK_UNLOCK(mbhc->resmgr); } } /* called only from interrupt which is under codec_resource_lock acquisition */ static short wcd9xxx_mbhc_setup_hs_polling(struct wcd9xxx_mbhc *mbhc, bool is_cs_enable) Loading Loading @@ -1096,15 +1117,6 @@ static short wcd9xxx_mbhc_setup_hs_polling(struct wcd9xxx_mbhc *mbhc, __func__); } /* * Request BG and clock. * These will be released by wcd9xxx_cleanup_hs_polling */ WCD9XXX_BG_CLK_LOCK(mbhc->resmgr); wcd9xxx_resmgr_get_bandgap(mbhc->resmgr, WCD9XXX_BANDGAP_AUDIO_MODE); wcd9xxx_resmgr_get_clk_block(mbhc->resmgr, WCD9XXX_CLK_RCO); WCD9XXX_BG_CLK_UNLOCK(mbhc->resmgr); snd_soc_update_bits(codec, WCD9XXX_A_CLK_BUFF_EN1, 0x05, 0x01); /* Make sure CFILT is in fast mode, save current mode */ Loading Loading @@ -1215,11 +1227,6 @@ static void wcd9xxx_cleanup_hs_polling(struct wcd9xxx_mbhc *mbhc) wcd9xxx_shutdown_hs_removal_detect(mbhc); /* Release clock and BG requested by wcd9xxx_mbhc_setup_hs_polling */ WCD9XXX_BG_CLK_LOCK(mbhc->resmgr); wcd9xxx_resmgr_put_clk_block(mbhc->resmgr, WCD9XXX_CLK_RCO); wcd9xxx_resmgr_put_bandgap(mbhc->resmgr, WCD9XXX_BANDGAP_MBHC_MODE); WCD9XXX_BG_CLK_UNLOCK(mbhc->resmgr); /* Disable external voltage source to micbias if present */ if (mbhc->mbhc_cb && mbhc->mbhc_cb->enable_mb_source) Loading Loading @@ -1694,6 +1701,7 @@ wcd9xxx_codec_cs_get_plug_type(struct wcd9xxx_mbhc *mbhc, bool highhph) BUG_ON(NUM_DCE_PLUG_INS_DETECT < 4); wcd9xxx_mbhc_ctrl_clk_bandgap(mbhc, true); rt[0].swap_gnd = false; rt[0].vddio = false; rt[0].hwvalue = true; Loading Loading @@ -1722,6 +1730,7 @@ wcd9xxx_codec_cs_get_plug_type(struct wcd9xxx_mbhc *mbhc, bool highhph) type = wcd9xxx_cs_find_plug_type(mbhc, rt, ARRAY_SIZE(rt), highhph, mbhc->event_state); wcd9xxx_mbhc_ctrl_clk_bandgap(mbhc, false); pr_debug("%s: plug_type:%d\n", __func__, type); return type; Loading Loading @@ -1762,6 +1771,8 @@ wcd9xxx_codec_get_plug_type(struct wcd9xxx_mbhc *mbhc, bool highhph) */ (void) wcd9xxx_pull_down_micbias(mbhc, WCD9XXX_MICBIAS_PULLDOWN_SETTLE_US); wcd9xxx_mbhc_ctrl_clk_bandgap(mbhc, true); rt[0].hphl_status = wcd9xxx_hphl_status(mbhc); rt[0].dce = wcd9xxx_mbhc_setup_hs_polling(mbhc, false); rt[0].swap_gnd = false; Loading Loading @@ -1801,6 +1812,7 @@ wcd9xxx_codec_get_plug_type(struct wcd9xxx_mbhc *mbhc, bool highhph) type = wcd9xxx_find_plug_type(mbhc, rt, ARRAY_SIZE(rt), mbhc->event_state); wcd9xxx_mbhc_ctrl_clk_bandgap(mbhc, false); pr_debug("%s: leave\n", __func__); return type; } Loading Loading @@ -1989,6 +2001,8 @@ static void wcd9xxx_find_plug_and_report(struct wcd9xxx_mbhc *mbhc, * only report the mic line */ wcd9xxx_report_plug(mbhc, 1, SND_JACK_HEADSET); /* Button detection required RC oscillator */ wcd9xxx_mbhc_ctrl_clk_bandgap(mbhc, true); msleep(100); /* if PA is already on, switch micbias source to VDDIO */ Loading Loading @@ -2323,6 +2337,9 @@ static void wcd9xxx_hs_remove_irq_noswch(struct wcd9xxx_mbhc *mbhc) * extension cable is still plugged in * report it as LINEOUT device */ if (mbhc->hph_status == SND_JACK_HEADSET) wcd9xxx_mbhc_ctrl_clk_bandgap(mbhc, false); wcd9xxx_report_plug(mbhc, 1, SND_JACK_LINEOUT); wcd9xxx_cleanup_hs_polling(mbhc); wcd9xxx_enable_hs_detect(mbhc, 1, Loading @@ -2341,6 +2358,7 @@ static void wcd9xxx_hs_remove_irq_noswch(struct wcd9xxx_mbhc *mbhc) wcd9xxx_switch_micbias(mbhc, 0); wcd9xxx_report_plug(mbhc, 0, SND_JACK_HEADSET); wcd9xxx_mbhc_ctrl_clk_bandgap(mbhc, false); wcd9xxx_cleanup_hs_polling(mbhc); wcd9xxx_enable_hs_detect(mbhc, 1, MBHC_USE_MB_TRIGGER | MBHC_USE_HPHL_TRIGGER, Loading Loading @@ -2879,6 +2897,7 @@ static void wcd9xxx_swch_irq_handler(struct wcd9xxx_mbhc *mbhc) is_removed = true; } else if (mbhc->current_plug == PLUG_TYPE_HEADSET) { wcd9xxx_pause_hs_polling(mbhc); wcd9xxx_mbhc_ctrl_clk_bandgap(mbhc, false); wcd9xxx_cleanup_hs_polling(mbhc); wcd9xxx_report_plug(mbhc, 0, SND_JACK_HEADSET); is_removed = true; Loading Loading @@ -4351,16 +4370,13 @@ static int wcd9xxx_detect_impedance(struct wcd9xxx_mbhc *mbhc, uint32_t *zl, */ mutex_lock(&codec->mutex); WCD9XXX_BG_CLK_LOCK(mbhc->resmgr); /* * Fast(mbhc) mode bandagap doesn't need to be enabled explicitly * since fast mode is set by MBHC hardware when override is on. * Enable bandgap mode to avoid unnecessary RCO disable and enable * during clock source change. */ wcd9xxx_resmgr_get_bandgap(mbhc->resmgr, WCD9XXX_BANDGAP_AUDIO_MODE); wcd9xxx_resmgr_get_clk_block(mbhc->resmgr, WCD9XXX_CLK_RCO); WCD9XXX_BG_CLK_UNLOCK(mbhc->resmgr); wcd9xxx_mbhc_ctrl_clk_bandgap(mbhc, true); wcd9xxx_turn_onoff_override(mbhc, true); pr_debug("%s: Setting impedance detection\n", __func__); Loading Loading @@ -4408,10 +4424,7 @@ static int wcd9xxx_detect_impedance(struct wcd9xxx_mbhc *mbhc, uint32_t *zl, mutex_unlock(&codec->mutex); WCD9XXX_BG_CLK_LOCK(mbhc->resmgr); wcd9xxx_resmgr_put_bandgap(mbhc->resmgr, WCD9XXX_BANDGAP_AUDIO_MODE); wcd9xxx_resmgr_put_clk_block(mbhc->resmgr, WCD9XXX_CLK_RCO); WCD9XXX_BG_CLK_UNLOCK(mbhc->resmgr); wcd9xxx_mbhc_ctrl_clk_bandgap(mbhc, false); wcd9xxx_turn_onoff_override(mbhc, false); mbhc->mbhc_cb->compute_impedance(l, r, zl, zr); Loading