]> git.alsa-project.org Git - alsa-lib.git/commitdiff
topology: Parse physical DAIs in text conf file
authorMengdong Lin <mengdong.lin@linux.intel.com>
Wed, 16 Nov 2016 06:42:33 +0000 (14:42 +0800)
committerTakashi Iwai <tiwai@suse.de>
Tue, 22 Nov 2016 06:50:26 +0000 (07:50 +0100)
Add support for parsing physical DAIs in the text configuration file.
The syntax of physical DAIs is described in document in topology.h

Signed-off-by: Mengdong Lin <mengdong.lin@linux.intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
include/topology.h
src/topology/data.c
src/topology/elem.c
src/topology/parser.c
src/topology/pcm.c
src/topology/tplg_local.h

index c52c580f5fb23d65fd927cc6ab0e44fdfa48dc6f..0581b1cdaabd843a320bcef63eab42651011952c 100644 (file)
@@ -663,6 +663,36 @@ extern "C" {
  * }
  * </pre>
  *
+ * <h4>Physical DAI</h4>
+ * A physical DAI (e.g. backend DAI for DPCM) is defined as a new section
+ * that can include a unique ID, playback and capture stream capabilities,
+ * optional flags, and private data. <br>
+ * Its PCM stream capablities are same as those for PCM objects,
+ * please refer to section 'PCM Capabilities'.
+ *
+ * <pre>
+ * SectionDAI."name" {
+ *
+ *     index "1"                       # Index number
+ *
+ *     id "0"                          # used for binding to the Backend DAI
+ *
+ *     pcm."playback" {
+ *             capabilities "capabilities1"    # capabilities for playback
+ *     }
+ *
+ *     pcm."capture" {
+ *             capabilities "capabilities2"    # capabilities for capture
+ *     }
+ *
+ *     symmetric_rates "true"                  # optional flags
+ *     symmetric_channels "true"
+ *     symmetric_sample_bits "false"
+ *
+ *     data "name"                     # optional private data
+ * }
+ * </pre>
+ *
  * <h4>Manifest Private Data</h4>
  * Manfiest may have private data. Users need to define a manifest section
  * and add the references to 1 or multiple data sections. Please refer to
