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

Commit 1e570a83 authored by Mark Brown's avatar Mark Brown
Browse files

Merge remote-tracking branches 'asoc/fix/da7219-pops' and 'asoc/fix/qcom' into asoc-linus

Loading
Loading
Loading
Loading
+14 −4
Original line number Diff line number Diff line
@@ -204,10 +204,19 @@ static void da7219_aad_hptest_work(struct work_struct *work)
	snd_soc_update_bits(codec, DA7219_MIXOUT_R_CTRL,
			    DA7219_MIXOUT_R_AMP_EN_MASK,
			    DA7219_MIXOUT_R_AMP_EN_MASK);
	snd_soc_write(codec, DA7219_HP_L_CTRL,
	snd_soc_update_bits(codec, DA7219_HP_L_CTRL,
			    DA7219_HP_L_AMP_OE_MASK | DA7219_HP_L_AMP_EN_MASK,
			    DA7219_HP_L_AMP_OE_MASK | DA7219_HP_L_AMP_EN_MASK);
	snd_soc_write(codec, DA7219_HP_R_CTRL,
	snd_soc_update_bits(codec, DA7219_HP_R_CTRL,
			    DA7219_HP_R_AMP_OE_MASK | DA7219_HP_R_AMP_EN_MASK,
			    DA7219_HP_R_AMP_OE_MASK | DA7219_HP_R_AMP_EN_MASK);
	msleep(DA7219_SETTLING_DELAY);
	snd_soc_update_bits(codec, DA7219_HP_L_CTRL,
			    DA7219_HP_L_AMP_MUTE_EN_MASK |
			    DA7219_HP_L_AMP_MIN_GAIN_EN_MASK, 0);
	snd_soc_update_bits(codec, DA7219_HP_R_CTRL,
			    DA7219_HP_R_AMP_MUTE_EN_MASK |
			    DA7219_HP_R_AMP_MIN_GAIN_EN_MASK, 0);

	/*
	 * If we're running from the internal oscillator then give audio paths
@@ -244,6 +253,7 @@ static void da7219_aad_hptest_work(struct work_struct *work)
	regcache_mark_dirty(da7219->regmap);
	regcache_sync_region(da7219->regmap, DA7219_HP_L_CTRL,
			     DA7219_HP_R_CTRL);
	msleep(DA7219_SETTLING_DELAY);
	regcache_sync_region(da7219->regmap, DA7219_MIXOUT_L_CTRL,
			     DA7219_MIXOUT_R_CTRL);
	regcache_sync_region(da7219->regmap, DA7219_DROUTING_ST_OUTFILT_1L,
+121 −18
Original line number Diff line number Diff line
@@ -823,6 +823,85 @@ static int da7219_dai_event(struct snd_soc_dapm_widget *w,
	}
}

static int da7219_settling_event(struct snd_soc_dapm_widget *w,
				 struct snd_kcontrol *kcontrol, int event)
{
	switch (event) {
	case SND_SOC_DAPM_POST_PMU:
	case SND_SOC_DAPM_POST_PMD:
		msleep(DA7219_SETTLING_DELAY);
		break;
	default:
		break;
	}

	return 0;
}

static int da7219_mixout_event(struct snd_soc_dapm_widget *w,
			       struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
	u8 hp_ctrl, min_gain_mask;

	switch (w->reg) {
	case DA7219_MIXOUT_L_CTRL:
		hp_ctrl = DA7219_HP_L_CTRL;
		min_gain_mask = DA7219_HP_L_AMP_MIN_GAIN_EN_MASK;
		break;
	case DA7219_MIXOUT_R_CTRL:
		hp_ctrl = DA7219_HP_R_CTRL;
		min_gain_mask = DA7219_HP_R_AMP_MIN_GAIN_EN_MASK;
		break;
	default:
		return -EINVAL;
	}

	switch (event) {
	case SND_SOC_DAPM_PRE_PMD:
		/* Enable minimum gain on HP to avoid pops */
		snd_soc_update_bits(codec, hp_ctrl, min_gain_mask,
				    min_gain_mask);

		msleep(DA7219_MIN_GAIN_DELAY);

		break;
	case SND_SOC_DAPM_POST_PMU:
		/* Remove minimum gain on HP */
		snd_soc_update_bits(codec, hp_ctrl, min_gain_mask, 0);

		break;
	}

	return 0;
}

