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, vinod.koul@intel.com,
	rakesh.a.ughreja@intel.com, liam.r.girdwood@intel.com,
	hardik.t.shah@intel.com, subhransu.s.prusty@intel.com
Subject: [PATCH 6/7] topology: Add support for parsing vendor tuples
Date: Thu, 24 Mar 2016 11:07:36 +0800	[thread overview]
Message-ID: <ea484928ce467eb5c4b1b105fa9311b1d42cbbee.1458788076.git.mengdong.lin@linux.intel.com> (raw)
In-Reply-To: <cover.1458788076.git.mengdong.lin@linux.intel.com>

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

Vendor can define several tuple arrays in 'SectionVendorTuples', as
well as the reference to a vendor token list object.

A later patche will copy vendor tuples in ABI format to the private
buffer of its parent data object in the building phase.

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

diff --git a/include/topology.h b/include/topology.h
index 0df112c..b47f422 100644
--- a/include/topology.h
+++ b/include/topology.h
@@ -579,6 +579,7 @@ enum snd_tplg_type {
 	SND_TPLG_TYPE_CC,		/*!< Hostless codec <-> codec link */
 	SND_TPLG_TYPE_MANIFEST,		/*!< Topology manifest */
 	SND_TPLG_TYPE_TOKEN,		/*!< Vendor tokens */
+	SND_TPLG_TYPE_TUPLE,		/*!< Vendor tuples */
 };
 
 /**
diff --git a/src/topology/data.c b/src/topology/data.c
index 8455c15..0d07842 100644
--- a/src/topology/data.c
+++ b/src/topology/data.c
@@ -253,6 +253,144 @@ static int tplg_parse_data_hex(snd_config_t *cfg, struct tplg_elem *elem,
 	return ret;
 }
 
+static int parse_tuple_set(snd_tplg_t *tplg, snd_config_t *cfg,
+	struct tplg_tuple_set **s)
+{
+	snd_config_iterator_t i, next;
+	snd_config_t *n;
+	const char *id, *value;
+	struct tplg_tuple_set *set;
+	unsigned int type, num_tuples = 0;
+	struct tplg_tuple *tuple;
+
+	snd_config_get_id(cfg, &id);
+
+	if (strcmp(id, "uuid") == 0)
+		type = SND_SOC_TPLG_TUPLE_TYPE_UUID;
+	else if (strcmp(id, "string") == 0)
+		type = SND_SOC_TPLG_TUPLE_TYPE_STRING;
+	else if (strcmp(id, "bool") == 0)
+		type = SND_SOC_TPLG_TUPLE_TYPE_BOOL;
+	else if (strcmp(id, "byte") == 0)
+		type = SND_SOC_TPLG_TUPLE_TYPE_BYTE;
+	else if (strcmp(id, "short") == 0)
+		type = SND_SOC_TPLG_TUPLE_TYPE_SHORT;
+	else if (strcmp(id, "word") == 0)
+		type = SND_SOC_TPLG_TUPLE_TYPE_WORD;
+	else {
+		SNDERR("error: invalid tuple type '%s'\n", id);
+		return -EINVAL;
+	}
+
+	snd_config_for_each(i, next, cfg)
+		num_tuples++;
+	if (!num_tuples)
+		return 0;
+
+	tplg_dbg("\t %d %s tuples:\n", num_tuples, id);
+	set = calloc(1, sizeof(*set) + num_tuples * sizeof(struct tplg_tuple));
+	if (!set)
+		return -ENOMEM;
+
+	set->type = type;
+
+	snd_config_for_each(i, next, cfg) {
+
+		n = snd_config_iterator_entry(i);
+
+		/* get id */
+		if (snd_config_get_id(n, &id) < 0)
+			continue;
+
+		/* get value */
+		if (snd_config_get_string(n, &value) < 0)
+			continue;
+
+		tuple = &set->tuple[set->num_tuples];
+		elem_copy_text(tuple->token, id,
+				SNDRV_CTL_ELEM_ID_NAME_MAXLEN);
+
+		switch (type) {
+		case SND_SOC_TPLG_TUPLE_TYPE_UUID:
+			memcpy(tuple->uuid, value, 16);
+			tplg_dbg("\t\t%s = %s\n", tuple->token, tuple->uuid);
+			break;
+
+		case SND_SOC_TPLG_TUPLE_TYPE_STRING:
+			elem_copy_text(tuple->string, value,
+				SNDRV_CTL_ELEM_ID_NAME_MAXLEN);
+			tplg_dbg("\t\t%s = %s\n", tuple->token, tuple->string);
+			break;
+
+		case SND_SOC_TPLG_TUPLE_TYPE_BOOL:
+			if (strcmp(value, "true") == 0)
+				tuple->value = 1;
+			tplg_dbg("\t\t%s = %d\n", tuple->token, tuple->value);
+			break;
+
+		case SND_SOC_TPLG_TUPLE_TYPE_BYTE:
+		case SND_SOC_TPLG_TUPLE_TYPE_SHORT:
+		case SND_SOC_TPLG_TUPLE_TYPE_WORD:
+			tuple->value = atoi(value);
+			tplg_dbg("\t\t%s = %d\n", tuple->token, tuple->value);
+			break;
+
+		default:
+			break;
+		}
+
+		set->num_tuples++;
+	}
+
+	*s = set;
+	return 0;
+}
+
+static int parse_tuple_sets(snd_tplg_t *tplg, snd_config_t *cfg,
+	struct tplg_vendor_tuples *tuples)
+{
+	snd_config_iterator_t i, next;
+	snd_config_t *n;
+	const char *id;
+	unsigned int num_tuple_sets = 0;
+	int err;
+
+	if (snd_config_get_type(cfg) != SND_CONFIG_TYPE_COMPOUND) {
+		SNDERR("error: compound type expected for %s", id);
+		return -EINVAL;
+	}
+
+	snd_config_for_each(i, next, cfg) {
+		num_tuple_sets++;
+	}
+
+	if (!num_tuple_sets)
+		return 0;
+
+	tuples->set = calloc(1, num_tuple_sets * sizeof(void *));
+	if (!tuples->set)
+		return -ENOMEM;
+
+	snd_config_for_each(i, next, cfg) {
+		n = snd_config_iterator_entry(i);
+		if (snd_config_get_type(n) != SND_CONFIG_TYPE_COMPOUND) {
+			SNDERR("error: compound type expected for %s, is %d",
+			id, snd_config_get_type(n));
+			return -EINVAL;
+		}
+
+		err = parse_tuple_set(tplg, n, &tuples->set[tuples->num_sets]);
+		if (err < 0)
+			return err;
+
+		/* overlook empty tuple sets */
+		if (tuples->set[tuples->num_sets])
+			tuples->num_sets++;
+	}
+
+	return 0;
+}
+
 /* Parse vendor tokens
  */
 int tplg_parse_tokens(snd_tplg_t *tplg, snd_config_t *cfg,
@@ -304,10 +442,69 @@ int tplg_parse_tokens(snd_tplg_t *tplg, snd_config_t *cfg,
 	return 0;
 }
 
+/* Parse vendor tuples.
+ */
+int tplg_parse_tuples(snd_tplg_t *tplg, snd_config_t *cfg,
+	void *private ATTRIBUTE_UNUSED)
+{
+	snd_config_iterator_t i, next;
+	snd_config_t *n;
+	const char *id, *value;
+	struct tplg_elem *elem;
+	struct tplg_vendor_tuples *tuples;
+	int err;
+
+	elem = tplg_elem_new_common(tplg, cfg, NULL, SND_TPLG_TYPE_TUPLE);
+	if (!elem)
+		return -ENOMEM;
+
+	tplg_dbg(" Vendor Tuples: %s\n", elem->id);
+
+	tuples = calloc(1, sizeof(*tuples));
+	if (!tuples)
+		return -ENOMEM;
+	elem->tuples = tuples;
+
+	snd_config_for_each(i, next, cfg) {
+
+		n = snd_config_iterator_entry(i);
+		if (snd_config_get_id(n, &id) < 0)
+			continue;
+
+		if (strcmp(id, "tokens") == 0) {
+			if (snd_config_get_string(n, &value) < 0)
+				return -EINVAL;
+			tplg_ref_add(elem, SND_TPLG_TYPE_TOKEN, value);
+			tplg_dbg("\t refer to vendor tokens: %s\n", value);
+		}
+
+		if (strcmp(id, "tuples") == 0) {
+			err = parse_tuple_sets(tplg, n, tuples);
+			if (err < 0)
+				return err;
+		}
+	}
+
+	return 0;
+}
+
+/* Free handler of tuples */
+void tplg_free_tuples(void *obj)
+{
+	struct tplg_vendor_tuples *tuples = (struct tplg_vendor_tuples *)obj;
+	int i;
+
+	if (!tuples)
+		return;
+
+	for (i = 0; i < tuples->num_sets; i++)
+		free(tuples->set[i]);
+}
+
 /* Parse Private data.
  *
  * Object private data can either be from file or defined as bytes, shorts,
- * words.
+ * words, tuples.
  */
 int tplg_parse_data(snd_tplg_t *tplg, snd_config_t *cfg,
 	void *private ATTRIBUTE_UNUSED)
@@ -365,6 +562,14 @@ int tplg_parse_data(snd_tplg_t *tplg, snd_config_t *cfg,
 			continue;
 		}
 
+		if (strcmp(id, "tuples") == 0) {
+			if (snd_config_get_string(n, &val) < 0)
+				return -EINVAL;
+			tplg_dbg(" Data: %s\n", val);
+			tplg_ref_add(elem, SND_TPLG_TYPE_TUPLE, val);
+			continue;
+		}
+
 		if (strcmp(id, "index") == 0) {
 			if (snd_config_get_string(n, &val) < 0)
 				return -EINVAL;
diff --git a/src/topology/elem.c b/src/topology/elem.c
index 95e3fd4..50414f0 100644
--- a/src/topology/elem.c
+++ b/src/topology/elem.c
@@ -196,6 +196,10 @@ struct tplg_elem* tplg_elem_new_common(snd_tplg_t *tplg,
 	case SND_TPLG_TYPE_TOKEN:
 		list_add_tail(&elem->list, &tplg->token_list);
 		break;
+	case SND_TPLG_TYPE_TUPLE:
+		list_add_tail(&elem->list, &tplg->tuple_list);
+		elem->free = tplg_free_tuples;
+		break;
 	default:
 		free(elem);
 		return NULL;
diff --git a/src/topology/parser.c b/src/topology/parser.c
index 264abc8..0d967b4 100644
--- a/src/topology/parser.c
+++ b/src/topology/parser.c
@@ -181,6 +181,14 @@ static int tplg_parse_config(snd_tplg_t *tplg, snd_config_t *cfg)
 			continue;
 		}
 
+		if (strcmp(id, "SectionVendorTuples") == 0) {
+			err = tplg_parse_compound(tplg, n, tplg_parse_tuples,
+				NULL);
+			if (err < 0)
+				return err;
+			continue;
+		}
+
 		SNDERR("error: unknown section %s\n", id);
 	}
 	return 0;
@@ -416,6 +424,7 @@ snd_tplg_t *snd_tplg_new(void)
 	INIT_LIST_HEAD(&tplg->enum_list);
 	INIT_LIST_HEAD(&tplg->bytes_ext_list);
 	INIT_LIST_HEAD(&tplg->token_list);
+	INIT_LIST_HEAD(&tplg->tuple_list);
 
 	return tplg;
 }
