On 27/03/2023 03:34, Kuninori Morimoto wrote: > dapm_connect_dai_pair() handles > "Normal/Codec2Codec" x "CPU/Codec" x "Playback/Capture". > > (A) is "Codec2Codec" case of "CPU" widget x "Playback/Capture", > (B) is "Normal" case of "CPU" widget x "Playback/Capture", > (C) is each case of "Codec" widget. > > (X) is handling "Playback" case DAI connecting, > (Y) is handling "Capture" case DAI connecting. > > static void dapm_connect_dai_pair(...) > { > ... > > (A) if (dai_link->params) { > playback_cpu = ... > capture_cpu = ... > (B) } else { > playback_cpu = ... > capture_cpu = ... > } > > ^ /* connect BE DAI playback if widgets are valid */ > | stream = SNDRV_PCM_STREAM_PLAYBACK; > | (C) codec = codec_dai->playback_widget; > | > | if (playback_cpu && codec) { > (X) if (dai_link->params && !rtd->c2c_widget[stream]) { > | ... > | } > | > | (z) dapm_connect_dai_routes(...); > v } > > capture: > ^ /* connect BE DAI capture if widgets are valid */ > | stream = SNDRV_PCM_STREAM_CAPTURE; > | (C) codec = codec_dai->capture_widget; > | > | if (codec && capture_cpu) { > (Y) if (dai_link->params && !rtd->c2c_widget[stream]) { > | ... > | } > | > | (z) dapm_connect_dai_routes(...); > v } > } > > (X) part and (Y) part are almost same. > Main purpose of these parts (and this function) is calling > dapm_connect_dai_routes() (= z) on each cases. > The difference is "parameter" > (= Normal/Codec2Codec x CPU/Codec x Playback/Capture). > > This patch cleanup these, but nothing changed for meaning. > > Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@xxxxxxxxxxx> > --- > sound/soc/soc-dapm.c | 93 +++++++++++++++++++++++++++----------------- > 1 file changed, 58 insertions(+), 35 deletions(-) > > diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c > index 3fa30a3afec2..064547e77063 100644 > --- a/sound/soc/soc-dapm.c > +++ b/sound/soc/soc-dapm.c > @@ -4325,60 +4325,83 @@ static void dapm_connect_dai_routes(struct snd_soc_dapm_context *dapm, > snd_soc_dapm_add_path(dapm, src, sink, NULL, NULL); > } > > +static int convert_stream(int stream) > +{ > + if (stream == SNDRV_PCM_STREAM_CAPTURE) > + return SNDRV_PCM_STREAM_PLAYBACK; > + > + return SNDRV_PCM_STREAM_CAPTURE; > +} int get_cpu_stream_direction(struct snd_soc_dai_link *dai_link, int stream) { if (!dai_link->c2c_params) return stream; if (stream == SNDRV_PCM_STREAM_CAPTURE) return SNDRV_PCM_STREAM_PLAYBACK; return SNDRV_PCM_STREAM_CAPTURE; } Add the comments here and use this to set the stream_cpu? The convert_stream() is an odd choice for the functionality. > + > static void dapm_connect_dai_pair(struct snd_soc_card *card, > struct snd_soc_pcm_runtime *rtd, > struct snd_soc_dai *codec_dai, > struct snd_soc_dai *cpu_dai) > { > struct snd_soc_dai_link *dai_link = rtd->dai_link; > - struct snd_soc_dapm_widget *dai, *codec, *playback_cpu, *capture_cpu; > - struct snd_pcm_substream *substream; > - struct snd_pcm_str *streams = rtd->pcm->streams; > + struct snd_soc_dapm_widget *codec, *cpu; > + struct snd_soc_dai *src_dai[] = { cpu_dai, codec_dai }; > + struct snd_soc_dai *sink_dai[] = { codec_dai, cpu_dai }; > + struct snd_soc_dapm_widget **src[] = { &cpu, &codec }; > + struct snd_soc_dapm_widget **sink[] = { &codec, &cpu }; > + char *widget_name[] = { "playback", "capture" }; > int stream; > > - if (dai_link->c2c_params) { > - playback_cpu = snd_soc_dai_get_widget_capture(cpu_dai); > - capture_cpu = snd_soc_dai_get_widget_playback(cpu_dai); > - } else { > - playback_cpu = snd_soc_dai_get_widget_playback(cpu_dai); > - capture_cpu = snd_soc_dai_get_widget_capture(cpu_dai); > - } > + for_each_pcm_streams(stream) { > + int stream_cpu, stream_codec; > > - /* connect BE DAI playback if widgets are valid */ > - stream = SNDRV_PCM_STREAM_PLAYBACK; > - codec = snd_soc_dai_get_widget(codec_dai, stream); > - > - if (playback_cpu && codec) { > - if (dai_link->c2c_params && !rtd->c2c_widget[stream]) { > - substream = streams[stream].substream; > - dai = snd_soc_dapm_new_dai(card, substream, "playback"); > - if (IS_ERR(dai)) > - goto capture; > - rtd->c2c_widget[stream] = dai; > + if (dai_link->c2c_params) { > + /* > + * [Codec2Codec] > + * > + * Playback > + * CPU : SNDRV_PCM_STREAM_CAPTURE > + * Codec: SNDRV_PCM_STREAM_PLAYBACK > + * > + * Capture > + * CPU : SNDRV_PCM_STREAM_PLAYBACK > + * Codec: SNDRV_PCM_STREAM_CAPTURE > + */ > + stream_cpu = convert_stream(stream); > + stream_codec = stream; > + } else { > + /* > + * [Normal] > + * > + * Playback > + * CPU : SNDRV_PCM_STREAM_PLAYBACK > + * Codec: SNDRV_PCM_STREAM_PLAYBACK > + * > + * Playback > + * CPU : SNDRV_PCM_STREAM_CAPTURE > + * Codec: SNDRV_PCM_STREAM_CAPTURE > + */ > + stream_cpu = stream; > + stream_codec = stream; > } > > - dapm_connect_dai_routes(&card->dapm, cpu_dai, playback_cpu, > - rtd->c2c_widget[stream], > - codec_dai, codec); > - } > + /* connect BE DAI playback if widgets are valid */ > + cpu = snd_soc_dai_get_widget(cpu_dai, stream_cpu); > + codec = snd_soc_dai_get_widget(codec_dai, stream_codec); > > -capture: > - /* connect BE DAI capture if widgets are valid */ > - stream = SNDRV_PCM_STREAM_CAPTURE; > - codec = snd_soc_dai_get_widget(codec_dai, stream); > + if (!cpu || !codec) > + continue; > > - if (codec && capture_cpu) { > + /* special handling for [Codec2Codec] */ > if (dai_link->c2c_params && !rtd->c2c_widget[stream]) { > - substream = streams[stream].substream; > - dai = snd_soc_dapm_new_dai(card, substream, "capture"); > + struct snd_pcm_substream *substream = rtd->pcm->streams[stream].substream; > + struct snd_soc_dapm_widget *dai = snd_soc_dapm_new_dai(card, substream, > + widget_name[stream]); > + > if (IS_ERR(dai)) > - return; > + continue; > + > rtd->c2c_widget[stream] = dai; > } > > - dapm_connect_dai_routes(&card->dapm, codec_dai, codec, > + dapm_connect_dai_routes(&card->dapm, src_dai[stream], *src[stream], > rtd->c2c_widget[stream], > - cpu_dai, capture_cpu); > + sink_dai[stream], *sink[stream]); > } > } > -- Péter