ASoC: simple-card-utils: enable flexible CPU/Codec/Platform
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Thu, 1 Apr 2021 04:15:23 +0000 (13:15 +0900)
committerMark Brown <broonie@kernel.org>
Thu, 8 Apr 2021 14:18:02 +0000 (15:18 +0100)
Current simple-card / audio-graph are assuming fixed
single-CPU/Codec/Platform.
This patch prepares multi-CPU/Codec/Platform support.

Note is that it is not yet full-multi-support.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87v996od2c.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
include/sound/simple_card_utils.h
sound/soc/generic/audio-graph-card.c
sound/soc/generic/simple-card-utils.c
sound/soc/generic/simple-card.c

index 86e46cb..475f8cb 100644 (file)
@@ -38,6 +38,12 @@ struct asoc_simple_jack {
        struct snd_soc_jack_gpio gpio;
 };
 
+struct prop_nums {
+       int cpus;
+       int codecs;
+       int platforms;
+};
+
 struct asoc_simple_priv {
        struct snd_soc_card snd_card;
        struct simple_dai_props {
@@ -48,6 +54,7 @@ struct asoc_simple_priv {
                struct snd_soc_dai_link_component *platforms;
                struct asoc_simple_data adata;
                struct snd_soc_codec_conf *codec_conf;
+               struct prop_nums num;
                unsigned int mclk_fs;
        } *dai_props;
        struct asoc_simple_jack hp_jack;
@@ -71,6 +78,7 @@ struct link_info {
        int link; /* number of link */
        int conf; /* number of codec_conf */
        int cpu;  /* turn for CPU / Codec */
+       struct prop_nums num[SNDRV_MINOR_DEVICES];
 };
 
 int asoc_simple_parse_daifmt(struct device *dev,
index 76036ea..5fe53c5 100644 (file)
@@ -628,6 +628,15 @@ static int graph_count_noml(struct asoc_simple_priv *priv,
 {
        struct device *dev = simple_priv_to_dev(priv);
 
+       if (li->link >= SNDRV_MINOR_DEVICES) {
+               dev_err(dev, "too many links\n");
+               return -EINVAL;
+       }
+
+       li->num[li->link].cpus          = 1;
+       li->num[li->link].codecs        = 1;
+       li->num[li->link].platforms     = 1;
+
        li->link += 1; /* 1xCPU-Codec */
        li->dais += 2; /* 1xCPU + 1xCodec */
 
@@ -643,10 +652,23 @@ static int graph_count_dpcm(struct asoc_simple_priv *priv,
 {
        struct device *dev = simple_priv_to_dev(priv);
 
+       if (li->link >= SNDRV_MINOR_DEVICES) {
+               dev_err(dev, "too many links\n");
+               return -EINVAL;
+       }
+
        if (li->cpu) {
+               li->num[li->link].cpus          = 1;
+               li->num[li->link].codecs        = 1;
+               li->num[li->link].platforms     = 1;
+
                li->link++; /* 1xCPU-dummy */
                li->dais++; /* 1xCPU */
        } else {
+               li->num[li->link].cpus          = 1;
+               li->num[li->link].codecs        = 1;
+               li->num[li->link].platforms     = 1;
+
                li->link++; /* 1xdummy-Codec */
                li->conf++; /* 1xdummy-Codec */
                li->dais++; /* 1xCodec */
index 3010ff6..1606b9b 100644 (file)
@@ -604,13 +604,27 @@ int asoc_simple_init_priv(struct asoc_simple_priv *priv,
        struct asoc_simple_dai *dais;
        struct snd_soc_dai_link_component *dlcs;
        struct snd_soc_codec_conf *cconf = NULL;
-       int i;
+       int i, dai_num = 0, dlc_num = 0;
 
        dai_props = devm_kcalloc(dev, li->link, sizeof(*dai_props), GFP_KERNEL);
        dai_link  = devm_kcalloc(dev, li->link, sizeof(*dai_link),  GFP_KERNEL);
-       dais      = devm_kcalloc(dev, li->dais, sizeof(*dais),      GFP_KERNEL);
-       dlcs      = devm_kcalloc(dev, li->link * 3, sizeof(*dai_props), GFP_KERNEL);
-       if (!dai_props || !dai_link || !dais || !dlcs)
+       if (!dai_props || !dai_link)
+               return -ENOMEM;
+
+       /*
+        * dais (= CPU+Codec)
+        * dlcs (= CPU+Codec+Platform)
+        */
+       for (i = 0; i < li->link; i++) {
+               int cc = li->num[i].cpus + li->num[i].codecs;
+
+               dai_num += cc;
+               dlc_num += cc + li->num[i].platforms;
+       }
+
+       dais = devm_kcalloc(dev, dai_num, sizeof(*dais),      GFP_KERNEL);
+       dlcs = devm_kcalloc(dev, dlc_num, sizeof(*dai_props), GFP_KERNEL);
+       if (!dais || !dlcs)
                return -ENOMEM;
 
        if (li->conf) {
@@ -619,24 +633,6 @@ int asoc_simple_init_priv(struct asoc_simple_priv *priv,
                        return -ENOMEM;
        }
 
-       /*
-        * "platform" might be removed
-        * see
-        *      simple-card-utils.c :: asoc_simple_canonicalize_platform()
-        */
-       for (i = 0; i < li->link; i++) {
-               dai_props[i].cpus       = dlcs + (3 * i) + 0;
-               dai_props[i].codecs     = dlcs + (3 * i) + 1;
-               dai_props[i].platforms  = dlcs + (3 * i) + 2;
-
-               dai_link[i].cpus                = dai_props[i].cpus;
-               dai_link[i].num_cpus            = 1;
-               dai_link[i].codecs              = dai_props[i].codecs;
-               dai_link[i].num_codecs          = 1;
-               dai_link[i].platforms           = dai_props[i].platforms;
-               dai_link[i].num_platforms       = 1;
-       }
-
        priv->dai_props         = dai_props;
        priv->dai_link          = dai_link;
        priv->dais              = dais;
@@ -648,6 +644,38 @@ int asoc_simple_init_priv(struct asoc_simple_priv *priv,
        card->codec_conf        = cconf;
        card->num_configs       = li->conf;
 
+       for (i = 0; i < li->link; i++) {
+               if (li->num[i].cpus) {
+                       /* Normal CPU */
+                       dai_props[i].cpus       =
+                       dai_link[i].cpus        = dlcs;
+                       dai_props[i].num.cpus   =
+                       dai_link[i].num_cpus    = li->num[i].cpus;
+
+                       dlcs += li->num[i].cpus;
+               }
+
+               if (li->num[i].codecs) {
+                       /* Normal Codec */
+                       dai_props[i].codecs     =
+                       dai_link[i].codecs      = dlcs;
+                       dai_props[i].num.codecs =
+                       dai_link[i].num_codecs  = li->num[i].codecs;
+
+                       dlcs += li->num[i].codecs;
+               }
+
+               if (li->num[i].platforms) {
+                       /* Have Platform */
+                       dai_props[i].platforms          =
+                       dai_link[i].platforms           = dlcs;
+                       dai_props[i].num.platforms      =
+                       dai_link[i].num_platforms       = li->num[i].platforms;
+
+                       dlcs += li->num[i].platforms;
+               }
+       }
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(asoc_simple_init_priv);
index 9a05f44..1fad570 100644 (file)
@@ -499,6 +499,17 @@ static int simple_count_noml(struct asoc_simple_priv *priv,
                             struct device_node *codec,
                             struct link_info *li, bool is_top)
 {
+       if (li->link >= SNDRV_MINOR_DEVICES) {
+               struct device *dev = simple_priv_to_dev(priv);
+
+               dev_err(dev, "too many links\n");
+               return -EINVAL;
+       }
+
+       li->num[li->link].cpus          = 1;
+       li->num[li->link].codecs        = 1;
+       li->num[li->link].platforms     = 1;
+
        li->link += 1;
        li->dais += 2;
 
@@ -510,10 +521,25 @@ static int simple_count_dpcm(struct asoc_simple_priv *priv,
                             struct device_node *codec,
                             struct link_info *li, bool is_top)
 {
+       if (li->link >= SNDRV_MINOR_DEVICES) {
+               struct device *dev = simple_priv_to_dev(priv);
+
+               dev_err(dev, "too many links\n");
+               return -EINVAL;
+       }
+
        if (li->cpu) {
+               li->num[li->link].cpus          = 1;
+               li->num[li->link].codecs        = 1;
+               li->num[li->link].platforms     = 1;
+
                li->link++; /* CPU-dummy */
                li->dais++;
        } else {
+               li->num[li->link].cpus          = 1;
+               li->num[li->link].codecs        = 1;
+               li->num[li->link].platforms     = 1;
+
                li->link++; /* dummy-Codec */
                li->dais++;
                li->conf++;
@@ -575,6 +601,10 @@ static void simple_get_dais_count(struct asoc_simple_priv *priv,
         *      => 1 ccnf  = 1xdummy-Codec
         */
        if (!top) {
+               li->num[0].cpus         = 1;
+               li->num[0].codecs       = 1;
+               li->num[0].platforms    = 1;
+
                li->link = 1;
                li->dais = 2;
                li->conf = 0;