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 <ranjani.sridharan@linux.intel.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
Ranjani Sridharan 2021-04-21 11:18:04 -07:00 committed by Jaroslav Kysela
parent df6cfa77e3
commit 1832f6f254

View file

@ -1168,6 +1168,33 @@ validate:
return 0; 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, static int tplg_construct_object_name(struct tplg_pre_processor *tplg_pp, snd_config_t *obj,
snd_config_t *class_cfg) snd_config_t *class_cfg)
{ {
@ -1306,6 +1333,7 @@ static int tplg_set_attribute_value(snd_config_t *attr, const char *value)
return 0; return 0;
} }
/* /*
* Find the unique attribute in the class definition and set its value and type. * Find the unique attribute in the class definition and set its value and type.
* Only string or integer types are allowed for unique values. * 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); 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, static int tplg_build_object(struct tplg_pre_processor *tplg_pp, snd_config_t *new_obj,
snd_config_t *parent) 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; 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); map = tplg_object_get_map(tplg_pp, new_obj);
if (!map) if (!map)
return 0; goto child;
/* build the object and save the sections to the output config */ /* build the object and save the sections to the output config */
builder = map->builder; 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 */ /* create top-level topology objects */