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

Commit 95caeb55 authored by Yeleswarapu Nagaradhesh's avatar Yeleswarapu Nagaradhesh Committed by Simmi Pateriya
Browse files

ASoC: wcd: move cap setting to codec driver



Cap setting is needed for any micbias and so it should be done
from codec driver instead of mbhc driver which uses only micbias2.
Codec driver will read the device tree to find out if external cap
is present or not and will set the bit for cap setting accordingly.

Change-Id: I20d2a104915977929a591260bcd0ea9a48ad475b
Signed-off-by: default avatarSimmi Pateriya <simmip@codeaurora.org>
Signed-off-by: default avatarYeleswarapu Nagaradhesh <nagaradh@codeaurora.org>
parent dbd2b72e
Loading
Loading
Loading
Loading
+53 −8
Original line number Diff line number Diff line
@@ -187,6 +187,8 @@ static void msm8x16_wcd_set_micb_v(struct snd_soc_codec *codec);
static void msm8x16_wcd_set_boost_v(struct snd_soc_codec *codec);
static void msm8x16_wcd_set_auto_zeroing(struct snd_soc_codec *codec,
		bool enable);
static void msm8x16_wcd_configure_cap(struct snd_soc_codec *codec,
		bool micbias1, bool micbias2);

struct msm8x16_wcd_spmi msm8x16_wcd_modules[MAX_MSM8X16_WCD_DEVICE];

@@ -243,6 +245,7 @@ static const struct wcd_mbhc_cb mbhc_cb = {
	.set_micbias_value = msm8x16_wcd_set_micb_v,
	.set_auto_zeroing = msm8x16_wcd_set_auto_zeroing,
	.get_hwdep_fw_cal = msm8x16_wcd_get_hwdep_fw_cal,
	.set_cap_mode = msm8x16_wcd_configure_cap,
};

