All of lore.kernel.org
 help / color / mirror / Atom feed
From: mengdong.lin@linux.intel.com
To: alsa-devel@alsa-project.org, broonie@kernel.org
Cc: Mengdong Lin <mengdong.lin@linux.intel.com>,
	tiwai@suse.de, mengdong.lin@intel.com, o-takashi@sakamocchi.jp,
	liam.r.girdwood@intel.com, shreyas.nc@intel.com
Subject: [PATCH v2 4/5] topology: Parse vendor private data for manifest
Date: Fri, 15 Jul 2016 20:19:41 +0800	[thread overview]
Message-ID: <9b41b27a1318e80f6720decf3d490a8aac78c903.1468583255.git.mengdong.lin@linux.intel.com> (raw)
In-Reply-To: <cover.1468583255.git.mengdong.lin@linux.intel.com>

From: Mengdong Lin <mengdong.lin@linux.intel.com>

In text conf file, user can define a manifest section and let it refer
to private data sections, in the same syntax as other element types.

The text conf file can have at most 1 manifest section.

Signed-off-by: Mengdong Lin <mengdong.lin@linux.intel.com>

diff --git a/include/topology.h b/include/topology.h
index 89bed6c..644e548 100644
--- a/include/topology.h
+++ b/include/topology.h
@@ -586,6 +586,20 @@ extern "C" {
  * }
  * </pre>
  *
+ * <h4>Manifest Private Data</h4>
+ * 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
+ * section 'How to define an element with private data'. <br>
+ * And the text conf file can have at most 1 manifest section. <br><br>
+ *
+ * Manifest section is defined as follows :-
+ *
+ * <pre>
+ * SectionManifest"name" {
+ *
+ *	data "name"			# optional private data
+ * }
+ * </pre>
  */
 
 /** Maximum number of channels supported in one control */
diff --git a/src/topology/data.c b/src/topology/data.c
index a0c5ea2..245a834 100644
--- a/src/topology/data.c
+++ b/src/topology/data.c
@@ -26,6 +26,10 @@ struct snd_soc_tplg_private *get_priv_data(struct tplg_elem *elem)
 	struct snd_soc_tplg_private *priv = NULL;
 
 	switch (elem->type) {
+	case SND_TPLG_TYPE_MANIFEST:
+		priv = &elem->manifest->priv;
+		break;
+
 	case SND_TPLG_TYPE_MIXER:
 		priv = &elem->mixer_ctrl->priv;
 		break;
@@ -834,6 +838,103 @@ void tplg_free_tuples(void *obj)
 	free(tuples->set);
 }
 
