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

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

Merge "ASoC: wcd: move cap setting to codec driver"

parents fbb06e90 95caeb55
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),

@@ -2187,6 +2187,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) {
@@ -2201,6 +2203,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)) {
@@ -2211,6 +2214,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);

@@ -2229,6 +2233,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)) {
@@ -2247,8 +2253,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;
@@ -3457,8 +3463,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,
@@ -3683,6 +3691,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);
@@ -3778,6 +3787,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;
@@ -3879,6 +3922,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__);
@@ -2279,6 +2296,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);