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. Link: https://lore.kernel.org/r/87ilen6ni4.wl-kuninori.morimoto.gx@xxxxxxxxxxx Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@xxxxxxxxxxx> --- v1 -> v2 - based on C2C update - use get_stream_cpu() sound/soc/soc-dapm.c | 93 +++++++++++++++++++++++++++----------------- 1 file changed, 57 insertions(+), 36 deletions(-) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index e7a0c28e0cb1..36e6f261bcf7 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -4325,60 +4325,81 @@ static void dapm_connect_dai_routes(struct snd_soc_dapm_context *dapm, snd_soc_dapm_add_path(dapm, src, sink, NULL, NULL); } +static int get_stream_cpu(struct snd_soc_dai_link *dai_link, int stream) +{ + /* + * [Normal] + * + * Playback + * CPU : SNDRV_PCM_STREAM_PLAYBACK + * Codec: SNDRV_PCM_STREAM_PLAYBACK + * + * Playback + * CPU : SNDRV_PCM_STREAM_CAPTURE + * Codec: SNDRV_PCM_STREAM_CAPTURE + */ + if (!dai_link->c2c_params) + return stream; + + /* + * [Codec2Codec] + * + * Playback + * CPU : SNDRV_PCM_STREAM_CAPTURE + * Codec: SNDRV_PCM_STREAM_PLAYBACK + * + * Capture + * CPU : SNDRV_PCM_STREAM_PLAYBACK + * Codec: SNDRV_PCM_STREAM_CAPTURE + */ + if (stream == SNDRV_PCM_STREAM_CAPTURE) + return SNDRV_PCM_STREAM_PLAYBACK; + + return SNDRV_PCM_STREAM_CAPTURE; +} + 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); + stream_cpu = get_stream_cpu(dai_link, stream); + stream_codec = 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; - } + /* 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); - dapm_connect_dai_routes(&card->dapm, cpu_dai, playback_cpu, - rtd->c2c_widget[stream], - codec_dai, 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]); } } -- 2.25.1