Accepting request 838541 from multimedia:libs
- Enable topology support for aarch64 - Backport upstream fixes: 0001-ucm-substitution-remove-duplicate-allow_empty-assign.patch 0002-ucm-fix-parse_get_safe_name-safe-name-must-be-checke.patch 0003-ucm-substitute-the-merged-tree-completely.patch 0004-ctl-improve-documentation-for-identifier-of-control-.patch 0005-pcm-dmix-make-lockless-operation-optional.patch 0006-pcm-dmix-Fix-semaphore-usage-with-lockless-operation.patch 0007-pcm-iec958-implement-HDMI-HBR-audio-formatting.patch 0008-pcm-iec958-set-channel-status-bits-according-to-rate.patch 0009-conf-pcm-USB-Added-S-PDIF-fix-for-Asus-Xonar-SE.patch 0010-control-ctlparse-fix-enum-values-in-or.patch 0011-conf-USB-Audio-Disable-IEC958-on-Lenovo-ThinkStation.patch 0012-pcm-dmix-fix-access-to-sum-buffer-in-non-interleaved.patch 0014-control-Add-documentation-for-snd_ctl_elem_list_.patch 0015-conf-quote-also-strings-with-and-characters-in-strin.patch 0016-topology-decode-Fix-channel-map-memory-allocation.patch 0017-topology-decode-Fix-infinite-loop-in-decoding-enum-c.patch 0018-topology-decode-Remove-decoding-values-for-enum-cont.patch 0019-topology-decode-Add-enum-control-texts-as-separate-e.patch 0020-topology-decode-Fix-printing-texts-section.patch 0021-topology-decode-Change-declaration-of-enum-decoding-.patch 0022-topology-decode-Fix-decoding-PCM-formats-and-rates.patch 0023-topology-decode-Print-sig_bits-field-in-PCM-capabili.patch 0024-topology-decode-Add-DAI-name-printing.patch 0025-topology-Make-buffer-for-saving-dynamic-size.patch 0026-topology-return-correct-value-in-tplg_save_printf.patch 0027-topology-fix-some-gcc10-warnings-labs-signess.patch 0028-topology-fix-sort_config.patch OBS-URL: https://build.opensuse.org/request/show/838541 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/alsa?expand=0&rev=204
This commit is contained in:
commit
5e9a347d3f
@ -0,0 +1,36 @@
|
||||
From 485930ea5dc8a14e0d215de44557372ca41b15f4 Mon Sep 17 00:00:00 2001
|
||||
From: Jaroslav Kysela <perex@perex.cz>
|
||||
Date: Tue, 30 Jun 2020 09:22:12 +0200
|
||||
Subject: [PATCH 01/32] ucm: substitution - remove duplicate allow_empty
|
||||
assignment
|
||||
|
||||
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
|
||||
---
|
||||
src/ucm/ucm_subs.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/ucm/ucm_subs.c b/src/ucm/ucm_subs.c
|
||||
index a154aa510ee8..d40e5478b084 100644
|
||||
--- a/src/ucm/ucm_subs.c
|
||||
+++ b/src/ucm/ucm_subs.c
|
||||
@@ -303,7 +303,6 @@ __std:
|
||||
} else if (value[1] != '{') {
|
||||
goto __std;
|
||||
}
|
||||
- allow_empty = false;
|
||||
fcn2 = NULL;
|
||||
MATCH_VARIABLE(value, "${OpenName}", rval_open_name, false);
|
||||
MATCH_VARIABLE(value, "${ConfTopDir}", rval_conf_topdir, false);
|
||||
@@ -365,7 +364,8 @@ __rval:
|
||||
}
|
||||
strncpy(r, value, idsize);
|
||||
r[idsize] = '\0';
|
||||
- uc_error("variable '%s' is not defined in this context!", r);
|
||||
+ uc_error("variable '%s' is %s in this context!", r,
|
||||
+ rval ? "empty" : "not defined");
|
||||
err = -EINVAL;
|
||||
goto __error;
|
||||
}
|
||||
--
|
||||
2.16.4
|
||||
|
@ -0,0 +1,35 @@
|
||||
From 30d12e930cfcba777a29af502a9c1dbfa5e37c04 Mon Sep 17 00:00:00 2001
|
||||
From: Jaroslav Kysela <perex@perex.cz>
|
||||
Date: Fri, 3 Jul 2020 14:48:18 +0200
|
||||
Subject: [PATCH 02/32] ucm: fix parse_get_safe_name() - safe name must be
|
||||
checked after substitution
|
||||
|
||||
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
|
||||
---
|
||||
src/ucm/parser.c | 9 +++++++--
|
||||
1 file changed, 7 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/ucm/parser.c b/src/ucm/parser.c
|
||||
index 3b7fc931362f..d034b8598a85 100644
|
||||
--- a/src/ucm/parser.c
|
||||
+++ b/src/ucm/parser.c
|
||||
@@ -234,9 +234,14 @@ int parse_get_safe_name(snd_use_case_mgr_t *uc_mgr, snd_config_t *n,
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
- if (!parse_is_name_safe(id))
|
||||
+ err = get_string3(uc_mgr, id, name);
|
||||
+ if (err < 0)
|
||||
+ return err;
|
||||
+ if (!parse_is_name_safe(*name)) {
|
||||
+ free(*name);
|
||||
return -EINVAL;
|
||||
- return get_string3(uc_mgr, id, name);
|
||||
+ }
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
--
|
||||
2.16.4
|
||||
|
147
0003-ucm-substitute-the-merged-tree-completely.patch
Normal file
147
0003-ucm-substitute-the-merged-tree-completely.patch
Normal file
@ -0,0 +1,147 @@
|
||||
From 32addac948a61c4770f9cdf459fa29879602df38 Mon Sep 17 00:00:00 2001
|
||||
From: Jaroslav Kysela <perex@perex.cz>
|
||||
Date: Mon, 6 Jul 2020 16:34:33 +0200
|
||||
Subject: [PATCH 03/32] ucm: substitute the merged tree completely
|
||||
|
||||
We need to define the common shared configuration like for multiple
|
||||
HDMI devices or so. Substitute the whole merged configuration tree
|
||||
including identifiers.
|
||||
|
||||
Fixes: https://github.com/alsa-project/alsa-lib/issues/67
|
||||
Fixes: https://github.com/alsa-project/alsa-ucm-conf/commit/dcef48f13d4f5db79b006755074940b94730a883
|
||||
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
|
||||
---
|
||||
src/ucm/ucm_cond.c | 2 +-
|
||||
src/ucm/ucm_include.c | 9 +++++++--
|
||||
src/ucm/ucm_local.h | 6 +++++-
|
||||
src/ucm/ucm_subs.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
4 files changed, 66 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/ucm/ucm_cond.c b/src/ucm/ucm_cond.c
|
||||
index cc4915396d71..3ca3096e0b19 100644
|
||||
--- a/src/ucm/ucm_cond.c
|
||||
+++ b/src/ucm/ucm_cond.c
|
||||
@@ -401,7 +401,7 @@ int uc_mgr_evaluate_condition(snd_use_case_mgr_t *uc_mgr,
|
||||
err = uc_mgr_evaluate_inplace(uc_mgr, a);
|
||||
if (err < 0)
|
||||
return err;
|
||||
- err = uc_mgr_config_tree_merge(parent, a, before, after);
|
||||
+ err = uc_mgr_config_tree_merge(uc_mgr, parent, a, before, after);
|
||||
if (err < 0)
|
||||
return err;
|
||||
snd_config_delete(a);
|
||||
diff --git a/src/ucm/ucm_include.c b/src/ucm/ucm_include.c
|
||||
index c69490f49c6e..94ae944d2001 100644
|
||||
--- a/src/ucm/ucm_include.c
|
||||
+++ b/src/ucm/ucm_include.c
|
||||
@@ -206,7 +206,8 @@ static int compound_merge(const char *id,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-int uc_mgr_config_tree_merge(snd_config_t *parent, snd_config_t *new_ctx,
|
||||
+int uc_mgr_config_tree_merge(snd_use_case_mgr_t *uc_mgr,
|
||||
+ snd_config_t *parent, snd_config_t *new_ctx,
|
||||
snd_config_t *before, snd_config_t *after)
|
||||
{
|
||||
snd_config_iterator_t i, next;
|
||||
@@ -214,6 +215,10 @@ int uc_mgr_config_tree_merge(snd_config_t *parent, snd_config_t *new_ctx,
|
||||
const char *id;
|
||||
int err;
|
||||
|
||||
+ err = uc_mgr_substitute_tree(uc_mgr, new_ctx);
|
||||
+ if (err < 0)
|
||||
+ return err;
|
||||
+
|
||||
snd_config_for_each(i, next, new_ctx) {
|
||||
n = snd_config_iterator_entry(i);
|
||||
err = snd_config_remove(n);
|
||||
@@ -271,7 +276,7 @@ int uc_mgr_evaluate_include(snd_use_case_mgr_t *uc_mgr,
|
||||
err = uc_mgr_evaluate_inplace(uc_mgr, a);
|
||||
if (err < 0)
|
||||
return err;
|
||||
- err = uc_mgr_config_tree_merge(parent, a, before, after);
|
||||
+ err = uc_mgr_config_tree_merge(uc_mgr, parent, a, before, after);
|
||||
if (err < 0)
|
||||
return err;
|
||||
snd_config_delete(a);
|
||||
diff --git a/src/ucm/ucm_local.h b/src/ucm/ucm_local.h
|
||||
index 709f4cbd5a20..dd72e3f55f95 100644
|
||||
--- a/src/ucm/ucm_local.h
|
||||
+++ b/src/ucm/ucm_local.h
|
||||
@@ -307,7 +307,11 @@ int uc_mgr_get_substituted_value(snd_use_case_mgr_t *uc_mgr,
|
||||
char **_rvalue,
|
||||
const char *value);
|
||||
|
||||
-int uc_mgr_config_tree_merge(snd_config_t *parent, snd_config_t *new_ctx,
|
||||
+int uc_mgr_substitute_tree(snd_use_case_mgr_t *uc_mgr,
|
||||
+ snd_config_t *node);
|
||||
+
|
||||
+int uc_mgr_config_tree_merge(snd_use_case_mgr_t *uc_mgr,
|
||||
+ snd_config_t *parent, snd_config_t *new_ctx,
|
||||
snd_config_t *before, snd_config_t *after);
|
||||
|
||||
int uc_mgr_evaluate_inplace(snd_use_case_mgr_t *uc_mgr,
|
||||
diff --git a/src/ucm/ucm_subs.c b/src/ucm/ucm_subs.c
|
||||
index d40e5478b084..f608bb0955a6 100644
|
||||
--- a/src/ucm/ucm_subs.c
|
||||
+++ b/src/ucm/ucm_subs.c
|
||||
@@ -395,3 +395,56 @@ __error:
|
||||
free(r);
|
||||
return err;
|
||||
}
|
||||
+
|
||||
+static inline int uc_mgr_substitute_check(const char *s)
|
||||
+{
|
||||
+ return s && strstr(s, "${") != NULL;
|
||||
+}
|
||||
+
|
||||
+int uc_mgr_substitute_tree(snd_use_case_mgr_t *uc_mgr, snd_config_t *node)
|
||||
+{
|
||||
+ snd_config_iterator_t i, next;
|
||||
+ snd_config_t *n;
|
||||
+ const char *id, *s2;
|
||||
+ char *s;
|
||||
+ int err;
|
||||
+
|
||||
+ err = snd_config_get_id(node, &id);
|
||||
+ if (err < 0)
|
||||
+ return err;
|
||||
+ if (uc_mgr_substitute_check(id)) {
|
||||
+ err = uc_mgr_get_substituted_value(uc_mgr, &s, id);
|
||||
+ if (err < 0)
|
||||
+ return err;
|
||||
+ err = snd_config_set_id(node, s);
|
||||
+ free(s);
|
||||
+ if (err < 0) {
|
||||
+ uc_error("unable to set substituted id '%s' (old id '%s')", s, id);
|
||||
+ return err;
|
||||
+ }
|
||||
+ }
|
||||
+ if (snd_config_get_type(node) != SND_CONFIG_TYPE_COMPOUND) {
|
||||
+ if (snd_config_get_type(node) == SND_CONFIG_TYPE_STRING) {
|
||||
+ err = snd_config_get_string(node, &s2);
|
||||
+ if (err < 0)
|
||||
+ return err;
|
||||
+ if (!uc_mgr_substitute_check(s2))
|
||||
+ return 0;
|
||||
+ err = uc_mgr_get_substituted_value(uc_mgr, &s, s2);
|
||||
+ if (err < 0)
|
||||
+ return err;
|
||||
+ err = snd_config_set_string(node, s);
|
||||
+ free(s);
|
||||
+ if (err < 0)
|
||||
+ return err;
|
||||
+ }
|
||||
+ return 0;
|
||||
+ }
|
||||
+ snd_config_for_each(i, next, node) {
|
||||
+ n = snd_config_iterator_entry(i);
|
||||
+ err = uc_mgr_substitute_tree(uc_mgr, n);
|
||||
+ if (err < 0)
|
||||
+ return err;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
--
|
||||
2.16.4
|
||||
|
@ -0,0 +1,36 @@
|
||||
From 877bdf95fdfdac840a7a664362ec69b85c59ecb0 Mon Sep 17 00:00:00 2001
|
||||
From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
|
||||
Date: Fri, 3 Jul 2020 09:37:51 +0900
|
||||
Subject: [PATCH 04/32] ctl: improve documentation for identifier of control
|
||||
element
|
||||
|
||||
In documentation, there're two ways relevant to the identifier of control
|
||||
element. However, the case of combination has the lack of parameters.
|
||||
|
||||
This commit improves documentation in this point.
|
||||
|
||||
Fixes: f3c24de8c0df ("ctl: add an overview for design of ALSA control interface")
|
||||
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
|
||||
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
|
||||
---
|
||||
src/control/control.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/control/control.c b/src/control/control.c
|
||||
index 19528ae30a0b..e21e8f1d2621 100644
|
||||
--- a/src/control/control.c
|
||||
+++ b/src/control/control.c
|
||||
@@ -49,8 +49,8 @@ are managed according to below model.
|
||||
- An element includes some members to have a value. The value of each member
|
||||
can be changed by both of userspace applications and drivers in kernel.
|
||||
|
||||
-Each element can be identified by two ways; a combination of name and index, or
|
||||
-numerical number (numid).
|
||||
+Each element can be identified by two ways; the numerical number (numid), or the
|
||||
+combination of interface, device, subdevice, name, and index.
|
||||
|
||||
The type of element set is one of integer, integerr64, boolean, enumerators,
|
||||
bytes and IEC958 structure. This indicates the type of value for each member in
|
||||
--
|
||||
2.16.4
|
||||
|
107
0005-pcm-dmix-make-lockless-operation-optional.patch
Normal file
107
0005-pcm-dmix-make-lockless-operation-optional.patch
Normal file
@ -0,0 +1,107 @@
|
||||
From 4759865c861c708ce4a68fc08060fc820628ccaf Mon Sep 17 00:00:00 2001
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Date: Fri, 19 Jun 2020 18:57:05 +0200
|
||||
Subject: [PATCH 05/32] pcm: dmix: make lockless operation optional
|
||||
|
||||
The recently reported (but a long-standing) bug about the
|
||||
unconditional semaphore usage in the dmix implies that basically we've
|
||||
had no problem with the locking in the practical usages over years.
|
||||
Although the lockless operation has a clear merit, it's a much higher
|
||||
CPU usage (especially on some uncached pages), and it might lead to a
|
||||
potential deadlock in theory (which is hard to reproduce at will,
|
||||
though).
|
||||
|
||||
This patch introduces a new configure option "--enable-lockless-dmix"
|
||||
or "--disable-lockless-dmix" to let user choose the default dmix
|
||||
operation mode. The usage of the lockless mixing has been already
|
||||
conditionally enabled via asoundrc and card config
|
||||
"direct_memory_access", so we just need to set the default value based
|
||||
on it.
|
||||
|
||||
In this patch, the default is set off to the lockless mixing, i.e. the
|
||||
generic mixing is chosen. It makes more sense from the performance
|
||||
POV. For any users who still require the lockless operation, it can
|
||||
be enabled either via configure option or the asoundrc.
|
||||
|
||||
The magic number used in the shmem is also changed depending on the
|
||||
operation mode. It's just for safety, not to conflict both operation
|
||||
modes with each other.
|
||||
|
||||
Reviewed-by: Jaroslav Kysela <perex@perex.cz>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
configure.ac | 13 +++++++++++++
|
||||
src/pcm/pcm_direct.c | 16 +++++++++++++---
|
||||
2 files changed, 26 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 93a54c909d1d..01357fb9310f 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -629,6 +629,19 @@ if test "$build_pcm_mmap_emul" = "yes"; then
|
||||
AC_DEFINE([BUILD_PCM_PLUGIN_MMAP_EMUL], "1", [Build PCM mmap-emul plugin])
|
||||
fi
|
||||
|
||||
+if test "$build_pcm_dmix" = "yes"; then
|
||||
+AC_MSG_CHECKING(for default lockless dmix)
|
||||
+AC_ARG_ENABLE(lockless-dmix,
|
||||
+ AS_HELP_STRING([--enable-lockless-dmix],
|
||||
+ [use lockless dmix as default on x86]),
|
||||
+ lockless_dmix="$enableval", lockless_dmix="no")
|
||||
+if test "$lockless_dmix" = "yes"; then
|
||||
+ AC_MSG_RESULT(yes)
|
||||
+ AC_DEFINE([LOCKLESS_DMIX_DEFAULT], "1", [Lockless dmix as default])
|
||||
+else
|
||||
+ AC_MSG_RESULT(no)
|
||||
+fi
|
||||
+fi
|
||||
|
||||
dnl Create PCM plugin symbol list for static library
|
||||
rm -f "$srcdir"/src/pcm/pcm_symbols_list.c
|
||||
diff --git a/src/pcm/pcm_direct.c b/src/pcm/pcm_direct.c
|
||||
index 665340954cf3..19c5a811262f 100644
|
||||
--- a/src/pcm/pcm_direct.c
|
||||
+++ b/src/pcm/pcm_direct.c
|
||||
@@ -82,7 +82,13 @@ int snd_pcm_direct_semaphore_create_or_connect(snd_pcm_direct_t *dmix)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-#define SND_PCM_DIRECT_MAGIC (0xa15ad300 + sizeof(snd_pcm_direct_share_t))
|
||||
+static unsigned int snd_pcm_direct_magic(snd_pcm_direct_t *dmix)
|
||||
+{
|
||||
+ if (!dmix->direct_memory_access)
|
||||
+ return 0xa15ad300 + sizeof(snd_pcm_direct_share_t);
|
||||
+ else
|
||||
+ return 0xb15ad300 + sizeof(snd_pcm_direct_share_t);
|
||||
+}
|
||||
|
||||
/*
|
||||
* global shared memory area
|
||||
@@ -132,10 +138,10 @@ retryget:
|
||||
buf.shm_perm.gid = dmix->ipc_gid;
|
||||
shmctl(dmix->shmid, IPC_SET, &buf);
|
||||
}
|
||||
- dmix->shmptr->magic = SND_PCM_DIRECT_MAGIC;
|
||||
+ dmix->shmptr->magic = snd_pcm_direct_magic(dmix);
|
||||
return 1;
|
||||
} else {
|
||||
- if (dmix->shmptr->magic != SND_PCM_DIRECT_MAGIC) {
|
||||
+ if (dmix->shmptr->magic != snd_pcm_direct_magic(dmix)) {
|
||||
snd_pcm_direct_shm_discard(dmix);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -1892,7 +1898,11 @@ int snd_pcm_direct_parse_open_conf(snd_config_t *root, snd_config_t *conf,
|
||||
rec->slowptr = 1;
|
||||
rec->max_periods = 0;
|
||||
rec->var_periodsize = 0;
|
||||
+#ifdef LOCKLESS_DMIX_DEFAULT
|
||||
rec->direct_memory_access = 1;
|
||||
+#else
|
||||
+ rec->direct_memory_access = 0;
|
||||
+#endif
|
||||
rec->hw_ptr_alignment = SND_PCM_HW_PTR_ALIGNMENT_AUTO;
|
||||
rec->tstamp_type = -1;
|
||||
|
||||
--
|
||||
2.16.4
|
||||
|
110
0006-pcm-dmix-Fix-semaphore-usage-with-lockless-operation.patch
Normal file
110
0006-pcm-dmix-Fix-semaphore-usage-with-lockless-operation.patch
Normal file
@ -0,0 +1,110 @@
|
||||
From d824b461ae807ea436e2df36da9c2212e485e3e6 Mon Sep 17 00:00:00 2001
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Date: Fri, 19 Jun 2020 18:40:46 +0200
|
||||
Subject: [PATCH 06/32] pcm: dmix: Fix semaphore usage with lockless operation
|
||||
|
||||
As Maarten Baert recently reported, the current dmix code applies the
|
||||
semaphore unnecessarily around mixing streams even when the lockless
|
||||
mix operation is used on x86. This was rather introduced mistakenly
|
||||
at the commit 267d7c728196 ("Add support of little-endian on
|
||||
i386/x86_64 dmix") where the generic dmix code was included on x86,
|
||||
too.
|
||||
|
||||
For achieving the original performance back, this patch changes the
|
||||
semaphore handling to be checked at run time instead of statically at
|
||||
compile time.
|
||||
|
||||
Reviewed-by: Jaroslav Kysela <perex@perex.cz>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/pcm/pcm_direct.h | 1 +
|
||||
src/pcm/pcm_dmix.c | 18 +++++++++++-------
|
||||
src/pcm/pcm_dmix_generic.c | 2 +-
|
||||
src/pcm/pcm_dmix_i386.c | 1 +
|
||||
src/pcm/pcm_dmix_x86_64.c | 1 +
|
||||
5 files changed, 15 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/src/pcm/pcm_direct.h b/src/pcm/pcm_direct.h
|
||||
index 8a236970a3a1..2150bce15449 100644
|
||||
--- a/src/pcm/pcm_direct.h
|
||||
+++ b/src/pcm/pcm_direct.h
|
||||
@@ -186,6 +186,7 @@ struct snd_pcm_direct {
|
||||
mix_areas_32_t *remix_areas_32;
|
||||
mix_areas_24_t *remix_areas_24;
|
||||
mix_areas_u8_t *remix_areas_u8;
|
||||
+ unsigned int use_sem;
|
||||
} dmix;
|
||||
struct {
|
||||
unsigned long long chn_mask;
|
||||
diff --git a/src/pcm/pcm_dmix.c b/src/pcm/pcm_dmix.c
|
||||
index 843fa3168756..e9343b19a536 100644
|
||||
--- a/src/pcm/pcm_dmix.c
|
||||
+++ b/src/pcm/pcm_dmix.c
|
||||
@@ -292,13 +292,17 @@ static void remix_areas(snd_pcm_direct_t *dmix,
|
||||
* the area via semaphore
|
||||
*/
|
||||
#ifndef DOC_HIDDEN
|
||||
-#ifdef NO_CONCURRENT_ACCESS
|
||||
-#define dmix_down_sem(dmix) snd_pcm_direct_semaphore_down(dmix, DIRECT_IPC_SEM_CLIENT)
|
||||
-#define dmix_up_sem(dmix) snd_pcm_direct_semaphore_up(dmix, DIRECT_IPC_SEM_CLIENT)
|
||||
-#else
|
||||
-#define dmix_down_sem(dmix)
|
||||
-#define dmix_up_sem(dmix)
|
||||
-#endif
|
||||
+static void dmix_down_sem(snd_pcm_direct_t *dmix)
|
||||
+{
|
||||
+ if (dmix->u.dmix.use_sem)
|
||||
+ snd_pcm_direct_semaphore_down(dmix, DIRECT_IPC_SEM_CLIENT);
|
||||
+}
|
||||
+
|
||||
+static void dmix_up_sem(snd_pcm_direct_t *dmix)
|
||||
+{
|
||||
+ if (dmix->u.dmix.use_sem)
|
||||
+ snd_pcm_direct_semaphore_up(dmix, DIRECT_IPC_SEM_CLIENT);
|
||||
+}
|
||||
#endif
|
||||
|
||||
/*
|
||||
diff --git a/src/pcm/pcm_dmix_generic.c b/src/pcm/pcm_dmix_generic.c
|
||||
index 40c08747a74a..8a5b6f148556 100644
|
||||
--- a/src/pcm/pcm_dmix_generic.c
|
||||
+++ b/src/pcm/pcm_dmix_generic.c
|
||||
@@ -43,7 +43,6 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
|
||||
#ifndef ARCH_ADD
|
||||
#define ARCH_ADD(p,a) (*(p) += (a))
|
||||
#define ARCH_CMPXCHG(p,a,b) (*(p)) /* fake */
|
||||
-#define NO_CONCURRENT_ACCESS /* use semaphore to avoid race */
|
||||
#define IS_CONCURRENT 0 /* no race check */
|
||||
#endif
|
||||
|
||||
@@ -530,6 +529,7 @@ static void generic_mix_select_callbacks(snd_pcm_direct_t *dmix)
|
||||
dmix->u.dmix.mix_areas_u8 = generic_mix_areas_u8;
|
||||
dmix->u.dmix.remix_areas_24 = generic_remix_areas_24;
|
||||
dmix->u.dmix.remix_areas_u8 = generic_remix_areas_u8;
|
||||
+ dmix->u.dmix.use_sem = 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
diff --git a/src/pcm/pcm_dmix_i386.c b/src/pcm/pcm_dmix_i386.c
|
||||
index 1ab983a8a373..82a91c5c2897 100644
|
||||
--- a/src/pcm/pcm_dmix_i386.c
|
||||
+++ b/src/pcm/pcm_dmix_i386.c
|
||||
@@ -135,4 +135,5 @@ static void mix_select_callbacks(snd_pcm_direct_t *dmix)
|
||||
dmix->u.dmix.mix_areas_24 = smp > 1 ? mix_areas_24_smp: mix_areas_24;
|
||||
dmix->u.dmix.remix_areas_24 = smp > 1 ? remix_areas_24_smp: remix_areas_24;
|
||||
}
|
||||
+ dmix->u.dmix.use_sem = 0;
|
||||
}
|
||||
diff --git a/src/pcm/pcm_dmix_x86_64.c b/src/pcm/pcm_dmix_x86_64.c
|
||||
index 34c40d4e9d1d..4d882bfd01bf 100644
|
||||
--- a/src/pcm/pcm_dmix_x86_64.c
|
||||
+++ b/src/pcm/pcm_dmix_x86_64.c
|
||||
@@ -102,4 +102,5 @@ static void mix_select_callbacks(snd_pcm_direct_t *dmix)
|
||||
dmix->u.dmix.remix_areas_32 = smp > 1 ? remix_areas_32_smp : remix_areas_32;
|
||||
dmix->u.dmix.mix_areas_24 = smp > 1 ? mix_areas_24_smp : mix_areas_24;
|
||||
dmix->u.dmix.remix_areas_24 = smp > 1 ? remix_areas_24_smp : remix_areas_24;
|
||||
+ dmix->u.dmix.use_sem = 0;
|
||||
}
|
||||
--
|
||||
2.16.4
|
||||
|
151
0007-pcm-iec958-implement-HDMI-HBR-audio-formatting.patch
Normal file
151
0007-pcm-iec958-implement-HDMI-HBR-audio-formatting.patch
Normal file
@ -0,0 +1,151 @@
|
||||
From 8defc5c2a65345a1aee613ebf0999d203c2e0433 Mon Sep 17 00:00:00 2001
|
||||
From: Matthias Reichl <hias@horus.com>
|
||||
Date: Mon, 13 Jul 2020 23:17:03 +0200
|
||||
Subject: [PATCH 07/32] pcm: iec958: implement HDMI HBR audio formatting
|
||||
|
||||
High bitrate compressed audio data like DTS HD or MAT is usually
|
||||
packed into 8-channel data. The HDMI specs state this has to be
|
||||
formatted as a single IEC958 stream, compared to normal multi-
|
||||
channel PCM data which has to be formatted as parallel IEC958 streams.
|
||||
|
||||
As this single-stream formatting mode may break existing setups that
|
||||
expect non-PCM multichannel data to be formatted as parallel IEC958
|
||||
streams it needs to be explicitly selected by setting the hdmi_mode
|
||||
option to true.
|
||||
|
||||
The single-stream formatting implementation is prepared to cope with
|
||||
arbitrary channel counts but only limited testing was done for channel
|
||||
counts other than 8.
|
||||
|
||||
Signed-off-by: Matthias Reichl <hias@horus.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/pcm/pcm_iec958.c | 37 +++++++++++++++++++++++++++++++++----
|
||||
1 file changed, 33 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/pcm/pcm_iec958.c b/src/pcm/pcm_iec958.c
|
||||
index 76d3ca7b8e3c..17ade9571cae 100644
|
||||
--- a/src/pcm/pcm_iec958.c
|
||||
+++ b/src/pcm/pcm_iec958.c
|
||||
@@ -63,6 +63,7 @@ struct snd_pcm_iec958 {
|
||||
unsigned int byteswap;
|
||||
unsigned char preamble[3]; /* B/M/W or Z/X/Y */
|
||||
snd_pcm_fast_ops_t fops;
|
||||
+ int hdmi_mode;
|
||||
};
|
||||
|
||||
enum { PREAMBLE_Z, PREAMBLE_X, PREAMBLE_Y };
|
||||
@@ -193,6 +194,10 @@ static void snd_pcm_iec958_encode(snd_pcm_iec958_t *iec,
|
||||
unsigned int channel;
|
||||
int32_t sample = 0;
|
||||
int counter = iec->counter;
|
||||
+ int single_stream = iec->hdmi_mode &&
|
||||
+ (iec->status[0] & IEC958_AES0_NONAUDIO) &&
|
||||
+ (channels == 8);
|
||||
+ int counter_step = single_stream ? ((channels + 1) >> 1) : 1;
|
||||
for (channel = 0; channel < channels; ++channel) {
|
||||
const char *src;
|
||||
uint32_t *dst;
|
||||
@@ -205,7 +210,12 @@ static void snd_pcm_iec958_encode(snd_pcm_iec958_t *iec,
|
||||
src_step = snd_pcm_channel_area_step(src_area);
|
||||
dst_step = snd_pcm_channel_area_step(dst_area) / sizeof(uint32_t);
|
||||
frames1 = frames;
|
||||
- iec->counter = counter;
|
||||
+
|
||||
+ if (single_stream)
|
||||
+ iec->counter = (counter + (channel >> 1)) % 192;
|
||||
+ else
|
||||
+ iec->counter = counter;
|
||||
+
|
||||
while (frames1-- > 0) {
|
||||
goto *get;
|
||||
#define GET32_END after
|
||||
@@ -217,9 +227,11 @@ static void snd_pcm_iec958_encode(snd_pcm_iec958_t *iec,
|
||||
*dst = sample;
|
||||
src += src_step;
|
||||
dst += dst_step;
|
||||
- iec->counter++;
|
||||
+ iec->counter += counter_step;
|
||||
iec->counter %= 192;
|
||||
}
|
||||
+ if (single_stream) /* set counter to ch0 value for next iteration */
|
||||
+ iec->counter = (counter + frames * counter_step) % 192;
|
||||
}
|
||||
}
|
||||
#endif /* DOC_HIDDEN */
|
||||
@@ -473,6 +485,7 @@ static const snd_pcm_ops_t snd_pcm_iec958_ops = {
|
||||
* \param close_slave When set, the slave PCM handle is closed with copy PCM
|
||||
* \param status_bits The IEC958 status bits
|
||||
* \param preamble_vals The preamble byte values
|
||||
+ * \param hdmi_mode When set, enable HDMI compliant formatting
|
||||
* \retval zero on success otherwise a negative error code
|
||||
* \warning Using of this function might be dangerous in the sense
|
||||
* of compatibility reasons. The prototype might be freely
|
||||
@@ -481,7 +494,8 @@ static const snd_pcm_ops_t snd_pcm_iec958_ops = {
|
||||
int snd_pcm_iec958_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sformat,
|
||||
snd_pcm_t *slave, int close_slave,
|
||||
const unsigned char *status_bits,
|
||||
- const unsigned char *preamble_vals)
|
||||
+ const unsigned char *preamble_vals,
|
||||
+ int hdmi_mode)
|
||||
{
|
||||
snd_pcm_t *pcm;
|
||||
snd_pcm_iec958_t *iec;
|
||||
@@ -519,6 +533,8 @@ int snd_pcm_iec958_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sfo
|
||||
|
||||
memcpy(iec->preamble, preamble_vals, 3);
|
||||
|
||||
+ iec->hdmi_mode = hdmi_mode;
|
||||
+
|
||||
err = snd_pcm_new(&pcm, SND_PCM_TYPE_IEC958, name, slave->stream, slave->mode);
|
||||
if (err < 0) {
|
||||
free(iec);
|
||||
@@ -566,9 +582,14 @@ pcm.name {
|
||||
[preamble.z or preamble.b val]
|
||||
[preamble.x or preamble.m val]
|
||||
[preamble.y or preamble.w val]
|
||||
+ [hdmi_mode true]
|
||||
}
|
||||
\endcode
|
||||
|
||||
+When <code>hdmi_mode</code> is true, 8-channel compressed data is
|
||||
+formatted as 4 contiguous frames of a single IEC958 stream as required
|
||||
+by the HDMI HBR specification.
|
||||
+
|
||||
\subsection pcm_plugins_iec958_funcref Function reference
|
||||
|
||||
<UL>
|
||||
@@ -605,6 +626,7 @@ int _snd_pcm_iec958_open(snd_pcm_t **pcmp, const char *name,
|
||||
unsigned char preamble_vals[3] = {
|
||||
0x08, 0x02, 0x04 /* Z, X, Y */
|
||||
};
|
||||
+ int hdmi_mode = 0;
|
||||
|
||||
snd_config_for_each(i, next, conf) {
|
||||
snd_config_t *n = snd_config_iterator_entry(i);
|
||||
@@ -633,6 +655,13 @@ int _snd_pcm_iec958_open(snd_pcm_t **pcmp, const char *name,
|
||||
preamble = n;
|
||||
continue;
|
||||
}
|
||||
+ if (strcmp(id, "hdmi_mode") == 0) {
|
||||
+ err = snd_config_get_bool(n);
|
||||
+ if (err < 0)
|
||||
+ continue;
|
||||
+ hdmi_mode = err;
|
||||
+ continue;
|
||||
+ }
|
||||
SNDERR("Unknown field %s", id);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -707,7 +736,7 @@ int _snd_pcm_iec958_open(snd_pcm_t **pcmp, const char *name,
|
||||
return err;
|
||||
err = snd_pcm_iec958_open(pcmp, name, sformat, spcm, 1,
|
||||
status ? status_bits : NULL,
|
||||
- preamble_vals);
|
||||
+ preamble_vals, hdmi_mode);
|
||||
if (err < 0)
|
||||
snd_pcm_close(spcm);
|
||||
return err;
|
||||
--
|
||||
2.16.4
|
||||
|
123
0008-pcm-iec958-set-channel-status-bits-according-to-rate.patch
Normal file
123
0008-pcm-iec958-set-channel-status-bits-according-to-rate.patch
Normal file
@ -0,0 +1,123 @@
|
||||
From 36e4b296d2f4ad0034f7028256c64b8af003068d Mon Sep 17 00:00:00 2001
|
||||
From: Matthias Reichl <hias@horus.com>
|
||||
Date: Mon, 13 Jul 2020 23:17:04 +0200
|
||||
Subject: [PATCH 08/32] pcm: iec958: set channel status bits according to rate
|
||||
and format
|
||||
|
||||
This mimics snd_pcm_create_iec958_consumer in the kernel.
|
||||
|
||||
The rate and wordlength bits will only be modified if they are
|
||||
set to "not indicated", which is now the default if no status
|
||||
option is used.
|
||||
|
||||
This allows applications to override parameters determined from
|
||||
the stream or implement channel status bits extensions without
|
||||
needing to change pcm_iec958 code.
|
||||
|
||||
Signed-off-by: Matthias Reichl <hias@horus.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/pcm/pcm_iec958.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++---
|
||||
1 file changed, 76 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/pcm/pcm_iec958.c b/src/pcm/pcm_iec958.c
|
||||
index 17ade9571cae..a11a043924f6 100644
|
||||
--- a/src/pcm/pcm_iec958.c
|
||||
+++ b/src/pcm/pcm_iec958.c
|
||||
@@ -365,9 +365,80 @@ static int snd_pcm_iec958_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params
|
||||
iec->byteswap = format != SND_PCM_FORMAT_IEC958_SUBFRAME;
|
||||
}
|
||||
}
|
||||
- /* FIXME: needs to adjust status_bits according to the format
|
||||
- * and sample rate
|
||||
- */
|
||||
+
|
||||
+ if ((iec->status[0] & IEC958_AES0_PROFESSIONAL) == 0) {
|
||||
+ if ((iec->status[3] & IEC958_AES3_CON_FS) == IEC958_AES3_CON_FS_NOTID) {
|
||||
+ unsigned int rate = 0;
|
||||
+ unsigned char fs;
|
||||
+
|
||||
+ err = INTERNAL(snd_pcm_hw_params_get_rate)(params, &rate, 0);
|
||||
+ if (err < 0)
|
||||
+ rate = 0;
|
||||
+
|
||||
+ switch (rate) {
|
||||
+ case 22050:
|
||||
+ fs = IEC958_AES3_CON_FS_22050;
|
||||
+ break;
|
||||
+ case 24000:
|
||||
+ fs = IEC958_AES3_CON_FS_24000;
|
||||
+ break;
|
||||
+ case 32000:
|
||||
+ fs = IEC958_AES3_CON_FS_32000;
|
||||
+ break;
|
||||
+ case 44100:
|
||||
+ fs = IEC958_AES3_CON_FS_44100;
|
||||
+ break;
|
||||
+ case 48000:
|
||||
+ fs = IEC958_AES3_CON_FS_48000;
|
||||
+ break;
|
||||
+ case 88200:
|
||||
+ fs = IEC958_AES3_CON_FS_88200;
|
||||
+ break;
|
||||
+ case 96000:
|
||||
+ fs = IEC958_AES3_CON_FS_96000;
|
||||
+ break;
|
||||
+ case 176400:
|
||||
+ fs = IEC958_AES3_CON_FS_176400;
|
||||
+ break;
|
||||
+ case 192000:
|
||||
+ fs = IEC958_AES3_CON_FS_192000;
|
||||
+ break;
|
||||
+ case 768000:
|
||||
+ fs = IEC958_AES3_CON_FS_768000;
|
||||
+ break;
|
||||
+ default:
|
||||
+ fs = IEC958_AES3_CON_FS_NOTID;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ iec->status[3] &= ~IEC958_AES3_CON_FS;
|
||||
+ iec->status[3] |= fs;
|
||||
+ }
|
||||
+
|
||||
+ if ((iec->status[4] & IEC958_AES4_CON_WORDLEN) == IEC958_AES4_CON_WORDLEN_NOTID) {
|
||||
+ unsigned char ws;
|
||||
+ switch (snd_pcm_format_width(format)) {
|
||||
+ case 16:
|
||||
+ ws = IEC958_AES4_CON_WORDLEN_20_16;
|
||||
+ break;
|
||||
+ case 18:
|
||||
+ ws = IEC958_AES4_CON_WORDLEN_22_18;
|
||||
+ break;
|
||||
+ case 20:
|
||||
+ ws = IEC958_AES4_CON_WORDLEN_20_16 | IEC958_AES4_CON_MAX_WORDLEN_24;
|
||||
+ break;
|
||||
+ case 24:
|
||||
+ case 32: /* Assume 24-bit width for 32-bit samples. */
|
||||
+ ws = IEC958_AES4_CON_WORDLEN_24_20 | IEC958_AES4_CON_MAX_WORDLEN_24;
|
||||
+ break;
|
||||
+ default:
|
||||
+ ws = IEC958_AES4_CON_WORDLEN_NOTID;
|
||||
+ break;
|
||||
+ }
|
||||
+ iec->status[4] &= ~(IEC958_AES4_CON_MAX_WORDLEN_24 | IEC958_AES4_CON_WORDLEN);
|
||||
+ iec->status[4] |= ws;
|
||||
+ }
|
||||
+ }
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -504,7 +575,8 @@ int snd_pcm_iec958_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sfo
|
||||
IEC958_AES0_CON_EMPHASIS_NONE,
|
||||
IEC958_AES1_CON_ORIGINAL | IEC958_AES1_CON_PCM_CODER,
|
||||
0,
|
||||
- IEC958_AES3_CON_FS_48000
|
||||
+ IEC958_AES3_CON_FS_NOTID, /* will be set in hwparams */
|
||||
+ IEC958_AES4_CON_WORDLEN_NOTID /* will be set in hwparams */
|
||||
};
|
||||
|
||||
assert(pcmp && slave);
|
||||
--
|
||||
2.16.4
|
||||
|
27
0009-conf-pcm-USB-Added-S-PDIF-fix-for-Asus-Xonar-SE.patch
Normal file
27
0009-conf-pcm-USB-Added-S-PDIF-fix-for-Asus-Xonar-SE.patch
Normal file
@ -0,0 +1,27 @@
|
||||
From a80606d1abfd3c2bccfa179c31af8b6e7c0a9031 Mon Sep 17 00:00:00 2001
|
||||
From: omar <odzinic@gmail.com>
|
||||
Date: Mon, 20 Jul 2020 11:46:46 -0400
|
||||
Subject: [PATCH 09/32] conf: pcm - USB - Added S/PDIF fix for Asus Xonar SE
|
||||
|
||||
Resolves #70
|
||||
From: omar <odzinic@gmail.com>
|
||||
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
|
||||
---
|
||||
src/conf/cards/USB-Audio.conf | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/src/conf/cards/USB-Audio.conf b/src/conf/cards/USB-Audio.conf
|
||||
index 01664abfc263..297629f34d77 100644
|
||||
--- a/src/conf/cards/USB-Audio.conf
|
||||
+++ b/src/conf/cards/USB-Audio.conf
|
||||
@@ -42,6 +42,7 @@ USB-Audio.pcm.iec958_device {
|
||||
"ASUS XONAR U5" 1
|
||||
"XONAR U5" 1
|
||||
"XONAR SOUND CARD" 1
|
||||
+ "Xonar SoundCard" 2
|
||||
|
||||
# The below don't have digital in/out, so prevent them from being opened.
|
||||
"Andrea PureAudio USB-SA Headset" 999
|
||||
--
|
||||
2.16.4
|
||||
|
60
0010-control-ctlparse-fix-enum-values-in-or.patch
Normal file
60
0010-control-ctlparse-fix-enum-values-in-or.patch
Normal file
@ -0,0 +1,60 @@
|
||||
From a3ca4803cb8db73d01231c69620e2d18573ffba9 Mon Sep 17 00:00:00 2001
|
||||
From: Jaroslav Kysela <perex@perex.cz>
|
||||
Date: Mon, 27 Jul 2020 13:18:20 +0200
|
||||
Subject: [PATCH 10/32] control: ctlparse - fix enum values in '' or ""
|
||||
|
||||
This comit fixes the enum value string parser
|
||||
(fixes aaf3a081bff1cc85635f7a3c3d4287c4addbbd84).
|
||||
|
||||
BugLink: https://github.com/alsa-project/alsa-ucm-conf/pull/40
|
||||
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
|
||||
---
|
||||
src/control/ctlparse.c | 26 +++++++++++++++-----------
|
||||
1 file changed, 15 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/src/control/ctlparse.c b/src/control/ctlparse.c
|
||||
index ee1e0602cbf7..74f76cca9ca4 100644
|
||||
--- a/src/control/ctlparse.c
|
||||
+++ b/src/control/ctlparse.c
|
||||
@@ -282,23 +282,27 @@ static int get_ctl_enum_item_index(snd_ctl_t *handle,
|
||||
if (items <= 0)
|
||||
return -1;
|
||||
|
||||
+ end = *ptr;
|
||||
+ if (end == '\'' || end == '"')
|
||||
+ ptr++;
|
||||
+ else
|
||||
+ end = '\0';
|
||||
+
|
||||
for (i = 0; i < items; i++) {
|
||||
snd_ctl_elem_info_set_item(info, i);
|
||||
if (snd_ctl_elem_info(handle, info) < 0)
|
||||
return -1;
|
||||
name = snd_ctl_elem_info_get_item_name(info);
|
||||
- end = *ptr;
|
||||
- if (end == '\'' || end == '"')
|
||||
- ptr++;
|
||||
- else
|
||||
- end = '\0';
|
||||
len = strlen(name);
|
||||
- if (strncmp(name, ptr, len) == 0) {
|
||||
- if (ptr[len] == end || ptr[len] == ',' || ptr[len] == '\n') {
|
||||
- ptr += len;
|
||||
- *ptrp = ptr;
|
||||
- return i;
|
||||
- }
|
||||
+ if (strncmp(name, ptr, len))
|
||||
+ continue;
|
||||
+ if (end == '\0' && (ptr[len] == '\0' || ptr[len] == ',' || ptr[len] == '\n')) {
|
||||
+ *ptrp = ptr + len;
|
||||
+ return i;
|
||||
+ }
|
||||
+ if (end != '\0' && ptr[len] == end) {
|
||||
+ *ptrp = ptr + len + 1;
|
||||
+ return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
--
|
||||
2.16.4
|
||||
|
@ -0,0 +1,31 @@
|
||||
From 464c2f8b61855cb22d61c4b232f74d6767fac5fb Mon Sep 17 00:00:00 2001
|
||||
From: Kai-Heng Feng <kai.heng.feng@canonical.com>
|
||||
Date: Mon, 3 Aug 2020 23:57:45 +0800
|
||||
Subject: [PATCH 11/32] conf: USB-Audio: Disable IEC958 on Lenovo ThinkStation
|
||||
P620
|
||||
|
||||
Both USB audio cards on Lenovo ThinkStation P620 don't support IEC958,
|
||||
so disable IEC958 accordingly.
|
||||
|
||||
Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/conf/cards/USB-Audio.conf | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/src/conf/cards/USB-Audio.conf b/src/conf/cards/USB-Audio.conf
|
||||
index 297629f34d77..9b64af3c0da9 100644
|
||||
--- a/src/conf/cards/USB-Audio.conf
|
||||
+++ b/src/conf/cards/USB-Audio.conf
|
||||
@@ -63,6 +63,8 @@ USB-Audio.pcm.iec958_device {
|
||||
"Scarlett 2i4 USB" 999
|
||||
"Sennheiser USB headset" 999
|
||||
"SWTOR Gaming Headset by Razer" 999
|
||||
+ "ThinkStation P620 Main" 999
|
||||
+ "ThinkStation P620 Rear" 999
|
||||
"Thunderbolt Dock Audio Headset" 999
|
||||
"Thunderbolt Dock Audio Module" 999
|
||||
"USB Device 0x46d_0x821" 999
|
||||
--
|
||||
2.16.4
|
||||
|
@ -0,0 +1,92 @@
|
||||
From 82cb27c165d4337fe3183668bd0fa21ff6287e8e Mon Sep 17 00:00:00 2001
|
||||
From: Vijay Palaniswamy <vijay.palaniswamy@in.bosch.com>
|
||||
Date: Thu, 23 Jul 2020 11:49:10 +0530
|
||||
Subject: [PATCH 12/32] pcm: dmix: fix access to sum-buffer in non-interleaved
|
||||
mixing mode
|
||||
|
||||
When dmix uses non-interleaved mixing mode the offset and step width
|
||||
to sum_buffer was calculated by using the dmix channels instead of
|
||||
the slave channels. This leads to audio distortions due to frame
|
||||
corruption.
|
||||
|
||||
example:
|
||||
- With below configuratio, Do aplay on both device in parallel for
|
||||
audio distortion
|
||||
|
||||
pcm.dmix_2_channels {
|
||||
type dmix
|
||||
ipc_key 5678293
|
||||
ipc_perm 0660
|
||||
ipc_gid audio
|
||||
bindings [0 1]
|
||||
|
||||
slave {
|
||||
pcm "hardware"
|
||||
channels 2
|
||||
periods 4
|
||||
period_time 40000
|
||||
}
|
||||
}
|
||||
|
||||
pcm.dmix_1_channels {
|
||||
type dmix
|
||||
ipc_key 5678293
|
||||
ipc_perm 0660
|
||||
ipc_gid audio
|
||||
bindings [0]
|
||||
|
||||
slave {
|
||||
pcm "hardware"
|
||||
channels 1
|
||||
periods 4
|
||||
period_time 40000
|
||||
}
|
||||
}
|
||||
|
||||
pcm.hardware {
|
||||
type hw
|
||||
card 0
|
||||
channels 2
|
||||
rate 48000
|
||||
format S16_LE
|
||||
}
|
||||
|
||||
Signed-off-by: Vijay Palaniswamy <vijay.palaniswamy@in.bosch.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/pcm/pcm_dmix.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/pcm/pcm_dmix.c b/src/pcm/pcm_dmix.c
|
||||
index e9343b19a536..8bce7aca85f7 100644
|
||||
--- a/src/pcm/pcm_dmix.c
|
||||
+++ b/src/pcm/pcm_dmix.c
|
||||
@@ -212,10 +212,10 @@ static void mix_areas(snd_pcm_direct_t *dmix,
|
||||
do_mix_areas(size,
|
||||
((unsigned char *)dst_areas[dchn].addr + dst_areas[dchn].first / 8) + dst_ofs * dst_step,
|
||||
((unsigned char *)src_areas[chn].addr + src_areas[chn].first / 8) + src_ofs * src_step,
|
||||
- dmix->u.dmix.sum_buffer + channels * dst_ofs + chn,
|
||||
+ dmix->u.dmix.sum_buffer + dmix->shmptr->s.channels * dst_ofs + dchn,
|
||||
dst_step,
|
||||
src_step,
|
||||
- channels * sizeof(signed int));
|
||||
+ dmix->shmptr->s.channels * sizeof(signed int));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,10 +280,10 @@ static void remix_areas(snd_pcm_direct_t *dmix,
|
||||
do_remix_areas(size,
|
||||
((unsigned char *)dst_areas[dchn].addr + dst_areas[dchn].first / 8) + dst_ofs * dst_step,
|
||||
((unsigned char *)src_areas[chn].addr + src_areas[chn].first / 8) + src_ofs * src_step,
|
||||
- dmix->u.dmix.sum_buffer + channels * dst_ofs + chn,
|
||||
+ dmix->u.dmix.sum_buffer + dmix->shmptr->s.channels * dst_ofs + dchn,
|
||||
dst_step,
|
||||
src_step,
|
||||
- channels * sizeof(signed int));
|
||||
+ dmix->shmptr->s.channels * sizeof(signed int));
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.16.4
|
||||
|
278
0014-control-Add-documentation-for-snd_ctl_elem_list_.patch
Normal file
278
0014-control-Add-documentation-for-snd_ctl_elem_list_.patch
Normal file
@ -0,0 +1,278 @@
|
||||
From e097dd491a8f25418a90d38aea549bb4668de955 Mon Sep 17 00:00:00 2001
|
||||
From: "Tanjeff-N. Moos" <tanjeff@cccmz.de>
|
||||
Date: Fri, 14 Aug 2020 08:40:28 +0200
|
||||
Subject: [PATCH 14/32] control: Add documentation for snd_ctl_elem_list_*.
|
||||
|
||||
Signed-off-by: Tanjeff-N. Moos <tanjeff@cccmz.de>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
include/control.h | 81 +++++++++++++++++++++++++++++++++++++++++++++++++--
|
||||
src/control/control.c | 80 +++++++++++++++++++++++++++++++++++++++++++-------
|
||||
2 files changed, 148 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/include/control.h b/include/control.h
|
||||
index 02db72d413ae..9deec6f3dee4 100644
|
||||
--- a/include/control.h
|
||||
+++ b/include/control.h
|
||||
@@ -56,7 +56,75 @@ typedef struct _snd_ctl_card_info snd_ctl_card_info_t;
|
||||
/** CTL element identifier container */
|
||||
typedef struct _snd_ctl_elem_id snd_ctl_elem_id_t;
|
||||
|
||||
-/** CTL element identifier list container */
|
||||
+/** CTL element list container
|
||||
+ *
|
||||
+ * This is a list of CTL elements. The list contains management
|
||||
+ * information (e.g. how many elements the sound card has) as well as
|
||||
+ * the element identifiers. All functions which operate on the list
|
||||
+ * are named snd_ctl_elem_list_*().
|
||||
+ *
|
||||
+ * \par Memory management
|
||||
+ *
|
||||
+ * There are two memory areas to deal with: The list container itself
|
||||
+ * and the memory for the element identifiers.
|
||||
+ *
|
||||
+ * To manage the area for the list container, the following functions
|
||||
+ * are used:
|
||||
+ *
|
||||
+ * - snd_ctl_elem_list_malloc() / snd_ctl_elem_list_free() to allocate
|
||||
+ * and free memory on the heap, or
|
||||
+ * - snd_ctl_elem_list_alloca() to allocate the memory on the
|
||||
+ * stack. This memory is auto-released when the stack is unwound.
|
||||
+ *
|
||||
+ * To manage the space for the element identifiers, the
|
||||
+ * snd_ctl_elem_list_alloc_space() and snd_ctl_elem_list_free_space()
|
||||
+ * are used. Allocating the right amount of space can be achieved by
|
||||
+ * first obtaining the number of elements and then calling
|
||||
+ * snd_ctl_elem_list_alloc_space():
|
||||
+ *
|
||||
+ * \code
|
||||
+ * snd_ctl_elem_list_t* list;
|
||||
+ * int count;
|
||||
+ *
|
||||
+ * // Initialise list
|
||||
+ * snd_ctl_elem_list_malloc(&list);
|
||||
+ *
|
||||
+ * // Get number of elements
|
||||
+ * snd_ctl_elem_list(ctl, list);
|
||||
+ * count = snd_ctl_elem_list_get_count(list);
|
||||
+ *
|
||||
+ * // Allocate space for identifiers
|
||||
+ * snd_ctl_elem_list_alloc_space(list, count);
|
||||
+ *
|
||||
+ * // Get identifiers
|
||||
+ * snd_ctl_elem_list(ctl, list); // yes, this is same as above :)
|
||||
+ *
|
||||
+ * // Do something useful with the list...
|
||||
+ *
|
||||
+ * // Cleanup
|
||||
+ * snd_ctl_elem_list_free_space(list);
|
||||
+ * snd_ctl_elem_list_free(list);
|
||||
+ * \endcode
|
||||
+ *
|
||||
+ *
|
||||
+ * \par The Elements
|
||||
+ *
|
||||
+ * The elements in the list are accessed using an index. This index is
|
||||
+ * the location in the list; Don't confuse it with the 'index' of the
|
||||
+ * element identifier. For example:
|
||||
+ *
|
||||
+ * \code
|
||||
+ * snd_ctl_elem_list_t list;
|
||||
+ * unsigned int element_index;
|
||||
+ *
|
||||
+ * // Allocate space, fill list ...
|
||||
+ *
|
||||
+ * element_index = snd_ctl_elem_list_get_index(&list, 2);
|
||||
+ * \endcode
|
||||
+ *
|
||||
+ * This will access the 3rd element in the list (index=2) and get the
|
||||
+ * elements index from the driver (which might be 13, for example).
|
||||
+ */
|
||||
typedef struct _snd_ctl_elem_list snd_ctl_elem_list_t;
|
||||
|
||||
/** CTL element info container */
|
||||
@@ -354,11 +422,18 @@ void snd_ctl_event_copy(snd_ctl_event_t *dst, const snd_ctl_event_t *src);
|
||||
snd_ctl_event_type_t snd_ctl_event_get_type(const snd_ctl_event_t *obj);
|
||||
|
||||
size_t snd_ctl_elem_list_sizeof(void);
|
||||
+
|
||||
/** \hideinitializer
|
||||
- * \brief allocate an invalid #snd_ctl_elem_list_t using standard alloca
|
||||
- * \param ptr returned pointer
|
||||
+ *
|
||||
+ * \brief Allocate a #snd_ctl_elem_list_t using standard alloca.
|
||||
+ *
|
||||
+ * The memory is allocated on the stack and will automatically be
|
||||
+ * released when the stack unwinds (i.e. no free() is needed).
|
||||
+ *
|
||||
+ * \param ptr Pointer to allocated memory.
|
||||
*/
|
||||
#define snd_ctl_elem_list_alloca(ptr) __snd_alloca(ptr, snd_ctl_elem_list)
|
||||
+
|
||||
int snd_ctl_elem_list_malloc(snd_ctl_elem_list_t **ptr);
|
||||
void snd_ctl_elem_list_free(snd_ctl_elem_list_t *obj);
|
||||
void snd_ctl_elem_list_clear(snd_ctl_elem_list_t *obj);
|
||||
diff --git a/src/control/control.c b/src/control/control.c
|
||||
index e21e8f1d2621..1bcf1ab2e431 100644
|
||||
--- a/src/control/control.c
|
||||
+++ b/src/control/control.c
|
||||
@@ -280,6 +280,21 @@ int snd_ctl_card_info(snd_ctl_t *ctl, snd_ctl_card_info_t *info)
|
||||
|
||||
/**
|
||||
* \brief Get a list of element identifiers
|
||||
+ *
|
||||
+ * Before calling this function, memoru must be allocated using
|
||||
+ * snd_ctl_elem_list_malloc().
|
||||
+ *
|
||||
+ * This function obtains data from the sound card driver and puts it
|
||||
+ * into the list.
|
||||
+ *
|
||||
+ * If there was space allocated for the element identifiers (using
|
||||
+ * snd_ctl_elem_list_alloc_space()), information will be filled in. If
|
||||
+ * too little space was allocated, only a part of the elements will be
|
||||
+ * queried. If there was too much space allocated, some of it remains
|
||||
+ * unused. Use snd_ctl_elem_list_get_count() and
|
||||
+ * snd_ctl_elem_list_get_used() to obtain information about space
|
||||
+ * usage. See #snd_ctl_elem_list_t to learn more.
|
||||
+ *
|
||||
* \param ctl CTL handle
|
||||
* \param list CTL element identifiers list pointer
|
||||
* \return 0 on success otherwise a negative error code
|
||||
@@ -1508,9 +1523,14 @@ const char *snd_ctl_event_type_name(snd_ctl_event_type_t type)
|
||||
|
||||
/**
|
||||
* \brief allocate space for CTL element identifiers list
|
||||
- * \param obj CTL element identifiers list
|
||||
- * \param entries Entries to allocate
|
||||
- * \return 0 on success otherwise a negative error code
|
||||
+ *
|
||||
+ * The space can be released with snd_ctl_elem_list_free_space().
|
||||
+ *
|
||||
+ * \param obj CTL element identifiers list.
|
||||
+ * \param entries How many entries to allocate. See
|
||||
+ * #snd_ctl_elem_list_t to learn how to obtain
|
||||
+ * this number in advance.
|
||||
+ * \return 0 on success otherwise a negative error code.
|
||||
*/
|
||||
int snd_ctl_elem_list_alloc_space(snd_ctl_elem_list_t *obj, unsigned int entries)
|
||||
{
|
||||
@@ -1526,6 +1546,10 @@ int snd_ctl_elem_list_alloc_space(snd_ctl_elem_list_t *obj, unsigned int entries
|
||||
|
||||
/**
|
||||
* \brief free previously allocated space for CTL element identifiers list
|
||||
+ *
|
||||
+ * Releases space previously allocated using
|
||||
+ * snd_ctl_elem_list_alloc_space().
|
||||
+ *
|
||||
* \param obj CTL element identifiers list
|
||||
*/
|
||||
void snd_ctl_elem_list_free_space(snd_ctl_elem_list_t *obj)
|
||||
@@ -2016,7 +2040,7 @@ snd_ctl_event_type_t snd_ctl_event_get_type(const snd_ctl_event_t *obj)
|
||||
}
|
||||
|
||||
/**
|
||||
- * \brief get size of #snd_ctl_elem_list_t
|
||||
+ * \brief get size of #snd_ctl_elem_list_t.
|
||||
* \return size in bytes
|
||||
*/
|
||||
size_t snd_ctl_elem_list_sizeof()
|
||||
@@ -2025,7 +2049,10 @@ size_t snd_ctl_elem_list_sizeof()
|
||||
}
|
||||
|
||||
/**
|
||||
- * \brief allocate an invalid #snd_ctl_elem_list_t using standard malloc
|
||||
+ * \brief allocate a #snd_ctl_elem_list_t using standard malloc.
|
||||
+ *
|
||||
+ * The memory can be released using snd_ctl_elem_list_free().
|
||||
+ *
|
||||
* \param ptr returned pointer
|
||||
* \return 0 on success otherwise negative error code
|
||||
*/
|
||||
@@ -2039,7 +2066,15 @@ int snd_ctl_elem_list_malloc(snd_ctl_elem_list_t **ptr)
|
||||
}
|
||||
|
||||
/**
|
||||
- * \brief frees a previously allocated #snd_ctl_elem_list_t
|
||||
+ * \brief frees a previously allocated #snd_ctl_elem_list_t.
|
||||
+ *
|
||||
+ * Release memory previously allocated using
|
||||
+ * snd_ctl_elem_list_malloc().
|
||||
+ *
|
||||
+ * If you used snd_ctl_elem_list_alloc_space() on the list, you must
|
||||
+ * use snd_ctl_elem_list_free_space() \em before calling this
|
||||
+ * function.
|
||||
+ *
|
||||
* \param obj pointer to object to free
|
||||
*/
|
||||
void snd_ctl_elem_list_free(snd_ctl_elem_list_t *obj)
|
||||
@@ -2048,7 +2083,15 @@ void snd_ctl_elem_list_free(snd_ctl_elem_list_t *obj)
|
||||
}
|
||||
|
||||
/**
|
||||
- * \brief clear given #snd_ctl_elem_list_t object
|
||||
+ * \brief Clear given #snd_ctl_elem_list_t object.
|
||||
+ *
|
||||
+ * This will make the stored identifiers inaccessible without freeing
|
||||
+ * their space.
|
||||
+ *
|
||||
+ * \warning The element identifier space cannot be freed after calling
|
||||
+ * this function. Therefore, snd_ctl_elem_list_free_space()
|
||||
+ * must be called in advance.
|
||||
+ *
|
||||
* \param obj pointer to object to clear
|
||||
*/
|
||||
void snd_ctl_elem_list_clear(snd_ctl_elem_list_t *obj)
|
||||
@@ -2057,7 +2100,11 @@ void snd_ctl_elem_list_clear(snd_ctl_elem_list_t *obj)
|
||||
}
|
||||
|
||||
/**
|
||||
- * \brief copy one #snd_ctl_elem_list_t to another
|
||||
+ * \brief copy one #snd_ctl_elem_list_t to another.
|
||||
+ *
|
||||
+ * This performs a shallow copy. That means the both lists will share
|
||||
+ * the same space for the elements. The elements will not be copied.
|
||||
+ *
|
||||
* \param dst pointer to destination
|
||||
* \param src pointer to source
|
||||
*/
|
||||
@@ -2080,6 +2127,12 @@ void snd_ctl_elem_list_set_offset(snd_ctl_elem_list_t *obj, unsigned int val)
|
||||
|
||||
/**
|
||||
* \brief Get number of used entries in CTL element identifiers list
|
||||
+ *
|
||||
+ * This function returns how many entries are actually filled with
|
||||
+ * useful information.
|
||||
+ *
|
||||
+ * See also snd_ctl_elem_list_get_count().
|
||||
+ *
|
||||
* \param obj CTL element identifier list
|
||||
* \return number of used entries
|
||||
*/
|
||||
@@ -2090,7 +2143,14 @@ unsigned int snd_ctl_elem_list_get_used(const snd_ctl_elem_list_t *obj)
|
||||
}
|
||||
|
||||
/**
|
||||
- * \brief Get total count of elements present in CTL device (information present in every filled CTL element identifiers list)
|
||||
+ * \brief Get total count of elements present in CTL device
|
||||
+ *
|
||||
+ * This function returns how many entries were allocated using
|
||||
+ * snd_ctl_elem_list_alloc_space(). This information is present after
|
||||
+ * snd_ctl_elem_list() was called.
|
||||
+ *
|
||||
+ * See also snd_ctl_elem_list_get_used().
|
||||
+ *
|
||||
* \param obj CTL element identifier list
|
||||
* \return total number of elements
|
||||
*/
|
||||
@@ -2140,7 +2200,7 @@ snd_ctl_elem_iface_t snd_ctl_elem_list_get_interface(const snd_ctl_elem_list_t *
|
||||
}
|
||||
|
||||
/**
|
||||
- * \brief Get device part of CTL element identifier for an entry of a CTL element identifiers list
|
||||
+ * \brief Get the device part of CTL element identifier for an entry of a CTL element identifiers list
|
||||
* \param obj CTL element identifier list
|
||||
* \param idx Index of entry
|
||||
* \return CTL element related device
|
||||
--
|
||||
2.16.4
|
||||
|
@ -0,0 +1,27 @@
|
||||
From ed752498522b0a99a9fbec99247d9c73b10abb3e Mon Sep 17 00:00:00 2001
|
||||
From: Jaroslav Kysela <perex@perex.cz>
|
||||
Date: Tue, 18 Aug 2020 16:53:23 +0200
|
||||
Subject: [PATCH 15/32] conf: quote also strings with '*' and '#' characters in
|
||||
string_print()
|
||||
|
||||
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
|
||||
---
|
||||
src/conf.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/src/conf.c b/src/conf.c
|
||||
index 8518f90c5d60..7df2b4e77759 100644
|
||||
--- a/src/conf.c
|
||||
+++ b/src/conf.c
|
||||
@@ -1536,6 +1536,8 @@ static void string_print(char *str, int id, snd_output_t *out)
|
||||
case ']':
|
||||
case '\'':
|
||||
case '"':
|
||||
+ case '*':
|
||||
+ case '#':
|
||||
goto quoted;
|
||||
default:
|
||||
if (*p <= 31 || *p >= 127)
|
||||
--
|
||||
2.16.4
|
||||
|
54
0016-topology-decode-Fix-channel-map-memory-allocation.patch
Normal file
54
0016-topology-decode-Fix-channel-map-memory-allocation.patch
Normal file
@ -0,0 +1,54 @@
|
||||
From 1ac965184eaefe503939e454273223a1d8d32f41 Mon Sep 17 00:00:00 2001
|
||||
From: Piotr Maziarz <piotrx.maziarz@linux.intel.com>
|
||||
Date: Mon, 31 Aug 2020 11:08:54 +0200
|
||||
Subject: [PATCH 16/32] topology: decode: Fix channel map memory allocation
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Memory allocated on the stack was referenced outside of the function scope
|
||||
caused undefined behaviour.
|
||||
|
||||
Signed-off-by: Piotr Maziarz <piotrx.maziarz@linux.intel.com>
|
||||
Reviewed-by: Cezary Rojewski <cezary.rojewski@intel.com>
|
||||
Reviewed-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
|
||||
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
|
||||
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
|
||||
---
|
||||
src/topology/ctl.c | 13 +++++++------
|
||||
1 file changed, 7 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/src/topology/ctl.c b/src/topology/ctl.c
|
||||
index 90241b6318c5..6e6c1d163aa3 100644
|
||||
--- a/src/topology/ctl.c
|
||||
+++ b/src/topology/ctl.c
|
||||
@@ -1330,7 +1330,6 @@ int tplg_decode_control_enum1(snd_tplg_t *tplg,
|
||||
void *bin, size_t size)
|
||||
{
|
||||
struct snd_soc_tplg_enum_control *ec = bin;
|
||||
- struct snd_tplg_channel_map_template cmt;
|
||||
int i;
|
||||
|
||||
if (size < sizeof(*ec)) {
|
||||
@@ -1375,11 +1374,13 @@ int tplg_decode_control_enum1(snd_tplg_t *tplg,
|
||||
}
|
||||
}
|
||||
|
||||
- et->map = &cmt;
|
||||
- memset(&cmt, 0, sizeof(cmt));
|
||||
- cmt.num_channels = ec->num_channels;
|
||||
- for (i = 0; i < cmt.num_channels; i++) {
|
||||
- struct snd_tplg_channel_elem *channel = &cmt.channel[i];
|
||||
+ et->map = tplg_calloc(heap, sizeof(struct snd_tplg_channel_map_template));
|
||||
+ if (!et->map)
|
||||
+ return -ENOMEM;
|
||||
+ et->map->num_channels = ec->num_channels;
|
||||
+ for (i = 0; i < et->map->num_channels; i++) {
|
||||
+ struct snd_tplg_channel_elem *channel = &et->map->channel[i];
|
||||
+
|
||||
tplg_log(tplg, 'D', pos + ((void *)&ec->channel[i] - (void *)ec),
|
||||
"enum: channel size %d", ec->channel[i].size);
|
||||
channel->reg = ec->channel[i].reg;
|
||||
--
|
||||
2.16.4
|
||||
|
@ -0,0 +1,36 @@
|
||||
From 346a5efa87c38a0d5ff9bd5b5d08be27b6c9bfaf Mon Sep 17 00:00:00 2001
|
||||
From: Piotr Maziarz <piotrx.maziarz@linux.intel.com>
|
||||
Date: Mon, 31 Aug 2020 11:08:55 +0200
|
||||
Subject: [PATCH 17/32] topology: decode: Fix infinite loop in decoding enum
|
||||
control
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Accessing memory outside of allocated boundaries caused segmentation fault.
|
||||
|
||||
Signed-off-by: Piotr Maziarz <piotrx.maziarz@linux.intel.com>
|
||||
Reviewed-by: Cezary Rojewski <cezary.rojewski@intel.com>
|
||||
Reviewed-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
|
||||
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
|
||||
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
|
||||
---
|
||||
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 6e6c1d163aa3..0aa49ab82c1e 100644
|
||||
--- a/src/topology/ctl.c
|
||||
+++ b/src/topology/ctl.c
|
||||
@@ -1367,7 +1367,7 @@ int tplg_decode_control_enum1(snd_tplg_t *tplg,
|
||||
et->texts = tplg_calloc(heap, sizeof(char *) * ec->items);
|
||||
if (!et->texts)
|
||||
return -ENOMEM;
|
||||
- for (i = 0; ec->items; i++) {
|
||||
+ for (i = 0; i < ec->items; i++) {
|
||||
unsigned int j = i * sizeof(int) * ENUM_VAL_SIZE;
|
||||
et->texts[i] = ec->texts[i];
|
||||
et->values[i] = (int *)&ec->values[j];
|
||||
--
|
||||
2.16.4
|
||||
|
@ -0,0 +1,42 @@
|
||||
From 11d4a5aa721dce2c3f7430996caf244a73dd5099 Mon Sep 17 00:00:00 2001
|
||||
From: Piotr Maziarz <piotrx.maziarz@linux.intel.com>
|
||||
Date: Mon, 31 Aug 2020 11:08:56 +0200
|
||||
Subject: [PATCH 18/32] topology: decode: Remove decoding values for enum
|
||||
control
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Values have no representation in standard ALSA configuration files,
|
||||
therefore there is no need to populate them. Also memory for values
|
||||
wasn't allocated which was causing undefined behaviour.
|
||||
|
||||
Signed-off-by: Piotr Maziarz <piotrx.maziarz@linux.intel.com>
|
||||
Reviewed-by: Cezary Rojewski <cezary.rojewski@intel.com>
|
||||
Reviewed-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
|
||||
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
|
||||
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
|
||||
---
|
||||
src/topology/ctl.c | 5 +----
|
||||
1 file changed, 1 insertion(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/topology/ctl.c b/src/topology/ctl.c
|
||||
index 0aa49ab82c1e..02e482e7d05d 100644
|
||||
--- a/src/topology/ctl.c
|
||||
+++ b/src/topology/ctl.c
|
||||
@@ -1367,11 +1367,8 @@ int tplg_decode_control_enum1(snd_tplg_t *tplg,
|
||||
et->texts = tplg_calloc(heap, sizeof(char *) * ec->items);
|
||||
if (!et->texts)
|
||||
return -ENOMEM;
|
||||
- for (i = 0; i < ec->items; i++) {
|
||||
- unsigned int j = i * sizeof(int) * ENUM_VAL_SIZE;
|
||||
+ for (i = 0; i < ec->items; i++)
|
||||
et->texts[i] = ec->texts[i];
|
||||
- et->values[i] = (int *)&ec->values[j];
|
||||
- }
|
||||
}
|
||||
|
||||
et->map = tplg_calloc(heap, sizeof(struct snd_tplg_channel_map_template));
|
||||
--
|
||||
2.16.4
|
||||
|
@ -0,0 +1,50 @@
|
||||
From f1435207a2fbe35bf616c6d58eecd8801dbe5642 Mon Sep 17 00:00:00 2001
|
||||
From: Piotr Maziarz <piotrx.maziarz@linux.intel.com>
|
||||
Date: Mon, 31 Aug 2020 11:08:57 +0200
|
||||
Subject: [PATCH 19/32] topology: decode: Add enum control texts as separate
|
||||
element
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Texts are separate sections that should referenced by enum control.
|
||||
|
||||
Signed-off-by: Piotr Maziarz <piotrx.maziarz@linux.intel.com>
|
||||
Reviewed-by: Cezary Rojewski <cezary.rojewski@intel.com>
|
||||
Reviewed-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
|
||||
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
|
||||
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
|
||||
---
|
||||
src/topology/ctl.c | 14 +++++++++++---
|
||||
1 file changed, 11 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/topology/ctl.c b/src/topology/ctl.c
|
||||
index 02e482e7d05d..1f3984616a65 100644
|
||||
--- a/src/topology/ctl.c
|
||||
+++ b/src/topology/ctl.c
|
||||
@@ -1088,11 +1088,19 @@ int tplg_add_enum(snd_tplg_t *tplg, struct snd_tplg_enum_template *enum_ctl,
|
||||
}
|
||||
|
||||
if (enum_ctl->texts != NULL) {
|
||||
+ struct tplg_elem *texts = tplg_elem_new_common(tplg, NULL,
|
||||
+ enum_ctl->hdr.name, SND_TPLG_TYPE_TEXT);
|
||||
+
|
||||
+ texts->texts->num_items = num_items;
|
||||
for (i = 0; i < num_items; i++) {
|
||||
- if (enum_ctl->texts[i] != NULL)
|
||||
- snd_strlcpy(ec->texts[i], enum_ctl->texts[i],
|
||||
- SNDRV_CTL_ELEM_ID_NAME_MAXLEN);
|
||||
+ if (!enum_ctl->texts[i])
|
||||
+ continue;
|
||||
+ snd_strlcpy(ec->texts[i], enum_ctl->texts[i],
|
||||
+ SNDRV_CTL_ELEM_ID_NAME_MAXLEN);
|
||||
+ snd_strlcpy(texts->texts->items[i], enum_ctl->texts[i],
|
||||
+ SNDRV_CTL_ELEM_ID_NAME_MAXLEN);
|
||||
}
|
||||
+ tplg_ref_add(elem, SND_TPLG_TYPE_TEXT, enum_ctl->hdr.name);
|
||||
}
|
||||
|
||||
if (enum_ctl->values != NULL) {
|
||||
--
|
||||
2.16.4
|
||||
|
33
0020-topology-decode-Fix-printing-texts-section.patch
Normal file
33
0020-topology-decode-Fix-printing-texts-section.patch
Normal file
@ -0,0 +1,33 @@
|
||||
From 56a096ca2ceaf1dec944258d961c274e6550b27a Mon Sep 17 00:00:00 2001
|
||||
From: Piotr Maziarz <piotrx.maziarz@linux.intel.com>
|
||||
Date: Mon, 31 Aug 2020 11:08:58 +0200
|
||||
Subject: [PATCH 20/32] topology: decode: Fix printing texts section
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Piotr Maziarz <piotrx.maziarz@linux.intel.com>
|
||||
Reviewed-by: Cezary Rojewski <cezary.rojewski@intel.com>
|
||||
Reviewed-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
|
||||
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
|
||||
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
|
||||
---
|
||||
src/topology/text.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/topology/text.c b/src/topology/text.c
|
||||
index 507c5450ab14..b899b2813ab4 100644
|
||||
--- a/src/topology/text.c
|
||||
+++ b/src/topology/text.c
|
||||
@@ -103,7 +103,7 @@ int tplg_save_text(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
||||
return 0;
|
||||
err = tplg_save_printf(dst, pfx, "'%s'.values [\n", elem->id);
|
||||
for (i = 0; err >= 0 && i < texts->num_items; i++)
|
||||
- err = tplg_save_printf(dst, pfx, "\t'%s'\n", texts->items[i][0]);
|
||||
+ err = tplg_save_printf(dst, pfx, "\t'%s'\n", texts->items[i]);
|
||||
if (err >= 0)
|
||||
err = tplg_save_printf(dst, pfx, "]\n");
|
||||
return err;
|
||||
--
|
||||
2.16.4
|
||||
|
@ -0,0 +1,95 @@
|
||||
From c32498603aea7cc2f3fa3f850f9e4ea0f6ce03b2 Mon Sep 17 00:00:00 2001
|
||||
From: Piotr Maziarz <piotrx.maziarz@linux.intel.com>
|
||||
Date: Mon, 31 Aug 2020 11:08:59 +0200
|
||||
Subject: [PATCH 21/32] topology: decode: Change declaration of enum decoding
|
||||
function
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Size constraints are always checked before invoking
|
||||
tplg_decode_control_enum1. There is no need to validate it twice.
|
||||
Alos moved debug print about size to invoking function, since now it's it
|
||||
responsibility to check size.
|
||||
|
||||
Signed-off-by: Piotr Maziarz <piotrx.maziarz@linux.intel.com>
|
||||
Reviewed-by: Cezary Rojewski <cezary.rojewski@intel.com>
|
||||
Reviewed-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
|
||||
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
|
||||
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
|
||||
---
|
||||
src/topology/ctl.c | 19 +++++--------------
|
||||
src/topology/dapm.c | 3 +--
|
||||
src/topology/tplg_local.h | 2 +-
|
||||
3 files changed, 7 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/src/topology/ctl.c b/src/topology/ctl.c
|
||||
index 1f3984616a65..47db400fd4d1 100644
|
||||
--- a/src/topology/ctl.c
|
||||
+++ b/src/topology/ctl.c
|
||||
@@ -1335,22 +1335,10 @@ int tplg_decode_control_enum1(snd_tplg_t *tplg,
|
||||
struct list_head *heap,
|
||||
struct snd_tplg_enum_template *et,
|
||||
size_t pos,
|
||||
- void *bin, size_t size)
|
||||
+ struct snd_soc_tplg_enum_control *ec)
|
||||
{
|
||||
- struct snd_soc_tplg_enum_control *ec = bin;
|
||||
int i;
|
||||
|
||||
- if (size < sizeof(*ec)) {
|
||||
- SNDERR("enum: small size %d", size);
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
- tplg_log(tplg, 'D', pos, "enum: size %d private size %d",
|
||||
- ec->size, ec->priv.size);
|
||||
- if (size != ec->size + ec->priv.size) {
|
||||
- SNDERR("enum: unexpected element size %d", size);
|
||||
- return -EINVAL;
|
||||
- }
|
||||
if (ec->num_channels > SND_TPLG_MAX_CHAN ||
|
||||
ec->num_channels > SND_SOC_TPLG_MAX_CHAN) {
|
||||
SNDERR("enum: unexpected channel count %d", ec->num_channels);
|
||||
@@ -1427,7 +1415,10 @@ next:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- err = tplg_decode_control_enum1(tplg, &heap, &et, pos, bin, size);
|
||||
+ tplg_log(tplg, 'D', pos, "enum: size %d private size %d",
|
||||
+ ec->size, ec->priv.size);
|
||||
+
|
||||
+ err = tplg_decode_control_enum1(tplg, &heap, &et, pos, ec);
|
||||
if (err >= 0) {
|
||||
t.enum_ctl = &et;
|
||||
err = snd_tplg_add_object(tplg, &t);
|
||||
diff --git a/src/topology/dapm.c b/src/topology/dapm.c
|
||||
index cd1a87704681..73a9390340c2 100644
|
||||
--- a/src/topology/dapm.c
|
||||
+++ b/src/topology/dapm.c
|
||||
@@ -972,8 +972,7 @@ next:
|
||||
err = -EINVAL;
|
||||
goto retval;
|
||||
}
|
||||
- err = tplg_decode_control_enum1(tplg, &heap, et, pos,
|
||||
- bin, size2);
|
||||
+ err = tplg_decode_control_enum1(tplg, &heap, et, pos, ec);
|
||||
break;
|
||||
case SND_SOC_TPLG_TYPE_BYTES:
|
||||
bt = tplg_calloc(&heap, sizeof(*bt));
|
||||
diff --git a/src/topology/tplg_local.h b/src/topology/tplg_local.h
|
||||
index 5ace0d1919e1..acb01a831f30 100644
|
||||
--- a/src/topology/tplg_local.h
|
||||
+++ b/src/topology/tplg_local.h
|
||||
@@ -398,7 +398,7 @@ int tplg_decode_control_enum1(snd_tplg_t *tplg,
|
||||
struct list_head *heap,
|
||||
struct snd_tplg_enum_template *et,
|
||||
size_t pos,
|
||||
- void *bin, size_t size);
|
||||
+ struct snd_soc_tplg_enum_control *ec);
|
||||
int tplg_decode_control_enum(snd_tplg_t *tplg, size_t pos,
|
||||
struct snd_soc_tplg_hdr *hdr,
|
||||
void *bin, size_t size);
|
||||
--
|
||||
2.16.4
|
||||
|
@ -0,0 +1,46 @@
|
||||
From acbb0e3b1741107d01f03ee06f7819fd7f90bec4 Mon Sep 17 00:00:00 2001
|
||||
From: Piotr Maziarz <piotrx.maziarz@linux.intel.com>
|
||||
Date: Mon, 31 Aug 2020 11:09:00 +0200
|
||||
Subject: [PATCH 22/32] topology: decode: Fix decoding PCM formats and rates
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Not checking _LAST format and rate, which are valid indexes in arrays,
|
||||
makes data loss while converting binary to standard ALSA configuration
|
||||
file.
|
||||
|
||||
Signed-off-by: Piotr Maziarz <piotrx.maziarz@linux.intel.com>
|
||||
Reviewed-by: Cezary Rojewski <cezary.rojewski@intel.com>
|
||||
Reviewed-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
|
||||
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
|
||||
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
|
||||
---
|
||||
src/topology/pcm.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/topology/pcm.c b/src/topology/pcm.c
|
||||
index b15b95045ab5..db401145f3ec 100644
|
||||
--- a/src/topology/pcm.c
|
||||
+++ b/src/topology/pcm.c
|
||||
@@ -549,7 +549,7 @@ int tplg_save_stream_caps(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
||||
if (err >= 0 && sc->formats) {
|
||||
err = tplg_save_printf(dst, pfx, "\tformats '");
|
||||
first = 1;
|
||||
- for (i = 0; err >= 0 && i < SND_PCM_FORMAT_LAST; i++) {
|
||||
+ for (i = 0; err >= 0 && i <= SND_PCM_FORMAT_LAST; i++) {
|
||||
if (sc->formats & (1ULL << i)) {
|
||||
s = snd_pcm_format_name(i);
|
||||
err = tplg_save_printf(dst, NULL, "%s%s",
|
||||
@@ -563,7 +563,7 @@ int tplg_save_stream_caps(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
||||
if (err >= 0 && sc->rates) {
|
||||
err = tplg_save_printf(dst, pfx, "\trates '");
|
||||
first = 1;
|
||||
- for (i = 0; err >= 0 && i < SND_PCM_RATE_LAST; i++) {
|
||||
+ for (i = 0; err >= 0 && i <= SND_PCM_RATE_LAST; i++) {
|
||||
if (sc->rates & (1ULL << i)) {
|
||||
s = get_rate_name(i);
|
||||
err = tplg_save_printf(dst, NULL, "%s%s",
|
||||
--
|
||||
2.16.4
|
||||
|
@ -0,0 +1,38 @@
|
||||
From d93b3462996a20951bc0ca753d0304bbbb9850fc Mon Sep 17 00:00:00 2001
|
||||
From: Piotr Maziarz <piotrx.maziarz@linux.intel.com>
|
||||
Date: Mon, 31 Aug 2020 11:09:01 +0200
|
||||
Subject: [PATCH 23/32] topology: decode: Print sig_bits field in PCM
|
||||
capabilities section
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Not printing this field makes data loss while converting from binary
|
||||
to standard ALSA configuration file.
|
||||
|
||||
Signed-off-by: Piotr Maziarz <piotrx.maziarz@linux.intel.com>
|
||||
Reviewed-by: Cezary Rojewski <cezary.rojewski@intel.com>
|
||||
Reviewed-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
|
||||
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
|
||||
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
|
||||
---
|
||||
src/topology/pcm.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/src/topology/pcm.c b/src/topology/pcm.c
|
||||
index db401145f3ec..49c5eaba8b82 100644
|
||||
--- a/src/topology/pcm.c
|
||||
+++ b/src/topology/pcm.c
|
||||
@@ -604,6 +604,9 @@ int tplg_save_stream_caps(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
||||
if (err >= 0 && sc->buffer_size_max)
|
||||
err = tplg_save_printf(dst, pfx, "\tbuffer_size_max %u\n",
|
||||
sc->buffer_size_max);
|
||||
+ if (err >= 0 && sc->sig_bits)
|
||||
+ err = tplg_save_printf(dst, pfx, "\tsig_bits %u\n",
|
||||
+ sc->sig_bits);
|
||||
if (err >= 0)
|
||||
err = tplg_save_printf(dst, pfx, "}\n");
|
||||
return err;
|
||||
--
|
||||
2.16.4
|
||||
|
38
0024-topology-decode-Add-DAI-name-printing.patch
Normal file
38
0024-topology-decode-Add-DAI-name-printing.patch
Normal file
@ -0,0 +1,38 @@
|
||||
From 6b0fb2bc7e0cfac8e1aedfcad183ab247c85173d Mon Sep 17 00:00:00 2001
|
||||
From: Piotr Maziarz <piotrx.maziarz@linux.intel.com>
|
||||
Date: Mon, 31 Aug 2020 11:09:02 +0200
|
||||
Subject: [PATCH 24/32] topology: decode: Add DAI name printing
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
DAI name is a part of topology binary. Not printing makes data loss while
|
||||
converting from binary to standard ALSA configuration file.
|
||||
|
||||
Signed-off-by: Piotr Maziarz <piotrx.maziarz@linux.intel.com>
|
||||
Reviewed-by: Cezary Rojewski <cezary.rojewski@intel.com>
|
||||
Reviewed-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
|
||||
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
|
||||
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
|
||||
---
|
||||
src/topology/pcm.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/topology/pcm.c b/src/topology/pcm.c
|
||||
index 49c5eaba8b82..5a54e1534c95 100644
|
||||
--- a/src/topology/pcm.c
|
||||
+++ b/src/topology/pcm.c
|
||||
@@ -781,7 +781,9 @@ int tplg_save_fe_dai(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
||||
struct snd_soc_tplg_pcm *pcm = elem->pcm;
|
||||
int err = 0;
|
||||
|
||||
- if (pcm->dai_id > 0)
|
||||
+ if (strlen(pcm->dai_name))
|
||||
+ err = tplg_save_printf(dst, pfx, "dai.'%s'.id %u\n", pcm->dai_name, pcm->dai_id);
|
||||
+ else if (pcm->dai_id > 0)
|
||||
err = tplg_save_printf(dst, pfx, "dai.0.id %u\n", pcm->dai_id);
|
||||
return err;
|
||||
}
|
||||
--
|
||||
2.16.4
|
||||
|
94
0025-topology-Make-buffer-for-saving-dynamic-size.patch
Normal file
94
0025-topology-Make-buffer-for-saving-dynamic-size.patch
Normal file
@ -0,0 +1,94 @@
|
||||
From d04e72c9a593015952e4858b92ab3f9d821560d9 Mon Sep 17 00:00:00 2001
|
||||
From: Piotr Maziarz <piotrx.maziarz@linux.intel.com>
|
||||
Date: Mon, 31 Aug 2020 11:09:03 +0200
|
||||
Subject: [PATCH 25/32] topology: Make buffer for saving dynamic size
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Some fields can exceed size limit, e.g. private data has no size
|
||||
restriction. Therefore it needs to be dynamically increased.
|
||||
|
||||
Signed-off-by: Piotr Maziarz <piotrx.maziarz@linux.intel.com>
|
||||
Reviewed-by: Cezary Rojewski <cezary.rojewski@intel.com>
|
||||
Reviewed-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
|
||||
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
|
||||
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
|
||||
---
|
||||
src/topology/save.c | 34 +++++++++++++++++++++++++++++-----
|
||||
1 file changed, 29 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/src/topology/save.c b/src/topology/save.c
|
||||
index 4ecf86c3ade4..9c74735aea36 100644
|
||||
--- a/src/topology/save.c
|
||||
+++ b/src/topology/save.c
|
||||
@@ -19,22 +19,43 @@
|
||||
#include "tplg_local.h"
|
||||
|
||||
#define SAVE_ALLOC_SHIFT (13) /* 8192 bytes */
|
||||
+#define PRINT_BUF_SIZE (1024)
|
||||
+#define PRINT_BUF_SIZE_MAX (1024 * 1024)
|
||||
|
||||
int tplg_save_printf(char **dst, const char *pfx, const char *fmt, ...)
|
||||
{
|
||||
va_list va;
|
||||
- char buf[1024], *s;
|
||||
+ char *buf, *s;
|
||||
size_t n, l, t, pl;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ buf = malloc(PRINT_BUF_SIZE);
|
||||
+ if (!buf)
|
||||
+ return -ENOMEM;
|
||||
|
||||
if (pfx == NULL)
|
||||
pfx = "";
|
||||
|
||||
va_start(va, fmt);
|
||||
- n = vsnprintf(buf, sizeof(buf), fmt, va);
|
||||
+ n = vsnprintf(buf, PRINT_BUF_SIZE, fmt, va);
|
||||
va_end(va);
|
||||
|
||||
- if (n >= sizeof(buf))
|
||||
- return -EOVERFLOW;
|
||||
+ if (n >= PRINT_BUF_SIZE_MAX) {
|
||||
+ ret = -EOVERFLOW;
|
||||
+ goto end;
|
||||
+ }
|
||||
+
|
||||
+ if (n >= PRINT_BUF_SIZE) {
|
||||
+ char *tmp = realloc(buf, n + 1);
|
||||
+ if (!tmp) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto end;
|
||||
+ }
|
||||
+ buf = tmp;
|
||||
+ va_start(va, fmt);
|
||||
+ n = vsnprintf(buf, n + 1, fmt, va);
|
||||
+ va_end(va);
|
||||
+ }
|
||||
|
||||
pl = strlen(pfx);
|
||||
l = *dst ? strlen(*dst) : 0;
|
||||
@@ -47,7 +68,8 @@ int tplg_save_printf(char **dst, const char *pfx, const char *fmt, ...)
|
||||
if (s == NULL) {
|
||||
free(*dst);
|
||||
*dst = NULL;
|
||||
- return -ENOMEM;
|
||||
+ ret = -ENOMEM;
|
||||
+ goto end;
|
||||
}
|
||||
} else {
|
||||
s = *dst;
|
||||
@@ -57,6 +79,8 @@ int tplg_save_printf(char **dst, const char *pfx, const char *fmt, ...)
|
||||
strcpy(s + l, pfx);
|
||||
strcpy(s + l + pl, buf);
|
||||
*dst = s;
|
||||
+end:
|
||||
+ free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
--
|
||||
2.16.4
|
||||
|
26
0026-topology-return-correct-value-in-tplg_save_printf.patch
Normal file
26
0026-topology-return-correct-value-in-tplg_save_printf.patch
Normal file
@ -0,0 +1,26 @@
|
||||
From dc778bade60812a71b98ac827c2c6e3c02f14cf1 Mon Sep 17 00:00:00 2001
|
||||
From: Jaroslav Kysela <perex@perex.cz>
|
||||
Date: Mon, 31 Aug 2020 13:21:26 +0200
|
||||
Subject: [PATCH 26/32] topology: return correct value in tplg_save_printf()
|
||||
|
||||
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
|
||||
---
|
||||
src/topology/save.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/topology/save.c b/src/topology/save.c
|
||||
index 9c74735aea36..16fd694638ef 100644
|
||||
--- a/src/topology/save.c
|
||||
+++ b/src/topology/save.c
|
||||
@@ -81,7 +81,7 @@ int tplg_save_printf(char **dst, const char *pfx, const char *fmt, ...)
|
||||
*dst = s;
|
||||
end:
|
||||
free(buf);
|
||||
- return 0;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
int tplg_nice_value_format(char *dst, size_t dst_size, unsigned int value)
|
||||
--
|
||||
2.16.4
|
||||
|
40
0027-topology-fix-some-gcc10-warnings-labs-signess.patch
Normal file
40
0027-topology-fix-some-gcc10-warnings-labs-signess.patch
Normal file
@ -0,0 +1,40 @@
|
||||
From 6ca1ddfbcdf97ad46c3767ba314d1144119361fd Mon Sep 17 00:00:00 2001
|
||||
From: Jaroslav Kysela <perex@perex.cz>
|
||||
Date: Mon, 31 Aug 2020 13:25:01 +0200
|
||||
Subject: [PATCH 27/32] topology: fix some gcc10 warnings (labs, signess)
|
||||
|
||||
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
|
||||
---
|
||||
src/topology/builder.c | 2 +-
|
||||
src/topology/ctl.c | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/topology/builder.c b/src/topology/builder.c
|
||||
index 15757668d7d4..f8aba830320e 100644
|
||||
--- a/src/topology/builder.c
|
||||
+++ b/src/topology/builder.c
|
||||
@@ -55,7 +55,7 @@ static ssize_t write_block_header(snd_tplg_t *tplg, unsigned int type,
|
||||
" offset 0x%zx is %s by %ld bytes",
|
||||
tplg->next_hdr_pos, tplg->bin_pos,
|
||||
tplg->bin_pos > tplg->next_hdr_pos ? "ahead" : "behind",
|
||||
- labs(tplg->bin_pos - tplg->next_hdr_pos));
|
||||
+ tplg->bin_pos - tplg->next_hdr_pos);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
diff --git a/src/topology/ctl.c b/src/topology/ctl.c
|
||||
index 47db400fd4d1..1d31b4944abf 100644
|
||||
--- a/src/topology/ctl.c
|
||||
+++ b/src/topology/ctl.c
|
||||
@@ -1363,7 +1363,7 @@ int tplg_decode_control_enum1(snd_tplg_t *tplg,
|
||||
et->texts = tplg_calloc(heap, sizeof(char *) * ec->items);
|
||||
if (!et->texts)
|
||||
return -ENOMEM;
|
||||
- for (i = 0; i < ec->items; i++)
|
||||
+ for (i = 0; (unsigned int)i < ec->items; i++)
|
||||
et->texts[i] = ec->texts[i];
|
||||
}
|
||||
|
||||
--
|
||||
2.16.4
|
||||
|
48
0028-topology-fix-sort_config.patch
Normal file
48
0028-topology-fix-sort_config.patch
Normal file
@ -0,0 +1,48 @@
|
||||
From 84c6aeef5ca89c0686ae2a9ed90504010f8fe9e6 Mon Sep 17 00:00:00 2001
|
||||
From: Jaroslav Kysela <perex@perex.cz>
|
||||
Date: Mon, 31 Aug 2020 14:25:56 +0200
|
||||
Subject: [PATCH 28/32] topology: fix sort_config()
|
||||
|
||||
The temporary config array must be initialized for all compound types.
|
||||
|
||||
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
|
||||
---
|
||||
src/topology/save.c | 14 ++++++--------
|
||||
1 file changed, 6 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/src/topology/save.c b/src/topology/save.c
|
||||
index 16fd694638ef..631d84b273bf 100644
|
||||
--- a/src/topology/save.c
|
||||
+++ b/src/topology/save.c
|
||||
@@ -143,7 +143,6 @@ static snd_config_t *sort_config(const char *id, snd_config_t *src)
|
||||
int index, array, count;
|
||||
|
||||
if (snd_config_get_type(src) != SND_CONFIG_TYPE_COMPOUND) {
|
||||
-
|
||||
if (snd_config_copy(&dst, src) >= 0)
|
||||
return dst;
|
||||
return NULL;
|
||||
@@ -155,14 +154,13 @@ static snd_config_t *sort_config(const char *id, snd_config_t *src)
|
||||
if (a == NULL)
|
||||
return NULL;
|
||||
array = snd_config_is_array(src);
|
||||
- if (array <= 0) {
|
||||
- index = 0;
|
||||
- snd_config_for_each(i, next, src) {
|
||||
- snd_config_t *s = snd_config_iterator_entry(i);
|
||||
- a[index++] = s;
|
||||
- }
|
||||
- qsort(a, count, sizeof(a[0]), _compar);
|
||||
+ index = 0;
|
||||
+ snd_config_for_each(i, next, src) {
|
||||
+ snd_config_t *s = snd_config_iterator_entry(i);
|
||||
+ a[index++] = s;
|
||||
}
|
||||
+ if (array <= 0)
|
||||
+ qsort(a, count, sizeof(a[0]), _compar);
|
||||
if (snd_config_make_compound(&dst, id, count == 1)) {
|
||||
free(a);
|
||||
return NULL;
|
||||
--
|
||||
2.16.4
|
||||
|
159
0029-topology-fix-the-unaligned-access.patch
Normal file
159
0029-topology-fix-the-unaligned-access.patch
Normal file
@ -0,0 +1,159 @@
|
||||
From ab73253924ad8d46f94ab1212e0f05ebc2e3dcc5 Mon Sep 17 00:00:00 2001
|
||||
From: Jaroslav Kysela <perex@perex.cz>
|
||||
Date: Mon, 31 Aug 2020 14:27:26 +0200
|
||||
Subject: [PATCH 29/32] topology: fix the unaligned access
|
||||
|
||||
Introduce unaligned_get32/put32 helpers to deal with the
|
||||
packed structures.
|
||||
|
||||
Use the gcc __BYTE_ORDER__ defines for the endian checks.
|
||||
It may be improved to support other compilation environment.
|
||||
|
||||
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
|
||||
---
|
||||
src/topology/parser.c | 6 ++----
|
||||
src/topology/pcm.c | 26 ++++++++++++++------------
|
||||
src/topology/tplg_local.h | 13 +++++++++++++
|
||||
3 files changed, 29 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/src/topology/parser.c b/src/topology/parser.c
|
||||
index 436e48416a43..f34de01bdc53 100644
|
||||
--- a/src/topology/parser.c
|
||||
+++ b/src/topology/parser.c
|
||||
@@ -427,10 +427,8 @@ void snd_tplg_verbose(snd_tplg_t *tplg, int verbose)
|
||||
|
||||
static bool is_little_endian(void)
|
||||
{
|
||||
-#ifdef __BYTE_ORDER
|
||||
- #if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
- return true;
|
||||
- #endif
|
||||
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ && __SIZEOF_INT__ == 4
|
||||
+ return true;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
diff --git a/src/topology/pcm.c b/src/topology/pcm.c
|
||||
index 5a54e1534c95..a60ba00d979a 100644
|
||||
--- a/src/topology/pcm.c
|
||||
+++ b/src/topology/pcm.c
|
||||
@@ -376,19 +376,19 @@ static int split_rate(struct snd_soc_tplg_stream_caps *caps, char *str)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int parse_unsigned(snd_config_t *n, unsigned int *dst)
|
||||
+static int parse_unsigned(snd_config_t *n, void *dst)
|
||||
{
|
||||
int ival;
|
||||
|
||||
if (tplg_get_integer(n, &ival, 0) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
- *dst = ival;
|
||||
+ unaligned_put32(dst, ival);
|
||||
#if TPLG_DEBUG
|
||||
{
|
||||
const char *id;
|
||||
if (snd_config_get_id(n, &id) >= 0)
|
||||
- tplg_dbg("\t\t%s: %d", id, *dst);
|
||||
+ tplg_dbg("\t\t%s: %d", id, ival);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
@@ -621,7 +621,7 @@ static int tplg_parse_streams(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
||||
struct tplg_elem *elem = private;
|
||||
struct snd_soc_tplg_pcm *pcm;
|
||||
struct snd_soc_tplg_dai *dai;
|
||||
- unsigned int *playback, *capture;
|
||||
+ void *playback, *capture;
|
||||
struct snd_soc_tplg_stream_caps *caps;
|
||||
const char *id, *value;
|
||||
int stream;
|
||||
@@ -651,10 +651,10 @@ static int tplg_parse_streams(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
||||
|
||||
if (strcmp(id, "playback") == 0) {
|
||||
stream = SND_SOC_TPLG_STREAM_PLAYBACK;
|
||||
- *playback = 1;
|
||||
+ unaligned_put32(playback, 1);
|
||||
} else if (strcmp(id, "capture") == 0) {
|
||||
stream = SND_SOC_TPLG_STREAM_CAPTURE;
|
||||
- *capture = 1;
|
||||
+ unaligned_put32(capture, 1);
|
||||
} else
|
||||
return -EINVAL;
|
||||
|
||||
@@ -747,6 +747,7 @@ static int tplg_parse_fe_dai(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
||||
snd_config_iterator_t i, next;
|
||||
snd_config_t *n;
|
||||
const char *id;
|
||||
+ unsigned int dai_id;
|
||||
|
||||
snd_config_get_id(cfg, &id);
|
||||
tplg_dbg("\t\tFE DAI %s:", id);
|
||||
@@ -761,12 +762,13 @@ static int tplg_parse_fe_dai(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
||||
continue;
|
||||
|
||||
if (strcmp(id, "id") == 0) {
|
||||
- if (tplg_get_unsigned(n, &pcm->dai_id, 0)) {
|
||||
+ if (tplg_get_unsigned(n, &dai_id, 0)) {
|
||||
SNDERR("invalid fe dai ID");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- tplg_dbg("\t\t\tindex: %d", pcm->dai_id);
|
||||
+ unaligned_put32(&pcm->dai_id, dai_id);
|
||||
+ tplg_dbg("\t\t\tindex: %d", dai_id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -790,7 +792,7 @@ int tplg_save_fe_dai(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
||||
|
||||
/* parse a flag bit of the given mask */
|
||||
static int parse_flag(snd_config_t *n, unsigned int mask_in,
|
||||
- unsigned int *mask, unsigned int *flags)
|
||||
+ void *mask, void *flags)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -798,11 +800,11 @@ static int parse_flag(snd_config_t *n, unsigned int mask_in,
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
- *mask |= mask_in;
|
||||
+ unaligned_put32(mask, unaligned_get32(mask) | mask_in);
|
||||
if (ret)
|
||||
- *flags |= mask_in;
|
||||
+ unaligned_put32(flags, unaligned_get32(flags) | mask_in);
|
||||
else
|
||||
- *flags &= ~mask_in;
|
||||
+ unaligned_put32(flags, unaligned_get32(flags) & (~mask_in));
|
||||
|
||||
return 0;
|
||||
}
|
||||
diff --git a/src/topology/tplg_local.h b/src/topology/tplg_local.h
|
||||
index acb01a831f30..0c7be2001a63 100644
|
||||
--- a/src/topology/tplg_local.h
|
||||
+++ b/src/topology/tplg_local.h
|
||||
@@ -225,6 +225,19 @@ struct tplg_table {
|
||||
extern struct tplg_table tplg_table[];
|
||||
extern unsigned int tplg_table_items;
|
||||
|
||||
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ && __SIZEOF_INT__ == 4
|
||||
+static inline unsigned int unaligned_get32(void *src)
|
||||
+{
|
||||
+ unsigned int ret;
|
||||
+ memcpy(&ret, src, sizeof(ret));
|
||||
+ return ret;
|
||||
+}
|
||||
+static inline void unaligned_put32(void *dst, unsigned int val)
|
||||
+{
|
||||
+ memcpy(dst, &val, sizeof(val));
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
#define tplg_log(tplg, type, pos, fmt, args...) do { \
|
||||
if ((tplg)->verbose) \
|
||||
tplg_log_((tplg), (type), (pos), (fmt), ##args); \
|
||||
--
|
||||
2.16.4
|
||||
|
666
0030-topology-improve-the-printf-buffer-management.patch
Normal file
666
0030-topology-improve-the-printf-buffer-management.patch
Normal file
@ -0,0 +1,666 @@
|
||||
From 472ab5db67a0ed04de634214773e7b17d10b5415 Mon Sep 17 00:00:00 2001
|
||||
From: Jaroslav Kysela <perex@perex.cz>
|
||||
Date: Mon, 31 Aug 2020 19:44:46 +0200
|
||||
Subject: [PATCH 30/32] topology: improve the printf buffer management
|
||||
|
||||
The commit d04e72c9a593015952e4858b92ab3f9d821560d9 introduced
|
||||
the dynamic printf buffer allocation for each tplg_save_printf()
|
||||
call.
|
||||
|
||||
Introduce 'struct tplg_buf' which carries extra information about
|
||||
the temporary printf buffer and the destination buffer to save allocation
|
||||
requests.
|
||||
|
||||
The printf buffer is also allocated using 1024 bytes chunks.
|
||||
|
||||
A comparison between 'alloc everyting' and 'cache+chunk alloc' for the
|
||||
random picked topology file:
|
||||
|
||||
1: 18,620 allocs, 18,620 frees, 7,239,688 bytes allocated
|
||||
2: 12,490 allocs, 12,490 frees, 962,568 bytes allocated
|
||||
|
||||
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
|
||||
---
|
||||
src/topology/channel.c | 3 +-
|
||||
src/topology/ctl.c | 14 +++---
|
||||
src/topology/dapm.c | 5 ++-
|
||||
src/topology/data.c | 15 ++++---
|
||||
src/topology/ops.c | 6 +--
|
||||
src/topology/pcm.c | 18 ++++----
|
||||
src/topology/save.c | 108 ++++++++++++++++++++++++++++------------------
|
||||
src/topology/text.c | 2 +-
|
||||
src/topology/tplg_local.h | 56 +++++++++++++-----------
|
||||
9 files changed, 130 insertions(+), 97 deletions(-)
|
||||
|
||||
diff --git a/src/topology/channel.c b/src/topology/channel.c
|
||||
index 47d5ea4c419a..ebdff46968f6 100644
|
||||
--- a/src/topology/channel.c
|
||||
+++ b/src/topology/channel.c
|
||||
@@ -138,7 +138,8 @@ int tplg_parse_channel(snd_tplg_t *tplg, snd_config_t *cfg,
|
||||
|
||||
int tplg_save_channels(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
||||
struct snd_soc_tplg_channel *channel,
|
||||
- unsigned int count, char **dst, const char *pfx)
|
||||
+ unsigned int count, struct tplg_buf *dst,
|
||||
+ const char *pfx)
|
||||
{
|
||||
struct snd_soc_tplg_channel *c;
|
||||
const char *s;
|
||||
diff --git a/src/topology/ctl.c b/src/topology/ctl.c
|
||||
index 1d31b4944abf..a38399631c54 100644
|
||||
--- a/src/topology/ctl.c
|
||||
+++ b/src/topology/ctl.c
|
||||
@@ -105,8 +105,8 @@ int parse_access(snd_config_t *cfg,
|
||||
|
||||
/* Save Access */
|
||||
static int tplg_save_access(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
||||
- struct snd_soc_tplg_ctl_hdr *hdr, char **dst,
|
||||
- const char *pfx)
|
||||
+ struct snd_soc_tplg_ctl_hdr *hdr,
|
||||
+ struct tplg_buf *dst, const char *pfx)
|
||||
{
|
||||
const char *last;
|
||||
unsigned int j, count, access, cval;
|
||||
@@ -399,7 +399,7 @@ int tplg_parse_tlv(snd_tplg_t *tplg, snd_config_t *cfg,
|
||||
/* save TLV data */
|
||||
int tplg_save_tlv(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
||||
struct tplg_elem *elem,
|
||||
- char **dst, const char *pfx)
|
||||
+ struct tplg_buf *dst, const char *pfx)
|
||||
{
|
||||
struct snd_soc_tplg_ctl_tlv *tlv = elem->tlv;
|
||||
struct snd_soc_tplg_tlv_dbscale *scale;
|
||||
@@ -557,7 +557,7 @@ int tplg_parse_control_bytes(snd_tplg_t *tplg,
|
||||
/* save control bytes */
|
||||
int tplg_save_control_bytes(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
||||
struct tplg_elem *elem,
|
||||
- char **dst, const char *pfx)
|
||||
+ struct tplg_buf *dst, const char *pfx)
|
||||
{
|
||||
struct snd_soc_tplg_bytes_control *be = elem->bytes_ext;
|
||||
char pfx2[16];
|
||||
@@ -697,7 +697,7 @@ int tplg_parse_control_enum(snd_tplg_t *tplg, snd_config_t *cfg,
|
||||
/* save control eunm */
|
||||
int tplg_save_control_enum(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
||||
struct tplg_elem *elem,
|
||||
- char **dst, const char *pfx)
|
||||
+ struct tplg_buf *dst, const char *pfx)
|
||||
{
|
||||
struct snd_soc_tplg_enum_control *ec = elem->enum_ctrl;
|
||||
char pfx2[16];
|
||||
@@ -858,8 +858,8 @@ int tplg_parse_control_mixer(snd_tplg_t *tplg,
|
||||
}
|
||||
|
||||
int tplg_save_control_mixer(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
||||
- struct tplg_elem *elem, char **dst,
|
||||
- const char *pfx)
|
||||
+ struct tplg_elem *elem,
|
||||
+ struct tplg_buf *dst, const char *pfx)
|
||||
{
|
||||
struct snd_soc_tplg_mixer_control *mc = elem->mixer_ctrl;
|
||||
char pfx2[16];
|
||||
diff --git a/src/topology/dapm.c b/src/topology/dapm.c
|
||||
index 73a9390340c2..46f2f8b3dae5 100644
|
||||
--- a/src/topology/dapm.c
|
||||
+++ b/src/topology/dapm.c
|
||||
@@ -416,7 +416,8 @@ int tplg_parse_dapm_graph(snd_tplg_t *tplg, snd_config_t *cfg,
|
||||
}
|
||||
|
||||
/* save DAPM graph */
|
||||
-int tplg_save_dapm_graph(snd_tplg_t *tplg, int index, char **dst, const char *pfx)
|
||||
+int tplg_save_dapm_graph(snd_tplg_t *tplg, int index,
|
||||
+ struct tplg_buf *dst, const char *pfx)
|
||||
{
|
||||
struct snd_soc_tplg_dapm_graph_elem *route;
|
||||
struct list_head *pos;
|
||||
@@ -669,7 +670,7 @@ int tplg_parse_dapm_widget(snd_tplg_t *tplg,
|
||||
/* save DAPM widget */
|
||||
int tplg_save_dapm_widget(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
||||
struct tplg_elem *elem,
|
||||
- char **dst, const char *pfx)
|
||||
+ struct tplg_buf *dst, const char *pfx)
|
||||
{
|
||||
struct snd_soc_tplg_dapm_widget *widget = elem->widget;
|
||||
const char *s;
|
||||
diff --git a/src/topology/data.c b/src/topology/data.c
|
||||
index 5742b35773f6..3585af309499 100644
|
||||
--- a/src/topology/data.c
|
||||
+++ b/src/topology/data.c
|
||||
@@ -121,7 +121,8 @@ int tplg_parse_refs(snd_config_t *cfg, struct tplg_elem *elem,
|
||||
/* save references */
|
||||
int tplg_save_refs(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
||||
struct tplg_elem *elem, unsigned int type,
|
||||
- const char *id, char **dst, const char *pfx)
|
||||
+ const char *id, struct tplg_buf *dst,
|
||||
+ const char *pfx)
|
||||
{
|
||||
struct tplg_ref *ref, *last;
|
||||
struct list_head *pos;
|
||||
@@ -890,7 +891,7 @@ err:
|
||||
/* save tuple set */
|
||||
static int tplg_save_tuple_set(struct tplg_vendor_tuples *tuples,
|
||||
unsigned int set_index,
|
||||
- char **dst, const char *pfx)
|
||||
+ struct tplg_buf *dst, const char *pfx)
|
||||
{
|
||||
struct tplg_tuple_set *set;
|
||||
struct tplg_tuple *tuple;
|
||||
@@ -1014,7 +1015,7 @@ static int parse_tuple_sets(snd_config_t *cfg,
|
||||
/* save tuple sets */
|
||||
int tplg_save_tuple_sets(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
||||
struct tplg_elem *elem,
|
||||
- char **dst, const char *pfx)
|
||||
+ struct tplg_buf *dst, const char *pfx)
|
||||
{
|
||||
struct tplg_vendor_tuples *tuples = elem->tuples;
|
||||
unsigned int i;
|
||||
@@ -1085,7 +1086,7 @@ int tplg_parse_tokens(snd_tplg_t *tplg, snd_config_t *cfg,
|
||||
/* save vendor tokens */
|
||||
int tplg_save_tokens(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
||||
struct tplg_elem *elem,
|
||||
- char **dst, const char *pfx)
|
||||
+ struct tplg_buf *dst, const char *pfx)
|
||||
{
|
||||
struct tplg_vendor_tokens *tokens = elem->tokens;
|
||||
unsigned int i;
|
||||
@@ -1156,7 +1157,7 @@ int tplg_parse_tuples(snd_tplg_t *tplg, snd_config_t *cfg,
|
||||
/* save vendor tuples */
|
||||
int tplg_save_tuples(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
||||
struct tplg_elem *elem,
|
||||
- char **dst, const char *pfx)
|
||||
+ struct tplg_buf *dst, const char *pfx)
|
||||
{
|
||||
char pfx2[16];
|
||||
int err;
|
||||
@@ -1242,7 +1243,7 @@ int tplg_parse_manifest_data(snd_tplg_t *tplg, snd_config_t *cfg,
|
||||
|
||||
/* save manifest data */
|
||||
int tplg_save_manifest_data(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
||||
- struct tplg_elem *elem, char **dst,
|
||||
+ struct tplg_elem *elem, struct tplg_buf *dst,
|
||||
const char *pfx)
|
||||
{
|
||||
struct list_head *pos;
|
||||
@@ -1420,7 +1421,7 @@ int tplg_parse_data(snd_tplg_t *tplg, snd_config_t *cfg,
|
||||
/* save data element */
|
||||
int tplg_save_data(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
||||
struct tplg_elem *elem,
|
||||
- char **dst, const char *pfx)
|
||||
+ struct tplg_buf *dst, const char *pfx)
|
||||
{
|
||||
struct snd_soc_tplg_private *priv = elem->data;
|
||||
struct list_head *pos;
|
||||
diff --git a/src/topology/ops.c b/src/topology/ops.c
|
||||
index 110eef58851d..da175608557a 100644
|
||||
--- a/src/topology/ops.c
|
||||
+++ b/src/topology/ops.c
|
||||
@@ -105,8 +105,8 @@ int tplg_parse_ops(snd_tplg_t *tplg ATTRIBUTE_UNUSED, snd_config_t *cfg,
|
||||
|
||||
/* save control operations */
|
||||
int tplg_save_ops(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
||||
- struct snd_soc_tplg_ctl_hdr *hdr, char **dst,
|
||||
- const char *pfx)
|
||||
+ struct snd_soc_tplg_ctl_hdr *hdr,
|
||||
+ struct tplg_buf *dst, const char *pfx)
|
||||
{
|
||||
const char *s;
|
||||
int err;
|
||||
@@ -191,7 +191,7 @@ int tplg_parse_ext_ops(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
||||
/* save external control operations */
|
||||
int tplg_save_ext_ops(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
||||
struct snd_soc_tplg_bytes_control *be,
|
||||
- char **dst, const char *pfx)
|
||||
+ struct tplg_buf *dst, const char *pfx)
|
||||
{
|
||||
const char *s;
|
||||
int err;
|
||||
diff --git a/src/topology/pcm.c b/src/topology/pcm.c
|
||||
index a60ba00d979a..191b7a0a92da 100644
|
||||
--- a/src/topology/pcm.c
|
||||
+++ b/src/topology/pcm.c
|
||||
@@ -538,7 +538,7 @@ int tplg_parse_stream_caps(snd_tplg_t *tplg,
|
||||
/* save stream caps */
|
||||
int tplg_save_stream_caps(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
||||
struct tplg_elem *elem,
|
||||
- char **dst, const char *pfx)
|
||||
+ struct tplg_buf *dst, const char *pfx)
|
||||
{
|
||||
struct snd_soc_tplg_stream_caps *sc = elem->stream_caps;
|
||||
const char *s;
|
||||
@@ -686,7 +686,7 @@ static int tplg_parse_streams(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
||||
/* Save the caps and config of a pcm stream */
|
||||
int tplg_save_streams(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
||||
struct tplg_elem *elem,
|
||||
- char **dst, const char *pfx)
|
||||
+ struct tplg_buf *dst, const char *pfx)
|
||||
{
|
||||
static const char *stream_ids[2] = {
|
||||
"playback",
|
||||
@@ -778,7 +778,7 @@ static int tplg_parse_fe_dai(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
||||
/* Save the caps and config of a pcm stream */
|
||||
int tplg_save_fe_dai(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
||||
struct tplg_elem *elem,
|
||||
- char **dst, const char *pfx)
|
||||
+ struct tplg_buf *dst, const char *pfx)
|
||||
{
|
||||
struct snd_soc_tplg_pcm *pcm = elem->pcm;
|
||||
int err = 0;
|
||||
@@ -810,7 +810,7 @@ static int parse_flag(snd_config_t *n, unsigned int mask_in,
|
||||
}
|
||||
|
||||
static int save_flags(unsigned int flags, unsigned int mask,
|
||||
- char **dst, const char *pfx)
|
||||
+ struct tplg_buf *dst, const char *pfx)
|
||||
{
|
||||
static unsigned int flag_masks[3] = {
|
||||
SND_SOC_TPLG_LNK_FLGBIT_SYMMETRIC_RATES,
|
||||
@@ -944,7 +944,7 @@ int tplg_parse_pcm(snd_tplg_t *tplg, snd_config_t *cfg,
|
||||
/* save PCM */
|
||||
int tplg_save_pcm(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
||||
struct tplg_elem *elem,
|
||||
- char **dst, const char *pfx)
|
||||
+ struct tplg_buf *dst, const char *pfx)
|
||||
{
|
||||
struct snd_soc_tplg_pcm *pcm = elem->pcm;
|
||||
char pfx2[16];
|
||||
@@ -1081,7 +1081,7 @@ int tplg_parse_dai(snd_tplg_t *tplg, snd_config_t *cfg,
|
||||
/* save DAI */
|
||||
int tplg_save_dai(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
||||
struct tplg_elem *elem,
|
||||
- char **dst, const char *pfx)
|
||||
+ struct tplg_buf *dst, const char *pfx)
|
||||
{
|
||||
struct snd_soc_tplg_dai *dai = elem->dai;
|
||||
char pfx2[16];
|
||||
@@ -1235,7 +1235,7 @@ int tplg_parse_link(snd_tplg_t *tplg, snd_config_t *cfg,
|
||||
/* save physical link */
|
||||
int tplg_save_link(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
||||
struct tplg_elem *elem,
|
||||
- char **dst, const char *pfx)
|
||||
+ struct tplg_buf *dst, const char *pfx)
|
||||
{
|
||||
struct snd_soc_tplg_link_config *link = elem->link;
|
||||
char pfx2[16];
|
||||
@@ -1315,7 +1315,7 @@ int tplg_parse_cc(snd_tplg_t *tplg, snd_config_t *cfg,
|
||||
/* save CC */
|
||||
int tplg_save_cc(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
||||
struct tplg_elem *elem,
|
||||
- char **dst, const char *pfx)
|
||||
+ struct tplg_buf *dst, const char *pfx)
|
||||
{
|
||||
struct snd_soc_tplg_link_config *link = elem->link;
|
||||
char pfx2[16];
|
||||
@@ -1611,7 +1611,7 @@ int tplg_parse_hw_config(snd_tplg_t *tplg, snd_config_t *cfg,
|
||||
/* save hw config */
|
||||
int tplg_save_hw_config(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
||||
struct tplg_elem *elem,
|
||||
- char **dst, const char *pfx)
|
||||
+ struct tplg_buf *dst, const char *pfx)
|
||||
{
|
||||
struct snd_soc_tplg_hw_config *hc = elem->hw_cfg;
|
||||
int err;
|
||||
diff --git a/src/topology/save.c b/src/topology/save.c
|
||||
index 631d84b273bf..56250af308b2 100644
|
||||
--- a/src/topology/save.c
|
||||
+++ b/src/topology/save.c
|
||||
@@ -19,25 +19,43 @@
|
||||
#include "tplg_local.h"
|
||||
|
||||
#define SAVE_ALLOC_SHIFT (13) /* 8192 bytes */
|
||||
-#define PRINT_BUF_SIZE (1024)
|
||||
+#define PRINT_ALLOC_SHIFT (10) /* 1024 bytes */
|
||||
#define PRINT_BUF_SIZE_MAX (1024 * 1024)
|
||||
+#define NEXT_CHUNK(val, shift) ((((val) >> (shift)) + 1) << (shift))
|
||||
|
||||
-int tplg_save_printf(char **dst, const char *pfx, const char *fmt, ...)
|
||||
+void tplg_buf_init(struct tplg_buf *buf)
|
||||
+{
|
||||
+ buf->dst = NULL;
|
||||
+ buf->dst_len = 0;
|
||||
+ buf->printf_buf = NULL;
|
||||
+ buf->printf_buf_size = 0;
|
||||
+}
|
||||
+
|
||||
+void tplg_buf_free(struct tplg_buf *buf)
|
||||
+{
|
||||
+ free(buf->dst);
|
||||
+ free(buf->printf_buf);
|
||||
+}
|
||||
+
|
||||
+char *tplg_buf_detach(struct tplg_buf *buf)
|
||||
+{
|
||||
+ char *ret = buf->dst;
|
||||
+ free(buf->printf_buf);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+int tplg_save_printf(struct tplg_buf *dst, const char *pfx, const char *fmt, ...)
|
||||
{
|
||||
va_list va;
|
||||
- char *buf, *s;
|
||||
+ char *s;
|
||||
size_t n, l, t, pl;
|
||||
int ret = 0;
|
||||
|
||||
- buf = malloc(PRINT_BUF_SIZE);
|
||||
- if (!buf)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
if (pfx == NULL)
|
||||
pfx = "";
|
||||
|
||||
va_start(va, fmt);
|
||||
- n = vsnprintf(buf, PRINT_BUF_SIZE, fmt, va);
|
||||
+ n = vsnprintf(dst->printf_buf, dst->printf_buf_size, fmt, va);
|
||||
va_end(va);
|
||||
|
||||
if (n >= PRINT_BUF_SIZE_MAX) {
|
||||
@@ -45,42 +63,41 @@ int tplg_save_printf(char **dst, const char *pfx, const char *fmt, ...)
|
||||
goto end;
|
||||
}
|
||||
|
||||
- if (n >= PRINT_BUF_SIZE) {
|
||||
- char *tmp = realloc(buf, n + 1);
|
||||
- if (!tmp) {
|
||||
+ if (n >= dst->printf_buf_size) {
|
||||
+ t = NEXT_CHUNK(n + 1, PRINT_ALLOC_SHIFT);
|
||||
+ s = realloc(dst->printf_buf, t);
|
||||
+ if (!s) {
|
||||
ret = -ENOMEM;
|
||||
goto end;
|
||||
}
|
||||
- buf = tmp;
|
||||
+ dst->printf_buf = s;
|
||||
+ dst->printf_buf_size = t;
|
||||
va_start(va, fmt);
|
||||
- n = vsnprintf(buf, n + 1, fmt, va);
|
||||
+ n = vsnprintf(dst->printf_buf, n + 1, fmt, va);
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
pl = strlen(pfx);
|
||||
- l = *dst ? strlen(*dst) : 0;
|
||||
+ l = dst->dst_len;
|
||||
t = l + pl + n + 1;
|
||||
/* allocate chunks */
|
||||
- if (*dst == NULL ||
|
||||
+ if (dst->dst == NULL ||
|
||||
(l >> SAVE_ALLOC_SHIFT) != (t >> SAVE_ALLOC_SHIFT)) {
|
||||
- s = realloc(*dst, ((t >> SAVE_ALLOC_SHIFT) + 1) <<
|
||||
- SAVE_ALLOC_SHIFT);
|
||||
+ s = realloc(dst->dst, NEXT_CHUNK(t, SAVE_ALLOC_SHIFT));
|
||||
if (s == NULL) {
|
||||
- free(*dst);
|
||||
- *dst = NULL;
|
||||
ret = -ENOMEM;
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
- s = *dst;
|
||||
+ s = dst->dst;
|
||||
}
|
||||
|
||||
if (pl > 0)
|
||||
strcpy(s + l, pfx);
|
||||
- strcpy(s + l + pl, buf);
|
||||
- *dst = s;
|
||||
+ strcpy(s + l + pl, dst->printf_buf);
|
||||
+ dst->dst = s;
|
||||
+ dst->dst_len = t - 1;
|
||||
end:
|
||||
- free(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -209,7 +226,7 @@ static int tplg_check_quoted(const unsigned char *p)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int tplg_save_quoted(char **dst, const char *str)
|
||||
+static int tplg_save_quoted(struct tplg_buf *dst, const char *str)
|
||||
{
|
||||
static const char nibble[16] = "0123456789abcdef";
|
||||
unsigned char *p, *d, *t;
|
||||
@@ -263,7 +280,7 @@ static int tplg_save_quoted(char **dst, const char *str)
|
||||
return tplg_save_printf(dst, NULL, "'%s'", d);
|
||||
}
|
||||
|
||||
-static int tplg_save_string(char **dst, const char *str, int id)
|
||||
+static int tplg_save_string(struct tplg_buf *dst, const char *str, int id)
|
||||
{
|
||||
const unsigned char *p = (const unsigned char *)str;
|
||||
|
||||
@@ -279,7 +296,7 @@ static int tplg_save_string(char **dst, const char *str, int id)
|
||||
return tplg_save_printf(dst, NULL, "%s", str);
|
||||
}
|
||||
|
||||
-static int save_config(char **dst, int level, const char *delim, snd_config_t *src)
|
||||
+static int save_config(struct tplg_buf *dst, int level, const char *delim, snd_config_t *src)
|
||||
{
|
||||
snd_config_iterator_t i, next;
|
||||
snd_config_t *s;
|
||||
@@ -400,7 +417,8 @@ retval:
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int tplg_save(snd_tplg_t *tplg, char **dst, int gindex, const char *prefix)
|
||||
+static int tplg_save(snd_tplg_t *tplg, struct tplg_buf *dst,
|
||||
+ int gindex, const char *prefix)
|
||||
{
|
||||
struct tplg_table *tptr;
|
||||
struct tplg_elem *elem;
|
||||
@@ -484,8 +502,6 @@ static int tplg_save(snd_tplg_t *tplg, char **dst, int gindex, const char *prefi
|
||||
return 0;
|
||||
|
||||
_err:
|
||||
- free(*dst);
|
||||
- *dst = NULL;
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -540,9 +556,9 @@ static int tplg_index_groups(snd_tplg_t *tplg, int **indexes)
|
||||
|
||||
int snd_tplg_save(snd_tplg_t *tplg, char **dst, int flags)
|
||||
{
|
||||
+ struct tplg_buf buf, buf2;
|
||||
snd_input_t *in;
|
||||
snd_config_t *top, *top2;
|
||||
- char *dst2;
|
||||
int *indexes, *a;
|
||||
int err;
|
||||
|
||||
@@ -550,35 +566,41 @@ int snd_tplg_save(snd_tplg_t *tplg, char **dst, int flags)
|
||||
assert(dst);
|
||||
*dst = NULL;
|
||||
|
||||
+ tplg_buf_init(&buf);
|
||||
+
|
||||
if (flags & SND_TPLG_SAVE_GROUPS) {
|
||||
err = tplg_index_groups(tplg, &indexes);
|
||||
if (err < 0)
|
||||
return err;
|
||||
for (a = indexes; err >= 0 && *a >= 0; a++) {
|
||||
- err = tplg_save_printf(dst, NULL,
|
||||
+ err = tplg_save_printf(&buf, NULL,
|
||||
"IndexGroup.%d {\n",
|
||||
*a);
|
||||
if (err >= 0)
|
||||
- err = tplg_save(tplg, dst, *a, "\t");
|
||||
+ err = tplg_save(tplg, &buf, *a, "\t");
|
||||
if (err >= 0)
|
||||
- err = tplg_save_printf(dst, NULL, "}\n");
|
||||
+ err = tplg_save_printf(&buf, NULL, "}\n");
|
||||
}
|
||||
free(indexes);
|
||||
} else {
|
||||
- err = tplg_save(tplg, dst, -1, NULL);
|
||||
+ err = tplg_save(tplg, &buf, -1, NULL);
|
||||
}
|
||||
|
||||
if (err < 0)
|
||||
goto _err;
|
||||
|
||||
- if (*dst == NULL)
|
||||
- return -EINVAL;
|
||||
+ if (buf.dst == NULL) {
|
||||
+ err = -EINVAL;
|
||||
+ goto _err;
|
||||
+ }
|
||||
|
||||
- if (flags & SND_TPLG_SAVE_NOCHECK)
|
||||
+ if (flags & SND_TPLG_SAVE_NOCHECK) {
|
||||
+ *dst = tplg_buf_detach(&buf);
|
||||
return 0;
|
||||
+ }
|
||||
|
||||
/* always load configuration - check */
|
||||
- err = snd_input_buffer_open(&in, *dst, strlen(*dst));
|
||||
+ err = snd_input_buffer_open(&in, buf.dst, strlen(buf.dst));
|
||||
if (err < 0) {
|
||||
SNDERR("could not create input buffer");
|
||||
goto _err;
|
||||
@@ -610,20 +632,20 @@ int snd_tplg_save(snd_tplg_t *tplg, char **dst, int flags)
|
||||
top = top2;
|
||||
}
|
||||
|
||||
- dst2 = NULL;
|
||||
- err = save_config(&dst2, 0, NULL, top);
|
||||
+ tplg_buf_init(&buf2);
|
||||
+ err = save_config(&buf2, 0, NULL, top);
|
||||
snd_config_delete(top);
|
||||
if (err < 0) {
|
||||
SNDERR("could not save configuration");
|
||||
goto _err;
|
||||
}
|
||||
|
||||
- free(*dst);
|
||||
- *dst = dst2;
|
||||
+ tplg_buf_free(&buf);
|
||||
+ *dst = tplg_buf_detach(&buf2);
|
||||
return 0;
|
||||
|
||||
_err:
|
||||
- free(*dst);
|
||||
+ tplg_buf_free(&buf);
|
||||
*dst = NULL;
|
||||
return err;
|
||||
}
|
||||
diff --git a/src/topology/text.c b/src/topology/text.c
|
||||
index b899b2813ab4..b07feb999db9 100644
|
||||
--- a/src/topology/text.c
|
||||
+++ b/src/topology/text.c
|
||||
@@ -93,7 +93,7 @@ int tplg_parse_text(snd_tplg_t *tplg, snd_config_t *cfg,
|
||||
/* save text data */
|
||||
int tplg_save_text(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
|
||||
struct tplg_elem *elem,
|
||||
- char **dst, const char *pfx)
|
||||
+ struct tplg_buf *dst, const char *pfx)
|
||||
{
|
||||
struct tplg_texts *texts = elem->texts;
|
||||
unsigned int i;
|
||||
diff --git a/src/topology/tplg_local.h b/src/topology/tplg_local.h
|
||||
index 0c7be2001a63..d553117e2333 100644
|
||||
--- a/src/topology/tplg_local.h
|
||||
+++ b/src/topology/tplg_local.h
|
||||
@@ -200,6 +200,14 @@ struct map_elem {
|
||||
int id;
|
||||
};
|
||||
|
||||
+/* output buffer */
|
||||
+struct tplg_buf {
|
||||
+ char *dst;
|
||||
+ size_t dst_len;
|
||||
+ char *printf_buf;
|
||||
+ size_t printf_buf_size;
|
||||
+};
|
||||
+
|
||||
/* mapping table */
|
||||
struct tplg_table {
|
||||
const char *name;
|
||||
@@ -214,9 +222,9 @@ struct tplg_table {
|
||||
void (*free)(void *);
|
||||
int (*parse)(snd_tplg_t *tplg, snd_config_t *cfg, void *priv);
|
||||
int (*save)(snd_tplg_t *tplg, struct tplg_elem *elem,
|
||||
- char **dst, const char *prefix);
|
||||
+ struct tplg_buf *dst, const char *prefix);
|
||||
int (*gsave)(snd_tplg_t *tplg, int index,
|
||||
- char **dst, const char *prefix);
|
||||
+ struct tplg_buf *dst, const char *prefix);
|
||||
int (*decod)(snd_tplg_t *tplg, size_t pos,
|
||||
struct snd_soc_tplg_hdr *hdr,
|
||||
void *bin, size_t size);
|
||||
@@ -348,49 +356,49 @@ int tplg_add_dai_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t);
|
||||
|
||||
int tplg_nice_value_format(char *dst, size_t dst_size, unsigned int value);
|
||||
|
||||
-int tplg_save_printf(char **dst, const char *prefix, const char *fmt, ...);
|
||||
+int tplg_save_printf(struct tplg_buf *dst, const char *prefix, const char *fmt, ...);
|
||||
int tplg_save_refs(snd_tplg_t *tplg, struct tplg_elem *elem, unsigned int type,
|
||||
- const char *id, char **dst, const char *pfx);
|
||||
+ const char *id, struct tplg_buf *dst, const char *pfx);
|
||||
int tplg_save_channels(snd_tplg_t *tplg, struct snd_soc_tplg_channel *channel,
|
||||
- unsigned int channel_count, char **dst, const char *pfx);
|
||||
+ unsigned int channel_count, struct tplg_buf *dst, const char *pfx);
|
||||
int tplg_save_ops(snd_tplg_t *tplg, struct snd_soc_tplg_ctl_hdr *hdr,
|
||||
- char **dst, const char *pfx);
|
||||
+ struct tplg_buf *dst, const char *pfx);
|
||||
int tplg_save_ext_ops(snd_tplg_t *tplg, struct snd_soc_tplg_bytes_control *be,
|
||||
- char **dst, const char *pfx);
|
||||
+ struct tplg_buf *dst, const char *pfx);
|
||||
int tplg_save_manifest_data(snd_tplg_t *tplg, struct tplg_elem *elem,
|
||||
- char **dst, const char *pfx);
|
||||
+ struct tplg_buf *dst, const char *pfx);
|
||||
int tplg_save_control_mixer(snd_tplg_t *tplg, struct tplg_elem *elem,
|
||||
- char **dst, const char *pfx);
|
||||
+ struct tplg_buf *dst, const char *pfx);
|
||||
int tplg_save_control_enum(snd_tplg_t *tplg, struct tplg_elem *elem,
|
||||
- char **dst, const char *pfx);
|
||||
+ struct tplg_buf *dst, const char *pfx);
|
||||
int tplg_save_control_bytes(snd_tplg_t *tplg, struct tplg_elem *elem,
|
||||
- char **dst, const char *pfx);
|
||||
+ struct tplg_buf *dst, const char *pfx);
|
||||
int tplg_save_tlv(snd_tplg_t *tplg, struct tplg_elem *elem,
|
||||
- char **dst, const char *pfx);
|
||||
+ struct tplg_buf *dst, const char *pfx);
|
||||
int tplg_save_data(snd_tplg_t *tplg, struct tplg_elem *elem,
|
||||
- char **dst, const char *pfx);
|
||||
+ struct tplg_buf *dst, const char *pfx);
|
||||
int tplg_save_text(snd_tplg_t *tplg, struct tplg_elem *elem,
|
||||
- char **dst, const char *pfx);
|
||||
+ struct tplg_buf *dst, const char *pfx);
|
||||
int tplg_save_tokens(snd_tplg_t *tplg, struct tplg_elem *elem,
|
||||
- char **dst, const char *pfx);
|
||||
+ struct tplg_buf *dst, const char *pfx);
|
||||
int tplg_save_tuples(snd_tplg_t *tplg, struct tplg_elem *elem,
|
||||
- char **dst, const char *pfx);
|
||||
+ struct tplg_buf *dst, const char *pfx);
|
||||
int tplg_save_dapm_graph(snd_tplg_t *tplg, int index,
|
||||
- char **dst, const char *pfx);
|
||||
+ struct tplg_buf *dst, const char *pfx);
|
||||
int tplg_save_dapm_widget(snd_tplg_t *tplg, struct tplg_elem *elem,
|
||||
- char **dst, const char *pfx);
|
||||
+ struct tplg_buf *dst, const char *pfx);
|
||||
int tplg_save_link(snd_tplg_t *tplg, struct tplg_elem *elem,
|
||||
- char **dst, const char *pfx);
|
||||
+ struct tplg_buf *dst, const char *pfx);
|
||||
int tplg_save_cc(snd_tplg_t *tplg, struct tplg_elem *elem,
|
||||
- char **dst, const char *pfx);
|
||||
+ struct tplg_buf *dst, const char *pfx);
|
||||
int tplg_save_pcm(snd_tplg_t *tplg, struct tplg_elem *elem,
|
||||
- char **dst, const char *pfx);
|
||||
+ struct tplg_buf *dst, const char *pfx);
|
||||
int tplg_save_hw_config(snd_tplg_t *tplg, struct tplg_elem *elem,
|
||||
- char **dst, const char *pfx);
|
||||
+ struct tplg_buf *dst, const char *pfx);
|
||||
int tplg_save_stream_caps(snd_tplg_t *tplg, struct tplg_elem *elem,
|
||||
- char **dst, const char *pfx);
|
||||
+ struct tplg_buf *dst, const char *pfx);
|
||||
int tplg_save_dai(snd_tplg_t *tplg, struct tplg_elem *elem,
|
||||
- char **dst, const char *pfx);
|
||||
+ struct tplg_buf *dst, const char *pfx);
|
||||
|
||||
int tplg_decode_template(snd_tplg_t *tplg,
|
||||
size_t pos,
|
||||
--
|
||||
2.16.4
|
||||
|
111
0031-control-Improve-general-control-interface-documentat.patch
Normal file
111
0031-control-Improve-general-control-interface-documentat.patch
Normal file
@ -0,0 +1,111 @@
|
||||
From 84185b5c94ec8a214103b8ec02d272f0158c24e6 Mon Sep 17 00:00:00 2001
|
||||
From: "Tanjeff-N. Moos" <tanjeff@cccmz.de>
|
||||
Date: Wed, 2 Sep 2020 11:27:26 +0200
|
||||
Subject: [PATCH 31/32] control: Improve general control interface
|
||||
documentation.
|
||||
|
||||
Signed-off-by: Tanjeff-N. Moos <tanjeff@cccmz.de>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/control/control.c | 72 ++++++++++++++++++++++++++++++++++++++++++++-------
|
||||
1 file changed, 63 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/src/control/control.c b/src/control/control.c
|
||||
index 1bcf1ab2e431..497a5399b7e6 100644
|
||||
--- a/src/control/control.c
|
||||
+++ b/src/control/control.c
|
||||
@@ -31,7 +31,7 @@
|
||||
/*! \page control Control interface
|
||||
|
||||
<P>Control interface is designed to access primitive controls. There is
|
||||
-also interface notifying about control and structure changes.
|
||||
+also an interface for notifying about control and structure changes.
|
||||
|
||||
\section control_general_overview General overview
|
||||
|
||||
@@ -43,20 +43,74 @@ are managed according to below model.
|
||||
Some element sets can be added to a sound card by drivers in kernel and
|
||||
userspace applications.
|
||||
- element
|
||||
- - An element can be identified by userspace applications. Each element has
|
||||
- own identical information.
|
||||
+ - A control element might be a master volume control, for example, or a
|
||||
+ read-only indicator, such as a sync status. An element has a type (e.g.
|
||||
+ INTEGER or BOOLEAN) and - depending on the type - min/max values, a step
|
||||
+ size, a set of possible values (for enums), etc.
|
||||
- member
|
||||
- - An element includes some members to have a value. The value of each member
|
||||
- can be changed by both of userspace applications and drivers in kernel.
|
||||
|
||||
-Each element can be identified by two ways; the numerical number (numid), or the
|
||||
-combination of interface, device, subdevice, name, and index.
|
||||
+ - An element includes one or more member(s) to have a value. For
|
||||
+ example, a stereo volume control element has two members (for
|
||||
+ left/right). The members share the same properties (e.g. both
|
||||
+ volume controls have the same min/max values). The value of each
|
||||
+ member can be changed by both of userspace applications and
|
||||
+ drivers in kernel.
|
||||
|
||||
-The type of element set is one of integer, integerr64, boolean, enumerators,
|
||||
+
|
||||
+\section identifying_elements Identifying the Elements
|
||||
+
|
||||
+Each element has the following identifying properties:
|
||||
+
|
||||
+ - The numid (a numeric identifier, assigned when the sound card is
|
||||
+ detected, constant while the sound card is kept connected)
|
||||
+
|
||||
+ - The interface type (e.g. MIXER, CARD or PCM)
|
||||
+ - The device
|
||||
+ - The subdevice
|
||||
+ - Its name
|
||||
+ - Its index
|
||||
+
|
||||
+An element can be identified either by its numid or by the tuple
|
||||
+(interface type, device, subdevice, name, index). This tuple is always
|
||||
+the same (driver updates can change it, but in practice this is
|
||||
+rare). The numid can change on each boot. In case of an USB sound
|
||||
+card, the numid can also change when it is reconnected.
|
||||
+
|
||||
+
|
||||
+\section element_lists Element Lists
|
||||
+
|
||||
+An element list can be used to obtain a list of all elements of the
|
||||
+sound card. The list contains generic information (e.g. how many
|
||||
+elements the card has), and the identifying properties of the elements
|
||||
+(numid, card, name, ...). See #snd_ctl_elem_list_t to learn more about
|
||||
+element lists.
|
||||
+
|
||||
+
|
||||
+\section working_with_elements Working with Elements
|
||||
+
|
||||
+It is possible to obtain information about an element using the
|
||||
+snd_ctl_elem_info_*() functions. For enums, the allowed values can be
|
||||
+obtained, for integers, the min/max values can be obtained, and so
|
||||
+on. In addition, these functions can report the identifying
|
||||
+properties. E.g. when the element is addressed using its numid, the
|
||||
+functions complements the name, index, etc.
|
||||
+
|
||||
+To access the values of a control, use the snd_ctl_elem_value*()
|
||||
+functions. These allow to get and set the actual values or
|
||||
+settings. It is also possible to get and set the ID values (such as
|
||||
+the numid or the name).
|
||||
+
|
||||
+
|
||||
+\section element_sets Element Sets
|
||||
+
|
||||
+The type of element set is one of integer, integer64, boolean, enumerators,
|
||||
bytes and IEC958 structure. This indicates the type of value for each member in
|
||||
elements included in the element set.
|
||||
|
||||
-When the value of member is changed, corresponding events are transferred to
|
||||
+
|
||||
+\section events Events
|
||||
+
|
||||
+When the value of a member is changed, corresponding events are transferred to
|
||||
userspace applications. The applications should subscribe any events in advance.
|
||||
|
||||
\section tlv_blob Supplemental data for elements in an element set
|
||||
--
|
||||
2.16.4
|
||||
|
828
0032-control-Add-documentation-for-snd_ctl_elem_value_.patch
Normal file
828
0032-control-Add-documentation-for-snd_ctl_elem_value_.patch
Normal file
@ -0,0 +1,828 @@
|
||||
From c1e72460de5ddcfdc8b93e73952c6fe9d6f60591 Mon Sep 17 00:00:00 2001
|
||||
From: "Tanjeff-N. Moos" <tanjeff@cccmz.de>
|
||||
Date: Wed, 2 Sep 2020 11:27:27 +0200
|
||||
Subject: [PATCH 32/32] control: Add documentation for snd_ctl_elem_value_*.
|
||||
|
||||
Signed-off-by: Tanjeff-N. Moos <tanjeff@cccmz.de>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
include/control.h | 61 ++++++-
|
||||
src/control/control.c | 454 +++++++++++++++++++++++++++++++++-----------------
|
||||
2 files changed, 357 insertions(+), 158 deletions(-)
|
||||
|
||||
diff --git a/include/control.h b/include/control.h
|
||||
index 9deec6f3dee4..8766f44097ea 100644
|
||||
--- a/include/control.h
|
||||
+++ b/include/control.h
|
||||
@@ -130,7 +130,53 @@ typedef struct _snd_ctl_elem_list snd_ctl_elem_list_t;
|
||||
/** CTL element info container */
|
||||
typedef struct _snd_ctl_elem_info snd_ctl_elem_info_t;
|
||||
|
||||
-/** CTL element value container */
|
||||
+/** CTL element value container
|
||||
+ *
|
||||
+ * Contains the value(s) (i.e. members) of a single element. All
|
||||
+ * values of a given element are of the same type.
|
||||
+ *
|
||||
+ * \par Memory management
|
||||
+ *
|
||||
+ * To access a value, a snd_ctl_elem_value_t must be allocated using
|
||||
+ * snd_ctl_elem_value_alloca() or snd_ctl_elem_value_malloc(). When
|
||||
+ * using the latter, it must be freed again using
|
||||
+ * snd_ctl_elem_value_free().
|
||||
+ *
|
||||
+ * \par Identifier
|
||||
+ *
|
||||
+ * Then, the ID must be filled. It is sufficient to fill only the
|
||||
+ * numid, if known. Otherwise, interface type, device, subdevice,
|
||||
+ * name, index must all be given. The following functions can be used
|
||||
+ * to fill the ID:
|
||||
+ *
|
||||
+ * - snd_ctl_elem_value_set_id(): Set the ID. Requires an
|
||||
+ * snd_ctl_elem_id_t object.
|
||||
+ * - snd_ctl_elem_value_set_numid(): Set the numid.
|
||||
+ * - Or use all of the following:
|
||||
+ *
|
||||
+ * - snd_ctl_elem_value_set_interface()
|
||||
+ * - snd_ctl_elem_value_set_device()
|
||||
+ * - snd_ctl_elem_value_set_subdevice()
|
||||
+ * - snd_ctl_elem_value_set_name()
|
||||
+ * - snd_ctl_elem_value_set_index()
|
||||
+ *
|
||||
+ * When communicating with the driver (snd_ctl_elem_read(),
|
||||
+ * snd_ctl_elem_write()), and the numid was given, the interface,
|
||||
+ * device, ... are filled (even if you set the before). When the numid
|
||||
+ * is unset (i.e. it is 0), it is filled.
|
||||
+ *
|
||||
+ * \par Communicating with the driver
|
||||
+ *
|
||||
+ * After the value container was created and filled with the ID of the
|
||||
+ * desired element, the value(s) can be fetched from the driver (and
|
||||
+ * thus from the hardware) or written to the driver.
|
||||
+ *
|
||||
+ * To fetch a value, use snd_ctl_elem_read(). Thereafter, use the
|
||||
+ * snd_ctl_elem_value_get_*() functions to obtain the actual value.
|
||||
+ *
|
||||
+ * To write a new value, first use a snd_ctl_elem_value_set_*() to set
|
||||
+ * it, then call snd_ctl_elem_write() to write it to the driver.
|
||||
+ */
|
||||
typedef struct _snd_ctl_elem_value snd_ctl_elem_value_t;
|
||||
|
||||
/** CTL event container */
|
||||
@@ -529,11 +575,20 @@ int snd_ctl_elem_add_iec958(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id);
|
||||
int snd_ctl_elem_remove(snd_ctl_t *ctl, snd_ctl_elem_id_t *id);
|
||||
|
||||
size_t snd_ctl_elem_value_sizeof(void);
|
||||
+
|
||||
/** \hideinitializer
|
||||
- * \brief allocate an invalid #snd_ctl_elem_value_t using standard alloca
|
||||
- * \param ptr returned pointer
|
||||
+ * \brief Allocate an invalid #snd_ctl_elem_value_t on the stack.
|
||||
+ *
|
||||
+ * Allocate space for a value object on the stack. The allocated
|
||||
+ * memory need not be freed, because is on the stack.
|
||||
+ *
|
||||
+ * See snd_ctl_elem_value_t for details.
|
||||
+ *
|
||||
+ * \param ptr Pointer to a snd_ctl_elem_value_t pointer. The address
|
||||
+ * of the allocated space will returned here.
|
||||
*/
|
||||
#define snd_ctl_elem_value_alloca(ptr) __snd_alloca(ptr, snd_ctl_elem_value)
|
||||
+
|
||||
int snd_ctl_elem_value_malloc(snd_ctl_elem_value_t **ptr);
|
||||
void snd_ctl_elem_value_free(snd_ctl_elem_value_t *obj);
|
||||
void snd_ctl_elem_value_clear(snd_ctl_elem_value_t *obj);
|
||||
diff --git a/src/control/control.c b/src/control/control.c
|
||||
index 497a5399b7e6..08058c067e28 100644
|
||||
--- a/src/control/control.c
|
||||
+++ b/src/control/control.c
|
||||
@@ -38,32 +38,39 @@ also an interface for notifying about control and structure changes.
|
||||
In ALSA control feature, each sound card can have control elements. The elements
|
||||
are managed according to below model.
|
||||
|
||||
- - element set
|
||||
+ - Element set
|
||||
+
|
||||
- A set of elements with the same attribute (i.e. name, get/put operations).
|
||||
Some element sets can be added to a sound card by drivers in kernel and
|
||||
userspace applications.
|
||||
- - element
|
||||
+
|
||||
+ - Element
|
||||
+
|
||||
- A control element might be a master volume control, for example, or a
|
||||
read-only indicator, such as a sync status. An element has a type (e.g.
|
||||
- INTEGER or BOOLEAN) and - depending on the type - min/max values, a step
|
||||
- size, a set of possible values (for enums), etc.
|
||||
- - member
|
||||
+ SNDRV_CTL_ELEM_TYPE_INTEGER or SNDRV_CTL_ELEM_TYPE_BOOLEAN) and - depending
|
||||
+ on the type - min/max values, a step size, a set of possible values (for
|
||||
+ enums), etc.
|
||||
+
|
||||
+ - Member
|
||||
|
||||
- - An element includes one or more member(s) to have a value. For
|
||||
- example, a stereo volume control element has two members (for
|
||||
- left/right). The members share the same properties (e.g. both
|
||||
- volume controls have the same min/max values). The value of each
|
||||
- member can be changed by both of userspace applications and
|
||||
- drivers in kernel.
|
||||
+ - An element usually includes one or more member(s) to have a value. For
|
||||
+ example, a stereo volume control element has two members (for left/right),
|
||||
+ while a mono volume has only one member. The member count can be obtained
|
||||
+ using snd_ctl_elem_info_get_count(). Elements of type
|
||||
+ "SNDRV_CTL_ELEM_TYPE_BYTES" or "SNDRV_CTL_ELEM_TYPE_IEC958" have no members
|
||||
+ at all (and thus no member count), they have just a single value. The
|
||||
+ members share the same properties (e.g. both volume control members have
|
||||
+ the same min/max values). The value of each member can be changed by both
|
||||
+ of userspace applications and drivers in kernel.
|
||||
|
||||
|
||||
-\section identifying_elements Identifying the Elements
|
||||
+\section identifying_elements Identifying Elements
|
||||
|
||||
Each element has the following identifying properties:
|
||||
|
||||
- The numid (a numeric identifier, assigned when the sound card is
|
||||
detected, constant while the sound card is kept connected)
|
||||
-
|
||||
- The interface type (e.g. MIXER, CARD or PCM)
|
||||
- The device
|
||||
- The subdevice
|
||||
@@ -95,10 +102,10 @@ on. In addition, these functions can report the identifying
|
||||
properties. E.g. when the element is addressed using its numid, the
|
||||
functions complements the name, index, etc.
|
||||
|
||||
-To access the values of a control, use the snd_ctl_elem_value*()
|
||||
-functions. These allow to get and set the actual values or
|
||||
-settings. It is also possible to get and set the ID values (such as
|
||||
-the numid or the name).
|
||||
+To access the members (i.e. values) of a control, use the
|
||||
+snd_ctl_elem_value*() functions. These allow to get and set the
|
||||
+actual values or settings. It is also possible to get and set the ID
|
||||
+values (such as the numid or the name).
|
||||
|
||||
|
||||
\section element_sets Element Sets
|
||||
@@ -931,10 +938,19 @@ int snd_ctl_elem_remove(snd_ctl_t *ctl, snd_ctl_elem_id_t *id)
|
||||
}
|
||||
|
||||
/**
|
||||
- * \brief Get CTL element value
|
||||
- * \param ctl CTL handle
|
||||
- * \param data Data of an element.
|
||||
- * \return 0 on success otherwise a negative error code
|
||||
+ * \brief Get CTL element value.
|
||||
+ *
|
||||
+ * Read information from sound card. You must set the ID of the
|
||||
+ * element before calling this function.
|
||||
+ *
|
||||
+ * See snd_ctl_elem_value_t for details.
|
||||
+ *
|
||||
+ * \param ctl CTL handle.
|
||||
+ * \param data The element value. The ID must be set before calling
|
||||
+ * the function, and the actual value will be returned
|
||||
+ * here.
|
||||
+ *
|
||||
+ * \return 0 on success otherwise a negative error code.
|
||||
*/
|
||||
int snd_ctl_elem_read(snd_ctl_t *ctl, snd_ctl_elem_value_t *data)
|
||||
{
|
||||
@@ -943,9 +959,16 @@ int snd_ctl_elem_read(snd_ctl_t *ctl, snd_ctl_elem_value_t *data)
|
||||
}
|
||||
|
||||
/**
|
||||
- * \brief Set CTL element value
|
||||
- * \param ctl CTL handle
|
||||
- * \param data Data of an element.
|
||||
+ * \brief Set CTL element value.
|
||||
+ *
|
||||
+ * Write new value(s) to the sound card. You must set the ID and the
|
||||
+ * value of the element before calling this function.
|
||||
+ *
|
||||
+ * See snd_ctl_elem_value_t for details.
|
||||
+ *
|
||||
+ * \param ctl CTL handle.
|
||||
+ * \param data The new value.
|
||||
+ *
|
||||
* \retval 0 on success
|
||||
* \retval >0 on success when value was changed
|
||||
* \retval <0 a negative error code
|
||||
@@ -2877,9 +2900,16 @@ size_t snd_ctl_elem_value_sizeof()
|
||||
}
|
||||
|
||||
/**
|
||||
- * \brief Allocate an invalid #snd_ctl_elem_value_t using standard malloc(3).
|
||||
- * \param ptr Returned pointer for data of an element.
|
||||
- * \return 0 on success otherwise negative error code.
|
||||
+ * \brief Allocate an invalid #snd_ctl_elem_value_t on the heap.
|
||||
+ *
|
||||
+ * Allocate space for a value object on the head. The allocated memory
|
||||
+ * must be freed using snd_ctl_elem_value_free().
|
||||
+ *
|
||||
+ * See snd_ctl_elem_value_t for details.
|
||||
+ *
|
||||
+ * \param ptr Pointer to a snd_ctl_elem_value_t pointer. The address
|
||||
+ * of the allocated space will be returned here.
|
||||
+ * \return 0 on success, otherwise a negative error code.
|
||||
*/
|
||||
int snd_ctl_elem_value_malloc(snd_ctl_elem_value_t **ptr)
|
||||
{
|
||||
@@ -2891,8 +2921,10 @@ int snd_ctl_elem_value_malloc(snd_ctl_elem_value_t **ptr)
|
||||
}
|
||||
|
||||
/**
|
||||
- * \brief Frees a previously allocated data of an element.
|
||||
- * \param obj Data of an element.
|
||||
+ * \brief Free an #snd_ctl_elem_value_t previously allocated using
|
||||
+ * snd_ctl_elem_value_malloc().
|
||||
+ *
|
||||
+ * \param obj Pointer to the snd_ctl_elem_value_t.
|
||||
*/
|
||||
void snd_ctl_elem_value_free(snd_ctl_elem_value_t *obj)
|
||||
{
|
||||
@@ -2901,6 +2933,9 @@ void snd_ctl_elem_value_free(snd_ctl_elem_value_t *obj)
|
||||
|
||||
/**
|
||||
* \brief Clear given data of an element.
|
||||
+ *
|
||||
+ * See snd_ctl_elem_value_t for details.
|
||||
+ *
|
||||
* \param obj Data of an element.
|
||||
*/
|
||||
void snd_ctl_elem_value_clear(snd_ctl_elem_value_t *obj)
|
||||
@@ -2909,7 +2944,7 @@ void snd_ctl_elem_value_clear(snd_ctl_elem_value_t *obj)
|
||||
}
|
||||
|
||||
/**
|
||||
- * \brief Copy two data of elements.
|
||||
+ * \brief Bitwise copy of a snd_ctl_elem_value_t value.
|
||||
* \param dst Pointer to destination.
|
||||
* \param src Pointer to source.
|
||||
*/
|
||||
@@ -2921,9 +2956,10 @@ void snd_ctl_elem_value_copy(snd_ctl_elem_value_t *dst,
|
||||
}
|
||||
|
||||
/**
|
||||
- * \brief Compare one data of an element to the other.
|
||||
- * \param left Pointer to first data.
|
||||
- * \param right Pointer to second data.
|
||||
+ * \brief Compare two snd_ctl_elem_value_t values, bytewise.
|
||||
+ *
|
||||
+ * \param left First value.
|
||||
+ * \param right Second value.
|
||||
* \return 0 on match, less than or greater than otherwise, see memcmp(3).
|
||||
*/
|
||||
int snd_ctl_elem_value_compare(snd_ctl_elem_value_t *left,
|
||||
@@ -2934,9 +2970,13 @@ int snd_ctl_elem_value_compare(snd_ctl_elem_value_t *left,
|
||||
}
|
||||
|
||||
/**
|
||||
- * \brief Get element identifier from given data of an element.
|
||||
- * \param obj Data of an element.
|
||||
- * \param ptr Pointer for element identifier.
|
||||
+ * \brief Get the element identifier from the given element value.
|
||||
+ *
|
||||
+ * See snd_ctl_elem_value_t for more details.
|
||||
+ *
|
||||
+ * \param obj The element value.
|
||||
+ * \param ptr Pointer to an identifier object. The identifier is
|
||||
+ * stored there.
|
||||
*/
|
||||
void snd_ctl_elem_value_get_id(const snd_ctl_elem_value_t *obj, snd_ctl_elem_id_t *ptr)
|
||||
{
|
||||
@@ -2945,9 +2985,12 @@ void snd_ctl_elem_value_get_id(const snd_ctl_elem_value_t *obj, snd_ctl_elem_id_
|
||||
}
|
||||
|
||||
/**
|
||||
- * \brief Get element numeric identifier from given data of an element.
|
||||
- * \param obj Data of an element.
|
||||
- * \return Element numeric identifier.
|
||||
+ * \brief Get the identifiers 'numid' part from the given element value.
|
||||
+ *
|
||||
+ * See snd_ctl_elem_value_t for more details.
|
||||
+ *
|
||||
+ * \param obj The element value.
|
||||
+ * \return The numid.
|
||||
*/
|
||||
unsigned int snd_ctl_elem_value_get_numid(const snd_ctl_elem_value_t *obj)
|
||||
{
|
||||
@@ -2956,10 +2999,12 @@ unsigned int snd_ctl_elem_value_get_numid(const snd_ctl_elem_value_t *obj)
|
||||
}
|
||||
|
||||
/**
|
||||
- * \brief Get interface part of element identifier from given data of an
|
||||
- * element.
|
||||
- * \param obj Data of an element.
|
||||
- * \return Interface part of element identifier.
|
||||
+ * \brief Get the identifiers 'interface' part from the given element value.
|
||||
+ *
|
||||
+ * See snd_ctl_elem_value_t for more details.
|
||||
+ *
|
||||
+ * \param obj The element value.
|
||||
+ * \return The interface part of element identifier.
|
||||
*/
|
||||
snd_ctl_elem_iface_t snd_ctl_elem_value_get_interface(const snd_ctl_elem_value_t *obj)
|
||||
{
|
||||
@@ -2968,9 +3013,12 @@ snd_ctl_elem_iface_t snd_ctl_elem_value_get_interface(const snd_ctl_elem_value_t
|
||||
}
|
||||
|
||||
/**
|
||||
- * \brief Get device part of element identifier from given data of an element.
|
||||
- * \param obj Data of an element.
|
||||
- * \return Device part of element identifier.
|
||||
+ * \brief Get the identifiers 'device' part from the given element value.
|
||||
+ *
|
||||
+ * See snd_ctl_elem_value_t for more details.
|
||||
+ *
|
||||
+ * \param obj The element value.
|
||||
+ * \return The device part of element identifier.
|
||||
*/
|
||||
unsigned int snd_ctl_elem_value_get_device(const snd_ctl_elem_value_t *obj)
|
||||
{
|
||||
@@ -2979,10 +3027,12 @@ unsigned int snd_ctl_elem_value_get_device(const snd_ctl_elem_value_t *obj)
|
||||
}
|
||||
|
||||
/**
|
||||
- * \brief Get subdevice part of element identifier from given data of an
|
||||
- * element.
|
||||
- * \param obj Data of an element.
|
||||
- * \return Subdevice part of element identifier.
|
||||
+ * \brief Get the identifiers 'subdevice' part from the given element value.
|
||||
+ *
|
||||
+ * See snd_ctl_elem_value_t for more details.
|
||||
+ *
|
||||
+ * \param obj The element value.
|
||||
+ * \return The subdevice part of element identifier.
|
||||
*/
|
||||
unsigned int snd_ctl_elem_value_get_subdevice(const snd_ctl_elem_value_t *obj)
|
||||
{
|
||||
@@ -2991,9 +3041,12 @@ unsigned int snd_ctl_elem_value_get_subdevice(const snd_ctl_elem_value_t *obj)
|
||||
}
|
||||
|
||||
/**
|
||||
- * \brief Get name part of element identifier from given data of an element.
|
||||
- * \param obj Data of an element.
|
||||
- * \return Name part of element identifier.
|
||||
+ * \brief Get the identifiers 'name' part from the given element value.
|
||||
+ *
|
||||
+ * See snd_ctl_elem_value_t for more details.
|
||||
+ *
|
||||
+ * \param obj The element value.
|
||||
+ * \return The "name" part of element identifier.
|
||||
*/
|
||||
const char *snd_ctl_elem_value_get_name(const snd_ctl_elem_value_t *obj)
|
||||
{
|
||||
@@ -3002,9 +3055,12 @@ const char *snd_ctl_elem_value_get_name(const snd_ctl_elem_value_t *obj)
|
||||
}
|
||||
|
||||
/**
|
||||
- * \brief Get index part of element identifier from given data of an element.
|
||||
- * \param obj Data of an element.
|
||||
- * \return Index part of element identifier.
|
||||
+ * \brief Get the identifiers 'index' part from the given element value.
|
||||
+ *
|
||||
+ * See snd_ctl_elem_value_t for more details.
|
||||
+ *
|
||||
+ * \param obj The element value.
|
||||
+ * \return The index part of element identifier.
|
||||
*/
|
||||
unsigned int snd_ctl_elem_value_get_index(const snd_ctl_elem_value_t *obj)
|
||||
{
|
||||
@@ -3012,10 +3068,14 @@ unsigned int snd_ctl_elem_value_get_index(const snd_ctl_elem_value_t *obj)
|
||||
return obj->id.index;
|
||||
}
|
||||
|
||||
+
|
||||
/**
|
||||
- * \brief Set element identifier to given data of an element.
|
||||
- * \param obj Data of an element.
|
||||
- * \param ptr Pointer to an element identifier.
|
||||
+ * \brief Set the element identifier within the given element value.
|
||||
+ *
|
||||
+ * See snd_ctl_elem_value_t for more details.
|
||||
+ *
|
||||
+ * \param obj The element value.
|
||||
+ * \param ptr The new identifier.
|
||||
*/
|
||||
void snd_ctl_elem_value_set_id(snd_ctl_elem_value_t *obj, const snd_ctl_elem_id_t *ptr)
|
||||
{
|
||||
@@ -3024,9 +3084,12 @@ void snd_ctl_elem_value_set_id(snd_ctl_elem_value_t *obj, const snd_ctl_elem_id_
|
||||
}
|
||||
|
||||
/**
|
||||
- * \brief Set numeric identifier to given data of an element.
|
||||
- * \param obj Data of an element.
|
||||
- * \param val Value for numeric identifier.
|
||||
+ * \brief Set the identifiers 'numid' part within the given element value.
|
||||
+ *
|
||||
+ * See snd_ctl_elem_value_t for more details.
|
||||
+ *
|
||||
+ * \param obj The element value.
|
||||
+ * \param val The new numid.
|
||||
*/
|
||||
void snd_ctl_elem_value_set_numid(snd_ctl_elem_value_t *obj, unsigned int val)
|
||||
{
|
||||
@@ -3035,9 +3098,12 @@ void snd_ctl_elem_value_set_numid(snd_ctl_elem_value_t *obj, unsigned int val)
|
||||
}
|
||||
|
||||
/**
|
||||
- * \brief Set interface part of element identifier to given data of an element.
|
||||
- * \param obj Data of an element.
|
||||
- * \param val Value for interface part of element identifier.
|
||||
+ * \brief Set the identifiers 'interface' part within the given element value.
|
||||
+ *
|
||||
+ * See snd_ctl_elem_value_t for more details.
|
||||
+ *
|
||||
+ * \param obj The element value.
|
||||
+ * \param val The new interface.
|
||||
*/
|
||||
void snd_ctl_elem_value_set_interface(snd_ctl_elem_value_t *obj, snd_ctl_elem_iface_t val)
|
||||
{
|
||||
@@ -3046,9 +3112,12 @@ void snd_ctl_elem_value_set_interface(snd_ctl_elem_value_t *obj, snd_ctl_elem_if
|
||||
}
|
||||
|
||||
/**
|
||||
- * \brief Set device part of element identifier to given data of an element.
|
||||
- * \param obj Data of an element.
|
||||
- * \param val Value for device part of element identifier.
|
||||
+ * \brief Set the identifiers 'device' part within the given element value.
|
||||
+ *
|
||||
+ * See snd_ctl_elem_value_t for more details.
|
||||
+ *
|
||||
+ * \param obj The element value.
|
||||
+ * \param val The new device.
|
||||
*/
|
||||
void snd_ctl_elem_value_set_device(snd_ctl_elem_value_t *obj, unsigned int val)
|
||||
{
|
||||
@@ -3057,9 +3126,12 @@ void snd_ctl_elem_value_set_device(snd_ctl_elem_value_t *obj, unsigned int val)
|
||||
}
|
||||
|
||||
/**
|
||||
- * \brief Set subdevice part of element identifier to given data of an element.
|
||||
- * \param obj Data of an element.
|
||||
- * \param val Value for subdevice part of element identifier.
|
||||
+ * \brief Set the identifiers 'subdevice' part within the given element value.
|
||||
+ *
|
||||
+ * See snd_ctl_elem_value_t for more details.
|
||||
+ *
|
||||
+ * \param obj The element value.
|
||||
+ * \param val The new subdevice.
|
||||
*/
|
||||
void snd_ctl_elem_value_set_subdevice(snd_ctl_elem_value_t *obj, unsigned int val)
|
||||
{
|
||||
@@ -3068,9 +3140,12 @@ void snd_ctl_elem_value_set_subdevice(snd_ctl_elem_value_t *obj, unsigned int va
|
||||
}
|
||||
|
||||
/**
|
||||
- * \brief Set name part of element identifier to given data of an element.
|
||||
- * \param obj Data of an element.
|
||||
- * \param val Value for name part of element identifier,
|
||||
+ * \brief Set the identifiers 'name' part within the given element value.
|
||||
+ *
|
||||
+ * See snd_ctl_elem_value_t for more details.
|
||||
+ *
|
||||
+ * \param obj The element value.
|
||||
+ * \param val The new name.
|
||||
*/
|
||||
void snd_ctl_elem_value_set_name(snd_ctl_elem_value_t *obj, const char *val)
|
||||
{
|
||||
@@ -3079,9 +3154,12 @@ void snd_ctl_elem_value_set_name(snd_ctl_elem_value_t *obj, const char *val)
|
||||
}
|
||||
|
||||
/**
|
||||
- * \brief Set index part of element identifier to given data of an element.
|
||||
- * \param obj Data of an element.
|
||||
- * \param val Value for index part of element identifier.
|
||||
+ * \brief Set the identifiers 'index' part within the given element value.
|
||||
+ *
|
||||
+ * See snd_ctl_elem_value_t for more details.
|
||||
+ *
|
||||
+ * \param obj The element value.
|
||||
+ * \param val The new index.
|
||||
*/
|
||||
void snd_ctl_elem_value_set_index(snd_ctl_elem_value_t *obj, unsigned int val)
|
||||
{
|
||||
@@ -3090,12 +3168,16 @@ void snd_ctl_elem_value_set_index(snd_ctl_elem_value_t *obj, unsigned int val)
|
||||
}
|
||||
|
||||
/**
|
||||
- * \brief Get value of a specified member from given data as an element of
|
||||
- * boolean type.
|
||||
- * \param obj Data of an element.
|
||||
- * \param idx Index of member in the element.
|
||||
- * \return Value for the member.
|
||||
- */
|
||||
+ * \brief Get an element members value.
|
||||
+ *
|
||||
+ * Use this function if the element is of type SNDRV_CTL_ELEM_TYPE_BOOLEAN. It
|
||||
+ * returns the value of one member. See \ref snd_ctl_elem_value_t and \ref
|
||||
+ * control for more details.
|
||||
+ *
|
||||
+ * \param obj The element value object
|
||||
+ * \param idx The index of the member.
|
||||
+ * \return The members value.
|
||||
+ */
|
||||
int snd_ctl_elem_value_get_boolean(const snd_ctl_elem_value_t *obj, unsigned int idx)
|
||||
{
|
||||
assert(obj);
|
||||
@@ -3104,12 +3186,16 @@ int snd_ctl_elem_value_get_boolean(const snd_ctl_elem_value_t *obj, unsigned int
|
||||
}
|
||||
|
||||
/**
|
||||
- * \brief Get value of a specified member from given data as an element of
|
||||
- * integer type.
|
||||
- * \param obj Data of an element.
|
||||
- * \param idx Index of member in the element.
|
||||
- * \return Value for the member.
|
||||
- */
|
||||
+ * \brief Get an element members value.
|
||||
+ *
|
||||
+ * Use this function if the element is of type SNDRV_CTL_ELEM_TYPE_INTEGER. It
|
||||
+ * returns the value of one member. See \ref snd_ctl_elem_value_t and \ref
|
||||
+ * control for more details.
|
||||
+ *
|
||||
+ * \param obj The element value object.
|
||||
+ * \param idx The index of the member.
|
||||
+ * \return The members value.
|
||||
+ */
|
||||
long snd_ctl_elem_value_get_integer(const snd_ctl_elem_value_t *obj, unsigned int idx)
|
||||
{
|
||||
assert(obj);
|
||||
@@ -3118,12 +3204,16 @@ long snd_ctl_elem_value_get_integer(const snd_ctl_elem_value_t *obj, unsigned in
|
||||
}
|
||||
|
||||
/**
|
||||
- * \brief Get value of a specified member from given data as an element of
|
||||
- * integer64 type.
|
||||
- * \param obj Data of an element.
|
||||
- * \param idx Index of member in the element.
|
||||
- * \return Value for the member.
|
||||
- */
|
||||
+ * \brief Get an element members value.
|
||||
+ *
|
||||
+ * Use this function if the element is of type SNDRV_CTL_ELEM_TYPE_INTEGER64. It
|
||||
+ * returns the value of one member. See \ref snd_ctl_elem_value_t and \ref
|
||||
+ * control for more details.
|
||||
+ *
|
||||
+ * \param obj The element value object.
|
||||
+ * \param idx The index of the member.
|
||||
+ * \return The members value.
|
||||
+ */
|
||||
long long snd_ctl_elem_value_get_integer64(const snd_ctl_elem_value_t *obj, unsigned int idx)
|
||||
{
|
||||
assert(obj);
|
||||
@@ -3132,12 +3222,16 @@ long long snd_ctl_elem_value_get_integer64(const snd_ctl_elem_value_t *obj, unsi
|
||||
}
|
||||
|
||||
/**
|
||||
- * \brief Get value of a specified member from given data as an element of
|
||||
- * enumerated type.
|
||||
- * \param obj Data of an element.
|
||||
- * \param idx Index of member in the element.
|
||||
- * \return Value for the member. This is an index of name set in the element.
|
||||
- */
|
||||
+ * \brief Get an element members value.
|
||||
+ *
|
||||
+ * Use this function if the element is of type
|
||||
+ * SNDRV_CTL_ELEM_TYPE_ENUMERATED. It returns the index of the active item. See
|
||||
+ * \ref snd_ctl_elem_value_t and \ref control for more details.
|
||||
+ *
|
||||
+ * \param obj The element value object.
|
||||
+ * \param idx The index of the requested member.
|
||||
+ * \return The index of the active item.
|
||||
+ */
|
||||
unsigned int snd_ctl_elem_value_get_enumerated(const snd_ctl_elem_value_t *obj, unsigned int idx)
|
||||
{
|
||||
assert(obj);
|
||||
@@ -3146,12 +3240,16 @@ unsigned int snd_ctl_elem_value_get_enumerated(const snd_ctl_elem_value_t *obj,
|
||||
}
|
||||
|
||||
/**
|
||||
- * \brief Get value of a specified member from given data as an element of
|
||||
- * bytes type.
|
||||
- * \param obj Data of an element.
|
||||
- * \param idx Index of member in the element.
|
||||
- * \return Value for the member.
|
||||
- */
|
||||
+ * \brief Get an element members value.
|
||||
+ *
|
||||
+ * Use this function if the element is of type SNDRV_CTL_ELEM_TYPE_BYTE. It
|
||||
+ * returns the value of one member. See \ref snd_ctl_elem_value_t and \ref
|
||||
+ * control for more details.
|
||||
+ *
|
||||
+ * \param obj The element value object.
|
||||
+ * \param idx The index of the member.
|
||||
+ * \return The members value.
|
||||
+ */
|
||||
unsigned char snd_ctl_elem_value_get_byte(const snd_ctl_elem_value_t *obj, unsigned int idx)
|
||||
{
|
||||
assert(obj);
|
||||
@@ -3160,12 +3258,16 @@ unsigned char snd_ctl_elem_value_get_byte(const snd_ctl_elem_value_t *obj, unsig
|
||||
}
|
||||
|
||||
/**
|
||||
- * \brief Set value of a specified member to given data as an element of
|
||||
- * boolean type.
|
||||
- * \param obj Data of an element.
|
||||
- * \param idx Index of member in the element.
|
||||
- * \param val Value for the member.
|
||||
- */
|
||||
+ * \brief Set an element members value.
|
||||
+ *
|
||||
+ * Use this function if the element is of type SNDRV_CTL_ELEM_TYPE_BOOLEAN. It
|
||||
+ * sets the value of one member. See \ref snd_ctl_elem_value_t and \ref control
|
||||
+ * for more details.
|
||||
+ *
|
||||
+ * \param obj The element value object.
|
||||
+ * \param idx The index of the member.
|
||||
+ * \param val The new value.
|
||||
+ */
|
||||
void snd_ctl_elem_value_set_boolean(snd_ctl_elem_value_t *obj, unsigned int idx, long val)
|
||||
{
|
||||
assert(obj);
|
||||
@@ -3174,12 +3276,16 @@ void snd_ctl_elem_value_set_boolean(snd_ctl_elem_value_t *obj, unsigned int idx,
|
||||
}
|
||||
|
||||
/**
|
||||
- * \brief Set value of a specified member to given data as an element of
|
||||
- * integer type.
|
||||
- * \param obj Data of an element.
|
||||
- * \param idx Index of member in the element.
|
||||
- * \param val Value for the member.
|
||||
- */
|
||||
+ * \brief Set an element members value.
|
||||
+ *
|
||||
+ * Use this function if the element is of type SNDRV_CTL_ELEM_TYPE_INTEGER. It
|
||||
+ * sets the value of one member. See \ref snd_ctl_elem_value_t and \ref control
|
||||
+ * for more details.
|
||||
+ *
|
||||
+ * \param obj The element value object.
|
||||
+ * \param idx The index of the member.
|
||||
+ * \param val The new value.
|
||||
+ */
|
||||
void snd_ctl_elem_value_set_integer(snd_ctl_elem_value_t *obj, unsigned int idx, long val)
|
||||
{
|
||||
assert(obj);
|
||||
@@ -3188,12 +3294,16 @@ void snd_ctl_elem_value_set_integer(snd_ctl_elem_value_t *obj, unsigned int idx,
|
||||
}
|
||||
|
||||
/**
|
||||
- * \brief Set value of a specified member to given data as an element of
|
||||
- * integer64 type.
|
||||
- * \param obj Data of an element.
|
||||
- * \param idx Index of member in the element.
|
||||
- * \param val Value for the member.
|
||||
- */
|
||||
+ * \brief Set an element members value.
|
||||
+ *
|
||||
+ * Use this function if the element is of type SNDRV_CTL_ELEM_TYPE_INTEGER64. It
|
||||
+ * sets the value of one member. See \ref snd_ctl_elem_value_t and \ref control
|
||||
+ * for more details.
|
||||
+ *
|
||||
+ * \param obj The element value object.
|
||||
+ * \param idx The index of the member.
|
||||
+ * \param val The new value.
|
||||
+ */
|
||||
void snd_ctl_elem_value_set_integer64(snd_ctl_elem_value_t *obj, unsigned int idx, long long val)
|
||||
{
|
||||
assert(obj);
|
||||
@@ -3202,12 +3312,16 @@ void snd_ctl_elem_value_set_integer64(snd_ctl_elem_value_t *obj, unsigned int id
|
||||
}
|
||||
|
||||
/**
|
||||
- * \brief Set value of a specified member to given data as an element of
|
||||
- * enumerated type.
|
||||
- * \param obj Data of an element.
|
||||
- * \param idx Index of member in the element.
|
||||
- * \param val Value for the member.
|
||||
- */
|
||||
+ * \brief Set an element members value.
|
||||
+ *
|
||||
+ * Use this function if the element is of type
|
||||
+ * SNDRV_CTL_ELEM_TYPE_ENUMERATED. It activates the specified item. See \ref
|
||||
+ * snd_ctl_elem_value_t and \ref control for more details.
|
||||
+ *
|
||||
+ * \param obj The element value object.
|
||||
+ * \param idx The index of the requested member.
|
||||
+ * \param val The new index of the item to be activated.
|
||||
+ */
|
||||
void snd_ctl_elem_value_set_enumerated(snd_ctl_elem_value_t *obj, unsigned int idx, unsigned int val)
|
||||
{
|
||||
assert(obj);
|
||||
@@ -3216,12 +3330,16 @@ void snd_ctl_elem_value_set_enumerated(snd_ctl_elem_value_t *obj, unsigned int i
|
||||
}
|
||||
|
||||
/**
|
||||
- * \brief Set value for a specified member to given data as an element of byte
|
||||
- * type.
|
||||
- * \param obj Data of an element.
|
||||
- * \param idx Index of member in the element.
|
||||
- * \param val Value for the member.
|
||||
- */
|
||||
+ * \brief Set an element members value.
|
||||
+ *
|
||||
+ * Use this function if the element is of type SNDRV_CTL_ELEM_TYPE_BYTE. It
|
||||
+ * sets the value of one member. See \ref snd_ctl_elem_value_t and \ref control
|
||||
+ * for more details.
|
||||
+ *
|
||||
+ * \param obj The element value object.
|
||||
+ * \param idx The index of the member.
|
||||
+ * \param val The new value.
|
||||
+ */
|
||||
void snd_ctl_elem_value_set_byte(snd_ctl_elem_value_t *obj, unsigned int idx, unsigned char val)
|
||||
{
|
||||
assert(obj);
|
||||
@@ -3230,10 +3348,17 @@ void snd_ctl_elem_value_set_byte(snd_ctl_elem_value_t *obj, unsigned int idx, un
|
||||
}
|
||||
|
||||
/**
|
||||
- * \brief Set values to given data as an element of bytes type.
|
||||
- * \param obj Data of an element.
|
||||
- * \param data Pointer for byte array.
|
||||
- * \param size The number of bytes included in the memory block.
|
||||
+ * \brief Replace the data stored within the element.
|
||||
+ *
|
||||
+ * Use this function if the element is of type SNDRV_CTL_ELEM_TYPE_BYTES. It
|
||||
+ * replaces the data stored in the element. Note that "bytes" elements don't
|
||||
+ * have members. They have only one single block of data.
|
||||
+ *
|
||||
+ * See \ref snd_ctl_elem_value_t and \ref control for more details.
|
||||
+ *
|
||||
+ * \param obj The element value object.
|
||||
+ * \param data Pointer to the new data.
|
||||
+ * \param size The size of the new data, in bytes.
|
||||
*/
|
||||
void snd_ctl_elem_set_bytes(snd_ctl_elem_value_t *obj, void *data, size_t size)
|
||||
{
|
||||
@@ -3243,10 +3368,17 @@ void snd_ctl_elem_set_bytes(snd_ctl_elem_value_t *obj, void *data, size_t size)
|
||||
}
|
||||
|
||||
/**
|
||||
- * \brief Get memory block from given data as an element of bytes type.
|
||||
- * \param obj Data of an element.
|
||||
- * \return Pointer for byte array.
|
||||
- */
|
||||
+ * \brief Get the data stored within the element.
|
||||
+ *
|
||||
+ * Use this function if the element is of type SNDRV_CTL_ELEM_TYPE_BYTES. It
|
||||
+ * returns the data stored in the element. Note that "bytes" elements don't have
|
||||
+ * members. They have only one single block of data.
|
||||
+ *
|
||||
+ * See \ref snd_ctl_elem_value_t and \ref control for more details.
|
||||
+ *
|
||||
+ * \param obj The element value object.
|
||||
+ * \return Pointer to the elements data.
|
||||
+ */
|
||||
const void * snd_ctl_elem_value_get_bytes(const snd_ctl_elem_value_t *obj)
|
||||
{
|
||||
assert(obj);
|
||||
@@ -3254,11 +3386,17 @@ const void * snd_ctl_elem_value_get_bytes(const snd_ctl_elem_value_t *obj)
|
||||
}
|
||||
|
||||
/**
|
||||
- * \brief Get value from given data to given pointer as an element of IEC958
|
||||
- * type.
|
||||
- * \param obj Data of an element.
|
||||
- * \param ptr Pointer to IEC958 data.
|
||||
- */
|
||||
+ * \brief Get an elements IEC958 data.
|
||||
+ *
|
||||
+ * Use this function if the element is of type SNDRV_CTL_ELEM_TYPE_IEC958. Note that
|
||||
+ * "IEC958" elements don't have members. They have only one single
|
||||
+ * IEC958 information block.
|
||||
+ *
|
||||
+ * See \ref snd_ctl_elem_value_t and \ref control for more details.
|
||||
+ *
|
||||
+ * \param obj The element value object.
|
||||
+ * \param ptr Pointer to an IEC958 structure. The data is stored there.
|
||||
+ */
|
||||
void snd_ctl_elem_value_get_iec958(const snd_ctl_elem_value_t *obj, snd_aes_iec958_t *ptr)
|
||||
{
|
||||
assert(obj && ptr);
|
||||
@@ -3266,11 +3404,17 @@ void snd_ctl_elem_value_get_iec958(const snd_ctl_elem_value_t *obj, snd_aes_iec9
|
||||
}
|
||||
|
||||
/**
|
||||
- * \brief Set value from given pointer to given data as an element of IEC958
|
||||
- * type.
|
||||
- * \param obj Data of an element.
|
||||
- * \param ptr Pointer to IEC958 data.
|
||||
- */
|
||||
+ * \brief Set an elements IEC958 data.
|
||||
+ *
|
||||
+ * Use this function if the element is of type SNDRV_CTL_ELEM_TYPE_IEC958. Note
|
||||
+ * that "IEC958" elements don't have members. They have only one single IEC958
|
||||
+ * information block.
|
||||
+ *
|
||||
+ * See \ref snd_ctl_elem_value_t and \ref control for more details.
|
||||
+ *
|
||||
+ * \param obj The element value object.
|
||||
+ * \param ptr Pointer to the new IEC958 data.
|
||||
+ */
|
||||
void snd_ctl_elem_value_set_iec958(snd_ctl_elem_value_t *obj, const snd_aes_iec958_t *ptr)
|
||||
{
|
||||
assert(obj && ptr);
|
||||
--
|
||||
2.16.4
|
||||
|
43
alsa.changes
43
alsa.changes
@ -1,3 +1,46 @@
|
||||
-------------------------------------------------------------------
|
||||
Tue Sep 29 08:57:00 UTC 2020 - Guillaume GARDET <guillaume.gardet@opensuse.org>
|
||||
|
||||
- Enable topology support for aarch64
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Sep 23 16:49:23 CEST 2020 - tiwai@suse.de
|
||||
|
||||
- Backport upstream fixes:
|
||||
0001-ucm-substitution-remove-duplicate-allow_empty-assign.patch
|
||||
0002-ucm-fix-parse_get_safe_name-safe-name-must-be-checke.patch
|
||||
0003-ucm-substitute-the-merged-tree-completely.patch
|
||||
0004-ctl-improve-documentation-for-identifier-of-control-.patch
|
||||
0005-pcm-dmix-make-lockless-operation-optional.patch
|
||||
0006-pcm-dmix-Fix-semaphore-usage-with-lockless-operation.patch
|
||||
0007-pcm-iec958-implement-HDMI-HBR-audio-formatting.patch
|
||||
0008-pcm-iec958-set-channel-status-bits-according-to-rate.patch
|
||||
0009-conf-pcm-USB-Added-S-PDIF-fix-for-Asus-Xonar-SE.patch
|
||||
0010-control-ctlparse-fix-enum-values-in-or.patch
|
||||
0011-conf-USB-Audio-Disable-IEC958-on-Lenovo-ThinkStation.patch
|
||||
0012-pcm-dmix-fix-access-to-sum-buffer-in-non-interleaved.patch
|
||||
0014-control-Add-documentation-for-snd_ctl_elem_list_.patch
|
||||
0015-conf-quote-also-strings-with-and-characters-in-strin.patch
|
||||
0016-topology-decode-Fix-channel-map-memory-allocation.patch
|
||||
0017-topology-decode-Fix-infinite-loop-in-decoding-enum-c.patch
|
||||
0018-topology-decode-Remove-decoding-values-for-enum-cont.patch
|
||||
0019-topology-decode-Add-enum-control-texts-as-separate-e.patch
|
||||
0020-topology-decode-Fix-printing-texts-section.patch
|
||||
0021-topology-decode-Change-declaration-of-enum-decoding-.patch
|
||||
0022-topology-decode-Fix-decoding-PCM-formats-and-rates.patch
|
||||
0023-topology-decode-Print-sig_bits-field-in-PCM-capabili.patch
|
||||
0024-topology-decode-Add-DAI-name-printing.patch
|
||||
0025-topology-Make-buffer-for-saving-dynamic-size.patch
|
||||
0026-topology-return-correct-value-in-tplg_save_printf.patch
|
||||
0027-topology-fix-some-gcc10-warnings-labs-signess.patch
|
||||
0028-topology-fix-sort_config.patch
|
||||
0029-topology-fix-the-unaligned-access.patch
|
||||
0030-topology-improve-the-printf-buffer-management.patch
|
||||
0031-control-Improve-general-control-interface-documentat.patch
|
||||
0032-control-Add-documentation-for-snd_ctl_elem_value_.patch
|
||||
- Build topology library conditionally;
|
||||
currently it's supported only for little-endian
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Jul 9 16:01:13 CEST 2020 - tiwai@suse.de
|
||||
|
||||
|
86
alsa.spec
86
alsa.spec
@ -25,6 +25,12 @@
|
||||
%define _udevrulesdir /lib/udev/rules.d/
|
||||
%endif
|
||||
|
||||
%ifarch %ix86 x86_64 %arm aarch64 ppc64le
|
||||
%define enable_topology 1
|
||||
%else
|
||||
%define enable_topology 0
|
||||
%endif
|
||||
|
||||
Name: alsa
|
||||
Version: 1.2.3.2
|
||||
Release: 0
|
||||
@ -47,6 +53,37 @@ Source30: all_notes_off
|
||||
Source31: all_notes_off.bin
|
||||
Source32: all_notes_off.mid
|
||||
Source34: alsa-init.sh
|
||||
Patch1: 0001-ucm-substitution-remove-duplicate-allow_empty-assign.patch
|
||||
Patch2: 0002-ucm-fix-parse_get_safe_name-safe-name-must-be-checke.patch
|
||||
Patch3: 0003-ucm-substitute-the-merged-tree-completely.patch
|
||||
Patch4: 0004-ctl-improve-documentation-for-identifier-of-control-.patch
|
||||
Patch5: 0005-pcm-dmix-make-lockless-operation-optional.patch
|
||||
Patch6: 0006-pcm-dmix-Fix-semaphore-usage-with-lockless-operation.patch
|
||||
Patch7: 0007-pcm-iec958-implement-HDMI-HBR-audio-formatting.patch
|
||||
Patch8: 0008-pcm-iec958-set-channel-status-bits-according-to-rate.patch
|
||||
Patch9: 0009-conf-pcm-USB-Added-S-PDIF-fix-for-Asus-Xonar-SE.patch
|
||||
Patch10: 0010-control-ctlparse-fix-enum-values-in-or.patch
|
||||
Patch11: 0011-conf-USB-Audio-Disable-IEC958-on-Lenovo-ThinkStation.patch
|
||||
Patch12: 0012-pcm-dmix-fix-access-to-sum-buffer-in-non-interleaved.patch
|
||||
Patch14: 0014-control-Add-documentation-for-snd_ctl_elem_list_.patch
|
||||
Patch15: 0015-conf-quote-also-strings-with-and-characters-in-strin.patch
|
||||
Patch16: 0016-topology-decode-Fix-channel-map-memory-allocation.patch
|
||||
Patch17: 0017-topology-decode-Fix-infinite-loop-in-decoding-enum-c.patch
|
||||
Patch18: 0018-topology-decode-Remove-decoding-values-for-enum-cont.patch
|
||||
Patch19: 0019-topology-decode-Add-enum-control-texts-as-separate-e.patch
|
||||
Patch20: 0020-topology-decode-Fix-printing-texts-section.patch
|
||||
Patch21: 0021-topology-decode-Change-declaration-of-enum-decoding-.patch
|
||||
Patch22: 0022-topology-decode-Fix-decoding-PCM-formats-and-rates.patch
|
||||
Patch23: 0023-topology-decode-Print-sig_bits-field-in-PCM-capabili.patch
|
||||
Patch24: 0024-topology-decode-Add-DAI-name-printing.patch
|
||||
Patch25: 0025-topology-Make-buffer-for-saving-dynamic-size.patch
|
||||
Patch26: 0026-topology-return-correct-value-in-tplg_save_printf.patch
|
||||
Patch27: 0027-topology-fix-some-gcc10-warnings-labs-signess.patch
|
||||
Patch28: 0028-topology-fix-sort_config.patch
|
||||
Patch29: 0029-topology-fix-the-unaligned-access.patch
|
||||
Patch30: 0030-topology-improve-the-printf-buffer-management.patch
|
||||
Patch31: 0031-control-Improve-general-control-interface-documentat.patch
|
||||
Patch32: 0032-control-Add-documentation-for-snd_ctl_elem_value_.patch
|
||||
# rest suse fixes
|
||||
Patch101: alsa-lib-ignore-non-accessible-ALSA_CONFIG_PATH.patch
|
||||
BuildRequires: doxygen
|
||||
@ -88,6 +125,7 @@ Provides: alsadev = %{version}
|
||||
This package contains all necessary include files and libraries needed
|
||||
to develop applications that require ALSA.
|
||||
|
||||
%if %enable_topology
|
||||
%package topology-devel
|
||||
Summary: Header files for ALSA topology development
|
||||
License: LGPL-2.1-or-later
|
||||
@ -98,6 +136,7 @@ Requires: libatopology2 = %{version}
|
||||
%description topology-devel
|
||||
This package contains all necessary include files and libraries needed
|
||||
to develop applications that require ALSA topology.
|
||||
%endif
|
||||
|
||||
%package docs
|
||||
Summary: Additional Package Documentation for ALSA
|
||||
@ -121,6 +160,7 @@ Provides: alsa-lib
|
||||
This package contains the library for ALSA, Advanced Linux Sound
|
||||
Architecture.
|
||||
|
||||
%if %enable_topology
|
||||
%package -n libatopology2
|
||||
Summary: ALSA Topology Library
|
||||
License: LGPL-2.1-or-later
|
||||
@ -128,9 +168,41 @@ Group: System/Libraries
|
||||
|
||||
%description -n libatopology2
|
||||
This package contains the library for ALSA topology support.
|
||||
%endif
|
||||
|
||||
%prep
|
||||
%setup -q -n alsa-lib-%{version}
|
||||
%patch1 -p1
|
||||
%patch2 -p1
|
||||
%patch3 -p1
|
||||
%patch4 -p1
|
||||
%patch5 -p1
|
||||
%patch6 -p1
|
||||
%patch7 -p1
|
||||
%patch8 -p1
|
||||
%patch9 -p1
|
||||
%patch10 -p1
|
||||
%patch11 -p1
|
||||
%patch12 -p1
|
||||
%patch14 -p1
|
||||
%patch15 -p1
|
||||
%patch16 -p1
|
||||
%patch17 -p1
|
||||
%patch18 -p1
|
||||
%patch19 -p1
|
||||
%patch20 -p1
|
||||
%patch21 -p1
|
||||
%patch22 -p1
|
||||
%patch23 -p1
|
||||
%patch24 -p1
|
||||
%patch25 -p1
|
||||
%patch26 -p1
|
||||
%patch27 -p1
|
||||
%patch28 -p1
|
||||
%patch29 -p1
|
||||
%patch30 -p1
|
||||
%patch31 -p1
|
||||
%patch32 -p1
|
||||
%patch101 -p1
|
||||
|
||||
%build
|
||||
@ -144,6 +216,9 @@ autoreconf -fi
|
||||
--enable-symbolic-functions \
|
||||
--disable-aload \
|
||||
--disable-alisp \
|
||||
%if !%enable_topology
|
||||
--disable-topology \
|
||||
%endif
|
||||
--disable-python
|
||||
make V=1 %{?_smp_mflags}
|
||||
# run doxygen
|
||||
@ -156,6 +231,9 @@ make -C doc doc %{?_smp_mflags}
|
||||
rm -f %{buildroot}%{_libdir}/*.*a
|
||||
# rm -f %{buildroot}%{_libdir}/alsa-lib/smixer/*.*a
|
||||
rm -f %{buildroot}%{_bindir}/aserver
|
||||
%if !%enable_topology
|
||||
rm -f %{buildroot}%{_libdir}/pkgconfig/alsa-topology.pc
|
||||
%endif
|
||||
#
|
||||
# install helper scripts
|
||||
mkdir -p %{buildroot}%{_bindir}
|
||||
@ -242,8 +320,10 @@ exit 0
|
||||
%post -n libasound2 -p /sbin/ldconfig
|
||||
%postun -n libasound2 -p /sbin/ldconfig
|
||||
|
||||
%if %enable_topology
|
||||
%post -n libatopology2 -p /sbin/ldconfig
|
||||
%postun -n libatopology2 -p /sbin/ldconfig
|
||||
%endif
|
||||
|
||||
%files
|
||||
%defattr(-, root, root)
|
||||
@ -266,16 +346,20 @@ exit 0
|
||||
%{_libdir}/libasound.so
|
||||
%{_includedir}/sys/*
|
||||
%{_includedir}/alsa
|
||||
%if %enable_topology
|
||||
%exclude %{_includedir}/alsa/topology.h
|
||||
%endif
|
||||
%{_includedir}/asoundlib.h
|
||||
%{_datadir}/aclocal/*.m4
|
||||
%{_libdir}/pkgconfig/alsa.pc
|
||||
|
||||
%if %enable_topology
|
||||
%files topology-devel
|
||||
%defattr(-, root, root)
|
||||
%{_libdir}/libatopology.so
|
||||
%{_includedir}/alsa/topology.h
|
||||
%{_libdir}/pkgconfig/alsa-topology.pc
|
||||
%endif
|
||||
|
||||
%files docs
|
||||
%defattr(-, root, root)
|
||||
@ -286,8 +370,10 @@ exit 0
|
||||
%{_libdir}/libasound.so.*
|
||||
%{_datadir}/alsa
|
||||
|
||||
%if %enable_topology
|
||||
%files -n libatopology2
|
||||
%defattr(-, root, root)
|
||||
%{_libdir}/libatopology.so.*
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
|
Loading…
Reference in New Issue
Block a user