From c82dbcbec1cfc7bd0a246cf12e9f100f0ca49e8f Mon Sep 17 00:00:00 2001 From: Bicycle Tsai Date: Mon, 6 Sep 2021 11:50:47 +0800 Subject: [PATCH] BACKPORT: ASoC: soc-pcm: Get all BEs along DAPM path dpcm_end_walk_at_be() stops the graph walk when first BE is found for the given FE component. In a component model we may want to connect multiple DAIs from different components. A new flag is introduced in 'snd_soc_card', which when set allows DAI/component chaining. Later PCM operations can be called for all these listed components for a valid DAPM path. Signed-off-by: Sameer Pujar Link: https://lore.kernel.org/r/1604329814-24779-3-git-send-email-spujar@nvidia.com Signed-off-by: Mark Brown Bug: 198732156 (cherry picked from commit aa293777bfeb75fb8872565ef99cc0e8b98b5c7d) [ refactored to avoid breaking KMI ] ALSA machine driver can setup component_chaining like below code slice. static int my_board_late_probe(struct snd_soc_card *card) { struct snd_soc_card_ext *card_ext = container_of(card, struct snd_soc_card_ext, card); card_ext->component_chaining = 1; return 0; } static struct snd_soc_card my_board_card = { .name = MY_BOARD_NAME, .owner = THIS_MODULE, .dai_link = my_board_dai_links, .num_links = ARRAY_SIZE(my_board_dai_links), .late_probe = my_board_late_probe, }; Change-Id: Icc9e9b120e721a620f7c9f49515342422f80edb7 Signed-off-by: Bicycle Tsai --- include/sound/soc.h | 6 ++++++ sound/soc/soc-core.c | 8 ++++++++ sound/soc/soc-pcm.c | 6 +++++- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 63338f68de48..330c82c58afe 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1105,6 +1105,12 @@ struct snd_soc_card { ANDROID_KABI_RESERVE(3); ANDROID_KABI_RESERVE(4); }; + +struct snd_soc_card_ext { + struct snd_soc_card card; + unsigned int component_chaining:1; +}; + #define for_each_card_prelinks(card, i, link) \ for ((i) = 0; \ ((i) < (card)->num_links) && ((link) = &(card)->dai_link[i]); \ diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 18dfc114ff9e..c234859bef16 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -2175,9 +2175,17 @@ EXPORT_SYMBOL_GPL(snd_soc_add_dai_controls); */ int snd_soc_register_card(struct snd_soc_card *card) { + struct snd_soc_card_ext *card_ext; + if (!card->name || !card->dev) return -EINVAL; + card_ext = devm_kzalloc(card->dev, + sizeof(struct snd_soc_card_ext), GFP_KERNEL); + + memcpy(&card_ext->card, card, sizeof(struct snd_soc_card)); + card = &card_ext->card; + dev_set_drvdata(card->dev, card); INIT_LIST_HEAD(&card->widgets); diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index cc735dc46a44..10afa8efde2a 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -1274,6 +1274,7 @@ int dpcm_path_get(struct snd_soc_pcm_runtime *fe, int stream, struct snd_soc_dapm_widget_list **list) { struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(fe, 0); + struct snd_soc_card_ext *card_ext; int paths; if (fe->num_cpus > 1) { @@ -1282,9 +1283,12 @@ int dpcm_path_get(struct snd_soc_pcm_runtime *fe, return -EINVAL; } + card_ext = container_of(fe->card, struct snd_soc_card_ext, card); + /* get number of valid DAI paths and their widgets */ paths = snd_soc_dapm_dai_get_connected_widgets(cpu_dai, stream, list, - dpcm_end_walk_at_be); + card_ext->component_chaining ? + NULL : dpcm_end_walk_at_be); dev_dbg(fe->dev, "ASoC: found %d audio %s paths\n", paths, stream ? "capture" : "playback");