Hello community,

here is the log from the commit of package alsa for openSUSE:Factory checked in 
at 2020-10-03 18:56:27
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/alsa (Old)
 and      /work/SRC/openSUSE:Factory/.alsa.new.4249 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "alsa"

Sat Oct  3 18:56:27 2020 rev:204 rq:838541 version:1.2.3.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/alsa/alsa.changes        2020-07-13 
09:04:48.635984570 +0200
+++ /work/SRC/openSUSE:Factory/.alsa.new.4249/alsa.changes      2020-10-03 
18:57:29.885614906 +0200
@@ -1,0 +2,43 @@
+Tue Sep 29 08:57:00 UTC 2020 - Guillaume GARDET <guillaume.gar...@opensuse.org>
+
+- Enable topology support for aarch64
+
+-------------------------------------------------------------------
+Wed Sep 23 16:49:23 CEST 2020 - ti...@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
+
+-------------------------------------------------------------------

New:
----
  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

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ alsa.spec ++++++
--- /var/tmp/diff_new_pack.ObxBbH/_old  2020-10-03 18:57:30.593615690 +0200
+++ /var/tmp/diff_new_pack.ObxBbH/_new  2020-10-03 18:57:30.597615695 +0200
@@ -25,6 +25,12 @@
 %define _udevrulesdir /lib/udev/rules.d/
 %endif
 
+%ifarch %ix86 x86_64 %arm aarch64 ppc64le
+%define enable_topology        1
+%else
+%define enable_topology        0
+%endif
+
 Name:           alsa
 Version:        1.2.3.2
 Release:        0
@@ -47,6 +53,37 @@
 Source31:       all_notes_off.bin
 Source32:       all_notes_off.mid
 Source34:       alsa-init.sh
+Patch1:         0001-ucm-substitution-remove-duplicate-allow_empty-assign.patch
+Patch2:         0002-ucm-fix-parse_get_safe_name-safe-name-must-be-checke.patch
+Patch3:         0003-ucm-substitute-the-merged-tree-completely.patch
+Patch4:         0004-ctl-improve-documentation-for-identifier-of-control-.patch
+Patch5:         0005-pcm-dmix-make-lockless-operation-optional.patch
+Patch6:         0006-pcm-dmix-Fix-semaphore-usage-with-lockless-operation.patch
+Patch7:         0007-pcm-iec958-implement-HDMI-HBR-audio-formatting.patch
+Patch8:         0008-pcm-iec958-set-channel-status-bits-according-to-rate.patch
+Patch9:         0009-conf-pcm-USB-Added-S-PDIF-fix-for-Asus-Xonar-SE.patch
+Patch10:        0010-control-ctlparse-fix-enum-values-in-or.patch
+Patch11:        0011-conf-USB-Audio-Disable-IEC958-on-Lenovo-ThinkStation.patch
+Patch12:        0012-pcm-dmix-fix-access-to-sum-buffer-in-non-interleaved.patch
+Patch14:        0014-control-Add-documentation-for-snd_ctl_elem_list_.patch
+Patch15:        0015-conf-quote-also-strings-with-and-characters-in-strin.patch
+Patch16:        0016-topology-decode-Fix-channel-map-memory-allocation.patch
+Patch17:        0017-topology-decode-Fix-infinite-loop-in-decoding-enum-c.patch
+Patch18:        0018-topology-decode-Remove-decoding-values-for-enum-cont.patch
+Patch19:        0019-topology-decode-Add-enum-control-texts-as-separate-e.patch
+Patch20:        0020-topology-decode-Fix-printing-texts-section.patch
+Patch21:        0021-topology-decode-Change-declaration-of-enum-decoding-.patch
+Patch22:        0022-topology-decode-Fix-decoding-PCM-formats-and-rates.patch
+Patch23:        0023-topology-decode-Print-sig_bits-field-in-PCM-capabili.patch
+Patch24:        0024-topology-decode-Add-DAI-name-printing.patch
+Patch25:        0025-topology-Make-buffer-for-saving-dynamic-size.patch
+Patch26:        0026-topology-return-correct-value-in-tplg_save_printf.patch
+Patch27:        0027-topology-fix-some-gcc10-warnings-labs-signess.patch
+Patch28:        0028-topology-fix-sort_config.patch
+Patch29:        0029-topology-fix-the-unaligned-access.patch
+Patch30:        0030-topology-improve-the-printf-buffer-management.patch
+Patch31:        0031-control-Improve-general-control-interface-documentat.patch
+Patch32:        0032-control-Add-documentation-for-snd_ctl_elem_value_.patch
 # rest suse fixes
 Patch101:       alsa-lib-ignore-non-accessible-ALSA_CONFIG_PATH.patch
 BuildRequires:  doxygen
