ASoC: soc-core: support dai_link with platforms_num != 1
authorJerome Brunet <jbrunet@baylibre.com>
Thu, 27 Jun 2019 12:13:50 +0000 (14:13 +0200)
committerMark Brown <broonie@kernel.org>
Fri, 28 Jun 2019 12:41:19 +0000 (13:41 +0100)
Add support platforms_num != 1 in dai_link. Initially, the main purpose of
this change was to make the platform optional in the dai_link, instead of
inserting the dummy platform driver.

This particular case had just been solved by Kuninori Morimoto with
commit 1d7689892878 ("ASoC: soc-core: allow no Platform on dai_link").

However, this change may still be useful for those who need multiple
platform components on a single dai_link (it solves one of the FIXME
note in soc-core)

Acked-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
include/sound/soc.h
sound/soc/soc-core.c

index 64405cd..4e80712 100644 (file)
@@ -997,6 +997,12 @@ struct snd_soc_dai_link {
             ((i) < link->num_codecs) && ((codec) = &link->codecs[i]);  \
             (i)++)
 
+#define for_each_link_platforms(link, i, platform)                     \
+       for ((i) = 0;                                                   \
+            ((i) < link->num_platforms) &&                             \
+            ((platform) = &link->platforms[i]);                        \
+            (i)++)
+
 /*
  * Sample 1 : Single CPU/Codec/Platform
  *
index b5f3c09..b9061cd 100644 (file)
@@ -896,7 +896,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card,
        struct snd_soc_dai_link *dai_link)
 {
        struct snd_soc_pcm_runtime *rtd;
-       struct snd_soc_dai_link_component *codecs;
+       struct snd_soc_dai_link_component *codec, *platform;
        struct snd_soc_component *component;
        int i;
 
@@ -926,13 +926,14 @@ static int soc_bind_dai_link(struct snd_soc_card *card,
 
        /* Find CODEC from registered CODECs */
        rtd->num_codecs = dai_link->num_codecs;
-       for_each_link_codecs(dai_link, i, codecs) {
-               rtd->codec_dais[i] = snd_soc_find_dai(codecs);
+       for_each_link_codecs(dai_link, i, codec) {
+               rtd->codec_dais[i] = snd_soc_find_dai(codec);
                if (!rtd->codec_dais[i]) {
                        dev_info(card->dev, "ASoC: CODEC DAI %s not registered\n",
-                                codecs->dai_name);
+                                codec->dai_name);
                        goto _err_defer;
                }
+
                snd_soc_rtdcom_add(rtd, rtd->codec_dais[i]->component);
        }
 
@@ -940,12 +941,13 @@ static int soc_bind_dai_link(struct snd_soc_card *card,
        rtd->codec_dai = rtd->codec_dais[0];
 
        /* Find PLATFORM from registered PLATFORMs */
-       for_each_component(component) {
-               if (!snd_soc_is_matching_component(dai_link->platforms,
-                                                  component))
-                       continue;
+       for_each_link_platforms(dai_link, i, platform) {
+               for_each_component(component) {
+                       if (!snd_soc_is_matching_component(platform, component))
+                               continue;
 
-               snd_soc_rtdcom_add(rtd, component);
+                       snd_soc_rtdcom_add(rtd, component);
+               }
        }
 
        soc_add_pcm_runtime(card, rtd);
@@ -1058,15 +1060,14 @@ static int soc_init_dai_link(struct snd_soc_card *card,
                             struct snd_soc_dai_link *link)
 {
        int i;
-       struct snd_soc_dai_link_component *codec;
+       struct snd_soc_dai_link_component *codec, *platform;
 
        for_each_link_codecs(link, i, codec) {
                /*
                 * Codec must be specified by 1 of name or OF node,
                 * not both or neither.
                 */
-               if (!!codec->name ==
-                   !!codec->of_node) {
+               if (!!codec->name == !!codec->of_node) {
                        dev_err(card->dev, "ASoC: Neither/both codec name/of_node are set for %s\n",
                                link->name);
                        return -EINVAL;
@@ -1087,36 +1088,24 @@ static int soc_init_dai_link(struct snd_soc_card *card,
                        return -EPROBE_DEFER;
        }
 
-       /*
-        * Platform may be specified by either name or OF node,
-        * or no Platform.
-        *
-        * FIXME
-        *
-        * We need multi-platform support
-        */
-       if (link->num_platforms > 0) {
-
-               if (link->num_platforms > 1) {
-                       dev_err(card->dev,
-                               "ASoC: multi platform is not yet supported %s\n",
-                               link->name);
-                       return -EINVAL;
-               }
-
-               if (link->platforms->name && link->platforms->of_node) {
+       for_each_link_platforms(link, i, platform) {
+               /*
+                * Platform may be specified by either name or OF node, but it
+                * can be left unspecified, then no components will be inserted
+                * in the rtdcom list
+                */
+               if (!!platform->name == !!platform->of_node) {
                        dev_err(card->dev,
-                               "ASoC: Both platform name/of_node are set for %s\n",
+                               "ASoC: Neither/both platform name/of_node are set for %s\n",
                                link->name);
                        return -EINVAL;
                }
 
                /*
-                * Defer card registartion if platform dai component is not
-                * added to component list.
+                * Defer card registration if platform component is not added to
+                * component list.
                 */
-               if ((link->platforms->of_node || link->platforms->name) &&
-                   !soc_find_component(link->platforms))
+               if (!soc_find_component(platform))
                        return -EPROBE_DEFER;
        }