summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMengdong Lin <mengdong.lin@linux.intel.com>2016-07-15 20:18:11 +0800
committerTakashi Iwai <tiwai@suse.de>2016-07-17 09:59:48 +0200
commit2481ef315f03fe438898bcee7f06374c0d101ee1 (patch)
tree66cdb60618a3097cf5c93c7926dbb4e73d12018b
parentbb03d929e85f82a82c91da68dd14c952b80b051d (diff)
downloadalsa-lib-2481ef315f03fe438898bcee7f06374c0d101ee1.tar.gz
topology: Merge lookup for data reference into tplg_copy_data()
Code refactor to reduce function calls. Now tplg_copy_data() can look up a referenced data element and merge its data. Signed-off-by: Mengdong Lin <mengdong.lin@linux.intel.com> Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--src/topology/ctl.c28
-rw-r--r--src/topology/dapm.c9
-rw-r--r--src/topology/data.c24
-rw-r--r--src/topology/tplg_local.h4
4 files changed, 34 insertions, 31 deletions
diff --git a/src/topology/ctl.c b/src/topology/ctl.c
index 7ded0a42..592dded7 100644
--- a/src/topology/ctl.c
+++ b/src/topology/ctl.c
@@ -140,9 +140,9 @@ static int tplg_build_mixer_control(snd_tplg_t *tplg,
err = copy_tlv(elem, ref->elem);
} else if (ref->type == SND_TPLG_TYPE_DATA) {
- ref->elem = tplg_elem_lookup(&tplg->pdata_list,
- ref->id, SND_TPLG_TYPE_DATA);
- err = tplg_copy_data(elem, ref->elem);
+ err = tplg_copy_data(tplg, elem, ref);
+ if (err < 0)
+ return err;
}
if (!ref->elem) {
@@ -188,9 +188,9 @@ static int tplg_build_enum_control(snd_tplg_t *tplg,
copy_enum_texts(elem, ref->elem);
} else if (ref->type == SND_TPLG_TYPE_DATA) {
- ref->elem = tplg_elem_lookup(&tplg->pdata_list,
- ref->id, SND_TPLG_TYPE_DATA);
- err = tplg_copy_data(elem, ref->elem);
+ err = tplg_copy_data(tplg, elem, ref);
+ if (err < 0)
+ return err;
}
if (!ref->elem) {
SNDERR("error: cannot find '%s' referenced by"
@@ -208,6 +208,7 @@ static int tplg_build_bytes_control(snd_tplg_t *tplg, struct tplg_elem *elem)
{
struct tplg_ref *ref;
struct list_head *base, *pos;
+ int err;
base = &elem->ref_list;
@@ -217,18 +218,11 @@ static int tplg_build_bytes_control(snd_tplg_t *tplg, struct tplg_elem *elem)
if (ref->id == NULL || ref->elem)
continue;
- /* bytes control only reference one private data section */
- ref->elem = tplg_elem_lookup(&tplg->pdata_list,
- ref->id, SND_TPLG_TYPE_DATA);
- if (!ref->elem) {
- SNDERR("error: cannot find data '%s'"
- " referenced by control '%s'\n",
- ref->id, elem->id);
- return -EINVAL;
+ if (ref->type == SND_TPLG_TYPE_DATA) {
+ err = tplg_copy_data(tplg, elem, ref);
+ if (err < 0)
+ return err;
}
-
- /* copy texts to enum elem */
- return tplg_copy_data(elem, ref->elem);
}
return 0;
diff --git a/src/topology/dapm.c b/src/topology/dapm.c
index d8eb10c1..4d343b2f 100644
--- a/src/topology/dapm.c
+++ b/src/topology/dapm.c
@@ -191,12 +191,11 @@ static int tplg_build_widget(snd_tplg_t *tplg,
break;
case SND_TPLG_TYPE_DATA:
- if (!ref->elem)
- ref->elem = tplg_elem_lookup(&tplg->pdata_list,
- ref->id, SND_TPLG_TYPE_DATA);
- if (ref->elem)
- err = tplg_copy_data(elem, ref->elem);
+ err = tplg_copy_data(tplg, elem, ref);
+ if (err < 0)
+ return err;
break;
+
default:
break;
}
diff --git a/src/topology/data.c b/src/topology/data.c
index 0c5469a8..e60114e9 100644
--- a/src/topology/data.c
+++ b/src/topology/data.c
@@ -889,22 +889,30 @@ int tplg_parse_data(snd_tplg_t *tplg, snd_config_t *cfg,
return err;
}
-/* Merge data from a referenced data element to the parent element's
- * private data buffer.
+/* Find a referenced data element and copy its data to the parent
+ * element's private data buffer.
* An element can refer to multiple data sections. Data of these sections
* will be merged in the their reference order.
*/
-int tplg_copy_data(struct tplg_elem *elem, struct tplg_elem *ref)
+int tplg_copy_data(snd_tplg_t *tplg, struct tplg_elem *elem,
+ struct tplg_ref *ref)
{
+ struct tplg_elem *ref_elem;
struct snd_soc_tplg_private *priv, *old_priv;
int priv_data_size, old_priv_data_size;
void *obj;
- if (!ref)
+ ref_elem = tplg_elem_lookup(&tplg->pdata_list,
+ ref->id, SND_TPLG_TYPE_DATA);
+ if (!ref_elem) {
+ SNDERR("error: cannot find data '%s' referenced by"
+ " element '%s'\n", ref->id, elem->id);
return -EINVAL;
+ }
tplg_dbg("Data '%s' used by '%s'\n", ref->id, elem->id);
- if (!ref->data || !ref->data->size) /* overlook empty private data */
+ /* overlook empty private data */
+ if (!ref_elem->data || !ref_elem->data->size)
return 0;
old_priv = get_priv_data(elem);
@@ -912,7 +920,7 @@ int tplg_copy_data(struct tplg_elem *elem, struct tplg_elem *ref)
return -EINVAL;
old_priv_data_size = old_priv->size;
- priv_data_size = ref->data->size;
+ priv_data_size = ref_elem->data->size;
obj = realloc(elem->obj,
elem->size + priv_data_size);
if (!obj)
@@ -926,9 +934,9 @@ int tplg_copy_data(struct tplg_elem *elem, struct tplg_elem *ref)
/* merge the new data block */
elem->size += priv_data_size;
priv->size = priv_data_size + old_priv_data_size;
- ref->compound_elem = 1;
+ ref_elem->compound_elem = 1;
memcpy(priv->data + old_priv_data_size,
- ref->data->data, priv_data_size);
+ ref_elem->data->data, priv_data_size);
return 0;
}
diff --git a/src/topology/tplg_local.h b/src/topology/tplg_local.h
index 4daa5407..518b81ed 100644
--- a/src/topology/tplg_local.h
+++ b/src/topology/tplg_local.h
@@ -228,7 +228,9 @@ int tplg_build_widgets(snd_tplg_t *tplg);
int tplg_build_routes(snd_tplg_t *tplg);
int tplg_build_pcm_dai(snd_tplg_t *tplg, unsigned int type);
-int tplg_copy_data(struct tplg_elem *elem, struct tplg_elem *ref);
+int tplg_copy_data(snd_tplg_t *tplg, struct tplg_elem *elem,
+ struct tplg_ref *ref);
+
int tplg_parse_data_refs(snd_config_t *cfg, struct tplg_elem *elem);
int tplg_ref_add(struct tplg_elem *elem, int type, const char* id);