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

Commit 41df0829 authored by Paul Handrigan's avatar Paul Handrigan Committed by Mark Brown
Browse files

ASoC: cs42l73: Add DAPM events for power down.



Add power down delays between setting PDN and MCLKDIS for spk amp, spklo amp, and ear amp.

Signed-off-by: default avatarPaul Handrigan <Paul.Handrigan@cirrus.com>
Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
parent a1ad500e
Loading
Loading
Loading
Loading
+72 −8
Original line number Original line Diff line number Diff line
@@ -40,6 +40,7 @@ struct cs42l73_private {
	u32 sysclk;
	u32 sysclk;
	u8 mclksel;
	u8 mclksel;
	u32 mclk;
	u32 mclk;
	int shutdwn_delay;
};
};


static const struct reg_default cs42l73_reg_defaults[] = {
static const struct reg_default cs42l73_reg_defaults[] = {
@@ -588,6 +589,57 @@ static const struct snd_kcontrol_new cs42l73_snd_controls[] = {
	SOC_ENUM("XSPOUT Mono/Stereo Select", xsp_output_mux_enum),
	SOC_ENUM("XSPOUT Mono/Stereo Select", xsp_output_mux_enum),
};
};


static int cs42l73_spklo_spk_amp_event(struct snd_soc_dapm_widget *w,
	struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_codec *codec = w->codec;
	struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
	switch (event) {
	case SND_SOC_DAPM_POST_PMD:
		/* 150 ms delay between setting PDN and MCLKDIS */
		priv->shutdwn_delay = 150;
		break;
	default:
		pr_err("Invalid event = 0x%x\n", event);
	}
	return 0;
}

static int cs42l73_ear_amp_event(struct snd_soc_dapm_widget *w,
	struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_codec *codec = w->codec;
	struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
	switch (event) {
	case SND_SOC_DAPM_POST_PMD:
		/* 50 ms delay between setting PDN and MCLKDIS */
		if (priv->shutdwn_delay < 50)
			priv->shutdwn_delay = 50;
		break;
	default:
		pr_err("Invalid event = 0x%x\n", event);
	}
	return 0;
}


static int cs42l73_hp_amp_event(struct snd_soc_dapm_widget *w,
	struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_codec *codec = w->codec;
	struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
	switch (event) {
	case SND_SOC_DAPM_POST_PMD:
		/* 30 ms delay between setting PDN and MCLKDIS */
		if (priv->shutdwn_delay < 30)
			priv->shutdwn_delay = 30;
		break;
	default:
		pr_err("Invalid event = 0x%x\n", event);
	}
	return 0;
}

static const struct snd_soc_dapm_widget cs42l73_dapm_widgets[] = {
static const struct snd_soc_dapm_widget cs42l73_dapm_widgets[] = {
	SND_SOC_DAPM_INPUT("DMICA"),
	SND_SOC_DAPM_INPUT("DMICA"),
	SND_SOC_DAPM_INPUT("DMICB"),
	SND_SOC_DAPM_INPUT("DMICB"),
@@ -676,16 +728,20 @@ static const struct snd_soc_dapm_widget cs42l73_dapm_widgets[] = {
	SND_SOC_DAPM_PGA("SPK DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
	SND_SOC_DAPM_PGA("SPK DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
	SND_SOC_DAPM_PGA("ESL DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
	SND_SOC_DAPM_PGA("ESL DAC", SND_SOC_NOPM, 0, 0, NULL, 0),


	SND_SOC_DAPM_SWITCH("HP Amp", CS42L73_PWRCTL3, 0, 1,
	SND_SOC_DAPM_SWITCH_E("HP Amp",  CS42L73_PWRCTL3, 0, 1,
			    &hp_amp_ctl),
			    &hp_amp_ctl, cs42l73_hp_amp_event,
			SND_SOC_DAPM_POST_PMD),
	SND_SOC_DAPM_SWITCH("LO Amp", CS42L73_PWRCTL3, 1, 1,
	SND_SOC_DAPM_SWITCH("LO Amp", CS42L73_PWRCTL3, 1, 1,
			    &lo_amp_ctl),
			    &lo_amp_ctl),
	SND_SOC_DAPM_SWITCH("SPK Amp", CS42L73_PWRCTL3, 2, 1,
	SND_SOC_DAPM_SWITCH_E("SPK Amp", CS42L73_PWRCTL3, 2, 1,
			    &spk_amp_ctl),
			&spk_amp_ctl, cs42l73_spklo_spk_amp_event,
	SND_SOC_DAPM_SWITCH("EAR Amp", CS42L73_PWRCTL3, 3, 1,
			SND_SOC_DAPM_POST_PMD),
			    &ear_amp_ctl),
	SND_SOC_DAPM_SWITCH_E("EAR Amp", CS42L73_PWRCTL3, 3, 1,
	SND_SOC_DAPM_SWITCH("SPKLO Amp", CS42L73_PWRCTL3, 4, 1,
			    &ear_amp_ctl, cs42l73_ear_amp_event,
			    &spklo_amp_ctl),
			SND_SOC_DAPM_POST_PMD),
	SND_SOC_DAPM_SWITCH_E("SPKLO Amp", CS42L73_PWRCTL3, 4, 1,
			    &spklo_amp_ctl, cs42l73_spklo_spk_amp_event,
			SND_SOC_DAPM_POST_PMD),


	SND_SOC_DAPM_OUTPUT("HPOUTA"),
	SND_SOC_DAPM_OUTPUT("HPOUTA"),
	SND_SOC_DAPM_OUTPUT("HPOUTB"),
	SND_SOC_DAPM_OUTPUT("HPOUTB"),
@@ -1171,6 +1227,14 @@ static int cs42l73_set_bias_level(struct snd_soc_codec *codec,


	case SND_SOC_BIAS_OFF:
	case SND_SOC_BIAS_OFF:
		snd_soc_update_bits(codec, CS42L73_PWRCTL1, PDN, 1);
		snd_soc_update_bits(codec, CS42L73_PWRCTL1, PDN, 1);
		if (cs42l73->shutdwn_delay > 0) {
			mdelay(cs42l73->shutdwn_delay);
			cs42l73->shutdwn_delay = 0;
		} else {
			mdelay(15); /* Min amount of time requred to power
				     * down.
				     */
		}
		snd_soc_update_bits(codec, CS42L73_DMMCC, MCLKDIS, 1);
		snd_soc_update_bits(codec, CS42L73_DMMCC, MCLKDIS, 1);
		break;
		break;
	}
	}