]> git.alsa-project.org Git - alsa-utils.git/commitdiff
topology: pre-process-object: add support for prepocessing child objects
authorRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Wed, 21 Apr 2021 18:18:04 +0000 (11:18 -0700)
committerJaroslav Kysela <perex@perex.cz>
Tue, 25 May 2021 16:26:51 +0000 (18:26 +0200)
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 <ranjani.sridharan@linux.intel.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
topology/pre-process-object.c

index 0117577b2a4bee7e1a63b1d0a9f8966999972a8a..fbf4b6a60fade9013529715dde9e0f40acc9999f 100644 (file)
@@ -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 */