@@ -88,6 +125,7 @@
 This package contains all necessary include files and libraries needed
 to develop applications that require ALSA.
 
+%if %enable_topology
 %package topology-devel
 Summary:        Header files for ALSA topology development
 License:        LGPL-2.1-or-later
@@ -98,6 +136,7 @@
 %description topology-devel
 This package contains all necessary include files and libraries needed
 to develop applications that require ALSA topology.
+%endif
 
 %package docs
 Summary:        Additional Package Documentation for ALSA
@@ -121,6 +160,7 @@
 This package contains the library for ALSA, Advanced Linux Sound
 Architecture.
 
+%if %enable_topology
 %package -n libatopology2
 Summary:        ALSA Topology Library
 License:        LGPL-2.1-or-later
@@ -128,9 +168,41 @@
 
 %description -n libatopology2
 This package contains the library for ALSA topology support.
+%endif
 
 %prep
 %setup -q -n alsa-lib-%{version}
+%patch1 -p1
+%patch2 -p1
+%patch3 -p1
+%patch4 -p1
+%patch5 -p1
+%patch6 -p1
+%patch7 -p1
+%patch8 -p1
+%patch9 -p1
+%patch10 -p1
+%patch11 -p1
+%patch12 -p1
+%patch14 -p1
+%patch15 -p1
+%patch16 -p1
+%patch17 -p1
+%patch18 -p1
+%patch19 -p1
+%patch20 -p1
+%patch21 -p1
+%patch22 -p1
+%patch23 -p1
+%patch24 -p1
+%patch25 -p1
+%patch26 -p1
+%patch27 -p1
+%patch28 -p1
+%patch29 -p1
+%patch30 -p1
+%patch31 -p1
+%patch32 -p1
 %patch101 -p1
 
 %build
@@ -144,6 +216,9 @@
   --enable-symbolic-functions \
   --disable-aload \
   --disable-alisp \
+%if !%enable_topology
+  --disable-topology \
+%endif
   --disable-python
 make V=1 %{?_smp_mflags}
 # run doxygen
