Skip to content

Commit

Permalink
ASoC: cs42l73: Add DAPM events for power down.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Paul Handrigan authored and Mark Brown committed Dec 10, 2012
1 parent a1ad500 commit 41df082
Showing 1 changed file with 72 additions and 8 deletions.
80 changes: 72 additions & 8 deletions sound/soc/codecs/cs42l73.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ struct cs42l73_private {
u32 sysclk;
u8 mclksel;
u32 mclk;
int shutdwn_delay;
};

static const struct reg_default cs42l73_reg_defaults[] = {
Expand Down Expand Up @@ -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"),
Expand Down Expand Up @@ -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"),
Expand Down Expand Up @@ -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;
}
Expand Down

0 comments on commit 41df082

Please sign in to comment.