diff options
Diffstat (limited to 'src/topology/pcm.c')
-rw-r--r-- | src/topology/pcm.c | 56 |
1 files changed, 50 insertions, 6 deletions
diff --git a/src/topology/pcm.c b/src/topology/pcm.c index 96a64e7e..7b67d918 100644 --- a/src/topology/pcm.c +++ b/src/topology/pcm.c @@ -168,7 +168,7 @@ static int build_link(snd_tplg_t *tplg, struct tplg_elem *elem) return 0; } -/* build BE/CC DAI link configurations */ +/* build physical DAI link configurations */ int tplg_build_links(snd_tplg_t *tplg, unsigned int type) { struct list_head *base, *pos; @@ -176,6 +176,7 @@ int tplg_build_links(snd_tplg_t *tplg, unsigned int type) int err = 0; switch (type) { + case SND_TPLG_TYPE_LINK: case SND_TPLG_TYPE_BE: base = &tplg->be_list; break; @@ -189,11 +190,6 @@ int tplg_build_links(snd_tplg_t *tplg, unsigned int type) list_for_each(pos, base) { elem = list_entry(pos, struct tplg_elem, list); - if (elem->type != type) { - SNDERR("error: invalid elem '%s'\n", elem->id); - return -EINVAL; - } - err = build_link(tplg, elem); if (err < 0) return err; @@ -741,6 +737,47 @@ int tplg_add_pcm_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t) return 0; } +/* Set link HW config from C API template */ +static int set_link_hw_config(struct snd_soc_tplg_hw_config *cfg, + struct snd_tplg_hw_config_template *tpl) +{ + int i; + + cfg->size = sizeof(*cfg); + cfg->id = tpl->id; + + cfg->fmt = tpl->fmt; + cfg->clock_gated = tpl->clock_gated; + cfg->invert_bclk = tpl->invert_bclk; + cfg->invert_fsync = tpl->invert_fsync; + cfg->bclk_master = tpl->bclk_master; + cfg->fsync_master = tpl->fsync_master; + cfg->mclk_direction = tpl->mclk_direction; + cfg->reserved = tpl->reserved; + cfg->mclk_rate = tpl->mclk_rate; + cfg->bclk_rate = tpl->bclk_rate; + cfg->fsync_rate = tpl->fsync_rate; + + cfg->tdm_slots = tpl->tdm_slots; + cfg->tdm_slot_width = tpl->tdm_slot_width; + cfg->tx_slots = tpl->tx_slots; + cfg->rx_slots = tpl->rx_slots; + + if (cfg->tx_channels > SND_SOC_TPLG_MAX_CHAN + || cfg->rx_channels > SND_SOC_TPLG_MAX_CHAN) + return -EINVAL; + + cfg->tx_channels = tpl->tx_channels; + for (i = 0; i < cfg->tx_channels; i++) + cfg->tx_chanmap[i] = tpl->tx_chanmap[i]; + + cfg->rx_channels = tpl->rx_channels; + for (i = 0; i < cfg->rx_channels; i++) + cfg->rx_chanmap[i] = tpl->rx_chanmap[i]; + + return 0; +} + /* Add a physical DAI link element from C API */ int tplg_add_link_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t) { @@ -771,5 +808,12 @@ int tplg_add_link_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t) for (i = 0; i < link->num_streams; i++) tplg_add_stream_object(&link->stream[i], &link_tpl->stream[i]); + /* HW configs */ + if (link_tpl->num_hw_configs > SND_SOC_TPLG_HW_CONFIG_MAX) + return -EINVAL; + link->num_hw_configs = link_tpl->num_hw_configs; + link->default_hw_config_id = link_tpl->default_hw_config_id; + for (i = 0; i < link->num_hw_configs; i++) + set_link_hw_config(&link->hw_config[i], &link_tpl->hw_config[i]); return 0; } |