diff options
| author | Paul Handrigan <Paul.Handrigan@cirrus.com> | 2012-12-07 14:53:43 -0600 | 
|---|---|---|
| committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-12-10 12:26:46 +0900 | 
| commit | 41df0829cee9e4c4ba68de33b4ca26cb18ac8ed7 (patch) | |
| tree | a90bc04f25fbe6eb31ebf1551b63eca1a9083c6c | |
| parent | a1ad500e369183796820bffb4012b876a8685219 (diff) | |
| download | olio-linux-3.10-41df0829cee9e4c4ba68de33b4ca26cb18ac8ed7.tar.xz olio-linux-3.10-41df0829cee9e4c4ba68de33b4ca26cb18ac8ed7.zip  | |
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: Paul Handrigan <Paul.Handrigan@cirrus.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
| -rw-r--r-- | sound/soc/codecs/cs42l73.c | 80 | 
1 files changed, 72 insertions, 8 deletions
diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c index 476679510df..fb9b178d6ff 100644 --- a/sound/soc/codecs/cs42l73.c +++ b/sound/soc/codecs/cs42l73.c @@ -40,6 +40,7 @@ struct  cs42l73_private {  	u32 sysclk;  	u8 mclksel;  	u32 mclk; +	int shutdwn_delay;  };  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),  }; +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[] = {  	SND_SOC_DAPM_INPUT("DMICA"),  	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("ESL DAC", SND_SOC_NOPM, 0, 0, NULL, 0), -	SND_SOC_DAPM_SWITCH("HP Amp", CS42L73_PWRCTL3, 0, 1, -			    &hp_amp_ctl), +	SND_SOC_DAPM_SWITCH_E("HP Amp",  CS42L73_PWRCTL3, 0, 1, +			    &hp_amp_ctl, cs42l73_hp_amp_event, +			SND_SOC_DAPM_POST_PMD),  	SND_SOC_DAPM_SWITCH("LO Amp", CS42L73_PWRCTL3, 1, 1,  			    &lo_amp_ctl), -	SND_SOC_DAPM_SWITCH("SPK Amp", CS42L73_PWRCTL3, 2, 1, -			    &spk_amp_ctl), -	SND_SOC_DAPM_SWITCH("EAR Amp", CS42L73_PWRCTL3, 3, 1, -			    &ear_amp_ctl), -	SND_SOC_DAPM_SWITCH("SPKLO Amp", CS42L73_PWRCTL3, 4, 1, -			    &spklo_amp_ctl), +	SND_SOC_DAPM_SWITCH_E("SPK Amp", CS42L73_PWRCTL3, 2, 1, +			&spk_amp_ctl, cs42l73_spklo_spk_amp_event, +			SND_SOC_DAPM_POST_PMD), +	SND_SOC_DAPM_SWITCH_E("EAR Amp", CS42L73_PWRCTL3, 3, 1, +			    &ear_amp_ctl, cs42l73_ear_amp_event, +			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("HPOUTB"), @@ -1171,6 +1227,14 @@ static int cs42l73_set_bias_level(struct snd_soc_codec *codec,  	case SND_SOC_BIAS_OFF:  		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);  		break;  	}  |