diff --git a/include/sound/soc.h b/include/sound/soc.h index 9f306f0710df..8326fc3db1cf 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -505,6 +505,9 @@ struct snd_soc_dai_link { /* codec/machine specific init - e.g. add machine controls */ int (*init)(struct snd_soc_codec *codec); + /* Keep DAI active over suspend */ + unsigned int ignore_suspend:1; + /* Symmetry requirements */ unsigned int symmetric_rates:1; diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 8661e5b4adb1..34f71bf60140 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -893,19 +893,31 @@ static int soc_suspend(struct device *dev) /* mute any active DAC's */ for (i = 0; i < card->num_links; i++) { struct snd_soc_dai *dai = card->dai_link[i].codec_dai; + + if (card->dai_link[i].ignore_suspend) + continue; + if (dai->ops->digital_mute && dai->playback.active) dai->ops->digital_mute(dai, 1); } /* suspend all pcms */ - for (i = 0; i < card->num_links; i++) + for (i = 0; i < card->num_links; i++) { + if (card->dai_link[i].ignore_suspend) + continue; + snd_pcm_suspend_all(card->dai_link[i].pcm); + } if (card->suspend_pre) card->suspend_pre(pdev, PMSG_SUSPEND); for (i = 0; i < card->num_links; i++) { struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai; + + if (card->dai_link[i].ignore_suspend) + continue; + if (cpu_dai->suspend && !cpu_dai->ac97_control) cpu_dai->suspend(cpu_dai); if (platform->suspend) @@ -918,6 +930,10 @@ static int soc_suspend(struct device *dev) for (i = 0; i < codec->num_dai; i++) { char *stream = codec->dai[i].playback.stream_name; + + if (card->dai_link[i].ignore_suspend) + continue; + if (stream != NULL) snd_soc_dapm_stream_event(codec, stream, SND_SOC_DAPM_STREAM_SUSPEND); @@ -943,6 +959,10 @@ static int soc_suspend(struct device *dev) for (i = 0; i < card->num_links; i++) { struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai; + + if (card->dai_link[i].ignore_suspend) + continue; + if (cpu_dai->suspend && cpu_dai->ac97_control) cpu_dai->suspend(cpu_dai); } @@ -982,6 +1002,10 @@ static void soc_resume_deferred(struct work_struct *work) for (i = 0; i < card->num_links; i++) { struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai; + + if (card->dai_link[i].ignore_suspend) + continue; + if (cpu_dai->resume && cpu_dai->ac97_control) cpu_dai->resume(cpu_dai); } @@ -1004,6 +1028,10 @@ static void soc_resume_deferred(struct work_struct *work) for (i = 0; i < codec->num_dai; i++) { char *stream = codec->dai[i].playback.stream_name; + + if (card->dai_link[i].ignore_suspend) + continue; + if (stream != NULL) snd_soc_dapm_stream_event(codec, stream, SND_SOC_DAPM_STREAM_RESUME); @@ -1016,12 +1044,20 @@ static void soc_resume_deferred(struct work_struct *work) /* unmute any active DACs */ for (i = 0; i < card->num_links; i++) { struct snd_soc_dai *dai = card->dai_link[i].codec_dai; + + if (card->dai_link[i].ignore_suspend) + continue; + if (dai->ops->digital_mute && dai->playback.active) dai->ops->digital_mute(dai, 0); } for (i = 0; i < card->num_links; i++) { struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai; + + if (card->dai_link[i].ignore_suspend) + continue; + if (cpu_dai->resume && !cpu_dai->ac97_control) cpu_dai->resume(cpu_dai); if (platform->resume)