mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-31 22:25:35 -04:00
topology: Parse physical DAIs in text conf file
Add support for parsing physical DAIs in the text configuration file. The syntax of physical DAIs is described in document in topology.h Signed-off-by: Mengdong Lin <mengdong.lin@linux.intel.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
50c77cdc7f
commit
0b6bd6c19a
6 changed files with 166 additions and 0 deletions
|
|
@ -663,6 +663,36 @@ extern "C" {
|
||||||
* }
|
* }
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
* <h4>Physical DAI</h4>
|
||||||
|
* A physical DAI (e.g. backend DAI for DPCM) is defined as a new section
|
||||||
|
* that can include a unique ID, playback and capture stream capabilities,
|
||||||
|
* optional flags, and private data. <br>
|
||||||
|
* Its PCM stream capablities are same as those for PCM objects,
|
||||||
|
* please refer to section 'PCM Capabilities'.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* SectionDAI."name" {
|
||||||
|
*
|
||||||
|
* index "1" # Index number
|
||||||
|
*
|
||||||
|
* id "0" # used for binding to the Backend DAI
|
||||||
|
*
|
||||||
|
* pcm."playback" {
|
||||||
|
* capabilities "capabilities1" # capabilities for playback
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* pcm."capture" {
|
||||||
|
* capabilities "capabilities2" # capabilities for capture
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* symmetric_rates "true" # optional flags
|
||||||
|
* symmetric_channels "true"
|
||||||
|
* symmetric_sample_bits "false"
|
||||||
|
*
|
||||||
|
* data "name" # optional private data
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
* <h4>Manifest Private Data</h4>
|
* <h4>Manifest Private Data</h4>
|
||||||
* Manfiest may have private data. Users need to define a manifest section
|
* Manfiest may have private data. Users need to define a manifest section
|
||||||
* and add the references to 1 or multiple data sections. Please refer to
|
* and add the references to 1 or multiple data sections. Please refer to
|
||||||
|
|
@ -735,6 +765,7 @@ enum snd_tplg_type {
|
||||||
SND_TPLG_TYPE_TUPLE, /*!< Vendor tuples */
|
SND_TPLG_TYPE_TUPLE, /*!< Vendor tuples */
|
||||||
SND_TPLG_TYPE_LINK, /*!< Physical DAI link */
|
SND_TPLG_TYPE_LINK, /*!< Physical DAI link */
|
||||||
SND_TPLG_TYPE_HW_CONFIG, /*!< Link HW config */
|
SND_TPLG_TYPE_HW_CONFIG, /*!< Link HW config */
|
||||||
|
SND_TPLG_TYPE_DAI, /*!< Physical DAI */
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,10 @@ struct snd_soc_tplg_private *get_priv_data(struct tplg_elem *elem)
|
||||||
priv = &elem->widget->priv;
|
priv = &elem->widget->priv;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SND_TPLG_TYPE_DAI:
|
||||||
|
priv = &elem->dai->priv;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
SNDERR("error: '%s': no support for private data for type %d\n",
|
SNDERR("error: '%s': no support for private data for type %d\n",
|
||||||
elem->id, elem->type);
|
elem->id, elem->type);
|
||||||
|
|
|
||||||
|
|
@ -192,6 +192,10 @@ struct tplg_elem* tplg_elem_new_common(snd_tplg_t *tplg,
|
||||||
list_add_tail(&elem->list, &tplg->pcm_list);
|
list_add_tail(&elem->list, &tplg->pcm_list);
|
||||||
obj_size = sizeof(struct snd_soc_tplg_pcm);
|
obj_size = sizeof(struct snd_soc_tplg_pcm);
|
||||||
break;
|
break;
|
||||||
|
case SND_TPLG_TYPE_DAI:
|
||||||
|
list_add_tail(&elem->list, &tplg->dai_list);
|
||||||
|
obj_size = sizeof(struct snd_soc_tplg_dai);
|
||||||
|
break;
|
||||||
case SND_TPLG_TYPE_BE:
|
case SND_TPLG_TYPE_BE:
|
||||||
case SND_TPLG_TYPE_LINK:
|
case SND_TPLG_TYPE_LINK:
|
||||||
list_add_tail(&elem->list, &tplg->be_list);
|
list_add_tail(&elem->list, &tplg->be_list);
|
||||||
|
|
|
||||||
|
|
@ -133,6 +133,14 @@ static int tplg_parse_config(snd_tplg_t *tplg, snd_config_t *cfg)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strcmp(id, "SectionDAI") == 0) {
|
||||||
|
err = tplg_parse_compound(tplg, n,
|
||||||
|
tplg_parse_dai, NULL);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (strcmp(id, "SectionHWConfig") == 0) {
|
if (strcmp(id, "SectionHWConfig") == 0) {
|
||||||
err = tplg_parse_compound(tplg, n, tplg_parse_hw_config,
|
err = tplg_parse_compound(tplg, n, tplg_parse_hw_config,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
@ -450,6 +458,7 @@ snd_tplg_t *snd_tplg_new(void)
|
||||||
INIT_LIST_HEAD(&tplg->tlv_list);
|
INIT_LIST_HEAD(&tplg->tlv_list);
|
||||||
INIT_LIST_HEAD(&tplg->widget_list);
|
INIT_LIST_HEAD(&tplg->widget_list);
|
||||||
INIT_LIST_HEAD(&tplg->pcm_list);
|
INIT_LIST_HEAD(&tplg->pcm_list);
|
||||||
|
INIT_LIST_HEAD(&tplg->dai_list);
|
||||||
INIT_LIST_HEAD(&tplg->be_list);
|
INIT_LIST_HEAD(&tplg->be_list);
|
||||||
INIT_LIST_HEAD(&tplg->cc_list);
|
INIT_LIST_HEAD(&tplg->cc_list);
|
||||||
INIT_LIST_HEAD(&tplg->route_list);
|
INIT_LIST_HEAD(&tplg->route_list);
|
||||||
|
|
@ -476,6 +485,7 @@ void snd_tplg_free(snd_tplg_t *tplg)
|
||||||
tplg_elem_free_list(&tplg->tlv_list);
|
tplg_elem_free_list(&tplg->tlv_list);
|
||||||
tplg_elem_free_list(&tplg->widget_list);
|
tplg_elem_free_list(&tplg->widget_list);
|
||||||
tplg_elem_free_list(&tplg->pcm_list);
|
tplg_elem_free_list(&tplg->pcm_list);
|
||||||
|
tplg_elem_free_list(&tplg->dai_list);
|
||||||
tplg_elem_free_list(&tplg->be_list);
|
tplg_elem_free_list(&tplg->be_list);
|
||||||
tplg_elem_free_list(&tplg->cc_list);
|
tplg_elem_free_list(&tplg->cc_list);
|
||||||
tplg_elem_free_list(&tplg->route_list);
|
tplg_elem_free_list(&tplg->route_list);
|
||||||
|
|
|
||||||
|
|
@ -341,6 +341,7 @@ static int tplg_parse_streams(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
||||||
snd_config_t *n;
|
snd_config_t *n;
|
||||||
struct tplg_elem *elem = private;
|
struct tplg_elem *elem = private;
|
||||||
struct snd_soc_tplg_pcm *pcm;
|
struct snd_soc_tplg_pcm *pcm;
|
||||||
|
struct snd_soc_tplg_dai *dai;
|
||||||
unsigned int *playback, *capture;
|
unsigned int *playback, *capture;
|
||||||
struct snd_soc_tplg_stream_caps *caps;
|
struct snd_soc_tplg_stream_caps *caps;
|
||||||
const char *id, *value;
|
const char *id, *value;
|
||||||
|
|
@ -357,6 +358,14 @@ static int tplg_parse_streams(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
||||||
capture = &pcm->capture;
|
capture = &pcm->capture;
|
||||||
caps = pcm->caps;
|
caps = pcm->caps;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SND_TPLG_TYPE_DAI:
|
||||||
|
dai = elem->dai;
|
||||||
|
playback = &dai->playback;
|
||||||
|
capture = &dai->capture;
|
||||||
|
caps = dai->caps;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
@ -557,6 +566,109 @@ int tplg_parse_pcm(snd_tplg_t *tplg,
|
||||||
return 0;
|
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 */
|
/* 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,
|
static int parse_hw_config_refs(snd_tplg_t *tplg, snd_config_t *cfg,
|
||||||
struct tplg_elem *elem)
|
struct tplg_elem *elem)
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,7 @@ struct snd_tplg {
|
||||||
struct list_head tlv_list;
|
struct list_head tlv_list;
|
||||||
struct list_head widget_list;
|
struct list_head widget_list;
|
||||||
struct list_head pcm_list;
|
struct list_head pcm_list;
|
||||||
|
struct list_head dai_list;
|
||||||
struct list_head be_list;
|
struct list_head be_list;
|
||||||
struct list_head cc_list;
|
struct list_head cc_list;
|
||||||
struct list_head route_list;
|
struct list_head route_list;
|
||||||
|
|
@ -145,6 +146,7 @@ struct tplg_elem {
|
||||||
struct snd_soc_tplg_bytes_control *bytes_ext;
|
struct snd_soc_tplg_bytes_control *bytes_ext;
|
||||||
struct snd_soc_tplg_dapm_widget *widget;
|
struct snd_soc_tplg_dapm_widget *widget;
|
||||||
struct snd_soc_tplg_pcm *pcm;
|
struct snd_soc_tplg_pcm *pcm;
|
||||||
|
struct snd_soc_tplg_dai *dai;
|
||||||
struct snd_soc_tplg_link_config *link;/* physical link */
|
struct snd_soc_tplg_link_config *link;/* physical link */
|
||||||
struct snd_soc_tplg_dapm_graph_elem *route;
|
struct snd_soc_tplg_dapm_graph_elem *route;
|
||||||
struct snd_soc_tplg_stream *stream_cfg;
|
struct snd_soc_tplg_stream *stream_cfg;
|
||||||
|
|
@ -222,6 +224,9 @@ int tplg_parse_stream_caps(snd_tplg_t *tplg,
|
||||||
int tplg_parse_pcm(snd_tplg_t *tplg,
|
int tplg_parse_pcm(snd_tplg_t *tplg,
|
||||||
snd_config_t *cfg, void *private ATTRIBUTE_UNUSED);
|
snd_config_t *cfg, void *private ATTRIBUTE_UNUSED);
|
||||||
|
|
||||||
|
int tplg_parse_dai(snd_tplg_t *tplg, snd_config_t *cfg,
|
||||||
|
void *private ATTRIBUTE_UNUSED);
|
||||||
|
|
||||||
int tplg_parse_link(snd_tplg_t *tplg,
|
int tplg_parse_link(snd_tplg_t *tplg,
|
||||||
snd_config_t *cfg, void *private ATTRIBUTE_UNUSED);
|
snd_config_t *cfg, void *private ATTRIBUTE_UNUSED);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue