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

Commit b8181945 authored by Simmi Pateriya's avatar Simmi Pateriya
Browse files

ASoC: wcd9xxx: Prevent disabling of internal micbias



If recording is also using internal micbias, then after recording
ends, the dapm widget power down callback will reset the state of
internal micbias in codec register. To avoid such issues make sure
internal micbias is enabled while headset detection, button press
detection and polling.

CRs-fixed: 565636
CRs-fixed: 565389
Change-Id: I3c98eae4b958fbf3e0050bc8aa49844755f4c21d
Signed-off-by: default avatarSimmi Pateriya <simmip@codeaurora.org>
parent 0afd40fe
Loading
Loading
Loading
Loading
+37 −6
Original line number Diff line number Diff line
@@ -222,6 +222,19 @@ static void wcd9xxx_start_hs_polling(struct wcd9xxx_mbhc *mbhc)
		pr_debug("Polling is not active, do not start polling\n");
		return;
	}

	/*
	 * setup internal micbias if codec uses internal micbias for
	 * headset detection
	 */
	if (mbhc->mbhc_cfg->use_int_rbias && !mbhc->int_rbias_on) {
		if (mbhc->mbhc_cb && mbhc->mbhc_cb->setup_int_rbias)
			mbhc->mbhc_cb->setup_int_rbias(codec, true);
		else
			pr_err("%s: internal bias requested but codec did not provide callback\n",
				__func__);
	}

	snd_soc_write(codec, WCD9XXX_A_MBHC_SCALING_MUX_1, 0x04);
	if (mbhc->mbhc_cb && mbhc->mbhc_cb->enable_mux_bias_block)
		mbhc->mbhc_cb->enable_mux_bias_block(codec);
@@ -1090,11 +1103,11 @@ static short wcd9xxx_mbhc_setup_hs_polling(struct wcd9xxx_mbhc *mbhc,
	 * setup internal micbias if codec uses internal micbias for
	 * headset detection
	 */
	if (mbhc->mbhc_cfg->use_int_rbias) {
	if (mbhc->mbhc_cfg->use_int_rbias && !mbhc->int_rbias_on) {
		if (mbhc->mbhc_cb && mbhc->mbhc_cb->setup_int_rbias)
			mbhc->mbhc_cb->setup_int_rbias(codec, true);
	else
		pr_err("%s: internal bias is requested but codec did not provide callback\n",
		pr_err("%s: internal bias requested but codec did not provide callback\n",
			__func__);
	}

@@ -3166,6 +3179,19 @@ irqreturn_t wcd9xxx_dce_handler(int irq, void *data)
		goto done;
	}

	/*
	 * setup internal micbias if codec uses internal micbias for
	 * headset detection
	 */
	if (mbhc->mbhc_cfg->use_int_rbias && !mbhc->int_rbias_on) {
		if (mbhc->mbhc_cb && mbhc->mbhc_cb->setup_int_rbias)
			mbhc->mbhc_cb->setup_int_rbias(codec, true);
		else
			pr_err("%s: internal bias requested but codec did not provide callback\n",
				__func__);
	}


	/* Measure scaled HW DCE */
	vddio = (mbhc->mbhc_data.micb_mv != VDDIO_MICBIAS_MV &&
		 mbhc->mbhc_micbias_switched);
@@ -3986,12 +4012,14 @@ int wcd9xxx_mbhc_start(struct wcd9xxx_mbhc *mbhc,
	 * headset detection
	 */
	if (mbhc->mbhc_cfg->use_int_rbias) {
		if (mbhc->mbhc_cb && mbhc->mbhc_cb->setup_int_rbias)
		if (mbhc->mbhc_cb && mbhc->mbhc_cb->setup_int_rbias) {
			mbhc->mbhc_cb->setup_int_rbias(codec, true);
		else
			pr_info("%s: internal bias is requested but codec did not provide callback\n",
			mbhc->int_rbias_on = true;
		} else {
			pr_info("%s: internal bias requested but codec did not provide callback\n",
				__func__);
		}
	}

	/*
	 * If codec has specific clock gating for MBHC,
@@ -4145,6 +4173,7 @@ static int wcd9xxx_event_notify(struct notifier_block *self, unsigned long val,
	case WCD9XXX_EVENT_PRE_MICBIAS_2_ON:
	case WCD9XXX_EVENT_PRE_MICBIAS_3_ON:
	case WCD9XXX_EVENT_PRE_MICBIAS_4_ON:
		mbhc->int_rbias_on = true;
		if (mbhc->mbhc_cfg && mbhc->mbhc_cfg->micbias ==
		    wcd9xxx_event_to_micbias(event)) {
			wcd9xxx_switch_micbias(mbhc, 0);
@@ -4172,6 +4201,7 @@ static int wcd9xxx_event_notify(struct notifier_block *self, unsigned long val,
	case WCD9XXX_EVENT_POST_MICBIAS_2_OFF:
	case WCD9XXX_EVENT_POST_MICBIAS_3_OFF:
	case WCD9XXX_EVENT_POST_MICBIAS_4_OFF:
		mbhc->int_rbias_on = false;
		if (mbhc->mbhc_cfg && mbhc->mbhc_cfg->micbias ==
		    wcd9xxx_event_to_micbias(event)) {
			if (mbhc->event_state &
@@ -4466,6 +4496,7 @@ int wcd9xxx_mbhc_init(struct wcd9xxx_mbhc *mbhc, struct wcd9xxx_resmgr *resmgr,
	mbhc->mbhc_cb = mbhc_cb;
	mbhc->intr_ids = mbhc_cdc_intr_ids;
	mbhc->impedance_detect = impedance_det_en;
	mbhc->int_rbias_on = false;

	if (mbhc->intr_ids == NULL) {
		pr_err("%s: Interrupt mapping not provided\n", __func__);
+1 −1
Original line number Diff line number Diff line
@@ -336,7 +336,7 @@ struct wcd9xxx_mbhc {
	u32 rco_clk_rate;

	bool update_z;

	bool int_rbias_on;
	/* Holds codec specific interrupt mapping */
	const struct wcd9xxx_mbhc_intr *intr_ids;