+/* Parse manifest's data references
+ */
+int tplg_parse_manifest_data(snd_tplg_t *tplg, snd_config_t *cfg,
+	void *private ATTRIBUTE_UNUSED)
+{
+	struct snd_soc_tplg_manifest *manifest;
+	struct tplg_elem *elem;
+	snd_config_iterator_t i, next;
+	snd_config_t *n;
+	const char *id;
+	int err;
+
+	if (!list_empty(&tplg->manifest_list)) {
+		SNDERR("error: already has manifest data\n");
+		return -EINVAL;
+	}
+
+	elem = tplg_elem_new_common(tplg, cfg, NULL, SND_TPLG_TYPE_MANIFEST);
+	if (!elem)
+		return -ENOMEM;
+
+	manifest = elem->manifest;
+	manifest->size = elem->size;
+
+	tplg_dbg(" Manifest: %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, "data") == 0) {
+			err = tplg_parse_data_refs(n, elem);
+			if (err < 0)
+				return err;
+			continue;
+		}
+	}
+
+	return 0;
+}
+
+/* merge private data of manifest */
+int tplg_build_manifest_data(snd_tplg_t *tplg)
+{
+	struct list_head *base, *pos;
+	struct tplg_elem *elem = NULL;
+	struct tplg_ref *ref;
+	struct snd_soc_tplg_manifest *manifest;
+	int err = 0;
+
+	base = &tplg->manifest_list;
+	list_for_each(pos, base) {
+
+		elem = list_entry(pos, struct tplg_elem, list);
+		break;
+	}
+
+	if (!elem) /* no manifest data */
+		return 0;
+
+	base = &elem->ref_list;
+
+	/* for each ref in this manifest elem */
+	list_for_each(pos, base) {
+
+		ref = list_entry(pos, struct tplg_ref, list);
+		if (ref->id == NULL || ref->elem)
+			continue;
+
+		if (ref->type == SND_TPLG_TYPE_DATA) {
+			err = tplg_copy_data(tplg, elem, ref);
+			if (err < 0)
+				return err;
+		}
+	}
+
+	manifest = elem->manifest;
+	if (!manifest->priv.size) /* no manifest data */
+		return 0;
+
+	tplg->manifest_pdata = malloc(manifest->priv.size);
+	if (!tplg->manifest_pdata)
+		return -ENOMEM;
+
+	tplg->manifest.priv.size = manifest->priv.size;
+	memcpy(tplg->manifest_pdata, manifest->priv.data, manifest->priv.size);
+	return 0;
+}
+
 /* Parse Private data.
  *
  * Object private data can either be from file or defined as bytes, shorts,
diff --git a/src/topology/elem.c b/src/topology/elem.c
index 50414f0..029c9ab 100644
--- a/src/topology/elem.c
+++ b/src/topology/elem.c
@@ -150,6 +150,10 @@ struct tplg_elem* tplg_elem_new_common(snd_tplg_t *tplg,
 	case SND_TPLG_TYPE_DATA:
 		list_add_tail(&elem->list, &tplg->pdata_list);
 		break;
+	case SND_TPLG_TYPE_MANIFEST:
+		list_add_tail(&elem->list, &tplg->manifest_list);
+		obj_size = sizeof(struct snd_soc_tplg_manifest);
+		break;
 	case SND_TPLG_TYPE_TEXT:
 		list_add_tail(&elem->list, &tplg->text_list);
 		break;
diff --git a/src/topology/parser.c b/src/topology/parser.c
index f6fc944..3ab64f4 100644
--- a/src/topology/parser.c
+++ b/src/topology/parser.c
@@ -189,6 +189,15 @@ static int tplg_parse_config(snd_tplg_t *tplg, snd_config_t *cfg)
 			continue;
 		}
 
+		if (strcmp(id, "SectionManifest") == 0) {
+			err = tplg_parse_compound(tplg, n,
+						  tplg_parse_manifest_data,
+				NULL);
+			if (err < 0)
+				return err;
+			continue;
+		}
+
 		SNDERR("error: unknown section %s\n", id);
 	}
 	return 0;
@@ -246,6 +255,10 @@ static int tplg_build_integ(snd_tplg_t *tplg)
 	if (err <  0)
 		return err;
 
+	err = tplg_build_manifest_data(tplg);
+	if (err <  0)
+		return err;
+
 	err = tplg_build_controls(tplg);
 	if (err <  0)
 		return err;
@@ -374,8 +387,16 @@ out:
 
 int snd_tplg_set_manifest_data(snd_tplg_t *tplg, const void *data, int len)
 {
+	if (len <= 0)
+		return 0;
+
 	tplg->manifest.priv.size = len;
-	tplg->manifest_pdata = data;
+
+	tplg->manifest_pdata = malloc(len);
+	if (!tplg->manifest_pdata)
+		return -ENOMEM;
+
+	memcpy(tplg->manifest_pdata, data, len);
 	return 0;
 }
 
@@ -423,6 +444,7 @@ snd_tplg_t *snd_tplg_new(void)
 	INIT_LIST_HEAD(&tplg->cc_list);
 	INIT_LIST_HEAD(&tplg->route_list);
 	INIT_LIST_HEAD(&tplg->pdata_list);
+	INIT_LIST_HEAD(&tplg->manifest_list);
 	INIT_LIST_HEAD(&tplg->text_list);
 	INIT_LIST_HEAD(&tplg->pcm_config_list);
 	INIT_LIST_HEAD(&tplg->pcm_caps_list);
@@ -437,6 +459,9 @@ snd_tplg_t *snd_tplg_new(void)
 
 void snd_tplg_free(snd_tplg_t *tplg)
 {
+	if (tplg->manifest_pdata)
+		free(tplg->manifest_pdata);
+
 	tplg_elem_free_list(&tplg->tlv_list);
 	tplg_elem_free_list(&tplg->widget_list);
 	tplg_elem_free_list(&tplg->pcm_list);
@@ -444,6 +469,7 @@ void snd_tplg_free(snd_tplg_t *tplg)
 	tplg_elem_free_list(&tplg->cc_list);
 	tplg_elem_free_list(&tplg->route_list);
 	tplg_elem_free_list(&tplg->pdata_list);
+	tplg_elem_free_list(&tplg->manifest_list);
 	tplg_elem_free_list(&tplg->text_list);
 	tplg_elem_free_list(&tplg->pcm_config_list);
 	tplg_elem_free_list(&tplg->pcm_caps_list);
diff --git a/src/topology/tplg_local.h b/src/topology/tplg_local.h
index 48db813..4d79aa7 100644
--- a/src/topology/tplg_local.h
+++ b/src/topology/tplg_local.h
@@ -58,7 +58,7 @@ struct snd_tplg {
 
 	/* manifest */
 	struct snd_soc_tplg_manifest manifest;