static int da7219_gain_ramp_event(struct snd_soc_dapm_widget *w,
				  struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
	struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);

	switch (event) {
	case SND_SOC_DAPM_PRE_PMU:
	case SND_SOC_DAPM_PRE_PMD:
		/* Ensure nominal gain ramping for DAPM sequence */
		da7219->gain_ramp_ctrl =
			snd_soc_read(codec, DA7219_GAIN_RAMP_CTRL);
		snd_soc_write(codec, DA7219_GAIN_RAMP_CTRL,
			      DA7219_GAIN_RAMP_RATE_NOMINAL);
		break;
	case SND_SOC_DAPM_POST_PMU:
	case SND_SOC_DAPM_POST_PMD:
		/* Restore previous gain ramp settings */
		snd_soc_write(codec, DA7219_GAIN_RAMP_CTRL,
			      da7219->gain_ramp_ctrl);
		break;
	}

	return 0;
}


/*
 * DAPM Widgets
@@ -907,30 +986,46 @@ static const struct snd_soc_dapm_widget da7219_dapm_widgets[] = {
			   ARRAY_SIZE(da7219_st_out_filtr_mix_controls)),

	/* DACs */
	SND_SOC_DAPM_DAC("DACL", NULL, DA7219_DAC_L_CTRL, DA7219_DAC_L_EN_SHIFT,
			 DA7219_NO_INVERT),
	SND_SOC_DAPM_DAC("DACR", NULL, DA7219_DAC_R_CTRL, DA7219_DAC_R_EN_SHIFT,
			 DA7219_NO_INVERT),
	SND_SOC_DAPM_DAC_E("DACL", NULL, DA7219_DAC_L_CTRL,
			   DA7219_DAC_L_EN_SHIFT, DA7219_NO_INVERT,
			   da7219_settling_event,
			   SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
	SND_SOC_DAPM_DAC_E("DACR", NULL, DA7219_DAC_R_CTRL,
			   DA7219_DAC_R_EN_SHIFT, DA7219_NO_INVERT,
			   da7219_settling_event,
			   SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),

	/* Output PGAs */
	SND_SOC_DAPM_PGA("Mixout Left PGA", DA7219_MIXOUT_L_CTRL,
	SND_SOC_DAPM_PGA_E("Mixout Left PGA", DA7219_MIXOUT_L_CTRL,
			   DA7219_MIXOUT_L_AMP_EN_SHIFT, DA7219_NO_INVERT,
			 NULL, 0),
	SND_SOC_DAPM_PGA("Mixout Right PGA", DA7219_MIXOUT_R_CTRL,
			   NULL, 0, da7219_mixout_event,
			   SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
	SND_SOC_DAPM_PGA_E("Mixout Right PGA", DA7219_MIXOUT_R_CTRL,
			   DA7219_MIXOUT_R_AMP_EN_SHIFT, DA7219_NO_INVERT,
			 NULL, 0),
	SND_SOC_DAPM_PGA("Headphone Left PGA", DA7219_HP_L_CTRL,
			 DA7219_HP_L_AMP_EN_SHIFT, DA7219_NO_INVERT, NULL, 0),
	SND_SOC_DAPM_PGA("Headphone Right PGA", DA7219_HP_R_CTRL,
			 DA7219_HP_R_AMP_EN_SHIFT, DA7219_NO_INVERT, NULL, 0),
			   NULL, 0, da7219_mixout_event,
			   SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
	SND_SOC_DAPM_SUPPLY_S("Headphone Left PGA", 1, DA7219_HP_L_CTRL,
			      DA7219_HP_L_AMP_EN_SHIFT, DA7219_NO_INVERT,
			      da7219_settling_event,
			      SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
	SND_SOC_DAPM_SUPPLY_S("Headphone Right PGA", 1, DA7219_HP_R_CTRL,
			      DA7219_HP_R_AMP_EN_SHIFT, DA7219_NO_INVERT,
			      da7219_settling_event,
			      SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),

	/* Output Supplies */
	SND_SOC_DAPM_SUPPLY("Charge Pump", DA7219_CP_CTRL, DA7219_CP_EN_SHIFT,
			    DA7219_NO_INVERT, NULL, 0),
	SND_SOC_DAPM_SUPPLY_S("Charge Pump", 0, DA7219_CP_CTRL,
			      DA7219_CP_EN_SHIFT, DA7219_NO_INVERT,
			      da7219_settling_event,
			      SND_SOC_DAPM_POST_PMU),

	/* Outputs */
	SND_SOC_DAPM_OUTPUT("HPL"),
	SND_SOC_DAPM_OUTPUT("HPR"),

	/* Pre/Post Power */
	SND_SOC_DAPM_PRE("Pre Power Gain Ramp", da7219_gain_ramp_event),
	SND_SOC_DAPM_POST("Post Power Gain Ramp", da7219_gain_ramp_event),
};


@@ -1003,8 +1098,8 @@ static const struct snd_soc_dapm_route da7219_audio_map[] = {
	{"Mixout Left PGA", NULL, "DACL"},
	{"Mixout Right PGA", NULL, "DACR"},

	{"Headphone Left PGA", NULL, "Mixout Left PGA"},
	{"Headphone Right PGA", NULL, "Mixout Right PGA"},
	{"HPL", NULL, "Mixout Left PGA"},
	{"HPR", NULL, "Mixout Right PGA"},

	{"HPL", NULL, "Headphone Left PGA"},
	{"HPR", NULL, "Headphone Right PGA"},
@@ -1712,6 +1807,14 @@ static int da7219_probe(struct snd_soc_codec *codec)
			    DA7219_HP_R_AMP_RAMP_EN_MASK,
			    DA7219_HP_R_AMP_RAMP_EN_MASK);

	/* Default minimum gain on HP to avoid pops during DAPM sequencing */
	snd_soc_update_bits(codec, DA7219_HP_L_CTRL,
			    DA7219_HP_L_AMP_MIN_GAIN_EN_MASK,
			    DA7219_HP_L_AMP_MIN_GAIN_EN_MASK);
	snd_soc_update_bits(codec, DA7219_HP_R_CTRL,
			    DA7219_HP_R_AMP_MIN_GAIN_EN_MASK,
			    DA7219_HP_R_AMP_MIN_GAIN_EN_MASK);

	/* Default infinite tone gen, start/stop by Kcontrol */
	snd_soc_write(codec, DA7219_TONE_GEN_CYCLES, DA7219_BEEP_CYCLES_MASK);

+5 −0
Original line number Diff line number Diff line
@@ -777,6 +777,10 @@
#define DA7219_SYS_STAT_CHECK_RETRIES	6
#define DA7219_SYS_STAT_CHECK_DELAY	50

/* Power up/down Delays */
#define DA7219_SETTLING_DELAY	40
#define DA7219_MIN_GAIN_DELAY	30

enum da7219_clk_src {
	DA7219_CLKSRC_MCLK = 0,
	DA7219_CLKSRC_MCLK_SQR,
@@ -814,6 +818,7 @@ struct da7219_priv {

	bool master;
	bool alc_en;
	u8 gain_ramp_ctrl;
};

#endif /* __DA7219_H */
+3 −0
Original line number Diff line number Diff line
@@ -78,6 +78,9 @@ static int lpass_platform_pcmops_open(struct snd_pcm_substream *substream)
	dma_ch = 0;
	if (v->alloc_dma_channel)
		dma_ch = v->alloc_dma_channel(drvdata, dir);
	else
		dma_ch = 0;

	if (dma_ch < 0)
		return dma_ch;