Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a23dbdab authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "ASoC: wcd9xxx: Correct clk and Bandgap handling"

parents b34c8598 2f8e4ff9
Loading
Loading
Loading
Loading
+35 −22
Original line number Diff line number Diff line
@@ -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)
@@ -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 */
@@ -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)
@@ -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;
@@ -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;
@@ -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;
@@ -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;
}
@@ -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 */
@@ -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,
@@ -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,
@@ -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;
@@ -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__);
@@ -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);