@@ -156,6 +231,9 @@
 rm -f %{buildroot}%{_libdir}/*.*a
 # rm -f %{buildroot}%{_libdir}/alsa-lib/smixer/*.*a
 rm -f %{buildroot}%{_bindir}/aserver
+%if !%enable_topology
+rm -f %{buildroot}%{_libdir}/pkgconfig/alsa-topology.pc
+%endif
 #
 # install helper scripts
 mkdir -p %{buildroot}%{_bindir}
@@ -242,8 +320,10 @@
 %post -n libasound2 -p /sbin/ldconfig
 %postun -n libasound2 -p /sbin/ldconfig
 
+%if %enable_topology
 %post -n libatopology2 -p /sbin/ldconfig
 %postun -n libatopology2 -p /sbin/ldconfig
+%endif
 
 %files
 %defattr(-, root, root)
@@ -266,16 +346,20 @@
 %{_libdir}/libasound.so
 %{_includedir}/sys/*
 %{_includedir}/alsa
+%if %enable_topology
 %exclude %{_includedir}/alsa/topology.h
+%endif
 %{_includedir}/asoundlib.h
 %{_datadir}/aclocal/*.m4
 %{_libdir}/pkgconfig/alsa.pc
 
+%if %enable_topology
 %files topology-devel
 %defattr(-, root, root)
 %{_libdir}/libatopology.so
 %{_includedir}/alsa/topology.h
 %{_libdir}/pkgconfig/alsa-topology.pc
+%endif
 
 %files docs
 %defattr(-, root, root)
@@ -286,8 +370,10 @@
 %{_libdir}/libasound.so.*
 %{_datadir}/alsa
 
+%if %enable_topology
 %files -n libatopology2
 %defattr(-, root, root)
 %{_libdir}/libatopology.so.*
+%endif
 
 %changelog

++++++ 0001-ucm-substitution-remove-duplicate-allow_empty-assign.patch ++++++
>From 485930ea5dc8a14e0d215de44557372ca41b15f4 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <pe...@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 <pe...@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

++++++ 0002-ucm-fix-parse_get_safe_name-safe-name-must-be-checke.patch ++++++
>From 30d12e930cfcba777a29af502a9c1dbfa5e37c04 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <pe...@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 <pe...@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

++++++ 0003-ucm-substitute-the-merged-tree-completely.patch ++++++
>From 32addac948a61c4770f9cdf459fa29879602df38 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <pe...@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 <pe...@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

++++++ 0004-ctl-improve-documentation-for-identifier-of-control-.patch ++++++
>From 877bdf95fdfdac840a7a664362ec69b85c59ecb0 Mon Sep 17 00:00:00 2001
From: Takashi Sakamoto <o-taka...@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-taka...@sakamocchi.jp>
Signed-off-by: Jaroslav Kysela <pe...@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

++++++ 0005-pcm-dmix-make-lockless-operation-optional.patch ++++++
>From 4759865c861c708ce4a68fc08060fc820628ccaf Mon Sep 17 00:00:00 2001
From: Takashi Iwai <ti...@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 <pe...@perex.cz>
Signed-off-by: Takashi Iwai <ti...@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

++++++ 0006-pcm-dmix-Fix-semaphore-usage-with-lockless-operation.patch ++++++
>From d824b461ae807ea436e2df36da9c2212e485e3e6 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <ti...@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 <pe...@perex.cz>
Signed-off-by: Takashi Iwai <ti...@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

++++++ 0007-pcm-iec958-implement-HDMI-HBR-audio-formatting.patch ++++++
>From 8defc5c2a65345a1aee613ebf0999d203c2e0433 Mon Sep 17 00:00:00 2001
From: Matthias Reichl <h...@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 <h...@horus.com>
Signed-off-by: Takashi Iwai <ti...@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

++++++ 0008-pcm-iec958-set-channel-status-bits-according-to-rate.patch ++++++
>From 36e4b296d2f4ad0034f7028256c64b8af003068d Mon Sep 17 00:00:00 2001
From: Matthias Reichl <h...@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 <h...@horus.com>
Signed-off-by: Takashi Iwai <ti...@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

++++++ 0009-conf-pcm-USB-Added-S-PDIF-fix-for-Asus-Xonar-SE.patch ++++++
>From a80606d1abfd3c2bccfa179c31af8b6e7c0a9031 Mon Sep 17 00:00:00 2001
From: omar <odzi...@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 <odzi...@gmail.com>
Signed-off-by: Jaroslav Kysela <pe...@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

++++++ 0010-control-ctlparse-fix-enum-values-in-or.patch ++++++
>From a3ca4803cb8db73d01231c69620e2d18573ffba9 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <pe...@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 <pe...@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

++++++ 0011-conf-USB-Audio-Disable-IEC958-on-Lenovo-ThinkStation.patch ++++++
>From 464c2f8b61855cb22d61c4b232f74d6767fac5fb Mon Sep 17 00:00:00 2001
From: Kai-Heng Feng <kai.heng.f...@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.f...@canonical.com>
Signed-off-by: Takashi Iwai <ti...@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

++++++ 0012-pcm-dmix-fix-access-to-sum-buffer-in-non-interleaved.patch ++++++
>From 82cb27c165d4337fe3183668bd0fa21ff6287e8e Mon Sep 17 00:00:00 2001
From: Vijay Palaniswamy <vijay.palanisw...@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.palanisw...@in.bosch.com>
Signed-off-by: Takashi Iwai <ti...@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

++++++ 0014-control-Add-documentation-for-snd_ctl_elem_list_.patch ++++++
>From e097dd491a8f25418a90d38aea549bb4668de955 Mon Sep 17 00:00:00 2001
From: "Tanjeff-N. Moos" <tanj...@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 <tanj...@cccmz.de>
Signed-off-by: Takashi Iwai <ti...@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

++++++ 0015-conf-quote-also-strings-with-and-characters-in-strin.patch ++++++
>From ed752498522b0a99a9fbec99247d9c73b10abb3e Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <pe...@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 <pe...@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

++++++ 0016-topology-decode-Fix-channel-map-memory-allocation.patch ++++++
>From 1ac965184eaefe503939e454273223a1d8d32f41 Mon Sep 17 00:00:00 2001
From: Piotr Maziarz <piotrx.mazi...@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.mazi...@linux.intel.com>
Reviewed-by: Cezary Rojewski <cezary.rojew...@intel.com>
Reviewed-by: Amadeusz Sławiński <amadeuszx.slawin...@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.boss...@linux.intel.com>
Signed-off-by: Jaroslav Kysela <pe...@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

++++++ 0017-topology-decode-Fix-infinite-loop-in-decoding-enum-c.patch ++++++
>From 346a5efa87c38a0d5ff9bd5b5d08be27b6c9bfaf Mon Sep 17 00:00:00 2001
From: Piotr Maziarz <piotrx.mazi...@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.mazi...@linux.intel.com>
Reviewed-by: Cezary Rojewski <cezary.rojew...@intel.com>
Reviewed-by: Amadeusz Sławiński <amadeuszx.slawin...@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.boss...@linux.intel.com>
Signed-off-by: Jaroslav Kysela <pe...@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

++++++ 0018-topology-decode-Remove-decoding-values-for-enum-cont.patch ++++++
>From 11d4a5aa721dce2c3f7430996caf244a73dd5099 Mon Sep 17 00:00:00 2001
From: Piotr Maziarz <piotrx.mazi...@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.mazi...@linux.intel.com>
Reviewed-by: Cezary Rojewski <cezary.rojew...@intel.com>
Reviewed-by: Amadeusz Sławiński <amadeuszx.slawin...@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.boss...@linux.intel.com>
Signed-off-by: Jaroslav Kysela <pe...@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

++++++ 0019-topology-decode-Add-enum-control-texts-as-separate-e.patch ++++++
>From f1435207a2fbe35bf616c6d58eecd8801dbe5642 Mon Sep 17 00:00:00 2001
From: Piotr Maziarz <piotrx.mazi...@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.mazi...@linux.intel.com>
Reviewed-by: Cezary Rojewski <cezary.rojew...@intel.com>
Reviewed-by: Amadeusz Sławiński <amadeuszx.slawin...@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.boss...@linux.intel.com>
Signed-off-by: Jaroslav Kysela <pe...@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

++++++ 0020-topology-decode-Fix-printing-texts-section.patch ++++++
>From 56a096ca2ceaf1dec944258d961c274e6550b27a Mon Sep 17 00:00:00 2001
From: Piotr Maziarz <piotrx.mazi...@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.mazi...@linux.intel.com>
Reviewed-by: Cezary Rojewski <cezary.rojew...@intel.com>
Reviewed-by: Amadeusz Sławiński <amadeuszx.slawin...@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.boss...@linux.intel.com>
Signed-off-by: Jaroslav Kysela <pe...@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

++++++ 0021-topology-decode-Change-declaration-of-enum-decoding-.patch ++++++
>From c32498603aea7cc2f3fa3f850f9e4ea0f6ce03b2 Mon Sep 17 00:00:00 2001
From: Piotr Maziarz <piotrx.mazi...@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.mazi...@linux.intel.com>
Reviewed-by: Cezary Rojewski <cezary.rojew...@intel.com>
Reviewed-by: Amadeusz Sławiński <amadeuszx.slawin...@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.boss...@linux.intel.com>
Signed-off-by: Jaroslav Kysela <pe...@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

++++++ 0022-topology-decode-Fix-decoding-PCM-formats-and-rates.patch ++++++
>From acbb0e3b1741107d01f03ee06f7819fd7f90bec4 Mon Sep 17 00:00:00 2001
From: Piotr Maziarz <piotrx.mazi...@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.mazi...@linux.intel.com>
Reviewed-by: Cezary Rojewski <cezary.rojew...@intel.com>
Reviewed-by: Amadeusz Sławiński <amadeuszx.slawin...@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.boss...@linux.intel.com>
Signed-off-by: Jaroslav Kysela <pe...@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

++++++ 0023-topology-decode-Print-sig_bits-field-in-PCM-capabili.patch ++++++
>From d93b3462996a20951bc0ca753d0304bbbb9850fc Mon Sep 17 00:00:00 2001
From: Piotr Maziarz <piotrx.mazi...@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.mazi...@linux.intel.com>
Reviewed-by: Cezary Rojewski <cezary.rojew...@intel.com>
Reviewed-by: Amadeusz Sławiński <amadeuszx.slawin...@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.boss...@linux.intel.com>
Signed-off-by: Jaroslav Kysela <pe...@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

++++++ 0024-topology-decode-Add-DAI-name-printing.patch ++++++
>From 6b0fb2bc7e0cfac8e1aedfcad183ab247c85173d Mon Sep 17 00:00:00 2001
From: Piotr Maziarz <piotrx.mazi...@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.mazi...@linux.intel.com>
Reviewed-by: Cezary Rojewski <cezary.rojew...@intel.com>
Reviewed-by: Amadeusz Sławiński <amadeuszx.slawin...@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.boss...@linux.intel.com>
Signed-off-by: Jaroslav Kysela <pe...@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

++++++ 0025-topology-Make-buffer-for-saving-dynamic-size.patch ++++++
>From d04e72c9a593015952e4858b92ab3f9d821560d9 Mon Sep 17 00:00:00 2001
From: Piotr Maziarz <piotrx.mazi...@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.mazi...@linux.intel.com>
Reviewed-by: Cezary Rojewski <cezary.rojew...@intel.com>
Reviewed-by: Amadeusz Sławiński <amadeuszx.slawin...@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.boss...@linux.intel.com>
Signed-off-by: Jaroslav Kysela <pe...@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

++++++ 0026-topology-return-correct-value-in-tplg_save_printf.patch ++++++
>From dc778bade60812a71b98ac827c2c6e3c02f14cf1 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <pe...@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 <pe...@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

++++++ 0027-topology-fix-some-gcc10-warnings-labs-signess.patch ++++++
>From 6ca1ddfbcdf97ad46c3767ba314d1144119361fd Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <pe...@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 <pe...@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

++++++ 0028-topology-fix-sort_config.patch ++++++
>From 84c6aeef5ca89c0686ae2a9ed90504010f8fe9e6 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <pe...@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 <pe...@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

++++++ 0029-topology-fix-the-unaligned-access.patch ++++++
>From ab73253924ad8d46f94ab1212e0f05ebc2e3dcc5 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <pe...@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 <pe...@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

++++++ 0030-topology-improve-the-printf-buffer-management.patch ++++++
++++ 666 lines (skipped)

++++++ 0031-control-Improve-general-control-interface-documentat.patch ++++++
>From 84185b5c94ec8a214103b8ec02d272f0158c24e6 Mon Sep 17 00:00:00 2001
From: "Tanjeff-N. Moos" <tanj...@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 <tanj...@cccmz.de>
Signed-off-by: Takashi Iwai <ti...@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

++++++ 0032-control-Add-documentation-for-snd_ctl_elem_value_.patch ++++++
++++ 828 lines (skipped)





Reply via email to