-	const void *manifest_pdata;	/* copied by builder at file write */
+	void *manifest_pdata;	/* copied by builder at file write */
 
 	/* list of each element type */
 	struct list_head tlv_list;
@@ -71,6 +71,7 @@ struct snd_tplg {
 	struct list_head pdata_list;
 	struct list_head token_list;
 	struct list_head tuple_list;
+	struct list_head manifest_list;
 	struct list_head pcm_config_list;
 	struct list_head pcm_caps_list;
 
@@ -154,6 +155,7 @@ struct tplg_elem {
 		struct snd_soc_tplg_private *data;
 		struct tplg_vendor_tokens *tokens;
 		struct tplg_vendor_tuples *tuples;
+		struct snd_soc_tplg_manifest *manifest;
 	};
 
 	/* an element may refer to other elements:
@@ -195,6 +197,9 @@ int tplg_parse_tuples(snd_tplg_t *tplg, snd_config_t *cfg,
 
 void tplg_free_tuples(void *obj);
 
+int tplg_parse_manifest_data(snd_tplg_t *tplg, snd_config_t *cfg,
+	void *private ATTRIBUTE_UNUSED);
+
 int tplg_parse_control_bytes(snd_tplg_t *tplg,
 	snd_config_t *cfg, void *private ATTRIBUTE_UNUSED);
 
@@ -223,6 +228,7 @@ int tplg_parse_cc(snd_tplg_t *tplg,
 	snd_config_t *cfg, void *private ATTRIBUTE_UNUSED);
 
 int tplg_build_data(snd_tplg_t *tplg);
+int tplg_build_manifest_data(snd_tplg_t *tplg);
 int tplg_build_controls(snd_tplg_t *tplg);
 int tplg_build_widgets(snd_tplg_t *tplg);
 int tplg_build_routes(snd_tplg_t *tplg);
-- 
2.5.0

  parent reply	other threads:[~2016-07-15 12:14 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-07-15 12:17 [PATCH v2 0/5] topology: Enhance support for private data mengdong.lin
2016-07-15 12:17 ` [PATCH v2 1/5] topology: An element can refer to multipe data sections in text conf file mengdong.lin
2016-07-15 12:18 ` [PATCH v2 2/5] topology: Merge lookup for data reference into tplg_copy_data() mengdong.lin
2016-07-15 12:18 ` [PATCH v2 3/5] topology: Change uuid value to 16 separate characters in text conf file mengdong.lin
2016-07-15 12:19 ` mengdong.lin [this message]
2016-07-15 12:19 ` [PATCH v2 5/5] topology: Tuple type can have an extenstion mengdong.lin
2016-07-16 12:58 ` [PATCH v2 0/5] topology: Enhance support for private data Takashi Sakamoto
2016-07-18  2:47   ` Mengdong Lin
2016-07-18  3:43     ` Takashi Sakamoto
2016-07-18 15:06       ` Lin, Mengdong
2016-07-19  3:59         ` Vinod Koul
2016-07-19  5:14           ` Takashi Sakamoto
2016-07-19  8:44           ` Lin, Mengdong
2016-07-17  8:03 ` Takashi Iwai

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=9b41b27a1318e80f6720decf3d490a8aac78c903.1468583255.git.mengdong.lin@linux.intel.com \
    --to=mengdong.lin@linux.intel.com \
    --cc=alsa-devel@alsa-project.org \
    --cc=broonie@kernel.org \
    --cc=liam.r.girdwood@intel.com \
    --cc=mengdong.lin@intel.com \
    --cc=o-takashi@sakamocchi.jp \
    --cc=shreyas.nc@intel.com \
    --cc=tiwai@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.