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

Commit 95b97c32 authored by Phani Kumar Uppalapati's avatar Phani Kumar Uppalapati
Browse files

ASoC: wcd9xxx: Do not use dapm to power up cdc-vdd-mic-bias



Do not use alsa dapm to power up cdc-vdd-mic-bias power supply.
Due to sound card is not initialized, powering up this dapm widget
would get delayed. This leads to wrong mbhc calibration values.

Change-Id: I4e1f3cf523ea9f771b9993317dfd515def2b0615
Signed-off-by: default avatarPhani Kumar Uppalapati <phaniu@codeaurora.org>
parent f75c756e
Loading
Loading
Loading
Loading
+66 −25
Original line number Diff line number Diff line
@@ -167,6 +167,10 @@ static char on_demand_supply_name[][MAX_ON_DEMAND_SUPPLY_NAME_LENGTH] = {
	"cdc-vdda-cp",
};

static int on_demand_regulator_control(struct on_demand_supply *supply,
				       bool enable,
				       u8 shift);

struct msm8x10_wcd_priv {
	struct snd_soc_codec *codec;
	u32 adc_count;
@@ -784,6 +788,39 @@ err:
	return NULL;
}

static int on_demand_regulator_control(struct on_demand_supply *supply,
				       bool enable,
				       u8 shift)
{
	int ret = 0;

	if (!supply || !supply->supply)
		return 0;

	if (enable) {
		if (atomic_inc_return(&supply->ref) == 1)
			ret = regulator_enable(supply->supply);
		if (ret)
			pr_err("%s: Failed to enable %s\n",
					__func__,
					on_demand_supply_name[shift]);
	} else {
		if (atomic_read(&supply->ref) == 0) {
			pr_debug("%s: %s supply has been disabled.\n",
					__func__, on_demand_supply_name[shift]);
			return 0;
		}
		if (atomic_dec_return(&supply->ref) == 0)
			ret = regulator_disable(supply->supply);
		if (ret)
			pr_err("%s: Failed to disable %s\n",
					__func__,
					on_demand_supply_name[shift]);
	}

	return ret;
}

static int msm8x10_wcd_codec_enable_on_demand_supply(
		struct snd_soc_dapm_widget *w,
		struct snd_kcontrol *kcontrol, int event)
