diff --git a/0050-topology-fix-element-object-type-is-switch.patch b/0050-topology-fix-element-object-type-is-switch.patch new file mode 100644 index 0000000..2e651aa --- /dev/null +++ b/0050-topology-fix-element-object-type-is-switch.patch @@ -0,0 +1,29 @@ +From 1bb4c2fc304515278e6510ba7288b94f99f50bcd Mon Sep 17 00:00:00 2001 +From: Liam Girdwood +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 +Signed-off-by: Takashi Iwai +--- + 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 + diff --git a/0051-topology-Add-element-ID-so-we-can-look-up-references.patch b/0051-topology-Add-element-ID-so-we-can-look-up-references.patch new file mode 100644 index 0000000..7c196b4 --- /dev/null +++ b/0051-topology-Add-element-ID-so-we-can-look-up-references.patch @@ -0,0 +1,207 @@ +From 120b3b8eadd9a2a4c2ede0a246bffa1cfac562a9 Mon Sep 17 00:00:00 2001 +From: Jin Yao +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 +Signed-off-by: Mengdong Lin +Signed-off-by: Takashi Iwai +--- + 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 + diff --git a/0052-topology-Add-support-for-writing-manifest-private-da.patch b/0052-topology-Add-support-for-writing-manifest-private-da.patch new file mode 100644 index 0000000..fba2b92 --- /dev/null +++ b/0052-topology-Add-support-for-writing-manifest-private-da.patch @@ -0,0 +1,90 @@ +From d5e7e8bb38681c2cbf3777314c422130a740810e Mon Sep 17 00:00:00 2001 +From: Mengdong Lin +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 +Signed-off-by: Liam Girdwood +Signed-off-by: Takashi Iwai +--- + 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 + diff --git a/0053-topology-update-ABI-to-improve-support-for-different.patch b/0053-topology-update-ABI-to-improve-support-for-different.patch new file mode 100644 index 0000000..58228f4 --- /dev/null +++ b/0053-topology-update-ABI-to-improve-support-for-different.patch @@ -0,0 +1,136 @@ +From 8c8372cc060ec16776db28f927c9402dcc09b001 Mon Sep 17 00:00:00 2001 +From: Mengdong Lin +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 +Signed-off-by: Liam Girdwood +Signed-off-by: Takashi Iwai +--- + 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 + diff --git a/0054-topology-Add-ops-support-to-byte-control-objects.patch b/0054-topology-Add-ops-support-to-byte-control-objects.patch new file mode 100644 index 0000000..c0bb903 --- /dev/null +++ b/0054-topology-Add-ops-support-to-byte-control-objects.patch @@ -0,0 +1,54 @@ +From 80a8283d179739f73ad007b5d60dbf28b80fddb9 Mon Sep 17 00:00:00 2001 +From: Mengdong Lin +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 +Signed-off-by: Liam Girdwood +Signed-off-by: Takashi Iwai +--- + 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 + diff --git a/0055-topology-treat-all-DAPM-controls-types-the-same-when.patch b/0055-topology-treat-all-DAPM-controls-types-the-same-when.patch new file mode 100644 index 0000000..924bc75 --- /dev/null +++ b/0055-topology-treat-all-DAPM-controls-types-the-same-when.patch @@ -0,0 +1,47 @@ +From ecf7fdaeef57d300b94a1cd00db8a8b04a2edceb Mon Sep 17 00:00:00 2001 +From: Mengdong Lin +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 +Signed-off-by: Liam Girdwood +Signed-off-by: Takashi Iwai +--- + 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 + diff --git a/0056-topology-print-error-prefix-on-error-message.patch b/0056-topology-print-error-prefix-on-error-message.patch new file mode 100644 index 0000000..babcf30 --- /dev/null +++ b/0056-topology-print-error-prefix-on-error-message.patch @@ -0,0 +1,29 @@ +From b47cf00197420d7dc9dc01dce75b41aaad49278e Mon Sep 17 00:00:00 2001 +From: Liam Girdwood +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 +Signed-off-by: Takashi Iwai +--- + 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 + diff --git a/0057-topology-rename-OBJECT_TYPE_-to-SND_TPLG_TYPE_.patch b/0057-topology-rename-OBJECT_TYPE_-to-SND_TPLG_TYPE_.patch new file mode 100644 index 0000000..4ee4269 --- /dev/null +++ b/0057-topology-rename-OBJECT_TYPE_-to-SND_TPLG_TYPE_.patch @@ -0,0 +1,782 @@ +From 634712d21c07a229a6b37658e900f0fd4c304a59 Mon Sep 17 00:00:00 2001 +From: Liam Girdwood +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 +Signed-off-by: Takashi Iwai +--- + 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 + diff --git a/0058-core-add-convenience-macros-to-local.h.patch b/0058-core-add-convenience-macros-to-local.h.patch new file mode 100644 index 0000000..cc2796e --- /dev/null +++ b/0058-core-add-convenience-macros-to-local.h.patch @@ -0,0 +1,47 @@ +From ab9633d581110a5da08bd2d2c7c070f3862fe9af Mon Sep 17 00:00:00 2001 +From: Liam Girdwood +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 +Signed-off-by: Takashi Iwai +--- + 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 + diff --git a/0059-topology-Add-C-templates-structure-for-building-topo.patch b/0059-topology-Add-C-templates-structure-for-building-topo.patch new file mode 100644 index 0000000..a07711b --- /dev/null +++ b/0059-topology-Add-C-templates-structure-for-building-topo.patch @@ -0,0 +1,248 @@ +From 1b148ef590f94fc30b4c814c1ce2bc31621af840 Mon Sep 17 00:00:00 2001 +From: Mengdong Lin +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 +Signed-off-by: Liam Girdwood +Signed-off-by: Takashi Iwai +--- + 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 + diff --git a/0060-topology-A-API-calls-to-directly-build-topology-data.patch b/0060-topology-A-API-calls-to-directly-build-topology-data.patch new file mode 100644 index 0000000..6757ffd --- /dev/null +++ b/0060-topology-A-API-calls-to-directly-build-topology-data.patch @@ -0,0 +1,732 @@ +From 5b518c91594d3b0c8847a87d9b65877f74c7a87b Mon Sep 17 00:00:00 2001 +From: Mengdong Lin +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 +Signed-off-by: Liam Girdwood +Signed-off-by: Takashi Iwai +--- + 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 + diff --git a/0061-pcm-Fix-doxygen-for-two-enums.patch b/0061-pcm-Fix-doxygen-for-two-enums.patch new file mode 100644 index 0000000..cf41edd --- /dev/null +++ b/0061-pcm-Fix-doxygen-for-two-enums.patch @@ -0,0 +1,50 @@ +From 3313f8740d936b1dbc6391ce3227ba467c6f603d Mon Sep 17 00:00:00 2001 +From: David Henningsson +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 +Signed-off-by: Takashi Iwai +--- + 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 + diff --git a/0062-pcm-ioplug-extplug-Fix-logic-errors-in-type-checks.patch b/0062-pcm-ioplug-extplug-Fix-logic-errors-in-type-checks.patch new file mode 100644 index 0000000..975c279 --- /dev/null +++ b/0062-pcm-ioplug-extplug-Fix-logic-errors-in-type-checks.patch @@ -0,0 +1,80 @@ +From fe8bb1fe02f9c7b7cb6048a17a8ff1ea30f97fc8 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +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 +Signed-off-by: Takashi Iwai +--- + 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 + diff --git a/0063-pcm-route-Remove-bogus-in-snd_config_get_id-checks.patch b/0063-pcm-route-Remove-bogus-in-snd_config_get_id-checks.patch new file mode 100644 index 0000000..bffaf59 --- /dev/null +++ b/0063-pcm-route-Remove-bogus-in-snd_config_get_id-checks.patch @@ -0,0 +1,39 @@ +From 03d6b15291e3534afb72c5aa36495a932ef0cc6a Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +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 +--- + 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 + diff --git a/0064-topology-builder-Fix-possibly-uninitialized-variable.patch b/0064-topology-builder-Fix-possibly-uninitialized-variable.patch new file mode 100644 index 0000000..2951ab6 --- /dev/null +++ b/0064-topology-builder-Fix-possibly-uninitialized-variable.patch @@ -0,0 +1,52 @@ +From 76b9cae026bf73a00ccf3ec8833ec56f0e64f451 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +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 +--- + 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 + diff --git a/0065-topology-ctl-Fix-access-type-checks.patch b/0065-topology-ctl-Fix-access-type-checks.patch new file mode 100644 index 0000000..6fe13c3 --- /dev/null +++ b/0065-topology-ctl-Fix-access-type-checks.patch @@ -0,0 +1,35 @@ +From f41fe763e9bc80783bf1471141ac06d514ffaef3 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +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 +--- + 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 + diff --git a/0066-topology-data-Fix-wrong-size-check-in-tplg_parse_dat.patch b/0066-topology-data-Fix-wrong-size-check-in-tplg_parse_dat.patch new file mode 100644 index 0000000..d57465d --- /dev/null +++ b/0066-topology-data-Fix-wrong-size-check-in-tplg_parse_dat.patch @@ -0,0 +1,41 @@ +From 5b21400c42877ff6c2a386c7c5ed5c6c6c9bf664 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +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 +--- + 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 + diff --git a/0067-topology-parser-Add-missing-return-value-to-snd_tplg.patch b/0067-topology-parser-Add-missing-return-value-to-snd_tplg.patch new file mode 100644 index 0000000..e004958 --- /dev/null +++ b/0067-topology-parser-Add-missing-return-value-to-snd_tplg.patch @@ -0,0 +1,35 @@ +From e38b13f128c743fe1f664e4491fdd0c880265da1 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +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 +--- + 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 + diff --git a/0068-topology-pcm-Remove-unused-variables.patch b/0068-topology-pcm-Remove-unused-variables.patch new file mode 100644 index 0000000..da574d1 --- /dev/null +++ b/0068-topology-pcm-Remove-unused-variables.patch @@ -0,0 +1,47 @@ +From 9a2fe5399c6ff987fe4e23907c6467c3d2baa307 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +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 +--- + 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 + diff --git a/0069-build-Do-not-try-to-detect-cross-compiler.patch b/0069-build-Do-not-try-to-detect-cross-compiler.patch new file mode 100644 index 0000000..a19f629 --- /dev/null +++ b/0069-build-Do-not-try-to-detect-cross-compiler.patch @@ -0,0 +1,44 @@ +From c82417650a1ea4446c19dd82bfab9d8e6cd5a969 Mon Sep 17 00:00:00 2001 +From: Khem Raj +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 +Signed-off-by: Takashi Iwai +--- + 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 + diff --git a/0070-topology-Add-API-to-set-a-vendor-specific-version-nu.patch b/0070-topology-Add-API-to-set-a-vendor-specific-version-nu.patch new file mode 100644 index 0000000..7c805c0 --- /dev/null +++ b/0070-topology-Add-API-to-set-a-vendor-specific-version-nu.patch @@ -0,0 +1,92 @@ +From 8b0a5310bf3cb6ca1f7d70e3f4149b25b17b453a Mon Sep 17 00:00:00 2001 +From: Mengdong Lin +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 +Reviewed-by: Liam Girdwood +Signed-off-by: Takashi Iwai +--- + 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 + diff --git a/0071-pcm-ladspa-Fix-segfault-due-to-a-wrong-channel-refer.patch b/0071-pcm-ladspa-Fix-segfault-due-to-a-wrong-channel-refer.patch new file mode 100644 index 0000000..99992ae --- /dev/null +++ b/0071-pcm-ladspa-Fix-segfault-due-to-a-wrong-channel-refer.patch @@ -0,0 +1,40 @@ +From f07e9af7eeebc950fd7bf4101a6af7f53ac741b6 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +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=, fini=, rtld_fini=, stack_end=0x7fffffffde18) at libc-start.c:287 + #6 0x0000000000402fdd in ?? () + +This patch corrects the wrong reference. + +Reported-and-tested-by: Andreas Hartmann +Signed-off-by: Takashi Iwai +--- + 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 + diff --git a/alsa.changes b/alsa.changes index 44d5968..f89a2ca 100644 --- a/alsa.changes +++ b/alsa.changes @@ -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 diff --git a/alsa.spec b/alsa.spec index d838164..59c5e64 100644 --- a/alsa.spec +++ b/alsa.spec @@ -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