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

Commit 02a2c6ee 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: ensure regulator is on during plug detection"

parents 33880fc4 91956c1a
Loading
Loading
Loading
Loading
+33 −1
Original line number Diff line number Diff line
@@ -189,6 +189,8 @@ static int msm8x16_wcd_dt_parse_vreg_info(struct device *dev,
	const char *vreg_name, bool ondemand);
static struct msm8x16_wcd_pdata *msm8x16_wcd_populate_dt_pdata(
	struct device *dev);
static int msm8x16_wcd_enable_ext_mb_source(struct snd_soc_codec *codec,
					    bool turn_on);

struct msm8x16_wcd_spmi msm8x16_wcd_modules[MAX_MSM8X16_WCD_DEVICE];

@@ -196,6 +198,11 @@ static void *modem_state_notifier;

static struct snd_soc_codec *registered_codec;

static const struct wcd_mbhc_cb mbhc_cb = {
	.enable_mb_source = msm8x16_wcd_enable_ext_mb_source,
};


static int get_spmi_msm8x16_wcd_device_info(u16 *reg,
			struct msm8x16_wcd_spmi **msm8x16_wcd)
{
@@ -1761,6 +1768,30 @@ static int msm8x16_wcd_codec_enable_dmic(struct snd_soc_dapm_widget *w,
	return 0;
}

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

	if (turn_on)
		ret = snd_soc_dapm_force_enable_pin(&codec->dapm,
				"MICBIAS_REGULATOR");
	else
		ret = snd_soc_dapm_disable_pin(&codec->dapm,
				"MICBIAS_REGULATOR");

	snd_soc_dapm_sync(&codec->dapm);

	if (ret)
		dev_err(codec->dev, "%s: Failed to %s external micbias source\n",
			__func__, turn_on ? "enable" : "disabled");
	else
		dev_dbg(codec->dev, "%s: %s external micbias source\n",
			 __func__, turn_on ? "Enabled" : "Disabled");

	return ret;
}

static int msm8x16_wcd_codec_enable_micbias(struct snd_soc_dapm_widget *w,
	struct snd_kcontrol *kcontrol, int event)
{
@@ -3171,7 +3202,8 @@ static int msm8x16_wcd_codec_probe(struct snd_soc_codec *codec)
				on_demand_supply_name[ON_DEMAND_MICBIAS]);
	atomic_set(&msm8x16_wcd_priv->on_demand_list[ON_DEMAND_MICBIAS].ref, 0);

	wcd_mbhc_init(&msm8x16_wcd_priv->mbhc, codec, &intr_ids, true);
	wcd_mbhc_init(&msm8x16_wcd_priv->mbhc, codec, &mbhc_cb, &intr_ids,
			false);

	msm8x16_wcd_priv->mclk_enabled = false;
	msm8x16_wcd_priv->clock_active = false;
+18 −0
Original line number Diff line number Diff line
@@ -609,6 +609,9 @@ static void wcd_correct_swch_plug(struct work_struct *work)
		plug_type = MBHC_PLUG_TYPE_INVALID;

	if (plug_type == MBHC_PLUG_TYPE_HIGH_HPH) {
		/* 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);

		/* Enable micbias if not already enabled*/
		snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_2_EN,
@@ -665,6 +668,10 @@ static void wcd_correct_swch_plug(struct work_struct *work)
		if (!mbhc->micbias_enable)
			snd_soc_write(codec, MSM8X16_WCD_A_ANALOG_MICB_1_VAL,
			0x20);

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

	wcd_mbhc_find_plug_and_report(mbhc, plug_type);
@@ -687,6 +694,11 @@ static void wcd_mbhc_detect_plug_type(struct wcd_mbhc *mbhc)
	snd_soc_update_bits(codec,
			MSM8X16_WCD_A_ANALOG_MICB_2_EN,
			0x80, 0x80);

	/* 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);

	/*
	 * Wait for 50msec for FSM to complete its task.
	 * wakeup if btn pres intr occurs
@@ -771,6 +783,10 @@ eu_us_switch:
	snd_soc_update_bits(codec,
		MSM8X16_WCD_A_ANALOG_MICB_2_EN,
		0x80, 0x00);
	/* Disable external voltage source to micbias if present */
	if (mbhc->mbhc_cb && mbhc->mbhc_cb->enable_mb_source)
		mbhc->mbhc_cb->enable_mb_source(codec, false);

	pr_debug("%s: Valid plug found, plug type is %d\n",
			 __func__, plug_type);
	if (plug_type != MBHC_PLUG_TYPE_HIGH_HPH &&
@@ -1175,6 +1191,7 @@ EXPORT_SYMBOL(wcd_mbhc_stop);
 * NOTE: mbhc->mbhc_cfg is not YET configure so shouldn't be used
 */
int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec,
		      const struct wcd_mbhc_cb *mbhc_cb,
		      const struct wcd_mbhc_intr *mbhc_cdc_intr_ids,
		      bool impedance_det_en)
{
@@ -1209,6 +1226,7 @@ int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec,
	mbhc->hphl_swh = hph_swh;
	mbhc->gnd_swh = gnd_swh;
	mbhc->micbias_enable = false;
	mbhc->mbhc_cb = mbhc_cb;

	if (mbhc->intr_ids == NULL) {
		pr_err("%s: Interrupt mapping not provided\n", __func__);
+6 −0
Original line number Diff line number Diff line
@@ -61,9 +61,14 @@ struct wcd_mbhc_intr {
	int hph_right_ocp;
};

struct wcd_mbhc_cb {
	int (*enable_mb_source) (struct snd_soc_codec *, bool);
};

struct wcd_mbhc {
	int buttons_pressed;
	struct wcd_mbhc_config *mbhc_cfg;
	const struct wcd_mbhc_cb *mbhc_cb;

	u32 hph_status; /* track headhpone status */
	u8 hphlocp_cnt; /* headphone left ocp retry */
@@ -107,6 +112,7 @@ int wcd_mbhc_start(struct wcd_mbhc *mbhc,
		       struct wcd_mbhc_config *mbhc_cfg);
void wcd_mbhc_stop(struct wcd_mbhc *mbhc);
int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec,
		      const struct wcd_mbhc_cb *mbhc_cb,
		      const struct wcd_mbhc_intr *mbhc_cdc_intr_ids,
		      bool impedance_det_en);
void wcd_mbhc_deinit(struct wcd_mbhc *mbhc);