static const uint32_t wcd_imped_val[] = {4, 8, 12, 16,
@@ -1391,9 +1394,6 @@ static const struct snd_kcontrol_new msm8x16_wcd_snd_controls[] = {
			  MSM8X16_WCD_A_CDC_IIR2_GAIN_B1_CTL,
			0,  -84, 40, digital_gain),

	SOC_SINGLE("MICBIAS CAPLESS Switch",
		   MSM8X16_WCD_A_ANALOG_MICB_1_EN, 6, 1, 0),

	SOC_ENUM("TX1 HPF cut off", cf_dec1_enum),
	SOC_ENUM("TX2 HPF cut off", cf_dec2_enum),

@@ -2207,6 +2207,8 @@ static int msm8x16_wcd_codec_enable_micbias(struct snd_soc_dapm_widget *w,
	char *internal2_text = "Internal2";
	char *internal3_text = "Internal3";
	char *external2_text = "External2";
	char *external_text = "External";
	bool micbias2;

	dev_dbg(codec->dev, "%s %d\n", __func__, event);
	switch (w->reg) {
@@ -2221,6 +2223,7 @@ static int msm8x16_wcd_codec_enable_micbias(struct snd_soc_dapm_widget *w,
		return -EINVAL;
	}

	micbias2 = (snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MICB_2_EN) & 0x80);
	switch (event) {
	case SND_SOC_DAPM_PRE_PMU:
		if (strnstr(w->name, internal1_text, 30)) {
@@ -2231,6 +2234,7 @@ static int msm8x16_wcd_codec_enable_micbias(struct snd_soc_dapm_widget *w,
		} else if (strnstr(w->name, internal3_text, 30)) {
			snd_soc_update_bits(codec, micb_int_reg, 0x2, 0x2);
		}
		if (!strnstr(w->name, external_text, 30))
			snd_soc_update_bits(codec,
				MSM8X16_WCD_A_ANALOG_MICB_1_EN, 0x05, 0x04);

@@ -2249,6 +2253,8 @@ static int msm8x16_wcd_codec_enable_micbias(struct snd_soc_dapm_widget *w,
			msm8x16_notifier_call(codec,
					WCD_EVENT_PRE_MICBIAS_2_ON);
		}
		if (w->reg == MSM8X16_WCD_A_ANALOG_MICB_1_EN)
			msm8x16_wcd_configure_cap(codec, true, micbias2);
		break;
	case SND_SOC_DAPM_POST_PMD:
		if (strnstr(w->name, internal1_text, 30)) {
@@ -2267,8 +2273,8 @@ static int msm8x16_wcd_codec_enable_micbias(struct snd_soc_dapm_widget *w,
					WCD_EVENT_PRE_MICBIAS_2_OFF);
			break;
		}
		snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN,
				0x44, 0x00);
		if (w->reg == MSM8X16_WCD_A_ANALOG_MICB_1_EN)
			msm8x16_wcd_configure_cap(codec, false, micbias2);
		break;
	}
	return 0;
@@ -3477,8 +3483,10 @@ static const struct snd_soc_dapm_widget msm8x16_wcd_dapm_widgets[] = {
	SND_SOC_DAPM_VIRT_MUX("ADC2 MUX", SND_SOC_NOPM, 0, 0,
		&tx_adc2_mux),

	SND_SOC_DAPM_MICBIAS("MIC BIAS External",
		MSM8X16_WCD_A_ANALOG_MICB_1_EN, 7, 0),
	SND_SOC_DAPM_MICBIAS_E("MIC BIAS External",
		MSM8X16_WCD_A_ANALOG_MICB_1_EN, 7, 0,
		msm8x16_wcd_codec_enable_micbias, SND_SOC_DAPM_POST_PMU |
		SND_SOC_DAPM_POST_PMD),

	SND_SOC_DAPM_MICBIAS_E("MIC BIAS External2",
		MSM8X16_WCD_A_ANALOG_MICB_2_EN, 7, 0,
@@ -3703,6 +3711,7 @@ static int msm8x16_wcd_device_up(struct snd_soc_codec *codec)
	msm8x16_wcd_set_boost_v(codec);

	msm8x16_wcd_set_micb_v(codec);
	msm8x16_wcd_configure_cap(codec, false, false);
	wcd_mbhc_stop(&msm8x16_wcd_priv->mbhc);
	wcd_mbhc_start(&msm8x16_wcd_priv->mbhc,
			msm8x16_wcd_priv->mbhc.mbhc_cfg);
@@ -3798,6 +3807,40 @@ static void msm8x16_wcd_set_boost_v(struct snd_soc_codec *codec)
			0x1F, msm8x16_wcd_priv->boost_voltage);
}

static void msm8x16_wcd_configure_cap(struct snd_soc_codec *codec,
		bool micbias1, bool micbias2)
{

	struct msm8916_asoc_mach_data *pdata = NULL;

	pdata = snd_soc_card_get_drvdata(codec->card);

	pr_debug("\n %s: micbias1 %x micbias2 = %d\n", __func__, micbias1,
			micbias2);
	if (micbias1 && micbias2) {
		if ((pdata->micbias1_cap_mode
		     == MICBIAS_EXT_BYP_CAP) ||
		    (pdata->micbias2_cap_mode
		     == MICBIAS_EXT_BYP_CAP))
			snd_soc_update_bits(codec,
				MSM8X16_WCD_A_ANALOG_MICB_1_EN,
				0x40, (MICBIAS_EXT_BYP_CAP << 6));
		else
			snd_soc_update_bits(codec,
				MSM8X16_WCD_A_ANALOG_MICB_1_EN,
				0x40, (MICBIAS_NO_EXT_BYP_CAP << 6));
	} else if (micbias2) {
		snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN,
				0x40, (pdata->micbias2_cap_mode << 6));
	} else if (micbias1) {
		snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN,
				0x40, (pdata->micbias1_cap_mode << 6));
	} else {
		snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN,
				0x40, 0x00);
	}
}

static int msm8x16_wcd_codec_probe(struct snd_soc_codec *codec)
{
	struct msm8x16_wcd_priv *msm8x16_wcd_priv;
@@ -3899,6 +3942,8 @@ static int msm8x16_wcd_codec_probe(struct snd_soc_codec *codec)
	/* Set initial MICBIAS voltage level */
	msm8x16_wcd_set_micb_v(codec);

	/* Set initial cap mode */
	msm8x16_wcd_configure_cap(codec, false, false);
	registered_codec = codec;
	modem_state_notifier =
	    subsys_notif_register_notifier("modem",
+2 −0
Original line number Diff line number Diff line
@@ -162,6 +162,8 @@ struct msm8916_asoc_mach_data {
	int us_euro_gpio;
	int mclk_freq;
	int lb_mode;
	u8 micbias1_cap_mode;
	u8 micbias2_cap_mode;
	atomic_t mclk_rsc_ref;
	atomic_t mclk_enabled;
	struct mutex cdc_mclk_mutex;
+21 −48
Original line number Diff line number Diff line
@@ -85,36 +85,6 @@ enum wcd_mbhc_cs_mb_en_flag {
	WCD_MBHC_EN_NONE,
};

static void wcd_configure_cap(struct wcd_mbhc *mbhc, bool micbias2)
{
	u16 micbias1;
	struct snd_soc_codec *codec = mbhc->codec;

	micbias1 = snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN);
	pr_debug("\n %s: micbias1 %x micbias2 = %d\n", __func__, micbias1,
			micbias2);
	if ((micbias1 & 0x80) && micbias2) {
		if ((mbhc->micbias1_cap_mode == MICBIAS_EXT_BYP_CAP) ||
			(mbhc->micbias2_cap_mode == MICBIAS_EXT_BYP_CAP))
			snd_soc_update_bits(codec,
				MSM8X16_WCD_A_ANALOG_MICB_1_EN,
				0x40, (MICBIAS_EXT_BYP_CAP << 6));
		else
			snd_soc_update_bits(codec,
				MSM8X16_WCD_A_ANALOG_MICB_1_EN,
				0x40, (MICBIAS_NO_EXT_BYP_CAP << 6));
	} else if (micbias2) {
		snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN,
				0x40, (mbhc->micbias2_cap_mode << 6));
	} else if (micbias1 & 0x80) {
		snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN,
				0x40, (mbhc->micbias1_cap_mode << 6));
	} else {
		snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN,
				0x40, 0x00);
	}
}

