[alsa-devel] [PATCH RFC v3 2/4] ASoC: Add multiple CPU DAI support for PCM ops
Pierre-Louis Bossart
pierre-louis.bossart at linux.intel.com
Fri Jan 17 12:10:55 CET 2020
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 *cpu_dai_drv;
> 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 *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;
> + int stream_capture;
> /* Adapt stream for codec2codec links */
> - 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);
> + (rtd->num_cpus > 1) ? "multicpu" : rtd->cpu_dai->name);
> return ret;
> }
>
>
More information about the Alsa-devel
mailing list