mirror of
https://github.com/alsa-project/alsa-utils
synced 2024-12-22 14:06:31 +01:00
topology: pre-process-object: Add support for pre-process objects with no builder
Some objects just need tobe processed to add their attributes to the private data section of their parent objects. An example of this would be the pdm_config objects for DMIC DAI's. Each pdm_config object's attributes need to be added as separate arrays in the DAI object's private data. Modify the signature of tplg_add_object_data() to pass the array_name parameter when multiple objects of the same type in the same parent are processed. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
parent
b848786f42
commit
48ebb1dc0c
1 changed files with 99 additions and 31 deletions
|
@ -469,11 +469,11 @@ static snd_config_t *tplg_object_lookup_in_config(struct tplg_pre_processor *tpl
|
|||
static int tplg_pp_add_object_tuple_section(struct tplg_pre_processor *tplg_pp,
|
||||
snd_config_t *class_cfg,
|
||||
snd_config_t *attr, char *data_name,
|
||||
const char *token_ref)
|
||||
const char *token_ref, const char *array_name)
|
||||
{
|
||||
snd_config_t *top, *tuple_cfg, *child, *cfg, *new;
|
||||
const char *id;
|
||||
char *token, *type;
|
||||
char *token, *type, *str;
|
||||
long tuple_value;
|
||||
int ret;
|
||||
|
||||
|
@ -500,6 +500,15 @@ static int tplg_pp_add_object_tuple_section(struct tplg_pre_processor *tplg_pp,
|
|||
return -ENOMEM;
|
||||
snprintf(token, strlen(token_ref) - strlen(type) + 1, "%s", token_ref);
|
||||
|
||||
if (!array_name)
|
||||
str = strdup(type + 1);
|
||||
else
|
||||
str = tplg_snprintf("%s.%s", type + 1, array_name);
|
||||
if (!str) {
|
||||
ret = -ENOMEM;
|
||||
goto free;
|
||||
}
|
||||
|
||||
tuple_cfg = tplg_find_config(top, data_name);
|
||||
if (!tuple_cfg) {
|
||||
/* add new SectionVendorTuples */
|
||||
|
@ -529,26 +538,29 @@ static int tplg_pp_add_object_tuple_section(struct tplg_pre_processor *tplg_pp,
|
|||
goto err;
|
||||
}
|
||||
|
||||
ret = tplg_config_make_add(&cfg, type + 1, SND_CONFIG_TYPE_COMPOUND,
|
||||
ret = tplg_config_make_add(&cfg, str, SND_CONFIG_TYPE_COMPOUND,
|
||||
child);
|
||||
if (ret < 0) {
|
||||
SNDERR("Error creating tuples type config for '%s'\n", data_name);
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
char *id;
|
||||
snd_config_t *tuples_cfg;
|
||||
|
||||
id = tplg_snprintf("tuples.%s", type + 1);
|
||||
if (!id) {
|
||||
ret = -ENOMEM;
|
||||
ret = snd_config_search(tuple_cfg, "tuples" , &tuples_cfg);
|
||||
if (ret < 0) {
|
||||
SNDERR("can't find tuples config in %s\n", data_name);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = snd_config_search(tuple_cfg, id , &cfg);
|
||||
free(id);
|
||||
if (ret < 0) {
|
||||
SNDERR("can't find type config %s\n", type + 1);
|
||||
goto err;
|
||||
cfg = tplg_find_config(tuples_cfg, str);
|
||||
if (!cfg) {
|
||||
ret = tplg_config_make_add(&cfg, str, SND_CONFIG_TYPE_COMPOUND,
|
||||
tuples_cfg);
|
||||
if (ret < 0) {
|
||||
SNDERR("Error creating tuples config for '%s' and type name %s\n", data_name, str);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -581,10 +593,9 @@ static int tplg_pp_add_object_tuple_section(struct tplg_pre_processor *tplg_pp,
|
|||
}
|
||||
|
||||
ret = snd_config_add(cfg, new);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
err:
|
||||
free(str);
|
||||
free:
|
||||
free(token);
|
||||
return ret;
|
||||
}
|
||||
|
@ -650,7 +661,7 @@ static int tplg_pp_add_object_data_section(struct tplg_pre_processor *tplg_pp,
|
|||
}
|
||||
|
||||
static int tplg_add_object_data(struct tplg_pre_processor *tplg_pp, snd_config_t *obj_cfg,
|
||||
snd_config_t *top)
|
||||
snd_config_t *top, const char *array_name)
|
||||
{
|
||||
snd_config_iterator_t i, next;
|
||||
snd_config_t *data_cfg, *class_cfg, *n, *obj;
|
||||
|
@ -701,7 +712,7 @@ static int tplg_add_object_data(struct tplg_pre_processor *tplg_pp, snd_config_t
|
|||
}
|
||||
|
||||
ret = tplg_pp_add_object_tuple_section(tplg_pp, class_cfg, n, data_cfg_name,
|
||||
token);
|
||||
token, array_name);
|
||||
if (ret < 0) {
|
||||
SNDERR("Failed to add data section %s\n", data_cfg_name);
|
||||
free(data_cfg_name);
|
||||
|
@ -758,6 +769,60 @@ static int tplg_object_add_attributes(snd_config_t *dst, snd_config_t *template,
|
|||
static const struct build_function_map *tplg_object_get_map(struct tplg_pre_processor *tplg_pp,
|
||||
snd_config_t *obj);
|
||||
|
||||
/* Add object attributes to the private data of the parent object config */
|
||||
static int tplg_build_parent_data(struct tplg_pre_processor *tplg_pp, snd_config_t *obj_cfg,
|
||||
snd_config_t *parent)
|
||||
{
|
||||
snd_config_t *obj, *parent_obj, *section_cfg, *top;
|
||||
const struct build_function_map *map;
|
||||
const char *id, *parent_id;
|
||||
int ret;
|
||||
|
||||
/* nothing to do if parent is NULL */
|
||||
if (!parent)
|
||||
return 0;
|
||||
|
||||
obj = tplg_object_get_instance_config(tplg_pp, obj_cfg);
|
||||
parent_obj = tplg_object_get_instance_config(tplg_pp, parent);
|
||||
|
||||
/* get object ID */
|
||||
if (snd_config_get_id(obj, &id) < 0) {
|
||||
SNDERR("Invalid ID for object\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* get parent object name or ID */
|
||||
parent_id = tplg_object_get_name(tplg_pp, parent_obj);
|
||||
if (!parent_id) {
|
||||
ret = snd_config_get_id(parent_obj, &parent_id);
|
||||
if (ret < 0) {
|
||||
SNDERR("Invalid ID for parent of object %s\n", id);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
map = tplg_object_get_map(tplg_pp, parent);
|
||||
if (!map) {
|
||||
SNDERR("Parent object %s not supported\n", parent_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* find parent config with ID */
|
||||
ret = snd_config_search(tplg_pp->output_cfg, map->section_name, §ion_cfg);
|
||||
if (ret < 0) {
|
||||
SNDERR("No SectionBE found\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
top = tplg_find_config(section_cfg, parent_id);
|
||||
if (!top) {
|
||||
SNDERR("SectionBE %s not found\n", parent_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return tplg_add_object_data(tplg_pp, obj_cfg, top, id);
|
||||
}
|
||||
|
||||
/*
|
||||
* Function to create a new "section" config based on the template. The new config will be
|
||||
* added to the output_cfg or the top_config input parameter.
|
||||
|
@ -855,7 +920,7 @@ static int tplg_build_generic_object(struct tplg_pre_processor *tplg_pp, snd_con
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = tplg_add_object_data(tplg_pp, obj_cfg, wtop);
|
||||
ret = tplg_add_object_data(tplg_pp, obj_cfg, wtop, NULL);
|
||||
if (ret < 0)
|
||||
SNDERR("Failed to add data section for %s\n", name);
|
||||
|
||||
|
@ -1461,28 +1526,31 @@ static int tplg_build_object(struct tplg_pre_processor *tplg_pp, snd_config_t *n
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* skip object if not supported and pre-process its child objects */
|
||||
/*
|
||||
* Build objects if object type is supported.
|
||||
* If not, process object attributes and add to parent's data section
|
||||
*/
|
||||
map = tplg_object_get_map(tplg_pp, new_obj);
|
||||
if (!map)
|
||||
goto child;
|
||||
if (map) {
|
||||
builder = map->builder;
|
||||
|
||||
/* update automatic attribute for current object */
|
||||
auto_attr_updater = map->auto_attr_updater;
|
||||
if(auto_attr_updater) {
|
||||
ret = auto_attr_updater(tplg_pp, obj_local, parent);
|
||||
if (ret < 0) {
|
||||
SNDERR("Failed to update automatic attributes for %s\n", id);
|
||||
return ret;
|
||||
/* update automatic attribute for current object */
|
||||
auto_attr_updater = map->auto_attr_updater;
|
||||
if(auto_attr_updater) {
|
||||
ret = auto_attr_updater(tplg_pp, obj_local, parent);
|
||||
if (ret < 0) {
|
||||
SNDERR("Failed to update automatic attributes for %s\n", id);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
builder = &tplg_build_parent_data;
|
||||
}
|
||||
|
||||
/* build the object and save the sections to the output config */
|
||||
builder = map->builder;
|
||||
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) {
|
||||
|
|
Loading…
Reference in a new issue