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
|
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/
|
%define _udevrulesdir /lib/udev/rules.d/
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
|
%ifarch %ix86 x86_64 %arm aarch64 ppc64le
|
||||||
|
%define enable_topology 1
|
||||||
|
%else
|
||||||
|
%define enable_topology 0
|
||||||
|
%endif
|
||||||
|
|
||||||
Name: alsa
|
Name: alsa
|
||||||
Version: 1.2.3.2
|
Version: 1.2.3.2
|
||||||
Release: 0
|
Release: 0
|
||||||
@ -47,6 +53,37 @@ Source30: all_notes_off
|
|||||||
Source31: all_notes_off.bin
|
Source31: all_notes_off.bin
|
||||||
Source32: all_notes_off.mid
|
Source32: all_notes_off.mid
|
||||||
Source34: alsa-init.sh
|
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
|
# rest suse fixes
|
||||||
Patch101: alsa-lib-ignore-non-accessible-ALSA_CONFIG_PATH.patch
|
Patch101: alsa-lib-ignore-non-accessible-ALSA_CONFIG_PATH.patch
|
||||||
BuildRequires: doxygen
|
BuildRequires: doxygen
|
||||||
@ -88,6 +125,7 @@ Provides: alsadev = %{version}
|
|||||||
This package contains all necessary include files and libraries needed
|
This package contains all necessary include files and libraries needed
|
||||||
to develop applications that require ALSA.
|
to develop applications that require ALSA.
|
||||||
|
|
||||||
|
%if %enable_topology
|
||||||
%package topology-devel
|
%package topology-devel
|
||||||
Summary: Header files for ALSA topology development
|
Summary: Header files for ALSA topology development
|
||||||
License: LGPL-2.1-or-later
|
License: LGPL-2.1-or-later
|
||||||
@ -98,6 +136,7 @@ Requires: libatopology2 = %{version}
|
|||||||
%description topology-devel
|
%description topology-devel
|
||||||
This package contains all necessary include files and libraries needed
|
This package contains all necessary include files and libraries needed
|
||||||
to develop applications that require ALSA topology.
|
to develop applications that require ALSA topology.
|
||||||
|
%endif
|
||||||
|
|
||||||
%package docs
|
%package docs
|
||||||
Summary: Additional Package Documentation for ALSA
|
Summary: Additional Package Documentation for ALSA
|
||||||
@ -121,6 +160,7 @@ Provides: alsa-lib
|
|||||||
This package contains the library for ALSA, Advanced Linux Sound
|
This package contains the library for ALSA, Advanced Linux Sound
|
||||||
Architecture.
|
Architecture.
|
||||||
|
|
||||||
|
%if %enable_topology
|
||||||
%package -n libatopology2
|
%package -n libatopology2
|
||||||
Summary: ALSA Topology Library
|
Summary: ALSA Topology Library
|
||||||
License: LGPL-2.1-or-later
|
License: LGPL-2.1-or-later
|
||||||
@ -128,9 +168,41 @@ Group: System/Libraries
|
|||||||
|
|
||||||
%description -n libatopology2
|
%description -n libatopology2
|
||||||
This package contains the library for ALSA topology support.
|
This package contains the library for ALSA topology support.
|
||||||
|
%endif
|
||||||
|
|
||||||
%prep
|
%prep
|
||||||
%setup -q -n alsa-lib-%{version}
|
%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
|
%patch101 -p1
|
||||||
|
|
||||||
%build
|
%build
|
||||||
@ -144,6 +216,9 @@ autoreconf -fi
|
|||||||
--enable-symbolic-functions \
|
--enable-symbolic-functions \
|
||||||
--disable-aload \
|
--disable-aload \
|
||||||
--disable-alisp \
|
--disable-alisp \
|
||||||
|
%if !%enable_topology
|
||||||
|
--disable-topology \
|
||||||
|
%endif
|
||||||
--disable-python
|
--disable-python
|
||||||
make V=1 %{?_smp_mflags}
|
make V=1 %{?_smp_mflags}
|
||||||
# run doxygen
|
# run doxygen
|
||||||
@ -156,6 +231,9 @@ make -C doc doc %{?_smp_mflags}
|
|||||||
rm -f %{buildroot}%{_libdir}/*.*a
|
rm -f %{buildroot}%{_libdir}/*.*a
|
||||||
# rm -f %{buildroot}%{_libdir}/alsa-lib/smixer/*.*a
|
# rm -f %{buildroot}%{_libdir}/alsa-lib/smixer/*.*a
|
||||||
rm -f %{buildroot}%{_bindir}/aserver
|
rm -f %{buildroot}%{_bindir}/aserver
|
||||||
|
%if !%enable_topology
|
||||||
|
rm -f %{buildroot}%{_libdir}/pkgconfig/alsa-topology.pc
|
||||||
|
%endif
|
||||||
#
|
#
|
||||||
# install helper scripts
|
# install helper scripts
|
||||||
mkdir -p %{buildroot}%{_bindir}
|
mkdir -p %{buildroot}%{_bindir}
|
||||||
@ -242,8 +320,10 @@ exit 0
|
|||||||
%post -n libasound2 -p /sbin/ldconfig
|
%post -n libasound2 -p /sbin/ldconfig
|
||||||
%postun -n libasound2 -p /sbin/ldconfig
|
%postun -n libasound2 -p /sbin/ldconfig
|
||||||
|
|
||||||
|
%if %enable_topology
|
||||||
%post -n libatopology2 -p /sbin/ldconfig
|
%post -n libatopology2 -p /sbin/ldconfig
|
||||||
%postun -n libatopology2 -p /sbin/ldconfig
|
%postun -n libatopology2 -p /sbin/ldconfig
|
||||||
|
%endif
|
||||||
|
|
||||||
%files
|
%files
|
||||||
%defattr(-, root, root)
|
%defattr(-, root, root)
|
||||||
@ -266,16 +346,20 @@ exit 0
|
|||||||
%{_libdir}/libasound.so
|
%{_libdir}/libasound.so
|
||||||
%{_includedir}/sys/*
|
%{_includedir}/sys/*
|
||||||
%{_includedir}/alsa
|
%{_includedir}/alsa
|
||||||
|
%if %enable_topology
|
||||||
%exclude %{_includedir}/alsa/topology.h
|
%exclude %{_includedir}/alsa/topology.h
|
||||||
|
%endif
|
||||||
%{_includedir}/asoundlib.h
|
%{_includedir}/asoundlib.h
|
||||||
%{_datadir}/aclocal/*.m4
|
%{_datadir}/aclocal/*.m4
|
||||||
%{_libdir}/pkgconfig/alsa.pc
|
%{_libdir}/pkgconfig/alsa.pc
|
||||||
|
|
||||||
|
%if %enable_topology
|
||||||
%files topology-devel
|
%files topology-devel
|
||||||
%defattr(-, root, root)
|
%defattr(-, root, root)
|
||||||
%{_libdir}/libatopology.so
|
%{_libdir}/libatopology.so
|
||||||
%{_includedir}/alsa/topology.h
|
%{_includedir}/alsa/topology.h
|
||||||
%{_libdir}/pkgconfig/alsa-topology.pc
|
%{_libdir}/pkgconfig/alsa-topology.pc
|
||||||
|
%endif
|
||||||
|
|
||||||
%files docs
|
%files docs
|
||||||
%defattr(-, root, root)
|
%defattr(-, root, root)
|
||||||
@ -286,8 +370,10 @@ exit 0
|
|||||||
%{_libdir}/libasound.so.*
|
%{_libdir}/libasound.so.*
|
||||||
%{_datadir}/alsa
|
%{_datadir}/alsa
|
||||||
|
|
||||||
|
%if %enable_topology
|
||||||
%files -n libatopology2
|
%files -n libatopology2
|
||||||
%defattr(-, root, root)
|
%defattr(-, root, root)
|
||||||
%{_libdir}/libatopology.so.*
|
%{_libdir}/libatopology.so.*
|
||||||
|
%endif
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
Loading…
x
Reference in New Issue
Block a user