From: Mengdong Lin mengdong.lin@linux.intel.com
Users can define private for PCM (FE DAI & DAI links) elements by both text conf file and C API:
- Text conf file may define multiple data blocks for a PCM and they will be merged in building phase;
- Add private data to C API template of PCM object.
Signed-off-by: Mengdong Lin mengdong.lin@linux.intel.com
diff --git a/include/topology.h b/include/topology.h index 0a07c94..f9e8285 100644 --- a/include/topology.h +++ b/include/topology.h @@ -613,6 +613,8 @@ extern "C" { * symmetric_sample_bits "true or false" * ignore_suspend "true or false" * ignore_powerdown_time "true or false" + * + * data "name" # optional private data * } * </pre> * @@ -872,6 +874,7 @@ struct snd_tplg_pcm_template { struct snd_tplg_stream_caps_template *caps[2]; /*!< playback & capture for DAI */ unsigned int flag_mask; /*!< bitmask of flags to configure */ unsigned int flags; /*!< flag value */ + struct snd_soc_tplg_private *priv; /*!< private data */ int num_streams; /*!< number of supported configs */ struct snd_tplg_stream_template stream[0]; /*!< supported configs */ }; diff --git a/src/topology/pcm.c b/src/topology/pcm.c index 72bab94..33940c6 100644 --- a/src/topology/pcm.c +++ b/src/topology/pcm.c @@ -73,12 +73,32 @@ static int tplg_build_stream_caps(snd_tplg_t *tplg, /* build a PCM (FE DAI & DAI link) element */ static int build_pcm(snd_tplg_t *tplg, struct tplg_elem *elem) { + struct tplg_ref *ref; + struct list_head *base, *pos; int err;
err = tplg_build_stream_caps(tplg, elem->id, elem->pcm->caps); if (err < 0) return err;
+ /* merge private data from the referenced data elements */ + base = &elem->ref_list; + list_for_each(pos, base) { + + ref = list_entry(pos, struct tplg_ref, list); + if (ref->type == SND_TPLG_TYPE_DATA) { + err = tplg_copy_data(tplg, elem, ref); + if (err < 0) + return err; + } + if (!ref->elem) { + SNDERR("error: cannot find '%s' referenced by" + " PCM '%s'\n", ref->id, elem->id); + return -EINVAL; + } else if (err < 0) + return err; + } + return 0; }
@@ -394,7 +414,7 @@ static int parse_flag(snd_config_t *n, unsigned int mask_in, return 0; }
-/* Parse pcm (for front end DAI & DAI link) */ +/* Parse PCM (for front end DAI & DAI link) in text conf file */ int tplg_parse_pcm(snd_tplg_t *tplg, snd_config_t *cfg, void *private ATTRIBUTE_UNUSED) { @@ -520,6 +540,7 @@ int tplg_parse_be(snd_tplg_t *tplg, 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_BE); if (!elem) @@ -559,6 +580,13 @@ int tplg_parse_be(snd_tplg_t *tplg, tplg_dbg("\t%s: %d\n", id, link->id); continue; } + + if (strcmp(id, "data") == 0) { + err = tplg_parse_data_refs(n, elem); + if (err < 0) + return err; + continue; + } }
return 0; @@ -652,10 +680,11 @@ static void tplg_add_stream_caps(struct snd_soc_tplg_stream_caps *caps, caps->sig_bits = caps_tpl->sig_bits; }
+/* Add a PCM element (FE DAI & DAI link) from C API */ int tplg_add_pcm_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t) { struct snd_tplg_pcm_template *pcm_tpl = t->pcm; - struct snd_soc_tplg_pcm *pcm; + struct snd_soc_tplg_pcm *pcm, *_pcm; struct tplg_elem *elem; int i;
@@ -694,6 +723,25 @@ int tplg_add_pcm_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t) for (i = 0; i < pcm_tpl->num_streams; i++) tplg_add_stream_object(&pcm->stream[i], &pcm_tpl->stream[i]);
+ /* private data */ + if (pcm_tpl->priv != NULL && pcm_tpl->priv->size) { + tplg_dbg("\t priv data size %d\n", pcm_tpl->priv->size); + _pcm = realloc(pcm, + elem->size + pcm_tpl->priv->size); + if (!_pcm) { + tplg_elem_free(elem); + return -ENOMEM; + } + + pcm = _pcm; + elem->pcm = pcm; + elem->size += pcm_tpl->priv->size; + + memcpy(pcm->priv.data, pcm_tpl->priv->data, + pcm_tpl->priv->size); + pcm->priv.size = pcm_tpl->priv->size; + } + return 0; }