diff options
Diffstat (limited to 'src/topology/pcm.c')
-rw-r--r-- | src/topology/pcm.c | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/src/topology/pcm.c b/src/topology/pcm.c index a9d32772..4093e2fc 100644 --- a/src/topology/pcm.c +++ b/src/topology/pcm.c @@ -341,6 +341,7 @@ static int tplg_parse_streams(snd_tplg_t *tplg ATTRIBUTE_UNUSED, snd_config_t *n; struct tplg_elem *elem = private; struct snd_soc_tplg_pcm *pcm; + struct snd_soc_tplg_dai *dai; unsigned int *playback, *capture; struct snd_soc_tplg_stream_caps *caps; const char *id, *value; @@ -357,6 +358,14 @@ static int tplg_parse_streams(snd_tplg_t *tplg ATTRIBUTE_UNUSED, capture = &pcm->capture; caps = pcm->caps; break; + + case SND_TPLG_TYPE_DAI: + dai = elem->dai; + playback = &dai->playback; + capture = &dai->capture; + caps = dai->caps; + break; + default: return -EINVAL; } @@ -557,6 +566,109 @@ int tplg_parse_pcm(snd_tplg_t *tplg, return 0; } +/* Parse physical DAI */ +int tplg_parse_dai(snd_tplg_t *tplg, + snd_config_t *cfg, void *private ATTRIBUTE_UNUSED) +{ + struct snd_soc_tplg_dai *dai; + struct tplg_elem *elem; + snd_config_iterator_t i, next; + snd_config_t *n; + const char *id, *val = NULL; + int err; + + elem = tplg_elem_new_common(tplg, cfg, NULL, SND_TPLG_TYPE_DAI); + if (!elem) + return -ENOMEM; + + dai = elem->dai; + dai->size = elem->size; + elem_copy_text(dai->dai_name, elem->id, + SNDRV_CTL_ELEM_ID_NAME_MAXLEN); + + tplg_dbg(" DAI: %s\n", elem->id); + + snd_config_for_each(i, next, cfg) { + + n = snd_config_iterator_entry(i); + if (snd_config_get_id(n, &id) < 0) + continue; + + /* skip comments */ + if (strcmp(id, "comment") == 0) + continue; + if (id[0] == '#') + continue; + + if (strcmp(id, "index") == 0) { + if (snd_config_get_string(n, &val) < 0) + return -EINVAL; + + elem->index = atoi(val); + tplg_dbg("\t%s: %d\n", id, elem->index); + continue; + } + + if (strcmp(id, "id") == 0) { + if (snd_config_get_string(n, &val) < 0) + return -EINVAL; + + dai->dai_id = atoi(val); + tplg_dbg("\t%s: %d\n", id, dai->dai_id); + continue; + } + + /* stream capabilities */ + if (strcmp(id, "pcm") == 0) { + err = tplg_parse_compound(tplg, n, + tplg_parse_streams, elem); + if (err < 0) + return err; + continue; + } + + /* flags */ + if (strcmp(id, "symmetric_rates") == 0) { + err = parse_flag(n, + SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_RATES, + &dai->flag_mask, &dai->flags); + if (err < 0) + return err; + continue; + } + + if (strcmp(id, "symmetric_channels") == 0) { + err = parse_flag(n, + SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_CHANNELS, + &dai->flag_mask, &dai->flags); + if (err < 0) + return err; + continue; + } + + if (strcmp(id, "symmetric_sample_bits") == 0) { + err = parse_flag(n, + SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_SAMPLEBITS, + &dai->flag_mask, &dai->flags); + if (err < 0) + return err; + continue; + } + + /* private data */ + if (strcmp(id, "data") == 0) { + if (snd_config_get_string(n, &val) < 0) + return -EINVAL; + + tplg_ref_add(elem, SND_TPLG_TYPE_DATA, val); + tplg_dbg("\t%s: %s\n", id, val); + continue; + } + } + + return 0; +} + /* parse physical link runtime supported HW configs in text conf file */ static int parse_hw_config_refs(snd_tplg_t *tplg, snd_config_t *cfg, struct tplg_elem *elem) |