aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/soc-core.c
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2010-05-07 16:11:40 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2010-05-10 05:36:48 -0400
commit1547aba993c990e5a316751431328145b38e1fea (patch)
treed9e549fa2d6bb67a632a0cfeefd39e3a077cac5d /sound/soc/soc-core.c
parent9949788b793826f2d19e929ac0219ad0e0891e2d (diff)
ASoC: Support leaving paths enabled over system suspend
Some devices can usefully run audio while the Linux system is suspended. One of the most common examples is smartphone systems, which are normally designed to allow audio to be run between the baseband and the CODEC without passing through the CPU and so can suspend the CPU when on a voice call for additional power savings. Support such systems by providing an API snd_soc_dapm_ignore_suspend(). This can be used to mark DAPM endpoints as not being sensitive to system suspend. When the system is being suspended paths between endpoints which are marked as ignoring suspend will be kept active. Both source and sink must be marked, and there must already be an active path between the two endpoints prior to suspend. When paths are active over suspend the bias management will hold the device bias in the ON state. This is used to avoid suspending the CODEC while it is still in use. Tested-by: Peter Ujfalusi <peter.ujfalusi@nokia.com> Acked-by: Liam Girdwood <lrg@slimlogic.co.uk> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/soc-core.c')
-rw-r--r--sound/soc/soc-core.c32
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)
927 SND_SOC_DAPM_STREAM_SUSPEND); 927 SND_SOC_DAPM_STREAM_SUSPEND);
928 } 928 }
929 929
930 if (codec_dev->suspend) 930 /* If there are paths active then the CODEC will be held with
931 codec_dev->suspend(pdev, PMSG_SUSPEND); 931 * bias _ON and should not be suspended. */
932 if (codec_dev->suspend) {
933 switch (codec->bias_level) {
934 case SND_SOC_BIAS_STANDBY:
935 case SND_SOC_BIAS_OFF:
936 codec_dev->suspend(pdev, PMSG_SUSPEND);
937 break;
938 default:
939 dev_dbg(socdev->dev, "CODEC is on over suspend\n");
940 break;
941 }
942 }
932 943
933 for (i = 0; i < card->num_links; i++) { 944 for (i = 0; i < card->num_links; i++) {
934 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai; 945 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)
975 cpu_dai->resume(cpu_dai); 986 cpu_dai->resume(cpu_dai);
976 } 987 }
977 988
978 if (codec_dev->resume) 989 /* If the CODEC was idle over suspend then it will have been
979 codec_dev->resume(pdev); 990 * left with bias OFF or STANDBY and suspended so we must now
991 * resume. Otherwise the suspend was suppressed.
992 */
993 if (codec_dev->resume) {
994 switch (codec->bias_level) {
995 case SND_SOC_BIAS_STANDBY:
996 case SND_SOC_BIAS_OFF:
997 codec_dev->resume(pdev);
998 break;
999 default:
1000 dev_dbg(socdev->dev, "CODEC was on over suspend\n");
1001 break;
1002 }
1003 }
980 1004
981 for (i = 0; i < codec->num_dai; i++) { 1005 for (i = 0; i < codec->num_dai; i++) {
982 char *stream = codec->dai[i].playback.stream_name; 1006 char *stream = codec->dai[i].playback.stream_name;