[alsa-devel] [PATCH] add support to reorder CPU and Codec DAI suspend/resume

Barry Song 21cnbao at gmail.com
Wed Nov 11 08:10:57 CET 2009


Due to some hardware dependence issues, some devices maybe require
different suspend/resume execution order for CPU and Codec DAI to
make sure the hardware can work normally after executing sleep and
wakeup.

In old ALSA driver, people include all suspend/resume operations of
both CPU and Codec in same entries. Then they change order according
to actual require. But in ASoC, we should give a chance to users to
reorder CPU/Codec DAI suspend/resume instead of defining the fixed
order if there are some strange hardware dependence problems.

Signed-off-by: Barry Song <21cnbao at gmail.com>
---
 include/sound/soc.h  |    4 ++++
 sound/soc/soc-core.c |   48 ++++++++++++++++++++++++++++++++++++------------
 2 files changed, 40 insertions(+), 12 deletions(-)

diff --git a/include/sound/soc.h b/include/sound/soc.h
index b1245e3..701c362 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -494,6 +494,10 @@ struct snd_soc_card {
 	struct snd_soc_dai_link *dai_link;
 	int num_links;
 
+	/* CPU <--> Codec DAI suspend/resume order */
+	int cpu_suspend_earlier; /* CPU DAI and platform suspend will be called earlier than Codec */
+	int cpu_resume_earlier;  /* CPU DAI and platform resume will be called earlier than Codec */
+
 	struct snd_soc_device *socdev;
 
 	struct snd_soc_codec *codec;
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 2d190df..a1cc855 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -660,12 +660,14 @@ static int soc_suspend(struct device *dev)
 	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 (cpu_dai->suspend && !cpu_dai->ac97_control)
-			cpu_dai->suspend(cpu_dai);
-		if (platform->suspend)
-			platform->suspend(cpu_dai);
+	if (card->cpu_suspend_earlier) {
+		for (i = 0; i < card->num_links; i++) {
+			struct snd_soc_dai  *cpu_dai = card->dai_link[i].cpu_dai;
+			if (cpu_dai->suspend && !cpu_dai->ac97_control)
+				cpu_dai->suspend(cpu_dai);
+			if (platform->suspend)
+				platform->suspend(cpu_dai);
+		}
 	}
 
 	/* close any waiting streams and save state */
@@ -692,6 +694,16 @@ static int soc_suspend(struct device *dev)
 			cpu_dai->suspend(cpu_dai);
 	}
 
+	if (!card->cpu_suspend_earlier) {
+		for (i = 0; i < card->num_links; i++) {
+			struct snd_soc_dai  *cpu_dai = card->dai_link[i].cpu_dai;
+			if (cpu_dai->suspend && !cpu_dai->ac97_control)
+				cpu_dai->suspend(cpu_dai);
+			if (platform->suspend)
+				platform->suspend(cpu_dai);
+		}
+	}
+
 	if (card->suspend_post)
 		card->suspend_post(pdev, PMSG_SUSPEND);
 
@@ -728,6 +740,16 @@ static void soc_resume_deferred(struct work_struct *work)
 			cpu_dai->resume(cpu_dai);
 	}
 
+	if (card->cpu_resume_earlier) {
+		for (i = 0; i < card->num_links; i++) {
+			struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
+			if (cpu_dai->resume && !cpu_dai->ac97_control)
+				cpu_dai->resume(cpu_dai);
+			if (platform->resume)
+				platform->resume(cpu_dai);
+		}
+	}
+
 	if (codec_dev->resume)
 		codec_dev->resume(pdev);
 
@@ -749,12 +771,14 @@ static void soc_resume_deferred(struct work_struct *work)
 			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 (cpu_dai->resume && !cpu_dai->ac97_control)
-			cpu_dai->resume(cpu_dai);
-		if (platform->resume)
-			platform->resume(cpu_dai);
+	if (!card->cpu_resume_earlier) {
+		for (i = 0; i < card->num_links; i++) {
+			struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
+			if (cpu_dai->resume && !cpu_dai->ac97_control)
+				cpu_dai->resume(cpu_dai);
+			if (platform->resume)
+				platform->resume(cpu_dai);
+		}
 	}
 
 	if (card->resume_post)
-- 
1.5.6.3



More information about the Alsa-devel mailing list