@@ -809,25 +846,14 @@ static int msm8x10_wcd_codec_enable_on_demand_supply(

	switch (event) {
	case SND_SOC_DAPM_PRE_PMU:
		if (atomic_inc_return(&supply->ref) == 1)
			ret = regulator_enable(supply->supply);
		if (ret)
			dev_err(codec->dev, "%s: Failed to enable %s\n",
				__func__,
				on_demand_supply_name[w->shift]);
		ret = on_demand_regulator_control(supply,
						  true,
						  w->shift);
		break;
	case SND_SOC_DAPM_POST_PMD:
		if (atomic_read(&supply->ref) == 0) {
			dev_dbg(codec->dev, "%s: %s supply has been disabled.\n",
				 __func__, on_demand_supply_name[w->shift]);
			goto out;
		}
		if (atomic_dec_return(&supply->ref) == 0)
			ret = regulator_disable(supply->supply);
			if (ret)
				dev_err(codec->dev, "%s: Failed to disable %s\n",
					__func__,
					on_demand_supply_name[w->shift]);
		ret = on_demand_regulator_control(supply,
						  false,
						  w->shift);
		break;
	default:
		break;
@@ -2737,10 +2763,12 @@ static void msm8x10_wcd_mbhc_txfe(struct snd_soc_codec *codec, bool on)
}

static int msm8x10_wcd_enable_ext_mb_source(struct snd_soc_codec *codec,
	bool turn_on)
					    bool turn_on,
					    bool use_dapm)
{
	int ret = 0;

	if (use_dapm) {
		if (turn_on)
			ret = snd_soc_dapm_force_enable_pin(&codec->dapm,
					"MICBIAS_REGULATOR");
@@ -2749,6 +2777,19 @@ static int msm8x10_wcd_enable_ext_mb_source(struct snd_soc_codec *codec,
					"MICBIAS_REGULATOR");

		snd_soc_dapm_sync(&codec->dapm);
	} else {
		struct on_demand_supply *supply;
		struct msm8x10_wcd_priv *msm8x10_wcd =
				snd_soc_codec_get_drvdata(codec);

		supply = &msm8x10_wcd->on_demand_list[ON_DEMAND_MICBIAS];
		if (!supply || !supply->supply || !msm8x10_wcd)
			return 0;

		ret = on_demand_regulator_control(supply,
						  turn_on,
						  ON_DEMAND_MICBIAS);
	}

	if (ret)
		dev_err(codec->dev, "%s: Failed to %s external micbias source\n",
+5 −5
Original line number Diff line number Diff line
/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -1155,7 +1155,7 @@ static short wcd9xxx_mbhc_setup_hs_polling(struct wcd9xxx_mbhc *mbhc,
	btn_det = WCD9XXX_MBHC_CAL_BTN_DET_PTR(mbhc->mbhc_cfg->calibration);
	/* Enable external voltage source to micbias if present */
	if (mbhc->mbhc_cb && mbhc->mbhc_cb->enable_mb_source)
		mbhc->mbhc_cb->enable_mb_source(codec, true);
		mbhc->mbhc_cb->enable_mb_source(codec, true, true);

	/*
	 * setup internal micbias if codec uses internal micbias for
@@ -1298,7 +1298,7 @@ static void wcd9xxx_cleanup_hs_polling(struct wcd9xxx_mbhc *mbhc)

	/* Disable external voltage source to micbias if present */
	if (mbhc->mbhc_cb && mbhc->mbhc_cb->enable_mb_source)
		mbhc->mbhc_cb->enable_mb_source(mbhc->codec, false);
		mbhc->mbhc_cb->enable_mb_source(mbhc->codec, false, true);

	mbhc->polling_active = false;
	mbhc->mbhc_state = MBHC_STATE_NONE;
@@ -3790,7 +3790,7 @@ static void wcd9xxx_mbhc_cal(struct wcd9xxx_mbhc *mbhc)
	 * turn on the external voltage source for Calibration.
	 */
	if (mbhc->mbhc_cb && mbhc->mbhc_cb->enable_mb_source)
		mbhc->mbhc_cb->enable_mb_source(codec, true);
		mbhc->mbhc_cb->enable_mb_source(codec, true, false);

	cfilt_mode = snd_soc_read(codec, mbhc->mbhc_bias_regs.cfilt_ctl);
	if (mbhc->mbhc_cb && mbhc->mbhc_cb->cfilt_fast_mode)
@@ -3912,7 +3912,7 @@ static void wcd9xxx_mbhc_cal(struct wcd9xxx_mbhc *mbhc)
	usleep_range(100, 100);

	if (mbhc->mbhc_cb && mbhc->mbhc_cb->enable_mb_source)
		mbhc->mbhc_cb->enable_mb_source(codec, false);
		mbhc->mbhc_cb->enable_mb_source(codec, false, false);

	wcd9xxx_enable_irq(mbhc->resmgr->core_res,
			   mbhc->intr_ids->dce_est_complete);
+2 −2
Original line number Diff line number Diff line
/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -274,7 +274,7 @@ struct wcd9xxx_mbhc_cb {
			   enum mbhc_impedance_detect_stages stage);
	void (*compute_impedance) (s16 *, s16 *, uint32_t *, uint32_t *);
	void (*enable_mbhc_txfe) (struct snd_soc_codec *, bool);
	int (*enable_mb_source) (struct snd_soc_codec *, bool);
	int (*enable_mb_source) (struct snd_soc_codec *, bool, bool);
	void (*setup_int_rbias) (struct snd_soc_codec *, bool);
	void (*pull_mb_to_vddio) (struct snd_soc_codec *, bool);
};