mirror of
https://github.com/alsa-project/alsa-utils
synced 2024-11-10 00:05:42 +01:00
topology: pre-process-dai: add support for pcm_caps objects
Add support for processing pcm_caps objects. For ex: Object.PCM.pcm."0" { name "Port0" direction "duplex" Object.Base.fe_dai."Port 0" {} Object.PCM.pcm_caps."playback" { name "Port0 Playback" } Object.PCM.pcm_caps."capture" { name "Port0 Capture" } } Would convert into: SectionPCMCapabilities { 'Port0 Playback' { formats 'S32_LE,S24_LE,S16_LE' rate_min 48000 rate_max 48000 channels_min 2 channels_max 2 periods_min 2 periods_max 16 period_size_min 192 period_size_max 16384 buffer_size_min 65536 buffer_size_max 65536 } 'Port0 Capture' { formats 'S32_LE,S24_LE,S16_LE' rate_min 48000 rate_max 48000 channels_min 2 channels_max 2 periods_min 2 periods_max 16 period_size_min 192 period_size_max 16384 buffer_size_min 65536 buffer_size_max 65536 } } and the SectionPCM updated as follows: SectionPCM { Port0 { id 0 dai { 'Port 0' { id 0 } } pcm { playback { capabilities 'Port0 Playback' } capture { capabilities 'Port0 Capture' } } } } Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
parent
3719c80a4d
commit
df6cfa77e3
3 changed files with 98 additions and 0 deletions
|
@ -51,3 +51,90 @@ int tplg_build_fe_dai_object(struct tplg_pre_processor *tplg_pp, snd_config_t *o
|
|||
{
|
||||
return tplg_build_base_object(tplg_pp, obj_cfg, parent, false);
|
||||
}
|
||||
|
||||
static int tplg_update_pcm_object(struct tplg_pre_processor *tplg_pp,
|
||||
snd_config_t *obj_cfg, snd_config_t *parent)
|
||||
{
|
||||
snd_config_t *top, *parent_obj, *obj, *dest, *cfg, *pcm, *child;
|
||||
const char *parent_name, *item_name, *direction;
|
||||
int ret;
|
||||
|
||||
/* get object name */
|
||||
obj = tplg_object_get_instance_config(tplg_pp, obj_cfg);
|
||||
item_name = tplg_object_get_name(tplg_pp, obj);
|
||||
if (!item_name)
|
||||
return -EINVAL;
|
||||
|
||||
/* get direction */
|
||||
ret = snd_config_search(obj, "direction", &cfg);
|
||||
if (ret < 0) {
|
||||
SNDERR("no direction attribute in %s\n", item_name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = snd_config_get_string(cfg, &direction);
|
||||
if (ret < 0) {
|
||||
SNDERR("Invalid direction attribute in %s\n", item_name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* add to parent section */
|
||||
top = tplg_object_get_section(tplg_pp, parent);
|
||||
if (!top) {
|
||||
SNDERR("Cannot find parent for %s\n", item_name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
parent_obj = tplg_object_get_instance_config(tplg_pp, parent);
|
||||
|
||||
/* get parent name. if parent has no name, skip adding config */
|
||||
parent_name = tplg_object_get_name(tplg_pp, parent_obj);
|
||||
if (!parent_name)
|
||||
return 0;
|
||||
|
||||
/* find parent config with name */
|
||||
dest = tplg_find_config(top, parent_name);
|
||||
if (!dest) {
|
||||
SNDERR("Cannot find parent section %s\n", parent_name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = snd_config_search(dest, "pcm", &pcm);
|
||||
if (ret < 0) {
|
||||
ret = tplg_config_make_add(&pcm, "pcm", SND_CONFIG_TYPE_COMPOUND, dest);
|
||||
if (ret < 0) {
|
||||
SNDERR("Error creating pcm config in %s\n", parent_name);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = snd_config_search(pcm, direction, &cfg);
|
||||
if (ret >= 0) {
|
||||
SNDERR("pcm.%s exists already in %s\n", direction, parent_name);
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
ret = tplg_config_make_add(&cfg, direction, SND_CONFIG_TYPE_COMPOUND, pcm);
|
||||
|
||||
if (ret >= 0)
|
||||
ret = tplg_config_make_add(&child, "capabilities", SND_CONFIG_TYPE_STRING, cfg);
|
||||
|
||||
if (ret >= 0)
|
||||
ret = snd_config_set_string(child, item_name);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tplg_build_pcm_caps_object(struct tplg_pre_processor *tplg_pp,
|
||||
snd_config_t *obj_cfg, snd_config_t *parent)
|
||||
{
|
||||
snd_config_t *caps;
|
||||
int ret;
|
||||
|
||||
ret = tplg_build_object_from_template(tplg_pp, obj_cfg, &caps, NULL, false);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* add pcm capabilities to parent */
|
||||
return tplg_update_pcm_object(tplg_pp, obj_cfg, parent);
|
||||
}
|
||||
|
|
|
@ -858,6 +858,13 @@ static int tplg_build_generic_object(struct tplg_pre_processor *tplg_pp, snd_con
|
|||
return ret;
|
||||
}
|
||||
|
||||
const struct config_template_items pcm_caps_config = {
|
||||
.int_config_ids = {"rate_min", "rate_max", "channels_min", "channels_max", "periods_min",
|
||||
"periods_max", "period_size_min", "period_size_max", "buffer_size_min",
|
||||
"buffer_size_max", "sig_bits"},
|
||||
.string_config_ids = {"formats", "rates"},
|
||||
};
|
||||
|
||||
const struct config_template_items fe_dai_config = {
|
||||
.int_config_ids = {"id"},
|
||||
};
|
||||
|
@ -932,6 +939,8 @@ const struct build_function_map object_build_map[] = {
|
|||
&bytes_control_config},
|
||||
{"Dai", "", "SectionBE", &tplg_build_generic_object, &be_dai_config},
|
||||
{"PCM", "pcm", "SectionPCM", &tplg_build_generic_object, &pcm_config},
|
||||
{"PCM", "pcm_caps", "SectionPCMCapabilities", &tplg_build_pcm_caps_object,
|
||||
&pcm_caps_config},
|
||||
};
|
||||
|
||||
static const struct build_function_map *tplg_object_get_map(struct tplg_pre_processor *tplg_pp,
|
||||
|
|
|
@ -73,6 +73,8 @@ int tplg_build_fe_dai_object(struct tplg_pre_processor *tplg_pp, snd_config_t *o
|
|||
snd_config_t *parent);
|
||||
int tplg_build_base_object(struct tplg_pre_processor *tplg_pp, snd_config_t *obj_cfg,
|
||||
snd_config_t *parent, bool skip_name);
|
||||
int tplg_build_pcm_caps_object(struct tplg_pre_processor *tplg_pp,
|
||||
snd_config_t *obj_cfg, snd_config_t *parent);
|
||||
int tplg_parent_update(struct tplg_pre_processor *tplg_pp, snd_config_t *parent,
|
||||
const char *section_name, const char *item_name);
|
||||
|
||||
|
|
Loading…
Reference in a new issue