Now multi-cpu-dai is supported. We have the same resaon as multi-codec-dai to skip CPUs which don't support the current stream.
Signed-off-by: Bard Liao yung-chuan.liao@linux.intel.com --- sound/soc/soc-pcm.c | 51 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-)
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index a1e84bbc5258..948363b3e610 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -417,6 +417,20 @@ static void soc_pcm_init_runtime_hw(struct snd_pcm_substream *substream)
/* first calculate min/max only for CPUs in the DAI link */ for_each_rtd_cpu_dai(rtd, i, cpu_dai) { + + /* + * Skip CPUs which don't support the current stream type. + * Otherwise, since the rate, channel, and format values will + * zero in that case, we would have no usable settings left, + * causing the resulting setup to fail. + * At least one CPU should match, otherwise we should have + * bailed out on a higher level, since there would be no + * CPU to support the transfer direction in that case. + */ + if (!snd_soc_dai_stream_valid(cpu_dai, + substream->stream)) + continue; + cpu_dai_drv = cpu_dai->driver; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) cpu_stream = &cpu_dai_drv->playback; @@ -945,6 +959,13 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, }
for_each_rtd_cpu_dai(rtd, i, cpu_dai) { + /* + * Skip CPUs which don't support the current stream + * type. See soc_pcm_init_runtime_hw() for more details + */ + if (!snd_soc_dai_stream_valid(cpu_dai, substream->stream)) + continue; + ret = snd_soc_dai_hw_params(cpu_dai, substream, params); if (ret < 0) goto interface_err; @@ -980,6 +1001,9 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
interface_err: for_each_rtd_cpu_dai_rollback(rtd, i, cpu_dai) { + if (!snd_soc_dai_stream_valid(cpu_dai, substream->stream)) + continue; + snd_soc_dai_hw_free(cpu_dai, substream); cpu_dai->rate = 0; } @@ -1055,8 +1079,12 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream) snd_soc_dai_hw_free(codec_dai, substream); }
- for_each_rtd_cpu_dai(rtd, i, cpu_dai) + for_each_rtd_cpu_dai(rtd, i, cpu_dai) { + if (!snd_soc_dai_stream_valid(cpu_dai, substream->stream)) + continue; + snd_soc_dai_hw_free(cpu_dai, substream); + }
mutex_unlock(&rtd->card->pcm_mutex); return 0; @@ -1807,6 +1835,13 @@ static void dpcm_runtime_merge_chan(struct snd_pcm_substream *substream, int i;
for_each_rtd_cpu_dai(be, i, dai) { + /* + * Skip CPUs which don't support the current stream + * type. See soc_pcm_init_runtime_hw() for more details + */ + if (!snd_soc_dai_stream_valid(dai, stream)) + continue; + cpu_dai_drv = dai->driver; if (stream == SNDRV_PCM_STREAM_PLAYBACK) cpu_stream = &cpu_dai_drv->playback; @@ -1866,6 +1901,13 @@ static void dpcm_runtime_merge_rate(struct snd_pcm_substream *substream, int i;
for_each_rtd_cpu_dai(be, i, dai) { + /* + * Skip CPUs which don't support the current stream + * type. See soc_pcm_init_runtime_hw() for more details + */ + if (!snd_soc_dai_stream_valid(dai, stream)) + continue; + cpu_dai_drv = dai->driver; if (stream == SNDRV_PCM_STREAM_PLAYBACK) cpu_stream = &cpu_dai_drv->playback; @@ -1911,6 +1953,13 @@ static void dpcm_set_fe_runtime(struct snd_pcm_substream *substream) int i;
for_each_rtd_cpu_dai(rtd, i, cpu_dai) { + /* + * Skip CPUs which don't support the current stream + * type. See soc_pcm_init_runtime_hw() for more details + */ + if (!snd_soc_dai_stream_valid(cpu_dai, substream->stream)) + continue; + cpu_dai_drv = cpu_dai->driver; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) dpcm_init_runtime_hw(runtime, &cpu_dai_drv->playback);