From cb65ce0195ed30f2f7ce18c1c38fd27f12a9fcda Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Mon, 26 Apr 2021 11:48:43 -0700 Subject: [PATCH] topology: pre-process-object: Add support for data objects 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 Signed-off-by: Jaroslav Kysela --- topology/pre-process-object.c | 104 ++++++++++++++++++++++++++++++++++ topology/pre-processor.h | 3 + 2 files changed, 107 insertions(+) diff --git a/topology/pre-process-object.c b/topology/pre-process-object.c index 66116b4..0777e8a 100644 --- a/topology/pre-process-object.c +++ b/topology/pre-process-object.c @@ -30,6 +30,105 @@ #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, diff --git a/topology/pre-processor.h b/topology/pre-processor.h index 8934e2f..c6d2df8 100644 --- a/topology/pre-processor.h +++ b/topology/pre-processor.h @@ -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 -- 2.47.1