diff options
-rw-r--r-- | include/sound/soc-dai.h | 3 | ||||
-rw-r--r-- | include/sound/soc.h | 2 | ||||
-rw-r--r-- | sound/soc/soc-pcm.c | 40 |
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 | ||
30 | static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream) | 30 | static 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 | ||
452 | out: | 462 | out: |
453 | mutex_unlock(&rtd->pcm_mutex); | 463 | mutex_unlock(&rtd->pcm_mutex); |