static void wcd_mbhc_jack_report(struct wcd_mbhc *mbhc,
				struct snd_soc_jack *jack, int status, int mask)
{
@@ -272,10 +242,12 @@ static int wcd_event_notify(struct notifier_block *self, unsigned long val,
	struct msm8x16_wcd_priv *msm8x16_wcd = snd_soc_codec_get_drvdata(codec);
	struct wcd_mbhc *mbhc = &msm8x16_wcd->mbhc;
	enum wcd_notify_event event = (enum wcd_notify_event)val;
	u16 micbias2;
	bool micbias2;
	bool micbias1;

	pr_debug("%s: event %d\n", __func__, event);
	micbias2 = (snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MICB_2_EN) & 0x80);
	micbias1 = (snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN) & 0x80);
	switch (event) {
	/* MICBIAS usage change */
	case WCD_EVENT_PRE_MICBIAS_2_ON:
@@ -301,7 +273,8 @@ static int wcd_event_notify(struct notifier_block *self, unsigned long val,
		wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_MB);
		mbhc->is_hs_recording = true;
		/* configure cap settings properly when micbias is enabled */
		wcd_configure_cap(mbhc, true);
		if (mbhc->mbhc_cb && mbhc->mbhc_cb->set_cap_mode)
			mbhc->mbhc_cb->set_cap_mode(codec, micbias1, true);
		break;
	/* MICBIAS usage change */
	case WCD_EVENT_PRE_MICBIAS_2_OFF:
@@ -321,7 +294,8 @@ static int wcd_event_notify(struct notifier_block *self, unsigned long val,
			wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_CS);

		/* configure cap settings properly when micbias is disabled */
		wcd_configure_cap(mbhc, false);
		if (mbhc->mbhc_cb && mbhc->mbhc_cb->set_cap_mode)
			mbhc->mbhc_cb->set_cap_mode(codec, micbias1, false);
		break;
	case WCD_EVENT_POST_HPHL_PA_OFF:
		if (mbhc->hph_status & SND_JACK_OC_HPHL)
@@ -963,7 +937,8 @@ static void wcd_correct_swch_plug(struct work_struct *work)
	bool wrk_complete = false;
	int pt_gnd_mic_swap_cnt = 0;
	bool is_pa_on;
	u16 micbias2;
	bool micbias2;
	bool micbias1;

	pr_debug("%s: enter\n", __func__);

@@ -1133,8 +1108,10 @@ report:
	wcd_mbhc_find_plug_and_report(mbhc, plug_type);
	WCD_MBHC_RSC_UNLOCK(mbhc);
exit:
	micbias2 = snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MICB_2_EN);
	wcd_configure_cap(mbhc, (micbias2 & 0x80));
	micbias1 = (snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN) & 0x80);
	micbias2 = (snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MICB_2_EN) & 0x80);
	if (mbhc->mbhc_cb && mbhc->mbhc_cb->set_cap_mode)
		mbhc->mbhc_cb->set_cap_mode(codec, micbias1, micbias2);
	wcd9xxx_spmi_unlock_sleep();
	pr_debug("%s: leave\n", __func__);
}
@@ -1147,14 +1124,17 @@ static void wcd_mbhc_detect_plug_type(struct wcd_mbhc *mbhc)
	enum wcd_mbhc_plug_type plug_type;
	int timeout_result;
	u16 result1, result2;
	bool micbias1;
	bool cross_conn;
	int try = 0;

	pr_debug("%s: enter\n", __func__);
	WCD_MBHC_RSC_ASSERT_LOCKED(mbhc);
	micbias1 = (snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN) & 0x80);
	if (mbhc->mbhc_cb && mbhc->mbhc_cb->set_cap_mode)
		mbhc->mbhc_cb->set_cap_mode(codec, micbias1, true);

	wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_MB);
	wcd_configure_cap(mbhc, true);
	/*
	 * Wait for 50msec for FSM to complete its task.
	 * wakeup if btn pres intr occurs
@@ -1234,8 +1214,8 @@ exit:
static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc)
{
	bool detection_type;
	bool micbias1;
	struct snd_soc_codec *codec = mbhc->codec;

	pr_debug("%s: enter\n", __func__);

	WCD_MBHC_RSC_LOCK(mbhc);
@@ -1257,6 +1237,7 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc)
			mbhc->current_plug, detection_type);
	wcd_cancel_hs_detect_plug(mbhc, &mbhc->correct_plug_swch);

	micbias1 = (snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN) & 0x80);
	if ((mbhc->current_plug == MBHC_PLUG_TYPE_NONE) &&
	    detection_type) {
		/* Make sure MASTER_BIAS_CTL is enabled */
