Accepting request 335924 from multimedia:libs

1

OBS-URL: https://build.opensuse.org/request/show/335924
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/alsa?expand=0&rev=164
This commit is contained in:
Dominique Leuenberger 2015-10-14 14:40:59 +00:00 committed by Git OBS Bridge
commit 3ed1c48715
24 changed files with 3029 additions and 0 deletions

View File

@ -0,0 +1,29 @@
From 1bb4c2fc304515278e6510ba7288b94f99f50bcd Mon Sep 17 00:00:00 2001
From: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Date: Tue, 4 Aug 2015 18:06:55 +0100
Subject: [PATCH] topology: fix element object type is switch()
Use the correct type for this object.
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
src/topology/elem.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/topology/elem.c b/src/topology/elem.c
index 32ba2c12375b..d7a1fd715d49 100644
--- a/src/topology/elem.c
+++ b/src/topology/elem.c
@@ -137,7 +137,7 @@ struct tplg_elem* tplg_elem_new_common(snd_tplg_t *tplg,
list_add_tail(&elem->list, &tplg->enum_list);
obj_size = sizeof(struct snd_soc_tplg_enum_control);
break;
- case SND_SOC_TPLG_TYPE_MIXER:
+ case OBJECT_TYPE_MIXER:
list_add_tail(&elem->list, &tplg->mixer_list);
obj_size = sizeof(struct snd_soc_tplg_mixer_control);
break;
--
2.5.3

View File

@ -0,0 +1,207 @@
From 120b3b8eadd9a2a4c2ede0a246bffa1cfac562a9 Mon Sep 17 00:00:00 2001
From: Jin Yao <yao.jin@linux.intel.com>
Date: Tue, 4 Aug 2015 18:09:12 +0100
Subject: [PATCH] topology: Add element ID so we can look up references by
name.
Add support to lookup elements by name. This is in preparation for adding
some new API calls that will allow building topology data using a C API. This
will allow applications to build their own topology data directly.
Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
Signed-off-by: Mengdong Lin <mengdong.lin@intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
src/topology/ctl.c | 9 ++++-----
src/topology/dapm.c | 2 +-
src/topology/data.c | 2 +-
src/topology/elem.c | 15 +++++++++++----
src/topology/pcm.c | 10 +++++-----
src/topology/text.c | 2 +-
src/topology/tplg_local.h | 2 +-
7 files changed, 24 insertions(+), 18 deletions(-)
diff --git a/src/topology/ctl.c b/src/topology/ctl.c
index 9c1333c1fc88..aa06ff64bc48 100644
--- a/src/topology/ctl.c
+++ b/src/topology/ctl.c
@@ -264,7 +264,7 @@ int tplg_parse_tlv(snd_tplg_t *tplg, snd_config_t *cfg,
int err = 0;
struct tplg_elem *elem;
- elem = tplg_elem_new_common(tplg, cfg, OBJECT_TYPE_TLV);
+ elem = tplg_elem_new_common(tplg, cfg, NULL, OBJECT_TYPE_TLV);
if (!elem)
return -ENOMEM;
@@ -298,7 +298,7 @@ int tplg_parse_control_bytes(snd_tplg_t *tplg,
const char *id, *val = NULL;
int err;
- elem = tplg_elem_new_common(tplg, cfg, OBJECT_TYPE_BYTES);
+ elem = tplg_elem_new_common(tplg, cfg, NULL, OBJECT_TYPE_BYTES);
if (!elem)
return -ENOMEM;
@@ -403,11 +403,10 @@ int tplg_parse_control_enum(snd_tplg_t *tplg, snd_config_t *cfg,
const char *id, *val = NULL;
int err, j;
- elem = tplg_elem_new_common(tplg, cfg, OBJECT_TYPE_ENUM);
+ elem = tplg_elem_new_common(tplg, cfg, NULL, OBJECT_TYPE_ENUM);
if (!elem)
return -ENOMEM;
- /* init new mixer */
ec = elem->enum_ctrl;
elem_copy_text(ec->hdr.name, elem->id, SNDRV_CTL_ELEM_ID_NAME_MAXLEN);
ec->hdr.type = SND_SOC_TPLG_TYPE_ENUM;
@@ -501,7 +500,7 @@ int tplg_parse_control_mixer(snd_tplg_t *tplg,
const char *id, *val = NULL;
int err, j;
- elem = tplg_elem_new_common(tplg, cfg, OBJECT_TYPE_MIXER);
+ elem = tplg_elem_new_common(tplg, cfg, NULL, OBJECT_TYPE_MIXER);
if (!elem)
return -ENOMEM;
diff --git a/src/topology/dapm.c b/src/topology/dapm.c
index 1da82adea470..7e26ea0326ec 100644
--- a/src/topology/dapm.c
+++ b/src/topology/dapm.c
@@ -420,7 +420,7 @@ int tplg_parse_dapm_widget(snd_tplg_t *tplg,
const char *id, *val = NULL;
int widget_type, err;
- elem = tplg_elem_new_common(tplg, cfg, OBJECT_TYPE_DAPM_WIDGET);
+ elem = tplg_elem_new_common(tplg, cfg, NULL, OBJECT_TYPE_DAPM_WIDGET);
if (!elem)
return -ENOMEM;
diff --git a/src/topology/data.c b/src/topology/data.c
index 13e1e2bb60fb..c768bc5b0b04 100644
--- a/src/topology/data.c
+++ b/src/topology/data.c
@@ -268,7 +268,7 @@ int tplg_parse_data(snd_tplg_t *tplg, snd_config_t *cfg,
int err = 0;
struct tplg_elem *elem;
- elem = tplg_elem_new_common(tplg, cfg, OBJECT_TYPE_DATA);
+ elem = tplg_elem_new_common(tplg, cfg, NULL, OBJECT_TYPE_DATA);
if (!elem)
return -ENOMEM;
diff --git a/src/topology/elem.c b/src/topology/elem.c
index d7a1fd715d49..7fee65332124 100644
--- a/src/topology/elem.c
+++ b/src/topology/elem.c
@@ -103,20 +103,27 @@ struct tplg_elem *tplg_elem_lookup(struct list_head *base, const char* id,
/* create a new common element and object */
struct tplg_elem* tplg_elem_new_common(snd_tplg_t *tplg,
- snd_config_t *cfg, enum object_type type)
+ snd_config_t *cfg, const char *name, enum object_type type)
{
struct tplg_elem *elem;
const char *id;
int obj_size = 0;
void *obj;
+ if (!cfg && !name)
+ return NULL;
+
elem = tplg_elem_new();
if (!elem)
return NULL;
- snd_config_get_id(cfg, &id);
- strncpy(elem->id, id, SNDRV_CTL_ELEM_ID_NAME_MAXLEN);
- elem->id[SNDRV_CTL_ELEM_ID_NAME_MAXLEN - 1] = 0;
+ /* do we get name from cfg */
+ if (cfg) {
+ snd_config_get_id(cfg, &id);
+ elem_copy_text(elem->id, id, SNDRV_CTL_ELEM_ID_NAME_MAXLEN);
+ elem->id[SNDRV_CTL_ELEM_ID_NAME_MAXLEN - 1] = 0;
+ } else if (name != NULL)
+ elem_copy_text(elem->id, name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN);
switch (type) {
case OBJECT_TYPE_DATA:
diff --git a/src/topology/pcm.c b/src/topology/pcm.c
index 8f23a6f12ec4..deae47b771be 100644
--- a/src/topology/pcm.c
+++ b/src/topology/pcm.c
@@ -228,7 +228,7 @@ int tplg_parse_pcm_config(snd_tplg_t *tplg,
const char *id;
int err;
- elem = tplg_elem_new_common(tplg, cfg, OBJECT_TYPE_STREAM_CONFIG);
+ elem = tplg_elem_new_common(tplg, cfg, NULL, OBJECT_TYPE_STREAM_CONFIG);
if (!elem)
return -ENOMEM;
@@ -294,7 +294,7 @@ int tplg_parse_pcm_caps(snd_tplg_t *tplg,
char *s;
int err;
- elem = tplg_elem_new_common(tplg, cfg, OBJECT_TYPE_STREAM_CAPS);
+ elem = tplg_elem_new_common(tplg, cfg, NULL, OBJECT_TYPE_STREAM_CAPS);
if (!elem)
return -ENOMEM;
@@ -461,7 +461,7 @@ int tplg_parse_pcm(snd_tplg_t *tplg,
const char *id, *val = NULL;
int err;
- elem = tplg_elem_new_common(tplg, cfg, OBJECT_TYPE_PCM);
+ elem = tplg_elem_new_common(tplg, cfg, NULL, OBJECT_TYPE_PCM);
if (!elem)
return -ENOMEM;
@@ -524,7 +524,7 @@ int tplg_parse_be(snd_tplg_t *tplg,
const char *id, *val = NULL;
int err;
- elem = tplg_elem_new_common(tplg, cfg, OBJECT_TYPE_BE);
+ elem = tplg_elem_new_common(tplg, cfg, NULL, OBJECT_TYPE_BE);
if (!elem)
return -ENOMEM;
@@ -587,7 +587,7 @@ int tplg_parse_cc(snd_tplg_t *tplg,
const char *id, *val = NULL;
int err;
- elem = tplg_elem_new_common(tplg, cfg, OBJECT_TYPE_CC);
+ elem = tplg_elem_new_common(tplg, cfg, NULL, OBJECT_TYPE_CC);
if (!elem)
return -ENOMEM;
diff --git a/src/topology/text.c b/src/topology/text.c
index ebb6e3840d62..7128056d5d34 100644
--- a/src/topology/text.c
+++ b/src/topology/text.c
@@ -64,7 +64,7 @@ int tplg_parse_text(snd_tplg_t *tplg, snd_config_t *cfg,
int err = 0;
struct tplg_elem *elem;
- elem = tplg_elem_new_common(tplg, cfg, OBJECT_TYPE_TEXT);
+ elem = tplg_elem_new_common(tplg, cfg, NULL, OBJECT_TYPE_TEXT);
if (!elem)
return -ENOMEM;
diff --git a/src/topology/tplg_local.h b/src/topology/tplg_local.h
index 688c78f3a6a4..62788e4b7ca1 100644
--- a/src/topology/tplg_local.h
+++ b/src/topology/tplg_local.h
@@ -216,7 +216,7 @@ struct tplg_elem *tplg_elem_lookup(struct list_head *base,
const char* id,
unsigned int type);
struct tplg_elem* tplg_elem_new_common(snd_tplg_t *tplg,
- snd_config_t *cfg, enum object_type type);
+ snd_config_t *cfg, const char *name, enum object_type type);
static inline void elem_copy_text(char *dest, const char *src, int len)
{
--
2.5.3

View File

@ -0,0 +1,90 @@
From d5e7e8bb38681c2cbf3777314c422130a740810e Mon Sep 17 00:00:00 2001
From: Mengdong Lin <mengdong.lin@intel.com>
Date: Tue, 4 Aug 2015 18:09:46 +0100
Subject: [PATCH] topology: Add support for writing manifest private data.
Allow manifest to contain private data and write this data to file.
Signed-off-by: Mengdong Lin <mengdong.lin@intel.com>
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
src/topology/builder.c | 37 ++++++++++++++++++++++++++++++++-----
src/topology/tplg_local.h | 1 +
2 files changed, 33 insertions(+), 5 deletions(-)
diff --git a/src/topology/builder.c b/src/topology/builder.c
index 0066b220353c..a944866a2d68 100644
--- a/src/topology/builder.c
+++ b/src/topology/builder.c
@@ -226,9 +226,6 @@ static int write_block(snd_tplg_t *tplg, struct list_head *base,
case OBJECT_TYPE_CC:
return write_elem_block(tplg, base, size,
SND_SOC_TPLG_TYPE_DAI_LINK, "cc");
- case OBJECT_TYPE_MANIFEST:
- return write_data_block(tplg, size, SND_SOC_TPLG_TYPE_MANIFEST,
- "manifest", &tplg->manifest);
case OBJECT_TYPE_DATA:
return write_elem_block(tplg, base, size,
SND_SOC_TPLG_TYPE_PDATA, "data");
@@ -239,13 +236,43 @@ static int write_block(snd_tplg_t *tplg, struct list_head *base,
return 0;
}
+/* write the manifest including its private data */
+static int write_manifest_data(snd_tplg_t *tplg)
+{
+ int ret;
+
+ /* write the header for this block */
+ ret = write_block_header(tplg, SND_SOC_TPLG_TYPE_MANIFEST, 0,
+ SND_SOC_TPLG_ABI_VERSION, 0,
+ sizeof(tplg->manifest) + tplg->manifest.priv.size, 1);
+ if (ret < 0) {
+ SNDERR("error: failed to write manifest block %d\n", ret);
+ return ret;
+ }
+
+ verbose(tplg, "manifest : write %d bytes\n", sizeof(tplg->manifest));
+ ret = write(tplg->out_fd, &tplg->manifest, sizeof(tplg->manifest));
+ if (ret < 0) {
+ SNDERR("error: failed to write manifest %d\n", ret);
+ return ret;
+ }
+
+ verbose(tplg, "manifest : write %d priv bytes\n", tplg->manifest.priv.size);
+ ret = write(tplg->out_fd, tplg->manifest_pdata, tplg->manifest.priv.size);
+ if (ret < 0) {
+ SNDERR("error: failed to write manifest priv data %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
int tplg_write_data(snd_tplg_t *tplg)
{
int ret;
/* write manifest */
- ret = write_data_block(tplg, sizeof(tplg->manifest),
- OBJECT_TYPE_MANIFEST, "manifest", &tplg->manifest);
+ ret = write_manifest_data(tplg);
if (ret < 0) {
SNDERR("failed to write manifest %d\n", ret);
return ret;
diff --git a/src/topology/tplg_local.h b/src/topology/tplg_local.h
index 62788e4b7ca1..ad38945056df 100644
--- a/src/topology/tplg_local.h
+++ b/src/topology/tplg_local.h
@@ -77,6 +77,7 @@ struct snd_tplg {
/* manifest */
struct snd_soc_tplg_manifest manifest;
+ const void *manifest_pdata; /* copied by builder at file write */
/* list of each element type */
struct list_head tlv_list;
--
2.5.3

View File

@ -0,0 +1,136 @@
From 8c8372cc060ec16776db28f927c9402dcc09b001 Mon Sep 17 00:00:00 2001
From: Mengdong Lin <mengdong.lin@intel.com>
Date: Wed, 5 Aug 2015 14:41:50 +0100
Subject: [PATCH] topology: update ABI to improve support for different TLV
object types.
Currently the TLV topology structure is targeted at only supporting the
DB scale data. This patch extends support for the other TLV types so they
can be easily added at a later stage.
TLV structure is moved to common topology control header since it's a
common field for controls and can be processed in a general way.
Users must set a proper access flag for a control since it's used to decide
if the TLV field is valid and if a TLV callback is needed.
Removed the following fields from topology TLV struct:
- size/count: type can decide the size.
- numid: not needed to initialize TLV for kcontrol.
- data: replaced by the type specific struct.
Added TLV structure to generic control header and removed TLV structure from
mixer control.
Signed-off-by: Mengdong Lin <mengdong.lin@intel.com>
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
include/sound/asoc.h | 19 +++++++++++++------
src/topology/ctl.c | 20 ++++++++------------
2 files changed, 21 insertions(+), 18 deletions(-)
diff --git a/include/sound/asoc.h b/include/sound/asoc.h
index bb6dcf3ff7b4..73eb80ef17cc 100644
--- a/include/sound/asoc.h
+++ b/include/sound/asoc.h
@@ -135,11 +135,19 @@ struct snd_soc_tplg_private {
/*
* Kcontrol TLV data.
*/
+struct snd_soc_tplg_tlv_dbscale {
+ __le32 min;
+ __le32 step;
+ __le32 mute;
+} __attribute__((packed));
+
struct snd_soc_tplg_ctl_tlv {
- __le32 size; /* in bytes aligned to 4 */
- __le32 numid; /* control element numeric identification */
- __le32 count; /* number of elem in data array */
- __le32 data[SND_SOC_TPLG_TLV_SIZE];
+ __le32 size; /* in bytes of this structure */
+ __le32 type; /* SNDRV_CTL_TLVT_*, type of TLV */
+ union {
+ __le32 data[SND_SOC_TPLG_TLV_SIZE];
+ struct snd_soc_tplg_tlv_dbscale scale;
+ };
} __attribute__((packed));
/*
@@ -170,7 +178,7 @@ struct snd_soc_tplg_ctl_hdr {
char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
__le32 access;
struct snd_soc_tplg_kcontrol_ops_id ops;
- __le32 tlv_size; /* non zero means control has TLV data */
+ struct snd_soc_tplg_ctl_tlv tlv;
} __attribute__((packed));
/*
@@ -258,7 +266,6 @@ struct snd_soc_tplg_mixer_control {
__le32 invert;
__le32 num_channels;
struct snd_soc_tplg_channel channel[SND_SOC_TPLG_MAX_CHAN];
- struct snd_soc_tplg_ctl_tlv tlv;
struct snd_soc_tplg_private priv;
} __attribute__((packed));
diff --git a/src/topology/ctl.c b/src/topology/ctl.c
index aa06ff64bc48..930b50897220 100644
--- a/src/topology/ctl.c
+++ b/src/topology/ctl.c
@@ -28,10 +28,7 @@ static int copy_tlv(struct tplg_elem *elem, struct tplg_elem *ref)
tplg_dbg("TLV '%s' used by '%s\n", ref->id, elem->id);
/* TLV has a fixed size */
- mixer_ctrl->tlv = *tlv;
-
- /* set size of TLV data */
- mixer_ctrl->hdr.tlv_size = tlv->count * sizeof(uint32_t);
+ mixer_ctrl->hdr.tlv = *tlv;
return 0;
}
@@ -209,20 +206,19 @@ static int tplg_parse_tlv_dbscale(snd_config_t *cfg, struct tplg_elem *elem)
snd_config_iterator_t i, next;
snd_config_t *n;
struct snd_soc_tplg_ctl_tlv *tplg_tlv;
+ struct snd_soc_tplg_tlv_dbscale *scale;
const char *id = NULL, *value = NULL;
- int *data;
tplg_dbg(" scale: %s\n", elem->id);
tplg_tlv = calloc(1, sizeof(*tplg_tlv));
if (!tplg_tlv)
return -ENOMEM;
- data = (int*)(tplg_tlv->data);
elem->tlv = tplg_tlv;
- tplg_tlv->numid = SNDRV_CTL_TLVT_DB_SCALE;
- tplg_tlv->count = 8;
- tplg_tlv->size = sizeof(*tplg_tlv);
+ tplg_tlv->size = sizeof(struct snd_soc_tplg_ctl_tlv);
+ tplg_tlv->type = SNDRV_CTL_TLVT_DB_SCALE;
+ scale = &tplg_tlv->scale;
snd_config_for_each(i, next, cfg) {
@@ -242,11 +238,11 @@ static int tplg_parse_tlv_dbscale(snd_config_t *cfg, struct tplg_elem *elem)
/* get TLV data */
if (strcmp(id, "min") == 0)
- data[0] = atoi(value);
+ scale->min = atoi(value);
else if (strcmp(id, "step") == 0)
- data[1] = atoi(value);
+ scale->step = atoi(value);
else if (strcmp(id, "mute") == 0)
- data[2] = atoi(value);
+ scale->mute = atoi(value);
else
SNDERR("error: unknown key %s\n", id);
}
--
2.5.3

View File

@ -0,0 +1,54 @@
From 80a8283d179739f73ad007b5d60dbf28b80fddb9 Mon Sep 17 00:00:00 2001
From: Mengdong Lin <mengdong.lin@intel.com>
Date: Wed, 5 Aug 2015 14:41:51 +0100
Subject: [PATCH] topology: Add ops support to byte control objects.
Rename the control ops structure to make it more generic so we can use it
with other objects like bytes controls. Add this structure to the byte
control structure.
Signed-off-by: Mengdong Lin <mengdong.lin@intel.com>
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
include/sound/asoc.h | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/include/sound/asoc.h b/include/sound/asoc.h
index 73eb80ef17cc..c642855e4b0c 100644
--- a/include/sound/asoc.h
+++ b/include/sound/asoc.h
@@ -161,9 +161,11 @@ struct snd_soc_tplg_channel {
} __attribute__((packed));
/*
- * Kcontrol Operations IDs
+ * Genericl Operations IDs, for binding Kcontrol or Bytes ext ops
+ * Kcontrol ops need get/put/info.
+ * Bytes ext ops need get/put.
*/
-struct snd_soc_tplg_kcontrol_ops_id {
+struct snd_soc_tplg_io_ops {
__le32 get;
__le32 put;
__le32 info;
@@ -177,7 +179,7 @@ struct snd_soc_tplg_ctl_hdr {
__le32 type;
char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
__le32 access;
- struct snd_soc_tplg_kcontrol_ops_id ops;
+ struct snd_soc_tplg_io_ops ops;
struct snd_soc_tplg_ctl_tlv tlv;
} __attribute__((packed));
@@ -309,6 +311,7 @@ struct snd_soc_tplg_bytes_control {
__le32 mask;
__le32 base;
__le32 num_regs;
+ struct snd_soc_tplg_io_ops ext_ops;
struct snd_soc_tplg_private priv;
} __attribute__((packed));
--
2.5.3

View File

@ -0,0 +1,47 @@
From ecf7fdaeef57d300b94a1cd00db8a8b04a2edceb Mon Sep 17 00:00:00 2001
From: Mengdong Lin <mengdong.lin@intel.com>
Date: Fri, 7 Aug 2015 16:39:15 +0100
Subject: [PATCH] topology: treat all DAPM controls types the same when copying
Copy all DAPM controls types using the same method.
Signed-off-by: Mengdong Lin <mengdong.lin@intel.com>
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
src/topology/dapm.c | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)
diff --git a/src/topology/dapm.c b/src/topology/dapm.c
index 7e26ea0326ec..a0a8b8656c21 100644
--- a/src/topology/dapm.c
+++ b/src/topology/dapm.c
@@ -107,8 +107,6 @@ static int tplg_parse_dapm_enums(snd_config_t *cfg, struct tplg_elem *elem)
static int copy_dapm_control(struct tplg_elem *elem, struct tplg_elem *ref)
{
struct snd_soc_tplg_dapm_widget *widget = elem->widget;
- struct snd_soc_tplg_mixer_control *mixer_ctrl = ref->mixer_ctrl;
- struct snd_soc_tplg_enum_control *enum_ctrl = ref->enum_ctrl;
tplg_dbg("Control '%s' used by '%s'\n", ref->id, elem->id);
tplg_dbg("\tparent size: %d + %d -> %d, priv size -> %d\n",
@@ -121,13 +119,10 @@ static int copy_dapm_control(struct tplg_elem *elem, struct tplg_elem *ref)
elem->widget = widget;
- /* copy new widget at the end */
- if (ref->type == OBJECT_TYPE_MIXER)
- memcpy((void*)widget + elem->size, mixer_ctrl, ref->size);
- else if (ref->type == OBJECT_TYPE_ENUM)
- memcpy((void*)widget + elem->size, enum_ctrl, ref->size);
-
+ /* append the control to the end of the widget */
+ memcpy((void*)widget + elem->size, ref->obj, ref->size);
elem->size += ref->size;
+
widget->num_kcontrols++;
ref->compound_elem = 1;
return 0;
--
2.5.3

View File

@ -0,0 +1,29 @@
From b47cf00197420d7dc9dc01dce75b41aaad49278e Mon Sep 17 00:00:00 2001
From: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Date: Fri, 7 Aug 2015 16:39:16 +0100
Subject: [PATCH] topology: print error prefix on error message.
Let the user know it's an error.
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
src/topology/data.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/topology/data.c b/src/topology/data.c
index c768bc5b0b04..090185174ce4 100644
--- a/src/topology/data.c
+++ b/src/topology/data.c
@@ -384,7 +384,7 @@ int tplg_copy_data(struct tplg_elem *elem, struct tplg_elem *ref)
break;
default:
- SNDERR("elem '%s': type %d private data not supported \n",
+ SNDERR("error: elem '%s': type %d private data not supported \n",
elem->id, elem->type);
return -EINVAL;
}
--
2.5.3

View File

@ -0,0 +1,782 @@
From 634712d21c07a229a6b37658e900f0fd4c304a59 Mon Sep 17 00:00:00 2001
From: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Date: Mon, 10 Aug 2015 19:13:47 +0100
Subject: [PATCH] topology: rename OBJECT_TYPE_ to SND_TPLG_TYPE_
rename OBJECT_TYPE_ to SND_TPLG_TYPE_ in preparation for exporting via
a new public API.
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
src/topology/builder.c | 38 +++++++++++++++++++-------------------
src/topology/ctl.c | 38 +++++++++++++++++++-------------------
src/topology/dapm.c | 43 +++++++++++++++++++++++--------------------
src/topology/data.c | 10 +++++-----
src/topology/elem.c | 26 +++++++++++++-------------
src/topology/parser.c | 6 +++---
src/topology/pcm.c | 34 +++++++++++++++++-----------------
src/topology/text.c | 2 +-
src/topology/tplg_local.h | 36 ++++++++++++++++++------------------
9 files changed, 118 insertions(+), 115 deletions(-)
diff --git a/src/topology/builder.c b/src/topology/builder.c
index a944866a2d68..3bccd44827cc 100644
--- a/src/topology/builder.c
+++ b/src/topology/builder.c
@@ -141,7 +141,7 @@ static int write_elem_block(snd_tplg_t *tplg,
if (elem->compound_elem)
continue;
- if (elem->type != OBJECT_TYPE_DAPM_GRAPH)
+ if (elem->type != SND_TPLG_TYPE_DAPM_GRAPH)
verbose(tplg, " %s '%s': write %d bytes\n",
obj_name, elem->id, elem->size);
else
@@ -202,31 +202,31 @@ static int write_block(snd_tplg_t *tplg, struct list_head *base,
/* write each elem for this block */
switch (type) {
- case OBJECT_TYPE_MIXER:
+ case SND_TPLG_TYPE_MIXER:
return write_elem_block(tplg, base, size,
SND_SOC_TPLG_TYPE_MIXER, "mixer");
- case OBJECT_TYPE_BYTES:
+ case SND_TPLG_TYPE_BYTES:
return write_elem_block(tplg, base, size,
SND_SOC_TPLG_TYPE_BYTES, "bytes");
- case OBJECT_TYPE_ENUM:
+ case SND_TPLG_TYPE_ENUM:
return write_elem_block(tplg, base, size,
SND_SOC_TPLG_TYPE_ENUM, "enum");
- case OBJECT_TYPE_DAPM_GRAPH:
+ case SND_TPLG_TYPE_DAPM_GRAPH:
return write_elem_block(tplg, base, size,
SND_SOC_TPLG_TYPE_DAPM_GRAPH, "route");
- case OBJECT_TYPE_DAPM_WIDGET:
+ case SND_TPLG_TYPE_DAPM_WIDGET:
return write_elem_block(tplg, base, size,
SND_SOC_TPLG_TYPE_DAPM_WIDGET, "widget");
- case OBJECT_TYPE_PCM:
+ case SND_TPLG_TYPE_PCM:
return write_elem_block(tplg, base, size,
SND_SOC_TPLG_TYPE_PCM, "pcm");
- case OBJECT_TYPE_BE:
+ case SND_TPLG_TYPE_BE:
return write_elem_block(tplg, base, size,
SND_SOC_TPLG_TYPE_DAI_LINK, "be");
- case OBJECT_TYPE_CC:
+ case SND_TPLG_TYPE_CC:
return write_elem_block(tplg, base, size,
SND_SOC_TPLG_TYPE_DAI_LINK, "cc");
- case OBJECT_TYPE_DATA:
+ case SND_TPLG_TYPE_DATA:
return write_elem_block(tplg, base, size,
SND_SOC_TPLG_TYPE_PDATA, "data");
default:
@@ -280,7 +280,7 @@ int tplg_write_data(snd_tplg_t *tplg)
/* write mixer elems. */
ret = write_block(tplg, &tplg->mixer_list,
- OBJECT_TYPE_MIXER);
+ SND_TPLG_TYPE_MIXER);
if (ret < 0) {
SNDERR("failed to write control elems %d\n", ret);
return ret;
@@ -288,7 +288,7 @@ int tplg_write_data(snd_tplg_t *tplg)
/* write enum control elems. */
ret = write_block(tplg, &tplg->enum_list,
- OBJECT_TYPE_ENUM);
+ SND_TPLG_TYPE_ENUM);
if (ret < 0) {
SNDERR("failed to write control elems %d\n", ret);
return ret;
@@ -296,7 +296,7 @@ int tplg_write_data(snd_tplg_t *tplg)
/* write bytes extended control elems. */
ret = write_block(tplg, &tplg->bytes_ext_list,
- OBJECT_TYPE_BYTES);
+ SND_TPLG_TYPE_BYTES);
if (ret < 0) {
SNDERR("failed to write control elems %d\n", ret);
return ret;
@@ -304,7 +304,7 @@ int tplg_write_data(snd_tplg_t *tplg)
/* write widget elems */
ret = write_block(tplg, &tplg->widget_list,
- OBJECT_TYPE_DAPM_WIDGET);
+ SND_TPLG_TYPE_DAPM_WIDGET);
if (ret < 0) {
SNDERR("failed to write widget elems %d\n", ret);
return ret;
@@ -312,7 +312,7 @@ int tplg_write_data(snd_tplg_t *tplg)
/* write pcm elems */
ret = write_block(tplg, &tplg->pcm_list,
- OBJECT_TYPE_PCM);
+ SND_TPLG_TYPE_PCM);
if (ret < 0) {
SNDERR("failed to write pcm elems %d\n", ret);
return ret;
@@ -320,7 +320,7 @@ int tplg_write_data(snd_tplg_t *tplg)
/* write be elems */
ret = write_block(tplg, &tplg->be_list,
- OBJECT_TYPE_BE);
+ SND_TPLG_TYPE_BE);
if (ret < 0) {
SNDERR("failed to write be elems %d\n", ret);
return ret;
@@ -328,7 +328,7 @@ int tplg_write_data(snd_tplg_t *tplg)
/* write cc elems */
ret = write_block(tplg, &tplg->cc_list,
- OBJECT_TYPE_CC);
+ SND_TPLG_TYPE_CC);
if (ret < 0) {
SNDERR("failed to write cc elems %d\n", ret);
return ret;
@@ -336,7 +336,7 @@ int tplg_write_data(snd_tplg_t *tplg)
/* write route elems */
ret = write_block(tplg, &tplg->route_list,
- OBJECT_TYPE_DAPM_GRAPH);
+ SND_TPLG_TYPE_DAPM_GRAPH);
if (ret < 0) {
SNDERR("failed to write graph elems %d\n", ret);
return ret;
@@ -344,7 +344,7 @@ int tplg_write_data(snd_tplg_t *tplg)
/* write private data */
ret = write_block(tplg, &tplg->pdata_list,
- OBJECT_TYPE_DATA);
+ SND_TPLG_TYPE_DATA);
if (ret < 0) {
SNDERR("failed to write private data %d\n", ret);
return ret;
diff --git a/src/topology/ctl.c b/src/topology/ctl.c
index 930b50897220..35f684ba8067 100644
--- a/src/topology/ctl.c
+++ b/src/topology/ctl.c
@@ -49,15 +49,15 @@ static int tplg_build_mixer_control(snd_tplg_t *tplg,
if (ref->id == NULL || ref->elem)
continue;
- if (ref->type == OBJECT_TYPE_TLV) {
+ if (ref->type == SND_TPLG_TYPE_TLV) {
ref->elem = tplg_elem_lookup(&tplg->tlv_list,
- ref->id, OBJECT_TYPE_TLV);
+ ref->id, SND_TPLG_TYPE_TLV);
if (ref->elem)
err = copy_tlv(elem, ref->elem);
- } else if (ref->type == OBJECT_TYPE_DATA) {
+ } else if (ref->type == SND_TPLG_TYPE_DATA) {
ref->elem = tplg_elem_lookup(&tplg->pdata_list,
- ref->id, OBJECT_TYPE_DATA);
+ ref->id, SND_TPLG_TYPE_DATA);
err = tplg_copy_data(elem, ref->elem);
}
@@ -97,15 +97,15 @@ static int tplg_build_enum_control(snd_tplg_t *tplg,
if (ref->id == NULL || ref->elem)
continue;
- if (ref->type == OBJECT_TYPE_TEXT) {
+ if (ref->type == SND_TPLG_TYPE_TEXT) {
ref->elem = tplg_elem_lookup(&tplg->text_list,
- ref->id, OBJECT_TYPE_TEXT);
+ ref->id, SND_TPLG_TYPE_TEXT);
if (ref->elem)
copy_enum_texts(elem, ref->elem);
- } else if (ref->type == OBJECT_TYPE_DATA) {
+ } else if (ref->type == SND_TPLG_TYPE_DATA) {
ref->elem = tplg_elem_lookup(&tplg->pdata_list,
- ref->id, OBJECT_TYPE_DATA);
+ ref->id, SND_TPLG_TYPE_DATA);
err = tplg_copy_data(elem, ref->elem);
}
if (!ref->elem) {
@@ -135,7 +135,7 @@ static int tplg_build_bytes_control(snd_tplg_t *tplg, struct tplg_elem *elem)
/* bytes control only reference one private data section */
ref->elem = tplg_elem_lookup(&tplg->pdata_list,
- ref->id, OBJECT_TYPE_DATA);
+ ref->id, SND_TPLG_TYPE_DATA);
if (!ref->elem) {
SNDERR("error: cannot find data '%s'"
" referenced by control '%s'\n",
@@ -260,7 +260,7 @@ int tplg_parse_tlv(snd_tplg_t *tplg, snd_config_t *cfg,
int err = 0;
struct tplg_elem *elem;
- elem = tplg_elem_new_common(tplg, cfg, NULL, OBJECT_TYPE_TLV);
+ elem = tplg_elem_new_common(tplg, cfg, NULL, SND_TPLG_TYPE_TLV);
if (!elem)
return -ENOMEM;
@@ -294,7 +294,7 @@ int tplg_parse_control_bytes(snd_tplg_t *tplg,
const char *id, *val = NULL;
int err;
- elem = tplg_elem_new_common(tplg, cfg, NULL, OBJECT_TYPE_BYTES);
+ elem = tplg_elem_new_common(tplg, cfg, NULL, SND_TPLG_TYPE_BYTES);
if (!elem)
return -ENOMEM;
@@ -365,7 +365,7 @@ int tplg_parse_control_bytes(snd_tplg_t *tplg,
if (snd_config_get_string(n, &val) < 0)
return -EINVAL;
- tplg_ref_add(elem, OBJECT_TYPE_DATA, val);
+ tplg_ref_add(elem, SND_TPLG_TYPE_DATA, val);
tplg_dbg("\t%s: %s\n", id, val);
continue;
}
@@ -374,7 +374,7 @@ int tplg_parse_control_bytes(snd_tplg_t *tplg,
if (snd_config_get_string(n, &val) < 0)
return -EINVAL;
- err = tplg_ref_add(elem, OBJECT_TYPE_TLV, val);
+ err = tplg_ref_add(elem, SND_TPLG_TYPE_TLV, val);
if (err < 0)
return err;
@@ -399,7 +399,7 @@ int tplg_parse_control_enum(snd_tplg_t *tplg, snd_config_t *cfg,
const char *id, *val = NULL;
int err, j;
- elem = tplg_elem_new_common(tplg, cfg, NULL, OBJECT_TYPE_ENUM);
+ elem = tplg_elem_new_common(tplg, cfg, NULL, SND_TPLG_TYPE_ENUM);
if (!elem)
return -ENOMEM;
@@ -440,7 +440,7 @@ int tplg_parse_control_enum(snd_tplg_t *tplg, snd_config_t *cfg,
if (snd_config_get_string(n, &val) < 0)
return -EINVAL;
- tplg_ref_add(elem, OBJECT_TYPE_TEXT, val);
+ tplg_ref_add(elem, SND_TPLG_TYPE_TEXT, val);
tplg_dbg("\t%s: %s\n", id, val);
continue;
}
@@ -473,7 +473,7 @@ int tplg_parse_control_enum(snd_tplg_t *tplg, snd_config_t *cfg,
if (snd_config_get_string(n, &val) < 0)
return -EINVAL;
- tplg_ref_add(elem, OBJECT_TYPE_DATA, val);
+ tplg_ref_add(elem, SND_TPLG_TYPE_DATA, val);
tplg_dbg("\t%s: %s\n", id, val);
continue;
}
@@ -496,7 +496,7 @@ int tplg_parse_control_mixer(snd_tplg_t *tplg,
const char *id, *val = NULL;
int err, j;
- elem = tplg_elem_new_common(tplg, cfg, NULL, OBJECT_TYPE_MIXER);
+ elem = tplg_elem_new_common(tplg, cfg, NULL, SND_TPLG_TYPE_MIXER);
if (!elem)
return -ENOMEM;
@@ -584,7 +584,7 @@ int tplg_parse_control_mixer(snd_tplg_t *tplg,
if (snd_config_get_string(n, &val) < 0)
return -EINVAL;
- err = tplg_ref_add(elem, OBJECT_TYPE_TLV, val);
+ err = tplg_ref_add(elem, SND_TPLG_TYPE_TLV, val);
if (err < 0)
return err;
@@ -598,7 +598,7 @@ int tplg_parse_control_mixer(snd_tplg_t *tplg,
if (snd_config_get_string(n, &val) < 0)
return -EINVAL;
- tplg_ref_add(elem, OBJECT_TYPE_DATA, val);
+ tplg_ref_add(elem, SND_TPLG_TYPE_DATA, val);
tplg_dbg("\t%s: %s\n", id, val);
continue;
}
diff --git a/src/topology/dapm.c b/src/topology/dapm.c
index a0a8b8656c21..3458aa77838b 100644
--- a/src/topology/dapm.c
+++ b/src/topology/dapm.c
@@ -74,7 +74,7 @@ static int tplg_parse_dapm_mixers(snd_config_t *cfg, struct tplg_elem *elem)
if (snd_config_get_string(n, &value) < 0)
continue;
- tplg_ref_add(elem, OBJECT_TYPE_MIXER, value);
+ tplg_ref_add(elem, SND_TPLG_TYPE_MIXER, value);
tplg_dbg("\t\t %s\n", value);
}
@@ -96,7 +96,7 @@ static int tplg_parse_dapm_enums(snd_config_t *cfg, struct tplg_elem *elem)
if (snd_config_get_string(n, &value) < 0)
continue;
- tplg_ref_add(elem, OBJECT_TYPE_ENUM, value);
+ tplg_ref_add(elem, SND_TPLG_TYPE_ENUM, value);
tplg_dbg("\t\t %s\n", value);
}
@@ -146,23 +146,26 @@ static int tplg_build_widget(snd_tplg_t *tplg,
continue;
switch (ref->type) {
- case OBJECT_TYPE_MIXER:
- ref->elem = tplg_elem_lookup(&tplg->mixer_list,
- ref->id, OBJECT_TYPE_MIXER);
+ case SND_TPLG_TYPE_MIXER:
+ if (!ref->elem)
+ ref->elem = tplg_elem_lookup(&tplg->mixer_list,
+ ref->id, SND_TPLG_TYPE_MIXER);
if (ref->elem)
err = copy_dapm_control(elem, ref->elem);
break;
- case OBJECT_TYPE_ENUM:
- ref->elem = tplg_elem_lookup(&tplg->enum_list,
- ref->id, OBJECT_TYPE_ENUM);
+ case SND_TPLG_TYPE_ENUM:
+ if (!ref->elem)
+ ref->elem = tplg_elem_lookup(&tplg->enum_list,
+ ref->id, SND_TPLG_TYPE_ENUM);
if (ref->elem)
err = copy_dapm_control(elem, ref->elem);
break;
- case OBJECT_TYPE_DATA:
- ref->elem = tplg_elem_lookup(&tplg->pdata_list,
- ref->id, OBJECT_TYPE_DATA);
+ 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);
break;
@@ -195,7 +198,7 @@ int tplg_build_widgets(snd_tplg_t *tplg)
list_for_each(pos, base) {
elem = list_entry(pos, struct tplg_elem, list);
- if (!elem->widget || elem->type != OBJECT_TYPE_DAPM_WIDGET) {
+ if (!elem->widget || elem->type != SND_TPLG_TYPE_DAPM_WIDGET) {
SNDERR("error: invalid widget '%s'\n",
elem->id);
return -EINVAL;
@@ -223,7 +226,7 @@ int tplg_build_routes(snd_tplg_t *tplg)
list_for_each(pos, base) {
elem = list_entry(pos, struct tplg_elem, list);
- if (!elem->route || elem->type != OBJECT_TYPE_DAPM_GRAPH) {
+ if (!elem->route || elem->type != SND_TPLG_TYPE_DAPM_GRAPH) {
SNDERR("error: invalid route '%s'\n",
elem->id);
return -EINVAL;
@@ -240,7 +243,7 @@ int tplg_build_routes(snd_tplg_t *tplg)
}
if (!tplg_elem_lookup(&tplg->widget_list, route->sink,
- OBJECT_TYPE_DAPM_WIDGET)) {
+ SND_TPLG_TYPE_DAPM_WIDGET)) {
SNDERR("warning: undefined sink widget/stream '%s'\n",
route->sink);
}
@@ -248,9 +251,9 @@ int tplg_build_routes(snd_tplg_t *tplg)
/* validate control name */
if (strlen(route->control)) {
if (!tplg_elem_lookup(&tplg->mixer_list,
- route->control, OBJECT_TYPE_MIXER) &&
+ route->control, SND_TPLG_TYPE_MIXER) &&
!tplg_elem_lookup(&tplg->enum_list,
- route->control, OBJECT_TYPE_ENUM)) {
+ route->control, SND_TPLG_TYPE_ENUM)) {
SNDERR("warning: Undefined mixer/enum control '%s'\n",
route->control);
}
@@ -263,7 +266,7 @@ int tplg_build_routes(snd_tplg_t *tplg)
}
if (!tplg_elem_lookup(&tplg->widget_list, route->source,
- OBJECT_TYPE_DAPM_WIDGET)) {
+ SND_TPLG_TYPE_DAPM_WIDGET)) {
SNDERR("warning: Undefined source widget/stream '%s'\n",
route->source);
}
@@ -347,7 +350,7 @@ static int tplg_parse_routes(snd_tplg_t *tplg, snd_config_t *cfg)
list_add_tail(&elem->list, &tplg->route_list);
strcpy(elem->id, "line");
- elem->type = OBJECT_TYPE_DAPM_GRAPH;
+ elem->type = SND_TPLG_TYPE_DAPM_GRAPH;
elem->size = sizeof(*line);
line = calloc(1, sizeof(*line));
@@ -415,7 +418,7 @@ int tplg_parse_dapm_widget(snd_tplg_t *tplg,
const char *id, *val = NULL;
int widget_type, err;
- elem = tplg_elem_new_common(tplg, cfg, NULL, OBJECT_TYPE_DAPM_WIDGET);
+ elem = tplg_elem_new_common(tplg, cfg, NULL, SND_TPLG_TYPE_DAPM_WIDGET);
if (!elem)
return -ENOMEM;
@@ -547,7 +550,7 @@ int tplg_parse_dapm_widget(snd_tplg_t *tplg,
if (snd_config_get_string(n, &val) < 0)
return -EINVAL;
- tplg_ref_add(elem, OBJECT_TYPE_DATA, val);
+ tplg_ref_add(elem, SND_TPLG_TYPE_DATA, val);
tplg_dbg("\t%s: %s\n", id, val);
continue;
}
diff --git a/src/topology/data.c b/src/topology/data.c
index 090185174ce4..4ee1f8a15f95 100644
--- a/src/topology/data.c
+++ b/src/topology/data.c
@@ -268,7 +268,7 @@ int tplg_parse_data(snd_tplg_t *tplg, snd_config_t *cfg,
int err = 0;
struct tplg_elem *elem;
- elem = tplg_elem_new_common(tplg, cfg, NULL, OBJECT_TYPE_DATA);
+ elem = tplg_elem_new_common(tplg, cfg, NULL, SND_TPLG_TYPE_DATA);
if (!elem)
return -ENOMEM;
@@ -350,7 +350,7 @@ int tplg_copy_data(struct tplg_elem *elem, struct tplg_elem *ref)
priv_data_size = ref->data->size;
switch (elem->type) {
- case OBJECT_TYPE_MIXER:
+ case SND_TPLG_TYPE_MIXER:
elem->mixer_ctrl = realloc(elem->mixer_ctrl,
elem->size + priv_data_size);
if (!elem->mixer_ctrl)
@@ -358,7 +358,7 @@ int tplg_copy_data(struct tplg_elem *elem, struct tplg_elem *ref)
priv = &elem->mixer_ctrl->priv;
break;
- case OBJECT_TYPE_ENUM:
+ case SND_TPLG_TYPE_ENUM:
elem->enum_ctrl = realloc(elem->enum_ctrl,
elem->size + priv_data_size);
if (!elem->enum_ctrl)
@@ -366,7 +366,7 @@ int tplg_copy_data(struct tplg_elem *elem, struct tplg_elem *ref)
priv = &elem->enum_ctrl->priv;
break;
- case OBJECT_TYPE_BYTES:
+ case SND_TPLG_TYPE_BYTES:
elem->bytes_ext = realloc(elem->bytes_ext,
elem->size + priv_data_size);
if (!elem->bytes_ext)
@@ -375,7 +375,7 @@ int tplg_copy_data(struct tplg_elem *elem, struct tplg_elem *ref)
break;
- case OBJECT_TYPE_DAPM_WIDGET:
+ case SND_TPLG_TYPE_DAPM_WIDGET:
elem->widget = realloc(elem->widget,
elem->size + priv_data_size);
if (!elem->widget)
diff --git a/src/topology/elem.c b/src/topology/elem.c
index 7fee65332124..daabe75ebdd2 100644
--- a/src/topology/elem.c
+++ b/src/topology/elem.c
@@ -103,7 +103,7 @@ struct tplg_elem *tplg_elem_lookup(struct list_head *base, const char* id,
/* create a new common element and object */
struct tplg_elem* tplg_elem_new_common(snd_tplg_t *tplg,
- snd_config_t *cfg, const char *name, enum object_type type)
+ snd_config_t *cfg, const char *name, enum snd_tplg_type type)
{
struct tplg_elem *elem;
const char *id;
@@ -126,49 +126,49 @@ struct tplg_elem* tplg_elem_new_common(snd_tplg_t *tplg,
elem_copy_text(elem->id, name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN);
switch (type) {
- case OBJECT_TYPE_DATA:
+ case SND_TPLG_TYPE_DATA:
list_add_tail(&elem->list, &tplg->pdata_list);
break;
- case OBJECT_TYPE_TEXT:
+ case SND_TPLG_TYPE_TEXT:
list_add_tail(&elem->list, &tplg->text_list);
break;
- case OBJECT_TYPE_TLV:
+ case SND_TPLG_TYPE_TLV:
list_add_tail(&elem->list, &tplg->tlv_list);
elem->size = sizeof(struct snd_soc_tplg_ctl_tlv);
break;
- case OBJECT_TYPE_BYTES:
+ case SND_TPLG_TYPE_BYTES:
list_add_tail(&elem->list, &tplg->bytes_ext_list);
obj_size = sizeof(struct snd_soc_tplg_bytes_control);
break;
- case OBJECT_TYPE_ENUM:
+ case SND_TPLG_TYPE_ENUM:
list_add_tail(&elem->list, &tplg->enum_list);
obj_size = sizeof(struct snd_soc_tplg_enum_control);
break;
- case OBJECT_TYPE_MIXER:
+ case SND_TPLG_TYPE_MIXER:
list_add_tail(&elem->list, &tplg->mixer_list);
obj_size = sizeof(struct snd_soc_tplg_mixer_control);
break;
- case OBJECT_TYPE_DAPM_WIDGET:
+ case SND_TPLG_TYPE_DAPM_WIDGET:
list_add_tail(&elem->list, &tplg->widget_list);
obj_size = sizeof(struct snd_soc_tplg_dapm_widget);
break;
- case OBJECT_TYPE_STREAM_CONFIG:
+ case SND_TPLG_TYPE_STREAM_CONFIG:
list_add_tail(&elem->list, &tplg->pcm_config_list);
obj_size = sizeof(struct snd_soc_tplg_stream_config);
break;
- case OBJECT_TYPE_STREAM_CAPS:
+ case SND_TPLG_TYPE_STREAM_CAPS:
list_add_tail(&elem->list, &tplg->pcm_caps_list);
obj_size = sizeof(struct snd_soc_tplg_stream_caps);
break;
- case OBJECT_TYPE_PCM:
+ case SND_TPLG_TYPE_PCM:
list_add_tail(&elem->list, &tplg->pcm_list);
obj_size = sizeof(struct snd_soc_tplg_pcm_dai);
break;
- case OBJECT_TYPE_BE:
+ case SND_TPLG_TYPE_BE:
list_add_tail(&elem->list, &tplg->be_list);
obj_size = sizeof(struct snd_soc_tplg_pcm_dai);
break;
- case OBJECT_TYPE_CC:
+ case SND_TPLG_TYPE_CC:
list_add_tail(&elem->list, &tplg->cc_list);
obj_size = sizeof(struct snd_soc_tplg_pcm_dai);
break;
diff --git a/src/topology/parser.c b/src/topology/parser.c
index ed25bb88d446..3e3e2b35da83 100644
--- a/src/topology/parser.c
+++ b/src/topology/parser.c
@@ -241,15 +241,15 @@ static int tplg_build_integ(snd_tplg_t *tplg)
if (err < 0)
return err;
- err = tplg_build_pcm_dai(tplg, OBJECT_TYPE_PCM);
+ err = tplg_build_pcm_dai(tplg, SND_TPLG_TYPE_PCM);
if (err < 0)
return err;
- err = tplg_build_pcm_dai(tplg, OBJECT_TYPE_BE);
+ err = tplg_build_pcm_dai(tplg, SND_TPLG_TYPE_BE);
if (err < 0)
return err;
- err = tplg_build_pcm_dai(tplg, OBJECT_TYPE_CC);
+ err = tplg_build_pcm_dai(tplg, SND_TPLG_TYPE_CC);
if (err < 0)
return err;
diff --git a/src/topology/pcm.c b/src/topology/pcm.c
index deae47b771be..6e42aa18b99b 100644
--- a/src/topology/pcm.c
+++ b/src/topology/pcm.c
@@ -28,7 +28,7 @@ struct tplg_elem *lookup_pcm_dai_stream(struct list_head *base, const char* id)
list_for_each(pos, base) {
elem = list_entry(pos, struct tplg_elem, list);
- if (elem->type != OBJECT_TYPE_PCM)
+ if (elem->type != SND_TPLG_TYPE_PCM)
return NULL;
pcm_dai = elem->pcm;
@@ -74,13 +74,13 @@ static int tplg_build_pcm_cfg_caps(snd_tplg_t *tplg, struct tplg_elem *elem)
unsigned int i, j;
switch (elem->type) {
- case OBJECT_TYPE_PCM:
+ case SND_TPLG_TYPE_PCM:
pcm_dai = elem->pcm;
break;
- case OBJECT_TYPE_BE:
+ case SND_TPLG_TYPE_BE:
pcm_dai = elem->be;
break;
- case OBJECT_TYPE_CC:
+ case SND_TPLG_TYPE_CC:
pcm_dai = elem->cc;
break;
default:
@@ -91,7 +91,7 @@ static int tplg_build_pcm_cfg_caps(snd_tplg_t *tplg, struct tplg_elem *elem)
capconf = &pcm_dai->capconf[i];
ref_elem = tplg_elem_lookup(&tplg->pcm_caps_list,
- capconf->caps.name, OBJECT_TYPE_STREAM_CAPS);
+ capconf->caps.name, SND_TPLG_TYPE_STREAM_CAPS);
if (ref_elem != NULL)
copy_pcm_caps(elem->id, &capconf->caps, ref_elem);
@@ -99,7 +99,7 @@ static int tplg_build_pcm_cfg_caps(snd_tplg_t *tplg, struct tplg_elem *elem)
for (j = 0; j < capconf->num_configs; j++) {
ref_elem = tplg_elem_lookup(&tplg->pcm_config_list,
capconf->configs[j].name,
- OBJECT_TYPE_STREAM_CONFIG);
+ SND_TPLG_TYPE_STREAM_CONFIG);
if (ref_elem != NULL)
copy_pcm_config(elem->id,
@@ -118,13 +118,13 @@ int tplg_build_pcm_dai(snd_tplg_t *tplg, unsigned int type)
int err = 0;
switch (type) {
- case OBJECT_TYPE_PCM:
+ case SND_TPLG_TYPE_PCM:
base = &tplg->pcm_list;
break;
- case OBJECT_TYPE_BE:
+ case SND_TPLG_TYPE_BE:
base = &tplg->be_list;
break;
- case OBJECT_TYPE_CC:
+ case SND_TPLG_TYPE_CC:
base = &tplg->cc_list;
break;
default:
@@ -228,7 +228,7 @@ int tplg_parse_pcm_config(snd_tplg_t *tplg,
const char *id;
int err;
- elem = tplg_elem_new_common(tplg, cfg, NULL, OBJECT_TYPE_STREAM_CONFIG);
+ elem = tplg_elem_new_common(tplg, cfg, NULL, SND_TPLG_TYPE_STREAM_CONFIG);
if (!elem)
return -ENOMEM;
@@ -294,7 +294,7 @@ int tplg_parse_pcm_caps(snd_tplg_t *tplg,
char *s;
int err;
- elem = tplg_elem_new_common(tplg, cfg, NULL, OBJECT_TYPE_STREAM_CAPS);
+ elem = tplg_elem_new_common(tplg, cfg, NULL, SND_TPLG_TYPE_STREAM_CAPS);
if (!elem)
return -ENOMEM;
@@ -396,11 +396,11 @@ int tplg_parse_pcm_cap_cfg(snd_tplg_t *tplg, snd_config_t *cfg,
const char *id, *value;
int err, stream;
- if (elem->type == OBJECT_TYPE_PCM)
+ if (elem->type == SND_TPLG_TYPE_PCM)
pcm_dai = elem->pcm;
- else if (elem->type == OBJECT_TYPE_BE)
+ else if (elem->type == SND_TPLG_TYPE_BE)
pcm_dai = elem->be;
- else if (elem->type == OBJECT_TYPE_CC)
+ else if (elem->type == SND_TPLG_TYPE_CC)
pcm_dai = elem->cc;
else
return -EINVAL;
@@ -461,7 +461,7 @@ int tplg_parse_pcm(snd_tplg_t *tplg,
const char *id, *val = NULL;
int err;
- elem = tplg_elem_new_common(tplg, cfg, NULL, OBJECT_TYPE_PCM);
+ elem = tplg_elem_new_common(tplg, cfg, NULL, SND_TPLG_TYPE_PCM);
if (!elem)
return -ENOMEM;
@@ -524,7 +524,7 @@ int tplg_parse_be(snd_tplg_t *tplg,
const char *id, *val = NULL;
int err;
- elem = tplg_elem_new_common(tplg, cfg, NULL, OBJECT_TYPE_BE);
+ elem = tplg_elem_new_common(tplg, cfg, NULL, SND_TPLG_TYPE_BE);
if (!elem)
return -ENOMEM;
@@ -587,7 +587,7 @@ int tplg_parse_cc(snd_tplg_t *tplg,
const char *id, *val = NULL;
int err;
- elem = tplg_elem_new_common(tplg, cfg, NULL, OBJECT_TYPE_CC);
+ elem = tplg_elem_new_common(tplg, cfg, NULL, SND_TPLG_TYPE_CC);
if (!elem)
return -ENOMEM;
diff --git a/src/topology/text.c b/src/topology/text.c
index 7128056d5d34..0c6594a1307d 100644
--- a/src/topology/text.c
+++ b/src/topology/text.c
@@ -64,7 +64,7 @@ int tplg_parse_text(snd_tplg_t *tplg, snd_config_t *cfg,
int err = 0;
struct tplg_elem *elem;
- elem = tplg_elem_new_common(tplg, cfg, NULL, OBJECT_TYPE_TEXT);
+ elem = tplg_elem_new_common(tplg, cfg, NULL, SND_TPLG_TYPE_TEXT);
if (!elem)
return -ENOMEM;
diff --git a/src/topology/tplg_local.h b/src/topology/tplg_local.h
index ad38945056df..febc1772fd04 100644
--- a/src/topology/tplg_local.h
+++ b/src/topology/tplg_local.h
@@ -40,22 +40,22 @@
struct tplg_ref;
struct tplg_elem;
-/* internal topology object type not used by kernel */
-enum object_type {
- OBJECT_TYPE_TLV = 0,
- OBJECT_TYPE_MIXER,
- OBJECT_TYPE_ENUM,
- OBJECT_TYPE_TEXT,
- OBJECT_TYPE_DATA,
- OBJECT_TYPE_BYTES,
- OBJECT_TYPE_STREAM_CONFIG,
- OBJECT_TYPE_STREAM_CAPS,
- OBJECT_TYPE_PCM,
- OBJECT_TYPE_DAPM_WIDGET,
- OBJECT_TYPE_DAPM_GRAPH,
- OBJECT_TYPE_BE,
- OBJECT_TYPE_CC,
- OBJECT_TYPE_MANIFEST,
+/** Topology object types */
+enum snd_tplg_type {
+ SND_TPLG_TYPE_TLV = 0, /*!< TLV Data */
+ SND_TPLG_TYPE_MIXER, /*!< Mixer control*/
+ SND_TPLG_TYPE_ENUM, /*!< Enumerated control */
+ SND_TPLG_TYPE_TEXT, /*!< Text data */
+ SND_TPLG_TYPE_DATA, /*!< Private data */
+ SND_TPLG_TYPE_BYTES, /*!< Byte control */
+ SND_TPLG_TYPE_STREAM_CONFIG, /*!< PCM Stream configuration */
+ SND_TPLG_TYPE_STREAM_CAPS, /*!< PCM Stream capabilities */
+ SND_TPLG_TYPE_PCM, /*!< PCM stream device */
+ SND_TPLG_TYPE_DAPM_WIDGET, /*!< DAPM widget */
+ SND_TPLG_TYPE_DAPM_GRAPH, /*!< DAPM graph elements */
+ SND_TPLG_TYPE_BE, /*!< BE DAI link */
+ SND_TPLG_TYPE_CC, /*!< Hostless codec <-> codec link */
+ SND_TPLG_TYPE_MANIFEST, /*!< Topology manifest */
};
struct snd_tplg {
@@ -114,7 +114,7 @@ struct tplg_elem {
char texts[SND_SOC_TPLG_NUM_TEXTS][SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
int index;
- enum object_type type;
+ enum snd_tplg_type type;
int size; /* total size of this object inc pdata and ref objects */
int compound_elem; /* dont write this element as individual elem */
@@ -217,7 +217,7 @@ struct tplg_elem *tplg_elem_lookup(struct list_head *base,
const char* id,
unsigned int type);
struct tplg_elem* tplg_elem_new_common(snd_tplg_t *tplg,
- snd_config_t *cfg, const char *name, enum object_type type);
+ snd_config_t *cfg, const char *name, enum snd_tplg_type type);
static inline void elem_copy_text(char *dest, const char *src, int len)
{
--
2.5.3

View File

@ -0,0 +1,47 @@
From ab9633d581110a5da08bd2d2c7c070f3862fe9af Mon Sep 17 00:00:00 2001
From: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Date: Tue, 11 Aug 2015 18:23:15 +0100
Subject: [PATCH] core: add convenience macros to local.h
Move ARRAY_SIZE() from tplg_local.h to local.h and add container_of()
macro to local.h. Both macros are generic but are initially used by
topology.
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
include/local.h | 7 +++++++
src/topology/tplg_local.h | 1 -
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/include/local.h b/include/local.h
index 660081638a1c..b429f5d0094c 100644
--- a/include/local.h
+++ b/include/local.h
@@ -350,4 +350,11 @@ int snd_config_search_alias_hooks(snd_config_t *config,
int _snd_conf_generic_id(const char *id);
+/* convenience macros */
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
+
+#define container_of(ptr, type, member) ({ \
+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
+ (type *)( (char *)__mptr - offsetof(type,member) );})
+
#endif
diff --git a/src/topology/tplg_local.h b/src/topology/tplg_local.h
index febc1772fd04..3982cc70dce5 100644
--- a/src/topology/tplg_local.h
+++ b/src/topology/tplg_local.h
@@ -32,7 +32,6 @@
#define MAX_FILE 256
#define TPLG_MAX_PRIV_SIZE (1024 * 128)
#define ALSA_TPLG_DIR ALSA_CONFIG_DIR "/topology"
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
/** The name of the environment variable containing the tplg directory */
#define ALSA_CONFIG_TPLG_VAR "ALSA_CONFIG_TPLG"
--
2.5.3

View File

@ -0,0 +1,248 @@
From 1b148ef590f94fc30b4c814c1ce2bc31621af840 Mon Sep 17 00:00:00 2001
From: Mengdong Lin <mengdong.lin@intel.com>
Date: Tue, 11 Aug 2015 18:23:16 +0100
Subject: [PATCH] topology: Add C templates structure for building topology
from C programs
Define structures that can be used by applications to directly build topology
data instead of using text files. The application will build up the topology
data by populating the template structures for each object type and then
registering the template with the topology core.
Signed-off-by: Mengdong Lin <mengdong.lin@intel.com>
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
include/topology.h | 176 ++++++++++++++++++++++++++++++++++++++++++++++
src/topology/tplg_local.h | 18 -----
2 files changed, 176 insertions(+), 18 deletions(-)
diff --git a/include/topology.h b/include/topology.h
index 0cb2d79e5574..aee43de6e009 100644
--- a/include/topology.h
+++ b/include/topology.h
@@ -456,9 +456,30 @@ extern "C" {
*
*/
+/** Maximum number of channels supported in one control */
+#define SND_TPLG_MAX_CHAN 8
+
/** Topology context */
typedef struct snd_tplg snd_tplg_t;
+/** Topology object types */
+enum snd_tplg_type {
+ SND_TPLG_TYPE_TLV = 0, /*!< TLV Data */
+ SND_TPLG_TYPE_MIXER, /*!< Mixer control*/
+ SND_TPLG_TYPE_ENUM, /*!< Enumerated control */
+ SND_TPLG_TYPE_TEXT, /*!< Text data */
+ SND_TPLG_TYPE_DATA, /*!< Private data */
+ SND_TPLG_TYPE_BYTES, /*!< Byte control */
+ SND_TPLG_TYPE_STREAM_CONFIG, /*!< PCM Stream configuration */
+ SND_TPLG_TYPE_STREAM_CAPS, /*!< PCM Stream capabilities */
+ SND_TPLG_TYPE_PCM, /*!< PCM stream device */
+ SND_TPLG_TYPE_DAPM_WIDGET, /*!< DAPM widget */
+ SND_TPLG_TYPE_DAPM_GRAPH, /*!< DAPM graph elements */
+ SND_TPLG_TYPE_BE, /*!< BE DAI link */
+ SND_TPLG_TYPE_CC, /*!< Hostless codec <-> codec link */
+ SND_TPLG_TYPE_MANIFEST, /*!< Topology manifest */
+};
+
/**
* \brief Create a new topology parser instance.
* \return New topology parser instance
@@ -488,6 +509,161 @@ int snd_tplg_build_file(snd_tplg_t *tplg, const char *infile,
*/
void snd_tplg_verbose(snd_tplg_t *tplg, int verbose);
+/** \struct snd_tplg_tlv_template
+ * \brief Template type for all TLV objects.
+ */
+struct snd_tplg_tlv_template {
+ int type; /*!< TLV type SNDRV_CTL_TLVT_ */
+};
+
+/** \struct snd_tplg_tlv_dbscale_template
+ * \brief Template type for TLV Scale objects.
+ */
+struct snd_tplg_tlv_dbscale_template {
+ struct snd_tplg_tlv_template hdr; /*!< TLV type header */
+ int min; /*!< dB minimum value in 0.1dB */
+ int step; /*!< dB step size in 0.1dB */
+ int mute; /*!< is min dB value mute ? */
+};
+
+/** \struct snd_tplg_channel_template
+ * \brief Template type for single channel mapping.
+ */
+struct snd_tplg_channel_elem {
+ int size; /*!< size in bytes of this structure */
+ int reg; /*!< channel control register */
+ int shift; /*!< channel shift for control bits */
+ int id; /*!< ID maps to Left, Right, LFE etc */
+};
+
+/** \struct snd_tplg_channel_map_template
+ * \brief Template type for channel mapping.
+ */
+struct snd_tplg_channel_map_template {
+ int num_channels; /*!< number of channel mappings */
+ struct snd_tplg_channel_elem channel[SND_TPLG_MAX_CHAN]; /*!< mapping */
+};
+
+/** \struct snd_tplg_pdata_template
+ * \brief Template type for private data objects.
+ */
+struct snd_tplg_pdata_template {
+ unsigned int length; /*!< data length */
+ const void *data; /*!< data */
+};
+
+/** \struct snd_tplg_io_ops_template
+ * \brief Template type for object operations mapping.
+ */
+struct snd_tplg_io_ops_template {
+ int get; /*!< get callback ID */
+ int put; /*!< put callback ID */
+ int info; /*!< info callback ID */
+};
+
+/** \struct snd_tplg_ctl_template
+ * \brief Template type for control objects.
+ */
+struct snd_tplg_ctl_template {
+ int type; /*!< Control type */
+ const char *name; /*!< Control name */
+ int access; /*!< Control access */
+ struct snd_tplg_io_ops_template ops; /*!< operations */
+ struct snd_tplg_tlv_template *tlv; /*!< non NULL means we have TLV data */
+};
+
+/** \struct snd_tplg_mixer_template
+ * \brief Template type for mixer control objects.
+ */
+struct snd_tplg_mixer_template {
+ struct snd_tplg_ctl_template hdr; /*!< control type header */
+ struct snd_tplg_channel_map_template *map; /*!< channel map */
+ int min; /*!< min value for mixer */
+ int max; /*!< max value for mixer */
+ int platform_max; /*!< max value for platform control */
+ int invert; /*!< whether controls bits are inverted */
+ struct snd_soc_tplg_private *priv; /*!< control private data */
+};
+
+/** \struct snd_tplg_enum_template
+ * \brief Template type for enumerated control objects.
+ */
+struct snd_tplg_enum_template {
+ struct snd_tplg_ctl_template hdr; /*!< control type header */
+ struct snd_tplg_channel_map_template *map; /*!< channel map */
+ int items; /*!< number of enumerated items in control */
+ int mask; /*!< register mask size */
+ const char **texts; /*!< control text items */
+ const int **values; /*!< control value items */
+ struct snd_soc_tplg_private *priv; /*!< control private data */
+};
+
+/** \struct snd_tplg_bytes_template
+ * \brief Template type for TLV Scale objects.
+ */
+struct snd_tplg_bytes_template {
+ struct snd_tplg_ctl_template hdr; /*!< control type header */
+ int max; /*!< max byte control value */
+ int mask; /*!< byte control mask */
+ int base; /*!< base register */
+ int num_regs; /*!< number of registers */
+ struct snd_tplg_io_ops_template ext_ops; /*!< ops mapping */
+ struct snd_soc_tplg_private *priv; /*!< control private data */
+};
+
+/** \struct snd_tplg_graph_elem
+ * \brief Template type for single DAPM graph element.
+ */
+struct snd_tplg_graph_elem {
+ const char *src; /*!< source widget name */
+ const char *ctl; /*!< control name or NULL if no control */
+ const char *sink; /*!< sink widget name */
+};
+
+/** \struct snd_tplg_graph_template
+ * \brief Template type for array of DAPM graph elements.
+ */
+struct snd_tplg_graph_template {
+ int count; /*!< Number of graph elements */
+ struct snd_tplg_graph_elem elem[0]; /*!< graph elements */
+};
+
+/** \struct snd_tplg_widget_template
+ * \brief Template type for DAPM widget objects.
+ */
+struct snd_tplg_widget_template {
+ int id; /*!< SND_SOC_DAPM_CTL */
+ const char *name; /*!< widget name */
+ const char *sname; /*!< stream name (certain widgets only) */
+ int reg; /*!< negative reg = no direct dapm */
+ int shift; /*!< bits to shift */
+ int mask; /*!< non-shifted mask */
+ int subseq; /*!< sort within widget type */
+ unsigned int invert; /*!< invert the power bit */
+ unsigned int ignore_suspend; /*!< kept enabled over suspend */
+ unsigned short event_flags; /*!< PM event sequence flags */
+ unsigned short event_type; /*!< PM event sequence type */
+ struct snd_soc_tplg_private *priv; /*!< widget private data */
+ int num_ctls; /*!< Number of controls used by widget */
+ struct snd_tplg_ctl_template *ctl[0]; /*!< array of widget controls */
+};
+
+/** \struct snd_tplg_obj_template
+ * \brief Generic Template Object
+ */
+typedef struct snd_tplg_obj_template {
+ enum snd_tplg_type type; /*!< template object type */
+ int index; /*!< group index for object */
+ int version; /*!< optional vendor specific version details */
+ int vendor_type; /*!< optional vendor specific type info */
+ union {
+ struct snd_tplg_widget_template *widget; /*!< DAPM widget */
+ struct snd_tplg_mixer_template *mixer; /*!< Mixer control */
+ struct snd_tplg_bytes_template *bytes_ctl; /*!< Bytes control */
+ struct snd_tplg_enum_template *enum_ctl; /*!< Enum control */
+ struct snd_tplg_graph_template *graph; /*!< Graph elements */
+ };
+} snd_tplg_obj_template_t;
/* \} */
#ifdef __cplusplus
diff --git a/src/topology/tplg_local.h b/src/topology/tplg_local.h
index 3982cc70dce5..ec6304599538 100644
--- a/src/topology/tplg_local.h
+++ b/src/topology/tplg_local.h
@@ -39,24 +39,6 @@
struct tplg_ref;
struct tplg_elem;
-/** Topology object types */
-enum snd_tplg_type {
- SND_TPLG_TYPE_TLV = 0, /*!< TLV Data */
- SND_TPLG_TYPE_MIXER, /*!< Mixer control*/
- SND_TPLG_TYPE_ENUM, /*!< Enumerated control */
- SND_TPLG_TYPE_TEXT, /*!< Text data */
- SND_TPLG_TYPE_DATA, /*!< Private data */
- SND_TPLG_TYPE_BYTES, /*!< Byte control */
- SND_TPLG_TYPE_STREAM_CONFIG, /*!< PCM Stream configuration */
- SND_TPLG_TYPE_STREAM_CAPS, /*!< PCM Stream capabilities */
- SND_TPLG_TYPE_PCM, /*!< PCM stream device */
- SND_TPLG_TYPE_DAPM_WIDGET, /*!< DAPM widget */
- SND_TPLG_TYPE_DAPM_GRAPH, /*!< DAPM graph elements */
- SND_TPLG_TYPE_BE, /*!< BE DAI link */
- SND_TPLG_TYPE_CC, /*!< Hostless codec <-> codec link */
- SND_TPLG_TYPE_MANIFEST, /*!< Topology manifest */
-};
-
struct snd_tplg {
/* opaque vendor data */
--
2.5.3

View File

@ -0,0 +1,732 @@
From 5b518c91594d3b0c8847a87d9b65877f74c7a87b Mon Sep 17 00:00:00 2001
From: Mengdong Lin <mengdong.lin@intel.com>
Date: Tue, 11 Aug 2015 18:23:17 +0100
Subject: [PATCH] topology: A API calls to directly build topology data from
templates
Add some new API calls so that applications can directly build topology data
using template structures.
Signed-off-by: Mengdong Lin <mengdong.lin@intel.com>
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
include/topology.h | 26 +++++
src/topology/ctl.c | 292 ++++++++++++++++++++++++++++++++++++++++++++++
src/topology/dapm.c | 183 ++++++++++++++++++++++++++---
src/topology/elem.c | 17 +++
src/topology/parser.c | 59 +++++++++-
src/topology/tplg_local.h | 14 +++
6 files changed, 573 insertions(+), 18 deletions(-)
diff --git a/include/topology.h b/include/topology.h
index aee43de6e009..6ff8c5fb4609 100644
--- a/include/topology.h
+++ b/include/topology.h
@@ -664,6 +664,32 @@ typedef struct snd_tplg_obj_template {
struct snd_tplg_graph_template *graph; /*!< Graph elements */
};
} snd_tplg_obj_template_t;
+
+/**
+ * \brief Register topology template object.
+ * \param tplg Topology instance.
+ * \param t Template object.
+ * \return Zero on success, otherwise a negative error code
+ */
+int snd_tplg_add_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t);
+
+/**
+ * \brief Build all registered topology data into binary file.
+ * \param tplg Topology instance.
+ * \param outfile Binary topology output file.
+ * \return Zero on success, otherwise a negative error code
+ */
+int snd_tplg_build(snd_tplg_t *tplg, const char *outfile);
+
+/**
+ * \brief Attach private data to topology manifest.
+ * \param tplg Topology instance.
+ * \param data Private data.
+ * \param len Length of data in bytes.
+ * \return Zero on success, otherwise a negative error code
+ */
+int snd_tplg_set_manifest_data(snd_tplg_t *tplg, const void *data, int len);
+
/* \} */
#ifdef __cplusplus
diff --git a/src/topology/ctl.c b/src/topology/ctl.c
index 35f684ba8067..68c4ce5803d1 100644
--- a/src/topology/ctl.c
+++ b/src/topology/ctl.c
@@ -19,6 +19,8 @@
#include "list.h"
#include "tplg_local.h"
+#define ENUM_VAL_SIZE (SNDRV_CTL_ELEM_ID_NAME_MAXLEN >> 2)
+
/* copy referenced TLV to the mixer control */
static int copy_tlv(struct tplg_elem *elem, struct tplg_elem *ref)
{
@@ -606,3 +608,293 @@ int tplg_parse_control_mixer(snd_tplg_t *tplg,
return 0;
}
+
+static int init_ctl_hdr(struct snd_soc_tplg_ctl_hdr *hdr,
+ struct snd_tplg_ctl_template *t)
+{
+ hdr->size = sizeof(struct snd_soc_tplg_ctl_hdr);
+ hdr->type = t->type;
+
+ elem_copy_text(hdr->name, t->name,
+ SNDRV_CTL_ELEM_ID_NAME_MAXLEN);
+
+ /* clean up access flag */
+ if (t->access == 0)
+ t->access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
+ t->access &= (SNDRV_CTL_ELEM_ACCESS_READWRITE |
+ SNDRV_CTL_ELEM_ACCESS_VOLATILE |
+ SNDRV_CTL_ELEM_ACCESS_INACTIVE |
+ SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE |
+ SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND |
+ SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK);
+
+ hdr->access = t->access;
+ hdr->ops.get = t->ops.get;
+ hdr->ops.put = t->ops.put;
+ hdr->ops.info = t->ops.info;
+
+ /* TLV */
+ if (hdr->access & SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE
+ && !(hdr->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK)) {
+
+ struct snd_tplg_tlv_template *tlvt = t->tlv;
+ struct snd_soc_tplg_ctl_tlv *tlv = &hdr->tlv;
+ struct snd_tplg_tlv_dbscale_template *scalet;
+ struct snd_soc_tplg_tlv_dbscale *scale;
+
+ if (!tlvt) {
+ SNDERR("error: missing TLV data\n");
+ return -EINVAL;
+ }
+
+ tlv->size = sizeof(struct snd_soc_tplg_ctl_tlv);
+ tlv->type = tlvt->type;
+
+ switch (tlvt->type) {
+ case SNDRV_CTL_TLVT_DB_SCALE:
+ scalet = container_of(tlvt,
+ struct snd_tplg_tlv_dbscale_template, hdr);
+ scale = &tlv->scale;
+ scale->min = scalet->min;
+ scale->step = scalet->step;
+ scale->mute = scalet->mute;
+ break;
+
+ /* TODO: add support for other TLV types */
+ default:
+ SNDERR("error: unsupported TLV type %d\n", tlv->type);
+ break;
+ }
+ }
+
+ return 0;
+}
+
+int tplg_add_mixer(snd_tplg_t *tplg, struct snd_tplg_mixer_template *mixer,
+ struct tplg_elem **e)
+{
+ struct snd_soc_tplg_private *priv = mixer->priv;
+ struct snd_soc_tplg_mixer_control *mc;
+ struct tplg_elem *elem;
+ int ret, i;
+
+ tplg_dbg(" Control Mixer: %s\n", mixer->hdr.name);
+
+ if (mixer->hdr.type != SND_SOC_TPLG_TYPE_MIXER) {
+ SNDERR("error: invalid mixer type %d\n", mixer->hdr.type);
+ return -EINVAL;
+ }
+
+ elem = tplg_elem_new_common(tplg, NULL, mixer->hdr.name,
+ SND_TPLG_TYPE_MIXER);
+ if (!elem)
+ return -ENOMEM;
+
+ /* init new mixer */
+ mc = elem->mixer_ctrl;
+ mc->size = elem->size;
+ ret = init_ctl_hdr(&mc->hdr, &mixer->hdr);
+ if (ret < 0) {
+ tplg_elem_free(elem);
+ return ret;
+ }
+
+ mc->min = mixer->min;
+ mc->max = mixer->max;
+ mc->platform_max = mixer->platform_max;
+ mc->invert = mixer->invert;
+
+ /* set channel reg to default state */
+ for (i = 0; i < SND_SOC_TPLG_MAX_CHAN; i++)
+ mc->channel[i].reg = -1;
+
+ if (mixer->map)
+ mc->num_channels = mixer->map->num_channels;
+ for (i = 0; i < mc->num_channels; i++) {
+ struct snd_tplg_channel_elem *channel = &mixer->map->channel[i];
+
+ mc->channel[i].size = channel->size;
+ mc->channel[i].reg = channel->reg;
+ mc->channel[i].shift = channel->shift;
+ mc->channel[i].id = channel->id;
+ }
+
+ /* priv data */
+ if (priv) {
+ mc = realloc(mc, elem->size + priv->size);
+ if (!mc) {
+ tplg_elem_free(elem);
+ return -ENOMEM;
+ }
+
+ elem->mixer_ctrl = mc;
+ elem->size += priv->size;
+ mc->priv.size = priv->size;
+ memcpy(mc->priv.data, priv->data, priv->size);
+ }
+
+ if (e)
+ *e = elem;
+ return 0;
+}
+
+int tplg_add_enum(snd_tplg_t *tplg, struct snd_tplg_enum_template *enum_ctl,
+ struct tplg_elem **e)
+{
+ struct snd_soc_tplg_enum_control *ec;
+ struct tplg_elem *elem;
+ int ret, i;
+
+ tplg_dbg(" Control Enum: %s\n", enum_ctl->hdr.name);
+
+ if (enum_ctl->hdr.type != SND_SOC_TPLG_TYPE_ENUM) {
+ SNDERR("error: invalid enum type %d\n", enum_ctl->hdr.type);
+ return -EINVAL;
+ }
+
+ elem = tplg_elem_new_common(tplg, NULL, enum_ctl->hdr.name,
+ SND_TPLG_TYPE_ENUM);
+ if (!elem)
+ return -ENOMEM;
+
+ ec = elem->enum_ctrl;
+ ec->size = elem->size;
+ ret = init_ctl_hdr(&ec->hdr, &enum_ctl->hdr);
+ if (ret < 0) {
+ tplg_elem_free(elem);
+ return ret;
+ }
+
+ ec->items = enum_ctl->items;
+ if (ec->items > SND_SOC_TPLG_NUM_TEXTS)
+ ec->items = SND_SOC_TPLG_NUM_TEXTS;
+
+ ec->mask = enum_ctl->mask;
+ ec->count = enum_ctl->items;
+
+ if (enum_ctl->texts != NULL) {
+ for (i = 0; i < ec->items; i++) {
+ if (enum_ctl->texts[i] != NULL)
+ strncpy(ec->texts[i], enum_ctl->texts[i],
+ SNDRV_CTL_ELEM_ID_NAME_MAXLEN);
+ }
+ }
+
+ if (enum_ctl->values != NULL) {
+ for (i = 0; i < ec->items; i++) {
+ if (enum_ctl->values[i])
+ continue;
+
+ memcpy(&ec->values[i * sizeof(int) * ENUM_VAL_SIZE],
+ enum_ctl->values[i],
+ sizeof(int) * ENUM_VAL_SIZE);
+ }
+ }
+
+ if (enum_ctl->priv != NULL) {
+ ec = realloc(ec,
+ elem->size + enum_ctl->priv->size);
+ if (!ec) {
+ tplg_elem_free(elem);
+ return -ENOMEM;
+ }
+
+ elem->enum_ctrl = ec;
+ elem->size += enum_ctl->priv->size;
+
+ memcpy(ec->priv.data, enum_ctl->priv->data,
+ enum_ctl->priv->size);
+
+ ec->priv.size = enum_ctl->priv->size;
+ }
+
+ if (e)
+ *e = elem;
+ return 0;
+}
+
+int tplg_add_bytes(snd_tplg_t *tplg, struct snd_tplg_bytes_template *bytes_ctl,
+ struct tplg_elem **e)
+{
+ struct snd_soc_tplg_bytes_control *be;
+ struct tplg_elem *elem;
+ int ret;
+
+ tplg_dbg(" Control Bytes: %s\n", bytes_ctl->hdr.name);
+
+ if (bytes_ctl->hdr.type != SND_SOC_TPLG_TYPE_BYTES) {
+ SNDERR("error: invalid bytes type %d\n", bytes_ctl->hdr.type);
+ return -EINVAL;
+ }
+
+ elem = tplg_elem_new_common(tplg, NULL, bytes_ctl->hdr.name,
+ SND_TPLG_TYPE_BYTES);
+ if (!elem)
+ return -ENOMEM;
+
+ be = elem->bytes_ext;
+ be->size = elem->size;
+ ret = init_ctl_hdr(&be->hdr, &bytes_ctl->hdr);
+ if (ret < 0) {
+ tplg_elem_free(elem);
+ return ret;
+ }
+
+ be->max = bytes_ctl->max;
+ be->mask = bytes_ctl->mask;
+ be->base = bytes_ctl->base;
+ be->num_regs = bytes_ctl->num_regs;
+ be->ext_ops.put = bytes_ctl->ext_ops.put;
+ be->ext_ops.get = bytes_ctl->ext_ops.get;
+
+ if (bytes_ctl->priv != NULL) {
+ be = realloc(be,
+ elem->size + bytes_ctl->priv->size);
+ if (!be) {
+ tplg_elem_free(elem);
+ return -ENOMEM;
+ }
+ elem->bytes_ext = be;
+ elem->size += bytes_ctl->priv->size;
+
+ memcpy(be->priv.data, bytes_ctl->priv->data,
+ bytes_ctl->priv->size);
+
+ be->priv.size = bytes_ctl->priv->size;
+ }
+
+ /* check on TLV bytes control */
+ if (be->hdr.access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
+ if (be->hdr.access & SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE
+ != SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE) {
+ SNDERR("error: Invalid TLV bytes control access 0x%x\n",
+ be->hdr.access);
+ tplg_elem_free(elem);
+ return -EINVAL;
+ }
+
+ if (!be->max) {
+ tplg_elem_free(elem);
+ return -EINVAL;
+ }
+ }
+
+ if (e)
+ *e = elem;
+ return 0;
+}
+
+int tplg_add_mixer_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t)
+{
+ return tplg_add_mixer(tplg, t->mixer, NULL);
+}
+
+int tplg_add_enum_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t)
+{
+ return tplg_add_enum(tplg, t->enum_ctl, NULL);
+}
+
+int tplg_add_bytes_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t)
+{
+ return tplg_add_bytes(tplg, t->bytes_ctl, NULL);
+}
diff --git a/src/topology/dapm.c b/src/topology/dapm.c
index 3458aa77838b..14969eedeea0 100644
--- a/src/topology/dapm.c
+++ b/src/topology/dapm.c
@@ -142,8 +142,6 @@ static int tplg_build_widget(snd_tplg_t *tplg,
list_for_each(pos, base) {
ref = list_entry(pos, struct tplg_ref, list);
- if (ref->id == NULL || ref->elem)
- continue;
switch (ref->type) {
case SND_TPLG_TYPE_MIXER:
@@ -162,6 +160,14 @@ static int tplg_build_widget(snd_tplg_t *tplg,
err = copy_dapm_control(elem, ref->elem);
break;
+ case SND_TPLG_TYPE_BYTES:
+ if (!ref->elem)
+ ref->elem = tplg_elem_lookup(&tplg->bytes_ext_list,
+ ref->id, SND_TPLG_TYPE_BYTES);
+ if (ref->elem)
+ err = copy_dapm_control(elem, ref->elem);
+ break;
+
case SND_TPLG_TYPE_DATA:
if (!ref->elem)
ref->elem = tplg_elem_lookup(&tplg->pdata_list,
@@ -278,6 +284,30 @@ int tplg_build_routes(snd_tplg_t *tplg)
return 0;
}
+struct tplg_elem* tplg_elem_new_route(snd_tplg_t *tplg)
+{
+ struct tplg_elem *elem;
+ struct snd_soc_tplg_dapm_graph_elem *line;
+
+ elem = tplg_elem_new();
+ if (!elem)
+ return NULL;
+
+ list_add_tail(&elem->list, &tplg->route_list);
+ strcpy(elem->id, "line");
+ elem->type = SND_TPLG_TYPE_DAPM_GRAPH;
+ elem->size = sizeof(*line);
+
+ line = calloc(1, sizeof(*line));
+ if (!line) {
+ tplg_elem_free(elem);
+ return NULL;
+ }
+ elem->route = line;
+
+ return elem;
+}
+
#define LINE_SIZE 1024
/* line is defined as '"source, control, sink"' */
@@ -334,7 +364,7 @@ static int tplg_parse_routes(snd_tplg_t *tplg, snd_config_t *cfg)
snd_config_iterator_t i, next;
snd_config_t *n;
struct tplg_elem *elem;
- struct snd_soc_tplg_dapm_graph_elem *line = NULL;
+ struct snd_soc_tplg_dapm_graph_elem *line;
int err;
snd_config_for_each(i, next, cfg) {
@@ -344,20 +374,11 @@ static int tplg_parse_routes(snd_tplg_t *tplg, snd_config_t *cfg)
if (snd_config_get_string(n, &val) < 0)
continue;
- elem = tplg_elem_new();
+ elem = tplg_elem_new_route(tplg);
if (!elem)
return -ENOMEM;
- list_add_tail(&elem->list, &tplg->route_list);
- strcpy(elem->id, "line");
- elem->type = SND_TPLG_TYPE_DAPM_GRAPH;
- elem->size = sizeof(*line);
-
- line = calloc(1, sizeof(*line));
- if (!line)
- return -ENOMEM;
-
- elem->route = line;
+ line = elem->route;
err = tplg_parse_line(val, line);
if (err < 0)
@@ -558,3 +579,137 @@ int tplg_parse_dapm_widget(snd_tplg_t *tplg,
return 0;
}
+
+int tplg_add_route(snd_tplg_t *tplg, struct snd_tplg_graph_elem *t)
+{
+ struct tplg_elem *elem;
+ struct snd_soc_tplg_dapm_graph_elem *line;
+
+ if (!t->src || !t->sink)
+ return -EINVAL;
+
+ elem = tplg_elem_new_route(tplg);
+ if (!elem)
+ return -ENOMEM;
+
+ line = elem->route;
+ elem_copy_text(line->source, t->src, SNDRV_CTL_ELEM_ID_NAME_MAXLEN);
+ if (t->ctl)
+ elem_copy_text(line->control, t->ctl,
+ SNDRV_CTL_ELEM_ID_NAME_MAXLEN);
+ elem_copy_text(line->sink, t->sink, SNDRV_CTL_ELEM_ID_NAME_MAXLEN);
+
+ return 0;
+}
+
+int tplg_add_graph_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t)
+{
+ struct snd_tplg_graph_template *gt = t->graph;
+ int i, ret;
+
+ for (i = 0; i < gt->count; i++) {
+ ret = tplg_add_route(tplg, gt->elem + i);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+int tplg_add_widget_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t)
+{
+ struct snd_tplg_widget_template *wt = t->widget;
+ struct snd_soc_tplg_dapm_widget *w;
+ struct tplg_elem *elem;
+ int i, ret = 0;
+
+ tplg_dbg("Widget: %s\n", wt->name);
+
+ elem = tplg_elem_new_common(tplg, NULL, wt->name,
+ SND_TPLG_TYPE_DAPM_WIDGET);
+ if (!elem)
+ return -ENOMEM;
+
+ /* init new widget */
+ w = elem->widget;
+ w->size = elem->size;
+
+ w->id = wt->id;
+ elem_copy_text(w->name, wt->name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN);
+ if (wt->sname)
+ elem_copy_text(w->sname, wt->sname, SNDRV_CTL_ELEM_ID_NAME_MAXLEN);
+ w->reg = wt->reg;
+ w->shift = wt->shift;
+ w->mask = wt->mask;
+ w->subseq = wt->subseq;
+ w->invert = wt->invert;
+ w->ignore_suspend = wt->ignore_suspend;
+ w->event_flags = wt->event_flags;
+ w->event_type = wt->event_type;
+
+ if (wt->priv != NULL) {
+ w = realloc(w,
+ elem->size + wt->priv->size);
+ if (!w) {
+ tplg_elem_free(elem);
+ return -ENOMEM;
+ }
+
+ elem->widget = w;
+ elem->size += wt->priv->size;
+
+ memcpy(w->priv.data, wt->priv->data,
+ wt->priv->size);
+ w->priv.size = wt->priv->size;
+ }
+
+ /* add controls to the widget's reference list */
+ for (i = 0 ; i < wt->num_ctls; i++) {
+ struct snd_tplg_ctl_template *ct = wt->ctl[i];
+ struct tplg_elem *elem_ctl;
+ struct snd_tplg_mixer_template *mt;
+ struct snd_tplg_bytes_template *bt;
+ struct snd_tplg_enum_template *et;
+
+ if (!ct) {
+ tplg_elem_free(elem);
+ return -EINVAL;
+ }
+
+ switch (ct->type) {
+ case SND_SOC_TPLG_TYPE_MIXER:
+ mt = container_of(ct, struct snd_tplg_mixer_template, hdr);
+ ret = tplg_add_mixer(tplg, mt, &elem_ctl);
+ break;
+
+ case SND_SOC_TPLG_TYPE_BYTES:
+ bt = container_of(ct, struct snd_tplg_bytes_template, hdr);
+ ret = tplg_add_bytes(tplg, bt, &elem_ctl);
+ break;
+
+ case SND_SOC_TPLG_TYPE_ENUM:
+ et = container_of(ct, struct snd_tplg_enum_template, hdr);
+ ret = tplg_add_enum(tplg, et, &elem_ctl);
+ break;
+
+ default:
+ SNDERR("error: widget %s: invalid type %d for ctl %d\n",
+ wt->name, ct->type, i);
+ ret = -EINVAL;
+ break;
+ }
+
+ if (ret < 0) {
+ tplg_elem_free(elem);
+ return ret;
+ }
+
+ ret = tplg_ref_add_elem(elem, elem_ctl);
+ if (ret < 0) {
+ tplg_elem_free(elem);
+ return ret;
+ }
+ }
+
+ return 0;
+}
diff --git a/src/topology/elem.c b/src/topology/elem.c
index daabe75ebdd2..d7842361e444 100644
--- a/src/topology/elem.c
+++ b/src/topology/elem.c
@@ -35,6 +35,23 @@ int tplg_ref_add(struct tplg_elem *elem, int type, const char* id)
return 0;
}
+/* directly add a reference elem */
+int tplg_ref_add_elem(struct tplg_elem *elem, struct tplg_elem *elem_ref)
+{
+ struct tplg_ref *ref;
+
+ ref = calloc(1, sizeof(*ref));
+ if (!ref)
+ return -ENOMEM;
+
+ ref->type = elem_ref->type;
+ ref->elem = elem_ref;
+ elem_copy_text(ref->id, elem_ref->id, SNDRV_CTL_ELEM_ID_NAME_MAXLEN);
+
+ list_add_tail(&ref->list, &elem->ref_list);
+ return 0;
+}
+
void tplg_ref_free_list(struct list_head *base)
{
struct list_head *pos, *npos;
diff --git a/src/topology/parser.c b/src/topology/parser.c
index 3e3e2b35da83..ca7de0689cea 100644
--- a/src/topology/parser.c
+++ b/src/topology/parser.c
@@ -266,11 +266,8 @@ int snd_tplg_build_file(snd_tplg_t *tplg, const char *infile,
snd_config_t *cfg = NULL;
int err = 0;
- /* delete any old output files */
- unlink(outfile);
-
tplg->out_fd =
- open(outfile, O_RDWR | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO);
+ open(outfile, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
if (tplg->out_fd < 0) {
SNDERR("error: failed to open %s err %d\n",
outfile, -errno);
@@ -309,6 +306,60 @@ out_close:
return err;
}
+int snd_tplg_add_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t)
+{
+ switch (t->type) {
+ case SND_TPLG_TYPE_MIXER:
+ return tplg_add_mixer_object(tplg, t);
+ case SND_TPLG_TYPE_ENUM:
+ return tplg_add_enum_object(tplg, t);
+ case SND_TPLG_TYPE_BYTES:
+ return tplg_add_bytes_object(tplg, t);
+ case SND_TPLG_TYPE_DAPM_WIDGET:
+ return tplg_add_widget_object(tplg, t);
+ case SND_TPLG_TYPE_DAPM_GRAPH:
+ return tplg_add_graph_object(tplg, t);
+ default:
+ SNDERR("error: invalid object type %d\n", t->type);
+ return -EINVAL;
+ };
+}
+
+int snd_tplg_build(snd_tplg_t *tplg, const char *outfile)
+{
+ int err;
+
+ tplg->out_fd =
+ open(outfile, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
+ if (tplg->out_fd < 0) {
+ SNDERR("error: failed to open %s err %d\n",
+ outfile, -errno);
+ return -errno;
+ }
+
+ err = tplg_build_integ(tplg);
+ if (err < 0) {
+ SNDERR("error: failed to check topology integrity\n");
+ goto out;
+ }
+
+ err = tplg_write_data(tplg);
+ if (err < 0) {
+ SNDERR("error: failed to write data %d\n", err);
+ goto out;
+ }
+
+out:
+ close(tplg->out_fd);
+ return err;
+}
+
+int snd_tplg_set_manifest_data(snd_tplg_t *tplg, const void *data, int len)
+{
+ tplg->manifest.priv.size = len;
+ tplg->manifest_pdata = data;
+}
+
void snd_tplg_verbose(snd_tplg_t *tplg, int verbose)
{
tplg->verbose = verbose;
diff --git a/src/topology/tplg_local.h b/src/topology/tplg_local.h
index ec6304599538..d2b9aa6ff8ab 100644
--- a/src/topology/tplg_local.h
+++ b/src/topology/tplg_local.h
@@ -190,6 +190,7 @@ 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_ref_add(struct tplg_elem *elem, int type, const char* id);
+int tplg_ref_add_elem(struct tplg_elem *elem, struct tplg_elem *elem_ref);
struct tplg_elem *tplg_elem_new(void);
void tplg_elem_free(struct tplg_elem *elem);
@@ -214,3 +215,16 @@ int tplg_parse_ops(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
struct tplg_elem *lookup_pcm_dai_stream(struct list_head *base,
const char* id);
+
+int tplg_add_mixer_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t);
+int tplg_add_enum_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t);
+int tplg_add_bytes_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t);
+int tplg_add_widget_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t);
+int tplg_add_graph_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t);
+
+int tplg_add_mixer(snd_tplg_t *tplg, struct snd_tplg_mixer_template *mixer,
+ struct tplg_elem **e);
+int tplg_add_enum(snd_tplg_t *tplg, struct snd_tplg_enum_template *enum_ctl,
+ struct tplg_elem **e);
+int tplg_add_bytes(snd_tplg_t *tplg, struct snd_tplg_bytes_template *bytes_ctl,
+ struct tplg_elem **e);
--
2.5.3

View File

@ -0,0 +1,50 @@
From 3313f8740d936b1dbc6391ce3227ba467c6f603d Mon Sep 17 00:00:00 2001
From: David Henningsson <david.henningsson@canonical.com>
Date: Mon, 24 Aug 2015 20:37:29 +0200
Subject: [PATCH] pcm: Fix doxygen for two enums
The doxygen comments were wrong, making doxygen output weird.
Signed-off-by: David Henningsson <david.henningsson@canonical.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
include/pcm.h | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/include/pcm.h b/include/pcm.h
index a1d14a989a47..0be1a321adba 100644
--- a/include/pcm.h
+++ b/include/pcm.h
@@ -324,9 +324,9 @@ typedef enum _snd_pcm_tstamp {
} snd_pcm_tstamp_t;
typedef enum _snd_pcm_tstamp_type {
- SND_PCM_TSTAMP_TYPE_GETTIMEOFDAY = 0, /** gettimeofday equivalent */
- SND_PCM_TSTAMP_TYPE_MONOTONIC, /** posix_clock_monotonic equivalent */
- SND_PCM_TSTAMP_TYPE_MONOTONIC_RAW, /** monotonic_raw (no NTP) */
+ SND_PCM_TSTAMP_TYPE_GETTIMEOFDAY = 0, /**< gettimeofday equivalent */
+ SND_PCM_TSTAMP_TYPE_MONOTONIC, /**< posix_clock_monotonic equivalent */
+ SND_PCM_TSTAMP_TYPE_MONOTONIC_RAW, /**< monotonic_raw (no NTP) */
SND_PCM_TSTAMP_TYPE_LAST = SND_PCM_TSTAMP_TYPE_MONOTONIC_RAW,
} snd_pcm_tstamp_type_t;
@@ -527,11 +527,11 @@ int snd_pcm_unlink(snd_pcm_t *pcm);
/** channel map list type */
enum snd_pcm_chmap_type {
- SND_CHMAP_TYPE_NONE = 0,/** unspecified channel position */
- SND_CHMAP_TYPE_FIXED, /** fixed channel position */
- SND_CHMAP_TYPE_VAR, /** freely swappable channel position */
- SND_CHMAP_TYPE_PAIRED, /** pair-wise swappable channel position */
- SND_CHMAP_TYPE_LAST = SND_CHMAP_TYPE_PAIRED, /** last entry */
+ SND_CHMAP_TYPE_NONE = 0,/**< unspecified channel position */
+ SND_CHMAP_TYPE_FIXED, /**< fixed channel position */
+ SND_CHMAP_TYPE_VAR, /**< freely swappable channel position */
+ SND_CHMAP_TYPE_PAIRED, /**< pair-wise swappable channel position */
+ SND_CHMAP_TYPE_LAST = SND_CHMAP_TYPE_PAIRED, /**< last entry */
};
/** channel positions */
--
2.5.3

View File

@ -0,0 +1,80 @@
From fe8bb1fe02f9c7b7cb6048a17a8ff1ea30f97fc8 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai@suse.de>
Date: Tue, 8 Sep 2015 20:57:47 +0200
Subject: [PATCH] pcm: ioplug,extplug: Fix logic errors in type checks
A few error checks are wrongly performed with logical and (&&) instead
of logical or (||), which condition never met.
Reported-by: David Binderman <dcb314@hotmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
src/pcm/pcm_extplug.c | 8 ++++----
src/pcm/pcm_ioplug.c | 4 ++--
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/pcm/pcm_extplug.c b/src/pcm/pcm_extplug.c
index a5de6d848e21..a04f826c90a0 100644
--- a/src/pcm/pcm_extplug.c
+++ b/src/pcm/pcm_extplug.c
@@ -766,7 +766,7 @@ void snd_pcm_extplug_params_reset(snd_pcm_extplug_t *extplug)
int snd_pcm_extplug_set_slave_param_list(snd_pcm_extplug_t *extplug, int type, unsigned int num_list, const unsigned int *list)
{
extplug_priv_t *ext = extplug->pcm->private_data;
- if (type < 0 && type >= SND_PCM_EXTPLUG_HW_PARAMS) {
+ if (type < 0 || type >= SND_PCM_EXTPLUG_HW_PARAMS) {
SNDERR("EXTPLUG: invalid parameter type %d", type);
return -EINVAL;
}
@@ -788,7 +788,7 @@ int snd_pcm_extplug_set_slave_param_list(snd_pcm_extplug_t *extplug, int type, u
int snd_pcm_extplug_set_slave_param_minmax(snd_pcm_extplug_t *extplug, int type, unsigned int min, unsigned int max)
{
extplug_priv_t *ext = extplug->pcm->private_data;
- if (type < 0 && type >= SND_PCM_EXTPLUG_HW_PARAMS) {
+ if (type < 0 || type >= SND_PCM_EXTPLUG_HW_PARAMS) {
SNDERR("EXTPLUG: invalid parameter type %d", type);
return -EINVAL;
}
@@ -814,7 +814,7 @@ int snd_pcm_extplug_set_slave_param_minmax(snd_pcm_extplug_t *extplug, int type,
int snd_pcm_extplug_set_param_list(snd_pcm_extplug_t *extplug, int type, unsigned int num_list, const unsigned int *list)
{
extplug_priv_t *ext = extplug->pcm->private_data;
- if (type < 0 && type >= SND_PCM_EXTPLUG_HW_PARAMS) {
+ if (type < 0 || type >= SND_PCM_EXTPLUG_HW_PARAMS) {
SNDERR("EXTPLUG: invalid parameter type %d", type);
return -EINVAL;
}
@@ -836,7 +836,7 @@ int snd_pcm_extplug_set_param_list(snd_pcm_extplug_t *extplug, int type, unsigne
int snd_pcm_extplug_set_param_minmax(snd_pcm_extplug_t *extplug, int type, unsigned int min, unsigned int max)
{
extplug_priv_t *ext = extplug->pcm->private_data;
- if (type < 0 && type >= SND_PCM_EXTPLUG_HW_PARAMS) {
+ if (type < 0 || type >= SND_PCM_EXTPLUG_HW_PARAMS) {
SNDERR("EXTPLUG: invalid parameter type %d", type);
return -EINVAL;
}
diff --git a/src/pcm/pcm_ioplug.c b/src/pcm/pcm_ioplug.c
index fe9347c835d5..43550c03875b 100644
--- a/src/pcm/pcm_ioplug.c
+++ b/src/pcm/pcm_ioplug.c
@@ -1019,7 +1019,7 @@ void snd_pcm_ioplug_params_reset(snd_pcm_ioplug_t *ioplug)
int snd_pcm_ioplug_set_param_list(snd_pcm_ioplug_t *ioplug, int type, unsigned int num_list, const unsigned int *list)
{
ioplug_priv_t *io = ioplug->pcm->private_data;
- if (type < 0 && type >= SND_PCM_IOPLUG_HW_PARAMS) {
+ if (type < 0 || type >= SND_PCM_IOPLUG_HW_PARAMS) {
SNDERR("IOPLUG: invalid parameter type %d", type);
return -EINVAL;
}
@@ -1043,7 +1043,7 @@ int snd_pcm_ioplug_set_param_list(snd_pcm_ioplug_t *ioplug, int type, unsigned i
int snd_pcm_ioplug_set_param_minmax(snd_pcm_ioplug_t *ioplug, int type, unsigned int min, unsigned int max)
{
ioplug_priv_t *io = ioplug->pcm->private_data;
- if (type < 0 && type >= SND_PCM_IOPLUG_HW_PARAMS) {
+ if (type < 0 || type >= SND_PCM_IOPLUG_HW_PARAMS) {
SNDERR("IOPLUG: invalid parameter type %d", type);
return -EINVAL;
}
--
2.5.3

View File

@ -0,0 +1,39 @@
From 03d6b15291e3534afb72c5aa36495a932ef0cc6a Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai@suse.de>
Date: Tue, 8 Sep 2015 21:48:17 +0200
Subject: [PATCH] pcm: route: Remove bogus ! in snd_config_get_id() checks
There are strange "!" added before snd_config_get_id() return value
checks in a couple of places in pcm_route.c. This essentially makes
the result always positive, making checks bogus.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
src/pcm/pcm_route.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/pcm/pcm_route.c b/src/pcm/pcm_route.c
index 2a437e88b93c..646517d2a9d2 100644
--- a/src/pcm/pcm_route.c
+++ b/src/pcm/pcm_route.c
@@ -770,7 +770,7 @@ static int determine_chmap(snd_config_t *tt, snd_pcm_chmap_t **tt_chmap)
snd_config_iterator_t j, jnext;
snd_config_t *in = snd_config_iterator_entry(i);
- if (!snd_config_get_id(in, &id) < 0)
+ if (snd_config_get_id(in, &id) < 0)
continue;
if (snd_config_get_type(in) != SND_CONFIG_TYPE_COMPOUND)
goto err;
@@ -1070,7 +1070,7 @@ static int _snd_pcm_route_determine_ttable(snd_config_t *tt,
snd_config_iterator_t j, jnext;
long cchannel;
const char *id;
- if (!snd_config_get_id(in, &id) < 0)
+ if (snd_config_get_id(in, &id) < 0)
continue;
err = safe_strtol(id, &cchannel);
if (err < 0) {
--
2.5.3

View File

@ -0,0 +1,52 @@
From 76b9cae026bf73a00ccf3ec8833ec56f0e64f451 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai@suse.de>
Date: Tue, 8 Sep 2015 22:04:48 +0200
Subject: [PATCH] topology: builder: Fix possibly uninitialized variable in
write_elem_block()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When an empty list is passed to write_elem_block(), it may leave
vendor_type uninitialized.
builder.c: In function write_elem_block:
builder.c:127:8: warning: vendor_type may be used uninitialized in this function [-Wmaybe-uninitialized]
ret = write_block_header(tplg, tplg_type, vendor_type,
^
builder.c:114:33: note: vendor_type was declared here
int ret, wsize = 0, count = 0, vendor_type;
^
Add an immediate return for count = 0 for avoiding it, and simplify
the code initializing vendor_type without using a one-shot loop.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
src/topology/builder.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/src/topology/builder.c b/src/topology/builder.c
index 3bccd44827cc..91412aadd098 100644
--- a/src/topology/builder.c
+++ b/src/topology/builder.c
@@ -116,13 +116,12 @@ static int write_elem_block(snd_tplg_t *tplg,
/* count number of elements */
list_for_each(pos, base)
count++;
+ if (!count)
+ return 0;
/* write the header for this block */
- list_for_each(pos, base) {
- elem = list_entry(pos, struct tplg_elem, list);
- vendor_type = elem->vendor_type;
- break;
- }
+ elem = list_entry(base->next, struct tplg_elem, list);
+ vendor_type = elem->vendor_type;
ret = write_block_header(tplg, tplg_type, vendor_type,
SND_SOC_TPLG_ABI_VERSION, 0, size, count);
--
2.5.3

View File

@ -0,0 +1,35 @@
From f41fe763e9bc80783bf1471141ac06d514ffaef3 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai@suse.de>
Date: Tue, 8 Sep 2015 22:09:44 +0200
Subject: [PATCH] topology: ctl: Fix access type checks
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Fix the wrong bit-and check by adding parentheses properly:
ctl.c: In function tplg_add_bytes:
ctl.c:868:22: warning: suggest parentheses around comparison in operand of & [-Wparentheses]
if (be->hdr.access & SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE
^
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
src/topology/ctl.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/topology/ctl.c b/src/topology/ctl.c
index 68c4ce5803d1..7d8787f347b8 100644
--- a/src/topology/ctl.c
+++ b/src/topology/ctl.c
@@ -865,7 +865,7 @@ int tplg_add_bytes(snd_tplg_t *tplg, struct snd_tplg_bytes_template *bytes_ctl,
/* check on TLV bytes control */
if (be->hdr.access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
- if (be->hdr.access & SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE
+ if ((be->hdr.access & SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE)
!= SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE) {
SNDERR("error: Invalid TLV bytes control access 0x%x\n",
be->hdr.access);
--
2.5.3

View File

@ -0,0 +1,41 @@
From 5b21400c42877ff6c2a386c7c5ed5c6c6c9bf664 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai@suse.de>
Date: Tue, 8 Sep 2015 22:11:48 +0200
Subject: [PATCH] topology: data: Fix wrong size check in tplg_parse_data_hex()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
A wrong, uninitialized variable is referred as the size to check in
tplg_parse_data_hex(). Spotted by gcc warning:
data.c: In function tplg_parse_data_hex:
data.c:228:5: warning: esize may be used uninitialized in this function [-Wmaybe-uninitialized]
if (esize > TPLG_MAX_PRIV_SIZE) {
^
data.c:211:12: note: esize was declared here
int size, esize, off, num;
^
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
src/topology/data.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/topology/data.c b/src/topology/data.c
index 4ee1f8a15f95..370c0faead36 100644
--- a/src/topology/data.c
+++ b/src/topology/data.c
@@ -225,8 +225,8 @@ static int tplg_parse_data_hex(snd_config_t *cfg, struct tplg_elem *elem,
size = num * width;
priv = elem->data;
- if (esize > TPLG_MAX_PRIV_SIZE) {
- SNDERR("error: data too big %d\n", esize);
+ if (size > TPLG_MAX_PRIV_SIZE) {
+ SNDERR("error: data too big %d\n", size);
return -EINVAL;
}
--
2.5.3

View File

@ -0,0 +1,35 @@
From e38b13f128c743fe1f664e4491fdd0c880265da1 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai@suse.de>
Date: Tue, 8 Sep 2015 22:13:50 +0200
Subject: [PATCH] topology: parser: Add missing return value to
snd_tplg_set_manifest_data()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Spotted by gcc warning:
parser.c: In function snd_tplg_set_manifest_data:
parser.c:361:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
src/topology/parser.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/topology/parser.c b/src/topology/parser.c
index ca7de0689cea..44c6146b22f2 100644
--- a/src/topology/parser.c
+++ b/src/topology/parser.c
@@ -358,6 +358,7 @@ int snd_tplg_set_manifest_data(snd_tplg_t *tplg, const void *data, int len)
{
tplg->manifest.priv.size = len;
tplg->manifest_pdata = data;
+ return 0;
}
void snd_tplg_verbose(snd_tplg_t *tplg, int verbose)
--
2.5.3

View File

@ -0,0 +1,47 @@
From 9a2fe5399c6ff987fe4e23907c6467c3d2baa307 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai@suse.de>
Date: Tue, 8 Sep 2015 22:15:02 +0200
Subject: [PATCH] topology: pcm: Remove unused variables
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Fix gcc warnings:
pcm.c: In function tplg_parse_stream_cfg:
pcm.c:160:6: warning: unused variable ret [-Wunused-variable]
int ret;
^
pcm.c: In function split_format:
pcm.c:267:13: warning: unused variable ret [-Wunused-variable]
int i = 0, ret;
^
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
src/topology/pcm.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/topology/pcm.c b/src/topology/pcm.c
index 6e42aa18b99b..18d5f0b1b040 100644
--- a/src/topology/pcm.c
+++ b/src/topology/pcm.c
@@ -157,7 +157,6 @@ static int tplg_parse_stream_cfg(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
struct snd_soc_tplg_stream *stream;
const char *id, *val;
snd_pcm_format_t format;
- int ret;
snd_config_get_id(cfg, &id);
@@ -264,7 +263,7 @@ static int split_format(struct snd_soc_tplg_stream_caps *caps, char *str)
{
char *s = NULL;
snd_pcm_format_t format;
- int i = 0, ret;
+ int i = 0;
s = strtok(str, ",");
while ((s != NULL) && (i < SND_SOC_TPLG_MAX_FORMATS)) {
--
2.5.3

View File

@ -0,0 +1,44 @@
From c82417650a1ea4446c19dd82bfab9d8e6cd5a969 Mon Sep 17 00:00:00 2001
From: Khem Raj <raj.khem@gmail.com>
Date: Tue, 15 Sep 2015 18:48:02 +0300
Subject: [PATCH] build: Do not try to detect cross-compiler
cross compilers are passed via path may not be a gcc based cross
compiler in such cases this check fails and try's to force gcc based
cross compiler detection, This code is a convenience that limits the
build system
Signed-off-by: Khem Raj <raj.khem@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
configure.ac | 14 --------------
1 file changed, 14 deletions(-)
diff --git a/configure.ac b/configure.ac
index a482b3e7f6ca..a14e52de5e3b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -27,20 +27,6 @@ AC_PREFIX_DEFAULT(/usr)
dnl Checks for programs.
-dnl try to gues cross-compiler if not set
-if test "x$host" != "x$build" -a -z "`echo $CC | grep -e '-gcc'`";
-then
- AC_MSG_CHECKING(for cross-compiler)
-
- which ${program_prefix}gcc >/dev/null 2>&1 && CC=${program_prefix}gcc
- which ${host_cpu}-${host_os}-gcc >/dev/null 2>&1 \
- && CC=${host_cpu}-${host_os}-gcc
- which ${host_cpu}-${host_vendor}-${host_os}-gcc >/dev/null 2>&1 \
- && CC=${host_cpu}-${host_vendor}-${host_os}-gcc
-
- AC_MSG_RESULT($CC)
-fi
-
CFLAGS="$CFLAGS -D_GNU_SOURCE"
--
2.5.3

View File

@ -0,0 +1,92 @@
From 8b0a5310bf3cb6ca1f7d70e3f4149b25b17b453a Mon Sep 17 00:00:00 2001
From: Mengdong Lin <mengdong.lin@intel.com>
Date: Wed, 16 Sep 2015 17:07:13 +0800
Subject: [PATCH] topology: Add API to set a vendor specific version number
This vendor-specific version number is optional. It will be written to
the 'version' field of each block header of the binary toplogy data file.
The vendor driver can check this number for further processing in kernel.
The topology ABI version number is still stored in the 'abi' field of
block headers.
Signed-off-by: Mengdong Lin <mengdong.lin@intel.com>
Reviewed-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
include/topology.h | 8 ++++++++
src/topology/builder.c | 6 +++---
src/topology/parser.c | 7 +++++++
3 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/include/topology.h b/include/topology.h
index 6ff8c5fb4609..9b84bd9331dc 100644
--- a/include/topology.h
+++ b/include/topology.h
@@ -690,6 +690,14 @@ int snd_tplg_build(snd_tplg_t *tplg, const char *outfile);
*/
int snd_tplg_set_manifest_data(snd_tplg_t *tplg, const void *data, int len);
+/**
+ * \brief Set an optional vendor specific version number.
+ * \param tplg Topology instance.
+ * \param version Vendor specific version number.
+ * \return Zero on success, otherwise a negative error code
+ */
+int snd_tplg_set_version(snd_tplg_t *tplg, unsigned int version);
+
/* \} */
#ifdef __cplusplus
diff --git a/src/topology/builder.c b/src/topology/builder.c
index 91412aadd098..8d57a8b719f7 100644
--- a/src/topology/builder.c
+++ b/src/topology/builder.c
@@ -89,7 +89,7 @@ static int write_data_block(snd_tplg_t *tplg, int size, int tplg_type,
/* write the header for this block */
ret = write_block_header(tplg, tplg_type, 0,
- SND_SOC_TPLG_ABI_VERSION, 0, size, 1);
+ tplg->version, 0, size, 1);
if (ret < 0) {
SNDERR("error: failed to write %s block %d\n", obj_name, ret);
return ret;
@@ -124,7 +124,7 @@ static int write_elem_block(snd_tplg_t *tplg,
vendor_type = elem->vendor_type;
ret = write_block_header(tplg, tplg_type, vendor_type,
- SND_SOC_TPLG_ABI_VERSION, 0, size, count);
+ tplg->version, 0, size, count);
if (ret < 0) {
SNDERR("error: failed to write %s block %d\n",
obj_name, ret);
@@ -242,7 +242,7 @@ static int write_manifest_data(snd_tplg_t *tplg)
/* write the header for this block */
ret = write_block_header(tplg, SND_SOC_TPLG_TYPE_MANIFEST, 0,
- SND_SOC_TPLG_ABI_VERSION, 0,
+ tplg->version, 0,
sizeof(tplg->manifest) + tplg->manifest.priv.size, 1);
if (ret < 0) {
SNDERR("error: failed to write manifest block %d\n", ret);
diff --git a/src/topology/parser.c b/src/topology/parser.c
index 44c6146b22f2..6671055ae226 100644
--- a/src/topology/parser.c
+++ b/src/topology/parser.c
@@ -361,6 +361,13 @@ int snd_tplg_set_manifest_data(snd_tplg_t *tplg, const void *data, int len)
return 0;
}
+int snd_tplg_set_version(snd_tplg_t *tplg, unsigned int version)
+{
+ tplg->version = version;
+
+ return 0;
+}
+
void snd_tplg_verbose(snd_tplg_t *tplg, int verbose)
{
tplg->verbose = verbose;
--
2.5.3

View File

@ -0,0 +1,40 @@
From f07e9af7eeebc950fd7bf4101a6af7f53ac741b6 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai@suse.de>
Date: Fri, 2 Oct 2015 11:55:36 +0200
Subject: [PATCH] pcm: ladspa: Fix segfault due to a wrong channel reference
Because of a typo in referencing the input array in
snd_pcm_ladspa_allocate_memory(), ladpsa PCM plugin may cause a
segfault at prepare when input and and output channels are different:
#0 0x00007ffff78623ef in snd_pcm_ladspa_allocate_memory (pcm=0x626fa0, pcm=0x626fa0, pcm=0x626fa0, ladspa=0x621ad0) at pcm_ladspa.c:753
#1 snd_pcm_ladspa_init (pcm=0x626fa0) at pcm_ladspa.c:834
#2 0x00007ffff7842946 in snd_pcm_plugin_prepare (pcm=0x626fa0) at pcm_plugin.c:171
#3 0x00007ffff784290f in snd_pcm_plugin_prepare (pcm=0x62c760) at pcm_plugin.c:162
#4 0x000000000040256a in ?? ()
#5 0x00007ffff7222ec5 in __libc_start_main (main=0x401d80,a argc=4, argv=0x7fffffffde28, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffde18) at libc-start.c:287
#6 0x0000000000402fdd in ?? ()
This patch corrects the wrong reference.
Reported-and-tested-by: Andreas Hartmann <mail@andreashartmann.eu>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
src/pcm/pcm_ladspa.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/pcm/pcm_ladspa.c b/src/pcm/pcm_ladspa.c
index 631ee0f35b73..6552b4379ec0 100644
--- a/src/pcm/pcm_ladspa.c
+++ b/src/pcm/pcm_ladspa.c
@@ -749,7 +749,7 @@ static int snd_pcm_ladspa_allocate_memory(snd_pcm_t *pcm, snd_pcm_ladspa_t *lads
return -ENOMEM;
}
for (idx = 0; idx < instance->input.channels.size; idx++) {
- chn = instance->output.channels.array[idx];
+ chn = instance->input.channels.array[idx];
if (pchannels[chn] == NULL && chn < ichannels) {
instance->input.data[idx] = NULL;
continue;
--
2.5.3

View File

@ -1,3 +1,32 @@
-------------------------------------------------------------------
Fri Oct 2 12:11:24 CEST 2015 - tiwai@suse.de
- Backport upsteram fixes: more topology API updates/fixes, misc
documentation fixes, some logical error fixes in PCM plugins,
LADSPA plugin segfault fix:
0050-topology-fix-element-object-type-is-switch.patch
0051-topology-Add-element-ID-so-we-can-look-up-references.patch
0052-topology-Add-support-for-writing-manifest-private-da.patch
0053-topology-update-ABI-to-improve-support-for-different.patch
0054-topology-Add-ops-support-to-byte-control-objects.patch
0055-topology-treat-all-DAPM-controls-types-the-same-when.patch
0056-topology-print-error-prefix-on-error-message.patch
0057-topology-rename-OBJECT_TYPE_-to-SND_TPLG_TYPE_.patch
0058-core-add-convenience-macros-to-local.h.patch
0059-topology-Add-C-templates-structure-for-building-topo.patch
0060-topology-A-API-calls-to-directly-build-topology-data.patch
0061-pcm-Fix-doxygen-for-two-enums.patch
0062-pcm-ioplug-extplug-Fix-logic-errors-in-type-checks.patch
0063-pcm-route-Remove-bogus-in-snd_config_get_id-checks.patch
0064-topology-builder-Fix-possibly-uninitialized-variable.patch
0065-topology-ctl-Fix-access-type-checks.patch
0066-topology-data-Fix-wrong-size-check-in-tplg_parse_dat.patch
0067-topology-parser-Add-missing-return-value-to-snd_tplg.patch
0068-topology-pcm-Remove-unused-variables.patch
0069-build-Do-not-try-to-detect-cross-compiler.patch
0070-topology-Add-API-to-set-a-vendor-specific-version-nu.patch
0071-pcm-ladspa-Fix-segfault-due-to-a-wrong-channel-refer.patch
-------------------------------------------------------------------
Tue Aug 4 17:41:39 CEST 2015 - tiwai@suse.de

View File

@ -98,6 +98,28 @@ Patch46: 0046-topology-doxygen-Add-doxygen-support-for-topology-co.patch
Patch47: 0047-conf-topology-Add-topology-file-for-broadwell-audio-.patch
Patch48: 0048-topology-Fix-missing-inclusion-of-ctype.h.patch
Patch49: 0049-topology-Fix-typos.patch
Patch50: 0050-topology-fix-element-object-type-is-switch.patch
Patch51: 0051-topology-Add-element-ID-so-we-can-look-up-references.patch
Patch52: 0052-topology-Add-support-for-writing-manifest-private-da.patch
Patch53: 0053-topology-update-ABI-to-improve-support-for-different.patch
Patch54: 0054-topology-Add-ops-support-to-byte-control-objects.patch
Patch55: 0055-topology-treat-all-DAPM-controls-types-the-same-when.patch
Patch56: 0056-topology-print-error-prefix-on-error-message.patch
Patch57: 0057-topology-rename-OBJECT_TYPE_-to-SND_TPLG_TYPE_.patch
Patch58: 0058-core-add-convenience-macros-to-local.h.patch
Patch59: 0059-topology-Add-C-templates-structure-for-building-topo.patch
Patch60: 0060-topology-A-API-calls-to-directly-build-topology-data.patch
Patch61: 0061-pcm-Fix-doxygen-for-two-enums.patch
Patch62: 0062-pcm-ioplug-extplug-Fix-logic-errors-in-type-checks.patch
Patch63: 0063-pcm-route-Remove-bogus-in-snd_config_get_id-checks.patch
Patch64: 0064-topology-builder-Fix-possibly-uninitialized-variable.patch
Patch65: 0065-topology-ctl-Fix-access-type-checks.patch
Patch66: 0066-topology-data-Fix-wrong-size-check-in-tplg_parse_dat.patch
Patch67: 0067-topology-parser-Add-missing-return-value-to-snd_tplg.patch
Patch68: 0068-topology-pcm-Remove-unused-variables.patch
Patch69: 0069-build-Do-not-try-to-detect-cross-compiler.patch
Patch70: 0070-topology-Add-API-to-set-a-vendor-specific-version-nu.patch
Patch71: 0071-pcm-ladspa-Fix-segfault-due-to-a-wrong-channel-refer.patch
# rest suse patches
Patch99: alsa-lib-doxygen-avoid-crash-for-11.3.diff
# suppress timestamp in documents
@ -217,6 +239,28 @@ Architecture.
%patch47 -p1
%patch48 -p1
%patch49 -p1
%patch50 -p1
%patch51 -p1
%patch52 -p1
%patch53 -p1
%patch54 -p1
%patch55 -p1
%patch56 -p1
%patch57 -p1
%patch58 -p1
%patch59 -p1
%patch60 -p1
%patch61 -p1
%patch62 -p1
%patch63 -p1
%patch64 -p1
%patch65 -p1
%patch66 -p1
%patch67 -p1
%patch68 -p1
%patch69 -p1
%patch70 -p1
%patch71 -p1
%if 0%{?suse_version} == 1130
%patch99 -p1
%endif