@@ -735,6 +765,7 @@ enum snd_tplg_type {
        SND_TPLG_TYPE_TUPLE,            /*!< Vendor tuples */
        SND_TPLG_TYPE_LINK,             /*!< Physical DAI link */
        SND_TPLG_TYPE_HW_CONFIG,        /*!< Link HW config */
+       SND_TPLG_TYPE_DAI,              /*!< Physical DAI */
 };
 
 /**
index 59bc97002a21334c0503f1f8e365439a7a119e5c..0d5c4301c8195076eb426b6b455e5ad85cf359f8 100644 (file)
@@ -46,6 +46,10 @@ struct snd_soc_tplg_private *get_priv_data(struct tplg_elem *elem)
                priv = &elem->widget->priv;
                break;
 
+       case SND_TPLG_TYPE_DAI:
+               priv = &elem->dai->priv;
+               break;
+
        default:
                SNDERR("error: '%s': no support for private data for type %d\n",
                        elem->id, elem->type);
index 01dce1f1b8626602ad53b7a2da8903c27c1f6439..1a5ac8413d6ce1a49a21173d7786d2a73ec1f6fa 100644 (file)
@@ -192,6 +192,10 @@ struct tplg_elem* tplg_elem_new_common(snd_tplg_t *tplg,
                list_add_tail(&elem->list, &tplg->pcm_list);
                obj_size = sizeof(struct snd_soc_tplg_pcm);
                break;
+       case SND_TPLG_TYPE_DAI:
+               list_add_tail(&elem->list, &tplg->dai_list);
+               obj_size = sizeof(struct snd_soc_tplg_dai);
+               break;
        case SND_TPLG_TYPE_BE:
        case SND_TPLG_TYPE_LINK:
                list_add_tail(&elem->list, &tplg->be_list);
index 7d0486cda0d43a6fec55fd99623e1b2422965fb9..72efef48626ff3bceb0e2143e6a47485d5051223 100644 (file)
@@ -133,6 +133,14 @@ static int tplg_parse_config(snd_tplg_t *tplg, snd_config_t *cfg)
                        continue;
                }
 
+               if (strcmp(id, "SectionDAI") == 0) {
+                       err = tplg_parse_compound(tplg, n,
+                               tplg_parse_dai, NULL);
+                       if (err < 0)
+                               return err;
+                       continue;
+               }
+
                if (strcmp(id, "SectionHWConfig") == 0) {
                        err = tplg_parse_compound(tplg, n, tplg_parse_hw_config,
                                NULL);
@@ -450,6 +458,7 @@ snd_tplg_t *snd_tplg_new(void)
        INIT_LIST_HEAD(&tplg->tlv_list);
        INIT_LIST_HEAD(&tplg->widget_list);
        INIT_LIST_HEAD(&tplg->pcm_list);
+       INIT_LIST_HEAD(&tplg->dai_list);
        INIT_LIST_HEAD(&tplg->be_list);
        INIT_LIST_HEAD(&tplg->cc_list);
        INIT_LIST_HEAD(&tplg->route_list);
@@ -476,6 +485,7 @@ void snd_tplg_free(snd_tplg_t *tplg)
        tplg_elem_free_list(&tplg->tlv_list);
        tplg_elem_free_list(&tplg->widget_list);
        tplg_elem_free_list(&tplg->pcm_list);
+       tplg_elem_free_list(&tplg->dai_list);
        tplg_elem_free_list(&tplg->be_list);
        tplg_elem_free_list(&tplg->cc_list);
        tplg_elem_free_list(&tplg->route_list);
index a9d32772cf31c13a0a68f8038c177fcab62624f5..4093e2fcac33be725c73dfa660fe90e7071909b3 100644 (file)
@@ -341,6 +341,7 @@ static int tplg_parse_streams(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
        snd_config_t *n;
        struct tplg_elem *elem = private;
        struct snd_soc_tplg_pcm *pcm;
+       struct snd_soc_tplg_dai *dai;
        unsigned int *playback, *capture;
        struct snd_soc_tplg_stream_caps *caps;
        const char *id, *value;
@@ -357,6 +358,14 @@ static int tplg_parse_streams(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
                capture = &pcm->capture;
                caps = pcm->caps;
                break;
+
+       case SND_TPLG_TYPE_DAI:
+               dai = elem->dai;
+               playback = &dai->playback;
+               capture = &dai->capture;
+               caps = dai->caps;
+               break;
+
        default:
                return -EINVAL;
        }
@@ -557,6 +566,109 @@ int tplg_parse_pcm(snd_tplg_t *tplg,
        return 0;
 }
 
+/* Parse physical DAI */
+int tplg_parse_dai(snd_tplg_t *tplg,
+       snd_config_t *cfg, void *private ATTRIBUTE_UNUSED)
+{
+       struct snd_soc_tplg_dai *dai;
+       struct tplg_elem *elem;
+       snd_config_iterator_t i, next;
+       snd_config_t *n;
+       const char *id, *val = NULL;
+       int err;
+
+       elem = tplg_elem_new_common(tplg, cfg, NULL, SND_TPLG_TYPE_DAI);
+       if (!elem)
+               return -ENOMEM;
+
+       dai = elem->dai;
+       dai->size = elem->size;
+       elem_copy_text(dai->dai_name, elem->id,
+               SNDRV_CTL_ELEM_ID_NAME_MAXLEN);
+
+       tplg_dbg(" DAI: %s\n", elem->id);
+
+       snd_config_for_each(i, next, cfg) {
+
+               n = snd_config_iterator_entry(i);
+               if (snd_config_get_id(n, &id) < 0)
+                       continue;
+
+               /* skip comments */
+               if (strcmp(id, "comment") == 0)
+                       continue;
+               if (id[0] == '#')
+                       continue;
+
+               if (strcmp(id, "index") == 0) {
+                       if (snd_config_get_string(n, &val) < 0)
+                               return -EINVAL;
+
+                       elem->index = atoi(val);
+                       tplg_dbg("\t%s: %d\n", id, elem->index);
+                       continue;
+               }
+
+               if (strcmp(id, "id") == 0) {
+                       if (snd_config_get_string(n, &val) < 0)
+                               return -EINVAL;
+
+                       dai->dai_id = atoi(val);
+                       tplg_dbg("\t%s: %d\n", id, dai->dai_id);
+                       continue;
+               }
+
+               /* stream capabilities */
+               if (strcmp(id, "pcm") == 0) {
+                       err = tplg_parse_compound(tplg, n,
+                               tplg_parse_streams, elem);
+                       if (err < 0)
+                               return err;
+                       continue;
+               }
+
+               /* flags */
+               if (strcmp(id, "symmetric_rates") == 0) {
+                       err = parse_flag(n,
+                               SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_RATES,
+                               &dai->flag_mask, &dai->flags);
+                       if (err < 0)
+                               return err;
+                       continue;
+               }
+
+               if (strcmp(id, "symmetric_channels") == 0) {
+                       err = parse_flag(n,
+                               SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_CHANNELS,
+                               &dai->flag_mask, &dai->flags);
+                       if (err < 0)
+                               return err;
+                       continue;
+               }
+
+               if (strcmp(id, "symmetric_sample_bits") == 0) {
+                       err = parse_flag(n,
+                               SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_SAMPLEBITS,
+                               &dai->flag_mask, &dai->flags);
+                       if (err < 0)
+                               return err;
+                       continue;
+               }
+
+               /* private data */
+               if (strcmp(id, "data") == 0) {
+                       if (snd_config_get_string(n, &val) < 0)
+                               return -EINVAL;
+
+                       tplg_ref_add(elem, SND_TPLG_TYPE_DATA, val);
+                       tplg_dbg("\t%s: %s\n", id, val);
+                       continue;
+               }
+       }
+
+       return 0;
+}
+
 /* parse physical link runtime supported HW configs in text conf file */
 static int parse_hw_config_refs(snd_tplg_t *tplg, snd_config_t *cfg,
                                struct tplg_elem *elem)