@@ -1300,7 +1281,8 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc)
		snd_soc_update_bits(codec,
				MSM8X16_WCD_A_ANALOG_MICB_1_EN,
				0x04, 0x00);
		wcd_configure_cap(mbhc, false);
		if (mbhc->mbhc_cb && mbhc->mbhc_cb->set_cap_mode)
			mbhc->mbhc_cb->set_cap_mode(codec, micbias1, false);
		mbhc->btn_press_intr = false;
		if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADPHONE) {
			wcd_mbhc_report_plug(mbhc, 0, SND_JACK_HEADPHONE);
@@ -1987,8 +1969,6 @@ int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec,
	struct snd_soc_card *card = codec->card;
	const char *hph_switch = "qcom,msm-mbhc-hphl-swh";
	const char *gnd_switch = "qcom,msm-mbhc-gnd-swh";
	const char *ext1_cap = "qcom,msm-micbias1-ext-cap";
	const char *ext2_cap = "qcom,msm-micbias2-ext-cap";

	pr_debug("%s: enter\n", __func__);

@@ -2005,13 +1985,6 @@ int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec,
			"%s: missing %s in dt node\n", __func__, gnd_switch);
		goto err;
	}
	mbhc->micbias1_cap_mode =
		(of_property_read_bool(card->dev->of_node, ext1_cap) ?
		MICBIAS_EXT_BYP_CAP : MICBIAS_NO_EXT_BYP_CAP);

	mbhc->micbias2_cap_mode =
		(of_property_read_bool(card->dev->of_node, ext2_cap) ?
		MICBIAS_EXT_BYP_CAP : MICBIAS_NO_EXT_BYP_CAP);

	mbhc->in_swch_irq_handler = false;
	mbhc->current_plug = MBHC_PLUG_TYPE_NONE;
+1 −0
Original line number Diff line number Diff line
@@ -146,6 +146,7 @@ struct wcd_mbhc_cb {
	void (*set_auto_zeroing) (struct snd_soc_codec *, bool);
	struct firmware_cal * (*get_hwdep_fw_cal)(struct snd_soc_codec *,
			enum wcd_cal_type);
	void (*set_cap_mode)(struct snd_soc_codec *, bool, bool);
};

struct wcd_mbhc {
+18 −0
Original line number Diff line number Diff line
@@ -1932,6 +1932,23 @@ static int msm8x16_setup_hs_jack(struct platform_device *pdev,
	return 0;
}

static void msm8x16_dt_parse_cap_info(struct platform_device *pdev,
			struct msm8916_asoc_mach_data *pdata)
{
	const char *ext1_cap = "qcom,msm-micbias1-ext-cap";
	const char *ext2_cap = "qcom,msm-micbias2-ext-cap";

	pdata->micbias1_cap_mode =
		(of_property_read_bool(pdev->dev.of_node, ext1_cap) ?
		MICBIAS_EXT_BYP_CAP : MICBIAS_NO_EXT_BYP_CAP);

	pdata->micbias2_cap_mode =
		(of_property_read_bool(pdev->dev.of_node, ext2_cap) ?
		MICBIAS_EXT_BYP_CAP : MICBIAS_NO_EXT_BYP_CAP);

	return;
}

int get_cdc_gpio_lines(struct pinctrl *pinctrl, int ext_pa)
{
	pr_debug("%s\n", __func__);
@@ -2200,6 +2217,7 @@ static int msm8x16_asoc_machine_probe(struct platform_device *pdev)
	pdata->lb_mode = false;

	msm8x16_setup_hs_jack(pdev, pdata);
	msm8x16_dt_parse_cap_info(pdev, pdata);

	card->dev = &pdev->dev;
	platform_set_drvdata(pdev, card);