From 1832f6f25439b9215d15cc6a0efd58ed08a15969 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Wed, 21 Apr 2021 11:18:04 -0700 Subject: [PATCH] topology: pre-process-object: add support for prepocessing child objects Add support for processing object instances embedded within objects and classes. For example: Object.Control.mixer."0" { #Channel register and shift for Front Left/Right Object.Base.channel."fl" { shift 0 } Object.Base.channel."fr" { } Object.Base.tlv."vtlv_m64s2" { Object.Base.scale."m64s2" { mute 1 } } Object.Base.ops."ctl" { info "volsw" #256 binds the mixer control to volume get/put handlers get 256 put 256 } } and pga class embeds the mixer objects as follows: Class.Widget."pga" { ... Object.Control { mixer."0" {...} mixer."1" {...} } The pre-processor starts with the top-pevel PGA widget object and processes the mixer objects in the class definition. This will recursively pre-processes its child objects to add the channels, tlv and ops. Signed-off-by: Ranjani Sridharan Signed-off-by: Jaroslav Kysela --- topology/pre-process-object.c | 53 ++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/topology/pre-process-object.c b/topology/pre-process-object.c index 0117577..fbf4b6a 100644 --- a/topology/pre-process-object.c +++ b/topology/pre-process-object.c @@ -1168,6 +1168,33 @@ validate: return 0; } +static int tplg_object_pre_process_children(struct tplg_pre_processor *tplg_pp, + snd_config_t *parent, snd_config_t *cfg) +{ + snd_config_iterator_t i, next; + snd_config_t *children, *n; + int ret; + + ret = snd_config_search(cfg, "Object", &children); + if (ret < 0) + return 0; + + /* create all embedded objects */ + snd_config_for_each(i, next, children) { + const char *id; + + n = snd_config_iterator_entry(i); + if (snd_config_get_id(n, &id) < 0) + continue; + + ret = tplg_pre_process_objects(tplg_pp, n, parent); + if (ret < 0) + return ret; + } + + return 0; +} + static int tplg_construct_object_name(struct tplg_pre_processor *tplg_pp, snd_config_t *obj, snd_config_t *class_cfg) { @@ -1306,6 +1333,7 @@ static int tplg_set_attribute_value(snd_config_t *attr, const char *value) return 0; } + /* * Find the unique attribute in the class definition and set its value and type. * Only string or integer types are allowed for unique values. @@ -1372,7 +1400,7 @@ snd_config_t *tplg_object_get_instance_config(struct tplg_pre_processor *tplg_pp return snd_config_iterator_entry(first); } -/* build object config */ +/* build object config and its child objects recursively */ static int tplg_build_object(struct tplg_pre_processor *tplg_pp, snd_config_t *new_obj, snd_config_t *parent) { @@ -1417,14 +1445,31 @@ static int tplg_build_object(struct tplg_pre_processor *tplg_pp, snd_config_t *n return ret; } - /* nothing to do if object is not supported */ + /* skip object if not supported and pre-process its child objects */ map = tplg_object_get_map(tplg_pp, new_obj); if (!map) - return 0; + goto child; /* build the object and save the sections to the output config */ builder = map->builder; - return builder(tplg_pp, new_obj, parent); + ret = builder(tplg_pp, new_obj, parent); + if (ret < 0) + return ret; + +child: + /* create child objects in the object instance */ + ret = tplg_object_pre_process_children(tplg_pp, new_obj, obj_local); + if (ret < 0) { + SNDERR("error processing child objects in object %s\n", id); + return ret; + } + + /* create child objects in the object's class definition */ + ret = tplg_object_pre_process_children(tplg_pp, new_obj, class_cfg); + if (ret < 0) + SNDERR("error processing child objects in class %s\n", class_id); + + return ret; } /* create top-level topology objects */