I noticed a couple of code changes, we should probably do a code refactor first and add those changes, then add the multi-cpu support.
@@ -892,10 +979,17 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, component_err: soc_pcm_components_hw_free(substream, component);
- snd_soc_dai_hw_free(cpu_dai, substream);
- cpu_dai->rate = 0;
i = rtd->num_cpus;
interface_err:
for_each_rtd_cpu_dai_rollback(rtd, i, cpu_dai) {
if (!snd_soc_dai_stream_valid(cpu_dai, substream->stream))
continue;
maybe this check should be added to the existing code before adding multi-cpu support? it looks copy/pasted from the codec case, but is it a miss in the existing code?
snd_soc_dai_hw_free(cpu_dai, substream);
cpu_dai->rate = 0;
- }
[...]
@@ -965,7 +1062,12 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream) snd_soc_dai_hw_free(codec_dai, substream); }
- snd_soc_dai_hw_free(cpu_dai, substream);
- 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);
- }
same here, the hw_free should be first made conditional on the stream being valid, before introducing multi-cpu-dai support?
@@ -1672,18 +1804,32 @@ static void dpcm_runtime_merge_chan(struct snd_pcm_substream *substream,
for_each_dpcm_be(fe, stream, dpcm) { struct snd_soc_pcm_runtime *be = dpcm->be;
struct snd_soc_dai_driver *cpu_dai_drv = be->cpu_dai->driver;
struct snd_soc_dai_driver *codec_dai_drv; struct snd_soc_pcm_stream *codec_stream; struct snd_soc_pcm_stream *cpu_stream;struct snd_soc_dai_driver *cpu_dai_drv;
struct snd_soc_dai *dai;
int i;
if (stream == SNDRV_PCM_STREAM_PLAYBACK)
cpu_stream = &cpu_dai_drv->playback;
else
cpu_stream = &cpu_dai_drv->capture;
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;
and here as well, this is a new test that didn't exist before?
@@ -2847,23 +3012,33 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) playback = rtd->dai_link->dpcm_playback; capture = rtd->dai_link->dpcm_capture; } else {
int stream_playback;
/* Adapt stream for codec2codec links */int stream_capture;
struct snd_soc_pcm_stream *cpu_capture = rtd->dai_link->params ?
&cpu_dai->driver->playback : &cpu_dai->driver->capture;
struct snd_soc_pcm_stream *cpu_playback = rtd->dai_link->params ?
&cpu_dai->driver->capture : &cpu_dai->driver->playback;
if (rtd->dai_link->params) {
stream_playback = SNDRV_PCM_STREAM_CAPTURE;
stream_capture = SNDRV_PCM_STREAM_PLAYBACK;
} else {
stream_playback = SNDRV_PCM_STREAM_PLAYBACK;
stream_capture = SNDRV_PCM_STREAM_CAPTURE;
}
for_each_rtd_codec_dai(rtd, i, codec_dai) {
if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_PLAYBACK) &&
snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_PLAYBACK))
the logic for this entire block isn't easy to follow, maybe we should first move the cpu case out of the codec_dai loop and refactor the code before adding the multi-cpu case.
playback = 1;
if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_CAPTURE) &&
snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_CAPTURE))
capture = 1;
playback = 1;
capture = 1;
for_each_rtd_cpu_dai(rtd, i, cpu_dai) {
if (!snd_soc_dai_stream_valid(cpu_dai, stream_playback))
playback = 0;
if (!snd_soc_dai_stream_valid(cpu_dai, stream_capture))
}capture = 0;
capture = capture && cpu_capture->channels_min;
playback = playback && cpu_playback->channels_min;
channels_min is no longer used so it's somewhat confusing if the new code is iso-functionality? I'd prefer a code refactor that we can double check, then add the cpu_dai loop.
for_each_rtd_codec_dai(rtd, i, codec_dai) {
if (!snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_PLAYBACK))
playback = 0;
if (!snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_CAPTURE))
capture = 0;
}
}
if (rtd->dai_link->playback_only) {
@@ -2977,7 +3152,7 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) out: dev_info(rtd->card->dev, "%s <-> %s mapping ok\n", (rtd->num_codecs > 1) ? "multicodec" : rtd->codec_dai->name,
cpu_dai->name);
return ret; }(rtd->num_cpus > 1) ? "multicpu" : rtd->cpu_dai->name);