index 9e67bf8126aad1ba6002a56516ffb9a4dcf6f6a9..eeeb0f11127ddbeef0c9d37df73c9e0c53883750 100644 (file)
@@ -64,6 +64,7 @@ struct snd_tplg {
        struct list_head tlv_list;
        struct list_head widget_list;
        struct list_head pcm_list;
+       struct list_head dai_list;
        struct list_head be_list;
        struct list_head cc_list;
        struct list_head route_list;
@@ -145,6 +146,7 @@ struct tplg_elem {
                struct snd_soc_tplg_bytes_control *bytes_ext;
                struct snd_soc_tplg_dapm_widget *widget;
                struct snd_soc_tplg_pcm *pcm;
+               struct snd_soc_tplg_dai *dai;
                struct snd_soc_tplg_link_config *link;/* physical link */
                struct snd_soc_tplg_dapm_graph_elem *route;
                struct snd_soc_tplg_stream *stream_cfg;
@@ -222,6 +224,9 @@ int tplg_parse_stream_caps(snd_tplg_t *tplg,
 int tplg_parse_pcm(snd_tplg_t *tplg,
        snd_config_t *cfg, void *private ATTRIBUTE_UNUSED);
 
+int tplg_parse_dai(snd_tplg_t *tplg, snd_config_t *cfg,
+                  void *private ATTRIBUTE_UNUSED);
+
 int tplg_parse_link(snd_tplg_t *tplg,
        snd_config_t *cfg, void *private ATTRIBUTE_UNUSED);