From: Ranjani Sridharan Date: Wed, 21 Apr 2021 18:18:04 +0000 (-0700) Subject: topology: pre-process-object: add support for prepocessing child objects X-Git-Tag: v1.2.5~4 X-Git-Url: https://git.alsa-project.org/?a=commitdiff_plain;h=1832f6f25439b9215d15cc6a0efd58ed08a15969;p=alsa-utils.git 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 --- 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 */