@@ -436,6 +445,7 @@ void snd_tplg_free(snd_tplg_t *tplg)
 	tplg_elem_free_list(&tplg->enum_list);
 	tplg_elem_free_list(&tplg->bytes_ext_list);
 	tplg_elem_free_list(&tplg->token_list);
+	tplg_elem_free_list(&tplg->tuple_list);
 
 	free(tplg);
 }
diff --git a/src/topology/tplg_local.h b/src/topology/tplg_local.h
index 679bfff..4d59a1f 100644
--- a/src/topology/tplg_local.h
+++ b/src/topology/tplg_local.h
@@ -70,6 +70,7 @@ struct snd_tplg {
 	struct list_head text_list;
 	struct list_head pdata_list;
 	struct list_head token_list;
+	struct list_head tuple_list;
 	struct list_head pcm_config_list;
 	struct list_head pcm_caps_list;
 
@@ -97,6 +98,28 @@ struct tplg_vendor_tokens {
 	unsigned int num_tokens;
 	struct tplg_token token[0];
 };
+
+/* element for vendor tuples */
+struct tplg_tuple {
+	char token[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
+	union {
+		char string[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
+		char uuid[16];
+		unsigned int value;
+	};
+};
+
+struct tplg_tuple_set {
+	unsigned int  type; /* uuid, bool, byte, short, word, string*/
+	unsigned int  num_tuples;
+	struct tplg_tuple tuple[0];
+};
+
+struct tplg_vendor_tuples {
+	unsigned int  num_sets;
+	struct tplg_tuple_set **set;
+};
+
 /* topology element */
 struct tplg_elem {
 
@@ -130,6 +153,7 @@ struct tplg_elem {
 		struct snd_soc_tplg_ctl_tlv *tlv;
 		struct snd_soc_tplg_private *data;
 		struct tplg_vendor_tokens *tokens;
+		struct tplg_vendor_tuples *tuples;
 	};
 
 	/* an element may refer to other elements:
@@ -166,6 +190,11 @@ int tplg_parse_data(snd_tplg_t *tplg, snd_config_t *cfg,
 int tplg_parse_tokens(snd_tplg_t *tplg, snd_config_t *cfg,
 	void *private ATTRIBUTE_UNUSED);
 
+int tplg_parse_tuples(snd_tplg_t *tplg, snd_config_t *cfg,
+	void *private ATTRIBUTE_UNUSED);
+
+void tplg_free_tuples(void *obj);
+
 int tplg_parse_control_bytes(snd_tplg_t *tplg,
 	snd_config_t *cfg, void *private ATTRIBUTE_UNUSED);
 
-- 
2.5.0

  parent reply	other threads:[~2016-03-24  3:05 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-03-24  3:05 [PATCH 0/7] topology: Add support for vendor tuples mengdong.lin
2016-03-24  3:06 ` [PATCH 1/7] topology: Use the generic pointer to free an element's object mengdong.lin
2016-03-24  3:06 ` [PATCH 2/7] topology: Define a free handler for the element mengdong.lin
2016-03-24  3:07 ` [PATCH 3/7] topology: Add doc for vendor tuples mengdong.lin
2016-03-24  3:07 ` [PATCH 4/7] topology: ABI - Define types " mengdong.lin
2016-03-24  3:07 ` [PATCH 5/7] topology: Add support for vendor tokens mengdong.lin
2016-03-24  3:07 ` mengdong.lin [this message]
2016-03-29 14:13   ` [PATCH 6/7] topology: Add support for parsing vendor tuples Takashi Iwai
2016-03-30  7:15     ` Mengdong Lin
2016-03-24  3:07 ` [PATCH 7/7] topology: Build data objects with tuples mengdong.lin
2016-03-24 11:20 ` [PATCH 0/7] topology: Add support for vendor tuples Mark Brown
2016-03-25  5:39   ` Mengdong Lin
2016-03-28  7:49     ` Mengdong Lin
2016-03-28  7:57       ` Takashi Iwai
2016-03-28  8:56         ` Mengdong Lin

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=ea484928ce467eb5c4b1b105fa9311b1d42cbbee.1458788076.git.mengdong.lin@linux.intel.com \
    --to=mengdong.lin@linux.intel.com \
    --cc=alsa-devel@alsa-project.org \
    --cc=broonie@kernel.org \
    --cc=hardik.t.shah@intel.com \
    --cc=liam.r.girdwood@intel.com \
    --cc=mengdong.lin@intel.com \
    --cc=rakesh.a.ughreja@intel.com \
    --cc=subhransu.s.prusty@intel.com \
    --cc=tiwai@suse.de \
    --cc=vinod.koul@intel.com \
    /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.