summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sound/soc-dai.h3
-rw-r--r--include/sound/soc.h2
-rw-r--r--sound/soc/soc-pcm.c40
3 files changed, 28 insertions, 17 deletions
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index 5ad5f3a50c68..12d98b435444 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -242,6 +242,9 @@ struct snd_soc_dai {
242 void *playback_dma_data; 242 void *playback_dma_data;
243 void *capture_dma_data; 243 void *capture_dma_data;
244 244
245 /* Symmetry data - only valid if symmetry is being enforced */
246 unsigned int rate;
247
245 /* parent platform/codec */ 248 /* parent platform/codec */
246 union { 249 union {
247 struct snd_soc_platform *platform; 250 struct snd_soc_platform *platform;
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 006f4f633c52..b499b37a6776 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -851,8 +851,6 @@ struct snd_soc_pcm_runtime {
851 unsigned int complete:1; 851 unsigned int complete:1;
852 unsigned int dev_registered:1; 852 unsigned int dev_registered:1;
853 853
854 /* Symmetry data - only valid if symmetry is being enforced */
855 unsigned int rate;
856 long pmdown_time; 854 long pmdown_time;
857 855
858 /* runtime devices */ 856 /* runtime devices */
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);