diff options
Diffstat (limited to 'sound/soc/soc-core.c')
-rw-r--r-- | sound/soc/soc-core.c | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 95739767ec45..8661e5b4adb1 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -927,8 +927,19 @@ static int soc_suspend(struct device *dev) SND_SOC_DAPM_STREAM_SUSPEND); } - if (codec_dev->suspend) - codec_dev->suspend(pdev, PMSG_SUSPEND); + /* If there are paths active then the CODEC will be held with + * bias _ON and should not be suspended. */ + if (codec_dev->suspend) { + switch (codec->bias_level) { + case SND_SOC_BIAS_STANDBY: + case SND_SOC_BIAS_OFF: + codec_dev->suspend(pdev, PMSG_SUSPEND); + break; + default: + dev_dbg(socdev->dev, "CODEC is on over suspend\n"); + break; + } + } for (i = 0; i < card->num_links; i++) { struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai; @@ -975,8 +986,21 @@ static void soc_resume_deferred(struct work_struct *work) cpu_dai->resume(cpu_dai); } - if (codec_dev->resume) - codec_dev->resume(pdev); + /* If the CODEC was idle over suspend then it will have been + * left with bias OFF or STANDBY and suspended so we must now + * resume. Otherwise the suspend was suppressed. + */ + if (codec_dev->resume) { + switch (codec->bias_level) { + case SND_SOC_BIAS_STANDBY: + case SND_SOC_BIAS_OFF: + codec_dev->resume(pdev); + break; + default: + dev_dbg(socdev->dev, "CODEC was on over suspend\n"); + break; + } + } for (i = 0; i < codec->num_dai; i++) { char *stream = codec->dai[i].playback.stream_name; |