]> git.alsa-project.org Git - alsa-utils.git/commitdiff
topology: pre-process-object: Add support for data objects
authorRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Mon, 26 Apr 2021 18:48:43 +0000 (11:48 -0700)
committerJaroslav Kysela <perex@perex.cz>
Tue, 25 May 2021 16:26:51 +0000 (18:26 +0200)
Pre-process data objects, create the SectionData and update
the parent object with the reference to the object.
For example, the following object instance:

Object.Base.data."SOF_ABI" {
bytes "0x03,0x12,0x01"
}

would update the SectionManifest as follows:
SectionManifest."sof_manifest" {
data [
"SOF_ABI"
]
}

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
topology/pre-process-object.c
topology/pre-processor.h

index 66116b42e425a71e79f4043b88f136e55e53da65..0777e8a58d9d8dfcd62057ad752c7536c1014cfc 100644 (file)
 #include "topology.h"
 #include "pre-processor.h"
 
+int tplg_parent_update(struct tplg_pre_processor *tplg_pp, snd_config_t *parent,
+                         const char *section_name, const char *item_name)
+{
+       snd_config_iterator_t i, next;
+       snd_config_t *child, *cfg, *top, *item_config, *n;
+       const char *parent_name;
+       char *item_id;
+       int ret, id = 0;
+
+       child = tplg_object_get_instance_config(tplg_pp, parent);
+       ret = snd_config_search(child, "name", &cfg);
+       if (ret < 0) {
+               ret = snd_config_get_id(child, &parent_name);
+               if (ret < 0) {
+                       SNDERR("No name config for parent\n");
+                       return ret;
+               }
+       } else {
+               ret = snd_config_get_string(cfg, &parent_name);
+               if (ret < 0) {
+                       SNDERR("Invalid name for parent\n");
+                       return ret;
+               }
+       }
+
+       top = tplg_object_get_section(tplg_pp, parent);
+       if (!top)
+               return -EINVAL;
+
+       /* get config with name */
+       cfg = tplg_find_config(top, parent_name);
+       if (!cfg)
+               return ret;
+
+       /* get section config */
+       ret = snd_config_search(cfg, section_name, &item_config);
+       if (ret < 0) {
+               ret = tplg_config_make_add(&item_config, section_name,
+                                         SND_CONFIG_TYPE_COMPOUND, cfg);
+               if (ret < 0) {
+                       SNDERR("Error creating section config widget %s for %s\n",
+                              section_name, parent_name);
+                       return ret;
+               }
+       }
+
+       snd_config_for_each(i, next, item_config) {
+               const char *name;
+
+               n = snd_config_iterator_entry(i);
+               if (snd_config_get_string(n, &name) < 0)
+                       continue;
+
+               /* item already exists */
+               if (!strcmp(name, item_name))
+                       return 0;
+               id++;
+       }
+
+       /* add new item */
+       item_id = tplg_snprintf("%d", id);
+       if (!item_id)
+               return -ENOMEM;
+
+       ret = snd_config_make(&cfg, item_id, SND_CONFIG_TYPE_STRING);
+       free(item_id);
+       if (ret < 0)
+               return ret;
+
+       ret = snd_config_set_string(cfg, item_name);
+       if (ret < 0)
+               return ret;
+
+       ret = snd_config_add(item_config, cfg);
+       if (ret < 0)
+               snd_config_delete(cfg);
+
+       return ret;
+}
+
+/* Parse data object, create the "SectionData" and save it. Only "bytes" data supported for now */
+int tplg_build_data_object(struct tplg_pre_processor *tplg_pp, snd_config_t *obj_cfg,
+                           snd_config_t *parent)
+{
+       snd_config_t *dtop;
+       const char *name;
+       int ret;
+
+       ret = tplg_build_object_from_template(tplg_pp, obj_cfg, &dtop, NULL, false);
+       if (ret < 0)
+               return ret;
+
+       ret = snd_config_get_id(dtop, &name);
+       if (ret < 0)
+               return ret;
+
+       return tplg_parent_update(tplg_pp, parent, "data", name);
+}
+
 static int tplg_create_config_template(struct tplg_pre_processor *tplg_pp,
                                       snd_config_t **template,
                                       const struct config_template_items *items)
@@ -699,8 +798,13 @@ static int tplg_build_generic_object(struct tplg_pre_processor *tplg_pp, snd_con
        return ret;
 }
 
+const struct config_template_items data_config = {
+       .string_config_ids = {"bytes"}
+};
+
 const struct build_function_map object_build_map[] = {
        {"Base", "manifest", "SectionManifest", &tplg_build_generic_object, NULL},
+       {"Base", "data", "SectionData", &tplg_build_data_object, &data_config},
 };
 
 static const struct build_function_map *tplg_object_get_map(struct tplg_pre_processor *tplg_pp,
index 8934e2f60c63d743c47f7e804bb01437cd746f83..c6d2df812bff19249670ef5ae021bb75309e83bb 100644 (file)
@@ -53,6 +53,8 @@ void tplg_pp_config_debug(struct tplg_pre_processor *tplg_pp, snd_config_t *cfg)
 int tplg_build_object_from_template(struct tplg_pre_processor *tplg_pp, snd_config_t *obj_cfg,
                                    snd_config_t **wtop, snd_config_t *top_config,
                                    bool skip_name);
+int tplg_parent_update(struct tplg_pre_processor *tplg_pp, snd_config_t *parent,
+                         const char *section_name, const char *item_name);
 
 /* object helpers */
 int tplg_pre_process_objects(struct tplg_pre_processor *tplg_pp, snd_config_t *cfg,
@@ -83,5 +85,6 @@ long tplg_class_attribute_valid_tuple_value(struct tplg_pre_processor *tplg_pp,
 snd_config_t *tplg_find_config(snd_config_t *config, const char *name);
 int tplg_config_make_add(snd_config_t **config, const char *id, snd_config_type_t type,
                         snd_config_t *parent);
+
 char *tplg_snprintf(char *fmt, ...);
 #endif