aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/soc-pcm.c
diff options
context:
space:
mode:
authorDong Aisheng <b29396@freescale.com>2011-08-29 05:15:14 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2011-09-21 10:59:46 -0400
commit17841020e9d3dbd4e8114c2142c2bc6d45c01da1 (patch)
tree7f7adb00fea156ae2c9e056439bee389d5ed10e8 /sound/soc/soc-pcm.c
parent548aae8cc497397310c66c336ed9c4f7dd5be4f4 (diff)
ASoC: soc-core: symmetry checking for each DAIs separately
The orginal code does not cover the case that one DAI such as codec may be shared between other two DAIs(CPU). When do symmetry checking, altough the codec DAI requires symmetry, the two CPU DAIs may still be configured to run on different rates. We change to check each DAI's state separately instead of only checking the dai link to prevent this issue. Signed-off-by: Dong Aisheng <b29396@freescale.com> Tested-by: Wolfram Sang <w.sang@pengutronix.de> Acked-by: Liam Girdwood <lrg@ti.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/soc-pcm.c')
-rw-r--r--sound/soc/soc-pcm.c40
1 files changed, 25 insertions, 15 deletions
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 1aee9fcdf650..8eb0f0711f8c 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -27,15 +27,13 @@
27#include <sound/soc.h> 27#include <sound/soc.h>
28#include <sound/initval.h> 28#include <sound/initval.h>
29 29
30static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream) 30static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream,
31 struct snd_soc_dai *soc_dai)
31{ 32{
32 struct snd_soc_pcm_runtime *rtd = substream->private_data; 33 struct snd_soc_pcm_runtime *rtd = substream->private_data;
33 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
34 struct snd_soc_dai *codec_dai = rtd->codec_dai;
35 int ret; 34 int ret;
36 35
37 if (!codec_dai->driver->symmetric_rates && 36 if (!soc_dai->driver->symmetric_rates &&
38 !cpu_dai->driver->symmetric_rates &&
39 !rtd->dai_link->symmetric_rates) 37 !rtd->dai_link->symmetric_rates)
40 return 0; 38 return 0;
41 39
@@ -43,19 +41,19 @@ static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream)
43 * the second can need to get its constraints before the first has 41 * the second can need to get its constraints before the first has
44 * picked a rate. Complain and allow the application to carry on. 42 * picked a rate. Complain and allow the application to carry on.
45 */ 43 */
46 if (!rtd->rate) { 44 if (!soc_dai->rate) {
47 dev_warn(&rtd->dev, 45 dev_warn(soc_dai->dev,
48 "Not enforcing symmetric_rates due to race\n"); 46 "Not enforcing symmetric_rates due to race\n");
49 return 0; 47 return 0;
50 } 48 }
51 49
52 dev_dbg(&rtd->dev, "Symmetry forces %dHz rate\n", rtd->rate); 50 dev_dbg(soc_dai->dev, "Symmetry forces %dHz rate\n", soc_dai->rate);
53 51
54 ret = snd_pcm_hw_constraint_minmax(substream->runtime, 52 ret = snd_pcm_hw_constraint_minmax(substream->runtime,
55 SNDRV_PCM_HW_PARAM_RATE, 53 SNDRV_PCM_HW_PARAM_RATE,
56 rtd->rate, rtd->rate); 54 soc_dai->rate, soc_dai->rate);
57 if (ret < 0) { 55 if (ret < 0) {
58 dev_err(&rtd->dev, 56 dev_err(soc_dai->dev,
59 "Unable to apply rate symmetry constraint: %d\n", ret); 57 "Unable to apply rate symmetry constraint: %d\n", ret);
60 return ret; 58 return ret;
61 } 59 }
@@ -185,8 +183,14 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
185 } 183 }
186 184
187 /* Symmetry only applies if we've already got an active stream. */ 185 /* Symmetry only applies if we've already got an active stream. */
188 if (cpu_dai->active || codec_dai->active) { 186 if (cpu_dai->active) {
189 ret = soc_pcm_apply_symmetry(substream); 187 ret = soc_pcm_apply_symmetry(substream, cpu_dai);
188 if (ret != 0)
189 goto config_err;
190 }
191
192 if (codec_dai->active) {
193 ret = soc_pcm_apply_symmetry(substream, codec_dai);
190 if (ret != 0) 194 if (ret != 0)
191 goto config_err; 195 goto config_err;
192 } 196 }
@@ -288,8 +292,12 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
288 codec_dai->active--; 292 codec_dai->active--;
289 codec->active--; 293 codec->active--;
290 294
291 if (!cpu_dai->active && !codec_dai->active) 295 /* clear the corresponding DAIs rate when inactive */
292 rtd->rate = 0; 296 if (!cpu_dai->active)
297 cpu_dai->rate = 0;
298
299 if (!codec_dai->active)
300 codec_dai->rate = 0;
293 301
294 /* Muting the DAC suppresses artifacts caused during digital 302 /* Muting the DAC suppresses artifacts caused during digital
295 * shutdown, for example from stopping clocks. 303 * shutdown, for example from stopping clocks.
@@ -447,7 +455,9 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
447 } 455 }
448 } 456 }
449 457
450 rtd->rate = params_rate(params); 458 /* store the rate for each DAIs */
459 cpu_dai->rate = params_rate(params);
460 codec_dai->rate = params_rate(params);
451 461
452out: 462out:
453 mutex_unlock(&rtd->pcm_mutex); 463 mutex_unlock(&rtd->pcm_mutex);