From c10ff71224e2b61a41b51f8fd159c8bd7a470cb3352e10e99b4e33840005d630 Mon Sep 17 00:00:00 2001 From: Ondrej Holecek Date: Wed, 25 Nov 2020 19:46:24 +0000 Subject: [PATCH 1/3] Accepting request 850788 from home:tiwai:branches:multimedia:libs - Update to pulseaudio 14.0: see details in: https://www.freedesktop.org/wiki/Software/PulseAudio/Notes/14.0/ - Drop obsoleted patches: 0001-alsa-mixer-path-test-Hide-unused-functions-when-buil.patch 0002-alsa-mixer-recognize-the-Speaker-Jack-control.patch 0003-alsa-mixer-add-support-for-SteelSeries-Arctis-Pro-20.patch 0004-alsa-mixer-Add-support-for-SteelSeries-Arctis-5-2019.patch 0005-alsa-mixer-add-support-for-LucidSound-LS31-and-creat.patch 0006-alsa-ucm-use-ucm2-name-for-the-direct-card-index-ope.patch 0007-alsa-ucm-add-mixer-IDs-to-ucm_items.patch 0008-alsa-mixer-handle-the-index-for-ALSA-mixer-element-i.patch 0009-alsa-mixer-improve-alsa_id_decode-function.patch 0010-alsa-ucm-Support-Playback-CaptureVolume.patch 0011-alsa-ucm-Fix-volume-control-based-on-review.patch 0012-alsa-ucm-use-the-correct-mixer-identifiers-as-first.patch 0013-alsa-ucm-add-support-for-master-volume.patch 0014-alsa-ucm-split-correctly-JackHWMute-device-names.patch 0015-alsa-ucm-fix-parsing-for-JackControl.patch 0016-alsa-ucm-add-comments-to-ucm_get_mixer_id.patch 0017-alsa-ucm-validate-access-to-PA_DEVICE_PORT_DATA.patch 0018-alsa-Skip-resume-PCM-if-hardware-doesn-t-support-it.patch 0019-alsa-ucm-parse-correctly-the-device-values.patch 0020-alsa-ucm-do-not-try-to-use-UCM-device-name-as-jack-n.patch 0021-alsa-util-do-not-try-to-guess-the-mixer-name-from-th.patch 0022-alsa-ucm-add-control-and-mixer-device-items.patch 0023-alsa-ucm-get-the-mixer-names-from-ucm-don-t-guess.patch 0024-alsa-ucm-use-the-proper-mixer-name-for-ucm-pcm-sink-.patch 0025-alsa-mixer-handle-interface-type-CARD-PCM-for-mixer-.patch 0026-alsa-mixer-Add-the-ability-to-pass-the-intended-role.patch OBS-URL: https://build.opensuse.org/request/show/850788 OBS-URL: https://build.opensuse.org/package/show/multimedia:libs/pulseaudio?expand=0&rev=222 --- disabled-start.diff | 16 +++-- pulseaudio-13.0.tar.xz | 3 - pulseaudio-14.0.tar.xz | 3 + pulseaudio-old-systemd-workaround.patch | 14 ++-- pulseaudio-wrong-memset.patch | 10 ++- pulseaudio.changes | 48 +++++++++++++ pulseaudio.spec | 91 ++----------------------- qpaeq-shebang.patch | 10 ++- suppress-socket-error-msg.diff | 8 +-- 9 files changed, 88 insertions(+), 115 deletions(-) delete mode 100644 pulseaudio-13.0.tar.xz create mode 100644 pulseaudio-14.0.tar.xz diff --git a/disabled-start.diff b/disabled-start.diff index e987ae9..9274bf8 100644 --- a/disabled-start.diff +++ b/disabled-start.diff @@ -1,8 +1,10 @@ -Index: src/daemon/start-pulseaudio-x11.in -=================================================================== ---- src/daemon/start-pulseaudio-x11.in.orig -+++ src/daemon/start-pulseaudio-x11.in -@@ -19,6 +19,12 @@ +--- + src/daemon/start-pulseaudio-x11.in | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/src/daemon/start-pulseaudio-x11.in ++++ b/src/daemon/start-pulseaudio-x11.in +@@ -17,6 +17,12 @@ set -e @@ -13,5 +15,5 @@ Index: src/daemon/start-pulseaudio-x11.in +fi + if [ x"$DISPLAY" != x ] ; then - - @PACTL_BINARY@ load-module module-x11-publish "display=$DISPLAY" > /dev/null + + @PACTL_BINARY@ load-module module-x11-publish "display=$DISPLAY xauthority=$XAUTHORITY" > /dev/null diff --git a/pulseaudio-13.0.tar.xz b/pulseaudio-13.0.tar.xz deleted file mode 100644 index 64ad314..0000000 --- a/pulseaudio-13.0.tar.xz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:961b23ca1acfd28f2bc87414c27bb40e12436efcf2158d29721b1e89f3f28057 -size 1901768 diff --git a/pulseaudio-14.0.tar.xz b/pulseaudio-14.0.tar.xz new file mode 100644 index 0000000..6ef960a --- /dev/null +++ b/pulseaudio-14.0.tar.xz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a834775d9382b055504e5ee7625dc50768daac29329531deb6597bf05e06c261 +size 1980800 diff --git a/pulseaudio-old-systemd-workaround.patch b/pulseaudio-old-systemd-workaround.patch index 110a3db..9c629b2 100644 --- a/pulseaudio-old-systemd-workaround.patch +++ b/pulseaudio-old-systemd-workaround.patch @@ -1,15 +1,13 @@ --- - src/daemon/systemd/user/pulseaudio.service.in | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) + src/daemon/systemd/user/pulseaudio.service.in | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) -Index: pulseaudio-13.0/src/daemon/systemd/user/pulseaudio.service.in -=================================================================== ---- pulseaudio-13.0.orig/src/daemon/systemd/user/pulseaudio.service.in 2019-09-13 15:10:23.000000000 +0200 -+++ pulseaudio-13.0/src/daemon/systemd/user/pulseaudio.service.in 2019-10-07 17:43:52.208067968 +0200 -@@ -18,13 +18,13 @@ +--- a/src/daemon/systemd/user/pulseaudio.service.in ++++ b/src/daemon/systemd/user/pulseaudio.service.in +@@ -18,13 +18,13 @@ ConditionUser=!root [Service] - ExecStart=@PA_BINARY@ --daemonize=no + ExecStart=@PA_BINARY@ --daemonize=no --log-target=journal -LockPersonality=yes +#LockPersonality=yes MemoryDenyWriteExecute=yes diff --git a/pulseaudio-wrong-memset.patch b/pulseaudio-wrong-memset.patch index 17b5e47..5e132bc 100644 --- a/pulseaudio-wrong-memset.patch +++ b/pulseaudio-wrong-memset.patch @@ -1,6 +1,10 @@ ---- src/modules/echo-cancel/adrian-aec.c.orig 2012-05-20 09:24:20.836607707 +0200 -+++ src/modules/echo-cancel/adrian-aec.c 2012-05-20 09:26:07.641603903 +0200 -@@ -167,7 +167,7 @@ +--- + src/modules/echo-cancel/adrian-aec.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/src/modules/echo-cancel/adrian-aec.c ++++ b/src/modules/echo-cancel/adrian-aec.c +@@ -171,7 +171,7 @@ static void AEC_leaky(AEC *a) } else if (1 == a->hangover) { --(a->hangover); // My Leaky NLMS is to erase vector w when hangover expires diff --git a/pulseaudio.changes b/pulseaudio.changes index 7666963..87af92f 100644 --- a/pulseaudio.changes +++ b/pulseaudio.changes @@ -1,3 +1,51 @@ +------------------------------------------------------------------- +Wed Nov 25 17:10:35 CET 2020 - tiwai@suse.de + +- Update to pulseaudio 14.0: + see details in: + https://www.freedesktop.org/wiki/Software/PulseAudio/Notes/14.0/ +- Drop obsoleted patches: + 0001-alsa-mixer-path-test-Hide-unused-functions-when-buil.patch + 0002-alsa-mixer-recognize-the-Speaker-Jack-control.patch + 0003-alsa-mixer-add-support-for-SteelSeries-Arctis-Pro-20.patch + 0004-alsa-mixer-Add-support-for-SteelSeries-Arctis-5-2019.patch + 0005-alsa-mixer-add-support-for-LucidSound-LS31-and-creat.patch + 0006-alsa-ucm-use-ucm2-name-for-the-direct-card-index-ope.patch + 0007-alsa-ucm-add-mixer-IDs-to-ucm_items.patch + 0008-alsa-mixer-handle-the-index-for-ALSA-mixer-element-i.patch + 0009-alsa-mixer-improve-alsa_id_decode-function.patch + 0010-alsa-ucm-Support-Playback-CaptureVolume.patch + 0011-alsa-ucm-Fix-volume-control-based-on-review.patch + 0012-alsa-ucm-use-the-correct-mixer-identifiers-as-first.patch + 0013-alsa-ucm-add-support-for-master-volume.patch + 0014-alsa-ucm-split-correctly-JackHWMute-device-names.patch + 0015-alsa-ucm-fix-parsing-for-JackControl.patch + 0016-alsa-ucm-add-comments-to-ucm_get_mixer_id.patch + 0017-alsa-ucm-validate-access-to-PA_DEVICE_PORT_DATA.patch + 0018-alsa-Skip-resume-PCM-if-hardware-doesn-t-support-it.patch + 0019-alsa-ucm-parse-correctly-the-device-values.patch + 0020-alsa-ucm-do-not-try-to-use-UCM-device-name-as-jack-n.patch + 0021-alsa-util-do-not-try-to-guess-the-mixer-name-from-th.patch + 0022-alsa-ucm-add-control-and-mixer-device-items.patch + 0023-alsa-ucm-get-the-mixer-names-from-ucm-don-t-guess.patch + 0024-alsa-ucm-use-the-proper-mixer-name-for-ucm-pcm-sink-.patch + 0025-alsa-mixer-handle-interface-type-CARD-PCM-for-mixer-.patch + 0026-alsa-mixer-Add-the-ability-to-pass-the-intended-role.patch + 0027-alsa-mixer-Set-the-intended-role-of-Steelseries-Arct.patch + 0028-alsa-rewrite-mixer-open-close-cache-mixer-accesses-i.patch + 0029-alsa-ucm-add-support-for-HDMI-ELD.patch + 0030-alsa-mixer-do-the-quick-card-number-lookup-to-save-m.patch + 0031-alsa-mixer-improve-check-for-the-empty-path-set-for-.patch + 0032-alsa-ucm-allow-to-set-profile-priority-from-UCM-valu.patch + 0033-alsa-Document-that-mixer-elements-can-be-identified-.patch + 0034-alsa-ucm-correct-the-channel-default-logic-stereo.patch + 0035-alsa-ucm-do-not-assign-JackHWMute-when-JackControl-i.patch + 0036-ucm-Don-t-log-errors-during-normal-operation.patch + 0037-alsa-handle-unavailbale-HW-volume-in-UCM.patch + 0038-alsa-ucm-use-the-right-profile-name.patch + 0039-ucm-fix-the-port-ucm-device-activation-on-boot.patch + 0040-alsa-sink-source-fix-the-mixer-initialization.patch + ------------------------------------------------------------------- Mon Jun 22 11:34:33 UTC 2020 - Callum Farmer diff --git a/pulseaudio.spec b/pulseaudio.spec index d95e52a..ad4c68f 100644 --- a/pulseaudio.spec +++ b/pulseaudio.spec @@ -21,12 +21,12 @@ %define _fillupdir /var/adm/fillup-templates %endif -%define drvver 13.0 +%define drvver 14.0 %define soname 0 %define _udevrulesdir %(pkg-config --variable=udevdir udev)/rules.d %define _bashcompletionsdir %{_datadir}/bash-completion/completions Name: pulseaudio -Version: 13.0 +Version: 14.0 Release: 0 Summary: A Networked Sound Server License: GPL-2.0-or-later AND LGPL-2.1-or-later @@ -50,47 +50,6 @@ Patch2: pulseaudio-wrong-memset.patch Patch5: qpaeq-shebang.patch # PATCH-FIX-OPENSUSE Workaround for old systemd on Leap 15.x Patch6: pulseaudio-old-systemd-workaround.patch -# PATCH-FIX-UPSTREAM -Patch1001: 0001-alsa-mixer-path-test-Hide-unused-functions-when-buil.patch -Patch1002: 0002-alsa-mixer-recognize-the-Speaker-Jack-control.patch -Patch1003: 0003-alsa-mixer-add-support-for-SteelSeries-Arctis-Pro-20.patch -Patch1004: 0004-alsa-mixer-Add-support-for-SteelSeries-Arctis-5-2019.patch -Patch1005: 0005-alsa-mixer-add-support-for-LucidSound-LS31-and-creat.patch -Patch1006: 0006-alsa-ucm-use-ucm2-name-for-the-direct-card-index-ope.patch -Patch1007: 0007-alsa-ucm-add-mixer-IDs-to-ucm_items.patch -Patch1008: 0008-alsa-mixer-handle-the-index-for-ALSA-mixer-element-i.patch -Patch1009: 0009-alsa-mixer-improve-alsa_id_decode-function.patch -Patch1010: 0010-alsa-ucm-Support-Playback-CaptureVolume.patch -Patch1011: 0011-alsa-ucm-Fix-volume-control-based-on-review.patch -Patch1012: 0012-alsa-ucm-use-the-correct-mixer-identifiers-as-first.patch -Patch1013: 0013-alsa-ucm-add-support-for-master-volume.patch -Patch1014: 0014-alsa-ucm-split-correctly-JackHWMute-device-names.patch -Patch1015: 0015-alsa-ucm-fix-parsing-for-JackControl.patch -Patch1016: 0016-alsa-ucm-add-comments-to-ucm_get_mixer_id.patch -Patch1017: 0017-alsa-ucm-validate-access-to-PA_DEVICE_PORT_DATA.patch -Patch1018: 0018-alsa-Skip-resume-PCM-if-hardware-doesn-t-support-it.patch -Patch1019: 0019-alsa-ucm-parse-correctly-the-device-values.patch -Patch1020: 0020-alsa-ucm-do-not-try-to-use-UCM-device-name-as-jack-n.patch -Patch1021: 0021-alsa-util-do-not-try-to-guess-the-mixer-name-from-th.patch -Patch1022: 0022-alsa-ucm-add-control-and-mixer-device-items.patch -Patch1023: 0023-alsa-ucm-get-the-mixer-names-from-ucm-don-t-guess.patch -Patch1024: 0024-alsa-ucm-use-the-proper-mixer-name-for-ucm-pcm-sink-.patch -Patch1025: 0025-alsa-mixer-handle-interface-type-CARD-PCM-for-mixer-.patch -Patch1026: 0026-alsa-mixer-Add-the-ability-to-pass-the-intended-role.patch -Patch1027: 0027-alsa-mixer-Set-the-intended-role-of-Steelseries-Arct.patch -Patch1028: 0028-alsa-rewrite-mixer-open-close-cache-mixer-accesses-i.patch -Patch1029: 0029-alsa-ucm-add-support-for-HDMI-ELD.patch -Patch1030: 0030-alsa-mixer-do-the-quick-card-number-lookup-to-save-m.patch -Patch1031: 0031-alsa-mixer-improve-check-for-the-empty-path-set-for-.patch -Patch1032: 0032-alsa-ucm-allow-to-set-profile-priority-from-UCM-valu.patch -Patch1033: 0033-alsa-Document-that-mixer-elements-can-be-identified-.patch -Patch1034: 0034-alsa-ucm-correct-the-channel-default-logic-stereo.patch -Patch1035: 0035-alsa-ucm-do-not-assign-JackHWMute-when-JackControl-i.patch -Patch1036: 0036-ucm-Don-t-log-errors-during-normal-operation.patch -Patch1037: 0037-alsa-handle-unavailbale-HW-volume-in-UCM.patch -Patch1038: 0038-alsa-ucm-use-the-right-profile-name.patch -Patch1039: 0039-ucm-fix-the-port-ucm-device-activation-on-boot.patch -Patch1040: 0040-alsa-sink-source-fix-the-mixer-initialization.patch BuildRequires: alsa-devel >= 1.0.19 BuildRequires: bluez-devel >= 5 BuildRequires: doxygen @@ -378,50 +337,10 @@ Optional dependency offering zsh completion for various PulseAudio utilities %prep %setup -q -T -b0 -%patch0 -%patch1001 -p1 -%patch1002 -p1 -%patch1003 -p1 -%patch1004 -p1 -%patch1005 -p1 -%patch1006 -p1 -%patch1007 -p1 -%patch1008 -p1 -%patch1009 -p1 -%patch1010 -p1 -%patch1011 -p1 -%patch1012 -p1 -%patch1013 -p1 -%patch1014 -p1 -%patch1015 -p1 -%patch1016 -p1 -%patch1017 -p1 -%patch1018 -p1 -%patch1019 -p1 -%patch1020 -p1 -%patch1021 -p1 -%patch1022 -p1 -%patch1023 -p1 -%patch1024 -p1 -%patch1025 -p1 -%patch1026 -p1 -%patch1027 -p1 -%patch1028 -p1 -%patch1029 -p1 -%patch1030 -p1 -%patch1031 -p1 -%patch1032 -p1 -%patch1033 -p1 -%patch1034 -p1 -%patch1035 -p1 -%patch1036 -p1 -%patch1037 -p1 -%patch1038 -p1 -%patch1039 -p1 -%patch1040 -p1 +%patch0 -p1 %patch1 -p1 -%patch2 -%patch5 +%patch2 -p1 +%patch5 -p1 # workaround for Leap 15.x %if 0%{?suse_version} < 1550 %patch6 -p1 diff --git a/qpaeq-shebang.patch b/qpaeq-shebang.patch index 4bae0bb..a554f96 100644 --- a/qpaeq-shebang.patch +++ b/qpaeq-shebang.patch @@ -1,7 +1,11 @@ ---- src/utils/qpaeq.org 2018-05-15 14:12:16.038877587 +0200 -+++ src/utils/qpaeq 2018-05-15 14:12:49.002967454 +0200 +--- + src/utils/qpaeq | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/src/utils/qpaeq ++++ b/src/utils/qpaeq @@ -1,4 +1,4 @@ --#!/usr/bin/env python +-#!/usr/bin/env python3 +#!/usr/bin/python3 # qpaeq is a equalizer interface for pulseaudio's equalizer sinks # Copyright (C) 2009 Jason Newton local = pa_socket_address_is_local(sa); if ((c->fd = pa_socket_cloexec(sa->sa_family, SOCK_STREAM, 0)) < 0) { From 43f2bf6d376a5bc143da483bea207310b894e40dece71d4d1db891b1e936dce4 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 26 Nov 2020 07:32:57 +0000 Subject: [PATCH 2/3] Accepting request 850818 from home:tiwai:branches:multimedia:libs Removed stale patches OBS-URL: https://build.opensuse.org/request/show/850818 OBS-URL: https://build.opensuse.org/package/show/multimedia:libs/pulseaudio?expand=0&rev=223 --- ...test-Hide-unused-functions-when-buil.patch | 48 - ...r-recognize-the-Speaker-Jack-control.patch | 30 - ...upport-for-SteelSeries-Arctis-Pro-20.patch | 104 --- ...upport-for-SteelSeries-Arctis-5-2019.patch | 29 - ...upport-for-LucidSound-LS31-and-creat.patch | 199 ----- ...2-name-for-the-direct-card-index-ope.patch | 61 -- ...-alsa-ucm-add-mixer-IDs-to-ucm_items.patch | 72 -- ...e-the-index-for-ALSA-mixer-element-i.patch | 820 ------------------ ...ixer-improve-alsa_id_decode-function.patch | 51 -- ...a-ucm-Support-Playback-CaptureVolume.patch | 795 ----------------- ...m-Fix-volume-control-based-on-review.patch | 242 ------ ...e-correct-mixer-identifiers-as-first.patch | 120 --- ...sa-ucm-add-support-for-master-volume.patch | 330 ------- ...it-correctly-JackHWMute-device-names.patch | 59 -- ...alsa-ucm-fix-parsing-for-JackControl.patch | 40 - ...ucm-add-comments-to-ucm_get_mixer_id.patch | 45 - ...lidate-access-to-PA_DEVICE_PORT_DATA.patch | 81 -- ...e-PCM-if-hardware-doesn-t-support-it.patch | 65 -- ...cm-parse-correctly-the-device-values.patch | 125 --- ...try-to-use-UCM-device-name-as-jack-n.patch | 44 - ...-try-to-guess-the-mixer-name-from-th.patch | 84 -- ...m-add-control-and-mixer-device-items.patch | 99 --- ...the-mixer-names-from-ucm-don-t-guess.patch | 244 ------ ...-proper-mixer-name-for-ucm-pcm-sink-.patch | 93 -- ...e-interface-type-CARD-PCM-for-mixer-.patch | 125 --- ...he-ability-to-pass-the-intended-role.patch | 51 -- ...he-intended-role-of-Steelseries-Arct.patch | 39 - ...er-open-close-cache-mixer-accesses-i.patch | 761 ---------------- 0029-alsa-ucm-add-support-for-HDMI-ELD.patch | 264 ------ ...e-quick-card-number-lookup-to-save-m.patch | 83 -- ...ve-check-for-the-empty-path-set-for-.patch | 134 --- ...o-set-profile-priority-from-UCM-valu.patch | 128 --- ...at-mixer-elements-can-be-identified-.patch | 80 -- ...ect-the-channel-default-logic-stereo.patch | 45 - ...assign-JackHWMute-when-JackControl-i.patch | 31 - ...t-log-errors-during-normal-operation.patch | 45 - ...-handle-unavailbale-HW-volume-in-UCM.patch | 41 - ...-alsa-ucm-use-the-right-profile-name.patch | 27 - ...e-port-ucm-device-activation-on-boot.patch | 83 -- ...-source-fix-the-mixer-initialization.patch | 61 -- 40 files changed, 5878 deletions(-) delete mode 100644 0001-alsa-mixer-path-test-Hide-unused-functions-when-buil.patch delete mode 100644 0002-alsa-mixer-recognize-the-Speaker-Jack-control.patch delete mode 100644 0003-alsa-mixer-add-support-for-SteelSeries-Arctis-Pro-20.patch delete mode 100644 0004-alsa-mixer-Add-support-for-SteelSeries-Arctis-5-2019.patch delete mode 100644 0005-alsa-mixer-add-support-for-LucidSound-LS31-and-creat.patch delete mode 100644 0006-alsa-ucm-use-ucm2-name-for-the-direct-card-index-ope.patch delete mode 100644 0007-alsa-ucm-add-mixer-IDs-to-ucm_items.patch delete mode 100644 0008-alsa-mixer-handle-the-index-for-ALSA-mixer-element-i.patch delete mode 100644 0009-alsa-mixer-improve-alsa_id_decode-function.patch delete mode 100644 0010-alsa-ucm-Support-Playback-CaptureVolume.patch delete mode 100644 0011-alsa-ucm-Fix-volume-control-based-on-review.patch delete mode 100644 0012-alsa-ucm-use-the-correct-mixer-identifiers-as-first.patch delete mode 100644 0013-alsa-ucm-add-support-for-master-volume.patch delete mode 100644 0014-alsa-ucm-split-correctly-JackHWMute-device-names.patch delete mode 100644 0015-alsa-ucm-fix-parsing-for-JackControl.patch delete mode 100644 0016-alsa-ucm-add-comments-to-ucm_get_mixer_id.patch delete mode 100644 0017-alsa-ucm-validate-access-to-PA_DEVICE_PORT_DATA.patch delete mode 100644 0018-alsa-Skip-resume-PCM-if-hardware-doesn-t-support-it.patch delete mode 100644 0019-alsa-ucm-parse-correctly-the-device-values.patch delete mode 100644 0020-alsa-ucm-do-not-try-to-use-UCM-device-name-as-jack-n.patch delete mode 100644 0021-alsa-util-do-not-try-to-guess-the-mixer-name-from-th.patch delete mode 100644 0022-alsa-ucm-add-control-and-mixer-device-items.patch delete mode 100644 0023-alsa-ucm-get-the-mixer-names-from-ucm-don-t-guess.patch delete mode 100644 0024-alsa-ucm-use-the-proper-mixer-name-for-ucm-pcm-sink-.patch delete mode 100644 0025-alsa-mixer-handle-interface-type-CARD-PCM-for-mixer-.patch delete mode 100644 0026-alsa-mixer-Add-the-ability-to-pass-the-intended-role.patch delete mode 100644 0027-alsa-mixer-Set-the-intended-role-of-Steelseries-Arct.patch delete mode 100644 0028-alsa-rewrite-mixer-open-close-cache-mixer-accesses-i.patch delete mode 100644 0029-alsa-ucm-add-support-for-HDMI-ELD.patch delete mode 100644 0030-alsa-mixer-do-the-quick-card-number-lookup-to-save-m.patch delete mode 100644 0031-alsa-mixer-improve-check-for-the-empty-path-set-for-.patch delete mode 100644 0032-alsa-ucm-allow-to-set-profile-priority-from-UCM-valu.patch delete mode 100644 0033-alsa-Document-that-mixer-elements-can-be-identified-.patch delete mode 100644 0034-alsa-ucm-correct-the-channel-default-logic-stereo.patch delete mode 100644 0035-alsa-ucm-do-not-assign-JackHWMute-when-JackControl-i.patch delete mode 100644 0036-ucm-Don-t-log-errors-during-normal-operation.patch delete mode 100644 0037-alsa-handle-unavailbale-HW-volume-in-UCM.patch delete mode 100644 0038-alsa-ucm-use-the-right-profile-name.patch delete mode 100644 0039-ucm-fix-the-port-ucm-device-activation-on-boot.patch delete mode 100644 0040-alsa-sink-source-fix-the-mixer-initialization.patch diff --git a/0001-alsa-mixer-path-test-Hide-unused-functions-when-buil.patch b/0001-alsa-mixer-path-test-Hide-unused-functions-when-buil.patch deleted file mode 100644 index 64af2fc..0000000 --- a/0001-alsa-mixer-path-test-Hide-unused-functions-when-buil.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 3dff31e19ca627fc4e0a8f13aeb44923118ecfa1 Mon Sep 17 00:00:00 2001 -From: Tanu Kaskinen -Date: Fri, 20 Sep 2019 17:09:40 +0300 -Subject: [PATCH] alsa-mixer-path-test: Hide unused functions when building - with Meson -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Silences these warnings: - -[509/574] Compiling C object 'src/tests/a4ccf2d@@alsa-mixer-path-test@exe/alsa-mixer-path-test.c.o'. -../src/tests/alsa-mixer-path-test.c:24:20: warning: ‘load_makefile’ defined but not used [-Wunused-function] - static pa_strlist *load_makefile() { - ^~~~~~~~~~~~~ -../src/tests/alsa-mixer-path-test.c:17:20: warning: ‘get_default_paths_dir’ defined but not used [-Wunused-function] - static const char *get_default_paths_dir(void) { - ^~~~~~~~~~~~~~~~~~~~~ ---- - src/tests/alsa-mixer-path-test.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/src/tests/alsa-mixer-path-test.c b/src/tests/alsa-mixer-path-test.c -index ee40587b7b13..75cf086138cc 100644 ---- a/src/tests/alsa-mixer-path-test.c -+++ b/src/tests/alsa-mixer-path-test.c -@@ -13,6 +13,10 @@ - #include - #include - -+/* This test inspects the Makefile, so this is not applicable when using -+ * Meson. */ -+#ifndef MESON_BUILD -+ - /* This function was copied from alsa-mixer.c */ - static const char *get_default_paths_dir(void) { - if (pa_run_from_build_tree()) -@@ -52,6 +56,7 @@ static pa_strlist *load_makefile() { - fclose(f); - return result; - } -+#endif /* end of #ifndef MESON_BUILD */ - - START_TEST (mixer_path_test) { - #ifdef MESON_BUILD --- -2.16.4 - diff --git a/0002-alsa-mixer-recognize-the-Speaker-Jack-control.patch b/0002-alsa-mixer-recognize-the-Speaker-Jack-control.patch deleted file mode 100644 index fb9f363..0000000 --- a/0002-alsa-mixer-recognize-the-Speaker-Jack-control.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 248a77c7fd2f9682c58d3d3dd6f3c2ba3ad2c111 Mon Sep 17 00:00:00 2001 -From: Tanu Kaskinen -Date: Sat, 2 Sep 2017 15:35:01 +0300 -Subject: [PATCH] alsa-mixer: recognize the "Speaker Jack" control - -This control has been seen in the wild: -https://lists.freedesktop.org/archives/pulseaudio-discuss/2017-August/028595.html -(The pastebin link in that mail might not work anymore, but the paste -just shows that there's a Speaker Jack control). ---- - src/modules/alsa/mixer/paths/analog-output-speaker.conf | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/src/modules/alsa/mixer/paths/analog-output-speaker.conf b/src/modules/alsa/mixer/paths/analog-output-speaker.conf -index 9f4dac414134..6f9968e1f537 100644 ---- a/src/modules/alsa/mixer/paths/analog-output-speaker.conf -+++ b/src/modules/alsa/mixer/paths/analog-output-speaker.conf -@@ -56,6 +56,9 @@ state.unplugged = unknown - state.plugged = no - state.unplugged = unknown - -+[Jack Speaker] -+required-any = any -+ - [Jack Speaker Phantom] - required-any = any - state.plugged = unknown --- -2.16.4 - diff --git a/0003-alsa-mixer-add-support-for-SteelSeries-Arctis-Pro-20.patch b/0003-alsa-mixer-add-support-for-SteelSeries-Arctis-Pro-20.patch deleted file mode 100644 index 260472e..0000000 --- a/0003-alsa-mixer-add-support-for-SteelSeries-Arctis-Pro-20.patch +++ /dev/null @@ -1,104 +0,0 @@ -From 7259e8c22fb97b1ae80ac4909713e51b293afc4a Mon Sep 17 00:00:00 2001 -From: Josh -Date: Sat, 25 May 2019 02:35:01 -0700 -Subject: [PATCH] alsa-mixer: add support for SteelSeries Arctis Pro 2019 - headset - -Signed-off-by: Dave Chiluk ---- - src/Makefile.am | 6 +++--- - src/modules/alsa/90-pulseaudio.rules | 10 +++++++--- - ...ut-chat.conf => steelseries-arctis-output-chat-common.conf} | 0 - ...ut-game.conf => steelseries-arctis-output-game-common.conf} | 0 - ...usb-audio.conf => steelseries-arctis-common-usb-audio.conf} | 4 ++-- - 5 files changed, 12 insertions(+), 8 deletions(-) - rename src/modules/alsa/mixer/paths/{steelseries-arctis-5-output-chat.conf => steelseries-arctis-output-chat-common.conf} (100%) - rename src/modules/alsa/mixer/paths/{steelseries-arctis-5-output-game.conf => steelseries-arctis-output-game-common.conf} (100%) - rename src/modules/alsa/mixer/profile-sets/{steelseries-arctis-5-usb-audio.conf => steelseries-arctis-common-usb-audio.conf} (80%) - -diff --git a/src/Makefile.am b/src/Makefile.am -index e3baf587a8a3..3db921a07e1b 100644 ---- a/src/Makefile.am -+++ b/src/Makefile.am -@@ -1353,7 +1353,7 @@ dist_alsaprofilesets_DATA = \ - modules/alsa/mixer/profile-sets/native-instruments-korecontroller.conf \ - modules/alsa/mixer/profile-sets/kinect-audio.conf \ - modules/alsa/mixer/profile-sets/sb-omni-surround-5.1.conf \ -- modules/alsa/mixer/profile-sets/steelseries-arctis-5-usb-audio.conf \ -+ modules/alsa/mixer/profile-sets/steelseries-arctis-common-usb-audio.conf \ - modules/alsa/mixer/profile-sets/steelseries-arctis-7-usb-audio.conf \ - modules/alsa/mixer/profile-sets/dell-dock-tb16-usb-audio.conf \ - modules/alsa/mixer/profile-sets/cmedia-high-speed-true-hdaudio.conf -@@ -1399,8 +1399,8 @@ dist_alsapaths_DATA = \ - modules/alsa/mixer/paths/hdmi-output-5.conf \ - modules/alsa/mixer/paths/hdmi-output-6.conf \ - modules/alsa/mixer/paths/hdmi-output-7.conf \ -- modules/alsa/mixer/paths/steelseries-arctis-5-output-chat.conf \ -- modules/alsa/mixer/paths/steelseries-arctis-5-output-game.conf \ -+ modules/alsa/mixer/paths/steelseries-arctis-output-chat-common.conf \ -+ modules/alsa/mixer/paths/steelseries-arctis-output-game-common.conf \ - modules/alsa/mixer/paths/steelseries-arctis-7-input.conf \ - modules/alsa/mixer/paths/steelseries-arctis-7-output-mono.conf \ - modules/alsa/mixer/paths/steelseries-arctis-7-output-stereo.conf -diff --git a/src/modules/alsa/90-pulseaudio.rules b/src/modules/alsa/90-pulseaudio.rules -index d85763917d76..9d34e6dfdd38 100644 ---- a/src/modules/alsa/90-pulseaudio.rules -+++ b/src/modules/alsa/90-pulseaudio.rules -@@ -109,16 +109,20 @@ ATTRS{idVendor}=="0763", ATTRS{idProduct}=="2012", ENV{PULSE_PROFILE_SET}="maudi - ATTRS{idVendor}=="045e", ATTRS{idProduct}=="02bb", ENV{PULSE_PROFILE_SET}="kinect-audio.conf" - ATTRS{idVendor}=="041e", ATTRS{idProduct}=="322c", ENV{PULSE_PROFILE_SET}="sb-omni-surround-5.1.conf" - ATTRS{idVendor}=="0bda", ATTRS{idProduct}=="4014", ENV{PULSE_PROFILE_SET}="dell-dock-tb16-usb-audio.conf" --ATTRS{idVendor}=="1038", ATTRS{idProduct}=="1250", ENV{PULSE_PROFILE_SET}="steelseries-arctis-5-usb-audio.conf" -+ - - # ID 1038:12ad is for the 2018 refresh of the Arctis 7. --# ID 1038:1294 is for Arctis Pro Wireless (which works with the Arctis 7 --# configuration). -+# ID 1038:1294 is for Arctis Pro Wireless (which works with the Arctis 7 configuration). - ATTRS{idVendor}=="1038", ATTRS{idProduct}=="1260", ENV{PULSE_PROFILE_SET}="steelseries-arctis-7-usb-audio.conf" - ATTRS{idVendor}=="1038", ATTRS{idProduct}=="12ad", ENV{PULSE_PROFILE_SET}="steelseries-arctis-7-usb-audio.conf" - ATTRS{idVendor}=="1038", ATTRS{idProduct}=="1294", ENV{PULSE_PROFILE_SET}="steelseries-arctis-7-usb-audio.conf" - ATTRS{idVendor}=="1038", ATTRS{idProduct}=="1730", ENV{PULSE_PROFILE_SET}="steelseries-arctis-7-usb-audio.conf" - -+# ID 1038:1250 is for the Arctis 5 -+# ID 1038:1252 is for Arctis Pro 2019 edition -+ATTRS{idVendor}=="1038", ATTRS{idProduct}=="1250", ENV{PULSE_PROFILE_SET}="steelseries-arctis-common-usb-audio.conf" -+ATTRS{idVendor}=="1038", ATTRS{idProduct}=="1252", ENV{PULSE_PROFILE_SET}="steelseries-arctis-common-usb-audio.conf" -+ - ATTRS{idVendor}=="147a", ATTRS{idProduct}=="e055", ENV{PULSE_PROFILE_SET}="cmedia-high-speed-true-hdaudio.conf" - - GOTO="pulseaudio_end" -diff --git a/src/modules/alsa/mixer/paths/steelseries-arctis-5-output-chat.conf b/src/modules/alsa/mixer/paths/steelseries-arctis-output-chat-common.conf -similarity index 100% -rename from src/modules/alsa/mixer/paths/steelseries-arctis-5-output-chat.conf -rename to src/modules/alsa/mixer/paths/steelseries-arctis-output-chat-common.conf -diff --git a/src/modules/alsa/mixer/paths/steelseries-arctis-5-output-game.conf b/src/modules/alsa/mixer/paths/steelseries-arctis-output-game-common.conf -similarity index 100% -rename from src/modules/alsa/mixer/paths/steelseries-arctis-5-output-game.conf -rename to src/modules/alsa/mixer/paths/steelseries-arctis-output-game-common.conf -diff --git a/src/modules/alsa/mixer/profile-sets/steelseries-arctis-5-usb-audio.conf b/src/modules/alsa/mixer/profile-sets/steelseries-arctis-common-usb-audio.conf -similarity index 80% -rename from src/modules/alsa/mixer/profile-sets/steelseries-arctis-5-usb-audio.conf -rename to src/modules/alsa/mixer/profile-sets/steelseries-arctis-common-usb-audio.conf -index fe353c38f09c..80c33707aea4 100644 ---- a/src/modules/alsa/mixer/profile-sets/steelseries-arctis-5-usb-audio.conf -+++ b/src/modules/alsa/mixer/profile-sets/steelseries-arctis-common-usb-audio.conf -@@ -6,13 +6,13 @@ description = Chat - device-strings = hw:%f,0,0 - channel-map = left,right - paths-input = analog-input-mic --paths-output = steelseries-arctis-5-output-chat -+paths-output = steelseries-arctis-output-chat-common - - [Mapping analog-game] - description = Game - device-strings = hw:%f,1,0 - channel-map = left,right --paths-output = steelseries-arctis-5-output-game -+paths-output = steelseries-arctis-output-game-common - direction = output - - [Profile output:analog-chat+output:analog-game+input:analog-chat] --- -2.16.4 - diff --git a/0004-alsa-mixer-Add-support-for-SteelSeries-Arctis-5-2019.patch b/0004-alsa-mixer-Add-support-for-SteelSeries-Arctis-5-2019.patch deleted file mode 100644 index dd9ac0a..0000000 --- a/0004-alsa-mixer-Add-support-for-SteelSeries-Arctis-5-2019.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 79d3b99ba4773651c4ebc082233f9d0b5f68bfad Mon Sep 17 00:00:00 2001 -From: Krzysztof Stasiowski -Date: Tue, 18 Jun 2019 11:50:35 +0000 -Subject: [PATCH] alsa-mixer: Add support for SteelSeries Arctis 5 2019 headset - -Signed-off-by: Dave Chiluk ---- - src/modules/alsa/90-pulseaudio.rules | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/src/modules/alsa/90-pulseaudio.rules b/src/modules/alsa/90-pulseaudio.rules -index 9d34e6dfdd38..61e7692543e8 100644 ---- a/src/modules/alsa/90-pulseaudio.rules -+++ b/src/modules/alsa/90-pulseaudio.rules -@@ -119,8 +119,10 @@ ATTRS{idVendor}=="1038", ATTRS{idProduct}=="1294", ENV{PULSE_PROFILE_SET}="steel - ATTRS{idVendor}=="1038", ATTRS{idProduct}=="1730", ENV{PULSE_PROFILE_SET}="steelseries-arctis-7-usb-audio.conf" - - # ID 1038:1250 is for the Arctis 5 --# ID 1038:1252 is for Arctis Pro 2019 edition -+# ID 1037:12aa is for the Arctis 5 2019 -+# ID 1038:1252 is for the Arctis Pro 2019 edition - ATTRS{idVendor}=="1038", ATTRS{idProduct}=="1250", ENV{PULSE_PROFILE_SET}="steelseries-arctis-common-usb-audio.conf" -+ATTRS{idVendor}=="1038", ATTRS{idProduct}=="12aa", ENV{PULSE_PROFILE_SET}="steelseries-arctis-common-usb-audio.conf" - ATTRS{idVendor}=="1038", ATTRS{idProduct}=="1252", ENV{PULSE_PROFILE_SET}="steelseries-arctis-common-usb-audio.conf" - - ATTRS{idVendor}=="147a", ATTRS{idProduct}=="e055", ENV{PULSE_PROFILE_SET}="cmedia-high-speed-true-hdaudio.conf" --- -2.16.4 - diff --git a/0005-alsa-mixer-add-support-for-LucidSound-LS31-and-creat.patch b/0005-alsa-mixer-add-support-for-LucidSound-LS31-and-creat.patch deleted file mode 100644 index 4953533..0000000 --- a/0005-alsa-mixer-add-support-for-LucidSound-LS31-and-creat.patch +++ /dev/null @@ -1,199 +0,0 @@ -From 1ee1f749e154d2f64b4661f833eebaa18ae1a081 Mon Sep 17 00:00:00 2001 -From: Dave Chiluk -Date: Thu, 8 Aug 2019 23:10:01 -0500 -Subject: [PATCH] alsa-mixer: add support for LucidSound LS31, and create - usb-gaming-headset profile - ---- - src/Makefile.am | 8 ++++---- - src/modules/alsa/90-pulseaudio.rules | 10 ++++++---- - ...tis-7-input.conf => usb-gaming-headset-input.conf} | 12 ++++++++++-- - ...-mono.conf => usb-gaming-headset-output-mono.conf} | 15 ++++++++++----- - ...reo.conf => usb-gaming-headset-output-stereo.conf} | 15 ++++++++++----- - ...rctis-7-usb-audio.conf => usb-gaming-headset.conf} | 19 ++++++++++++------- - 6 files changed, 52 insertions(+), 27 deletions(-) - rename src/modules/alsa/mixer/paths/{steelseries-arctis-7-input.conf => usb-gaming-headset-input.conf} (66%) - rename src/modules/alsa/mixer/paths/{steelseries-arctis-7-output-mono.conf => usb-gaming-headset-output-mono.conf} (66%) - rename src/modules/alsa/mixer/paths/{steelseries-arctis-7-output-stereo.conf => usb-gaming-headset-output-stereo.conf} (68%) - rename src/modules/alsa/mixer/profile-sets/{steelseries-arctis-7-usb-audio.conf => usb-gaming-headset.conf} (79%) - -diff --git a/src/Makefile.am b/src/Makefile.am -index 3db921a07e1b..0f1ded7f96c5 100644 ---- a/src/Makefile.am -+++ b/src/Makefile.am -@@ -1354,7 +1354,7 @@ dist_alsaprofilesets_DATA = \ - modules/alsa/mixer/profile-sets/kinect-audio.conf \ - modules/alsa/mixer/profile-sets/sb-omni-surround-5.1.conf \ - modules/alsa/mixer/profile-sets/steelseries-arctis-common-usb-audio.conf \ -- modules/alsa/mixer/profile-sets/steelseries-arctis-7-usb-audio.conf \ -+ modules/alsa/mixer/profile-sets/usb-gaming-headset.conf \ - modules/alsa/mixer/profile-sets/dell-dock-tb16-usb-audio.conf \ - modules/alsa/mixer/profile-sets/cmedia-high-speed-true-hdaudio.conf - -@@ -1401,9 +1401,9 @@ dist_alsapaths_DATA = \ - modules/alsa/mixer/paths/hdmi-output-7.conf \ - modules/alsa/mixer/paths/steelseries-arctis-output-chat-common.conf \ - modules/alsa/mixer/paths/steelseries-arctis-output-game-common.conf \ -- modules/alsa/mixer/paths/steelseries-arctis-7-input.conf \ -- modules/alsa/mixer/paths/steelseries-arctis-7-output-mono.conf \ -- modules/alsa/mixer/paths/steelseries-arctis-7-output-stereo.conf -+ modules/alsa/mixer/paths/usb-gaming-headset-input.conf \ -+ modules/alsa/mixer/paths/usb-gaming-headset-output-mono.conf \ -+ modules/alsa/mixer/paths/usb-gaming-headset-output-stereo.conf - - endif - -diff --git a/src/modules/alsa/90-pulseaudio.rules b/src/modules/alsa/90-pulseaudio.rules -index 61e7692543e8..fa43cb802a8e 100644 ---- a/src/modules/alsa/90-pulseaudio.rules -+++ b/src/modules/alsa/90-pulseaudio.rules -@@ -113,10 +113,12 @@ ATTRS{idVendor}=="0bda", ATTRS{idProduct}=="4014", ENV{PULSE_PROFILE_SET}="dell- - - # ID 1038:12ad is for the 2018 refresh of the Arctis 7. - # ID 1038:1294 is for Arctis Pro Wireless (which works with the Arctis 7 configuration). --ATTRS{idVendor}=="1038", ATTRS{idProduct}=="1260", ENV{PULSE_PROFILE_SET}="steelseries-arctis-7-usb-audio.conf" --ATTRS{idVendor}=="1038", ATTRS{idProduct}=="12ad", ENV{PULSE_PROFILE_SET}="steelseries-arctis-7-usb-audio.conf" --ATTRS{idVendor}=="1038", ATTRS{idProduct}=="1294", ENV{PULSE_PROFILE_SET}="steelseries-arctis-7-usb-audio.conf" --ATTRS{idVendor}=="1038", ATTRS{idProduct}=="1730", ENV{PULSE_PROFILE_SET}="steelseries-arctis-7-usb-audio.conf" -+ATTRS{idVendor}=="1038", ATTRS{idProduct}=="1260", ENV{PULSE_PROFILE_SET}="usb-gaming-headset.conf" -+ATTRS{idVendor}=="1038", ATTRS{idProduct}=="12ad", ENV{PULSE_PROFILE_SET}="usb-gaming-headset.conf" -+ATTRS{idVendor}=="1038", ATTRS{idProduct}=="1294", ENV{PULSE_PROFILE_SET}="usb-gaming-headset.conf" -+ATTRS{idVendor}=="1038", ATTRS{idProduct}=="1730", ENV{PULSE_PROFILE_SET}="usb-gaming-headset.conf" -+# Lucidsound LS31 -+ATTRS{idVendor}=="2f12", ATTRS{idProduct}=="0109", ENV{PULSE_PROFILE_SET}="usb-gaming-headset.conf" - - # ID 1038:1250 is for the Arctis 5 - # ID 1037:12aa is for the Arctis 5 2019 -diff --git a/src/modules/alsa/mixer/paths/steelseries-arctis-7-input.conf b/src/modules/alsa/mixer/paths/usb-gaming-headset-input.conf -similarity index 66% -rename from src/modules/alsa/mixer/paths/steelseries-arctis-7-input.conf -rename to src/modules/alsa/mixer/paths/usb-gaming-headset-input.conf -index 3fa36e9385a5..9fa7fe908587 100644 ---- a/src/modules/alsa/mixer/paths/steelseries-arctis-7-input.conf -+++ b/src/modules/alsa/mixer/paths/usb-gaming-headset-input.conf -@@ -13,8 +13,16 @@ - # You should have received a copy of the GNU Lesser General Public License - # along with PulseAudio; if not, see . - --; Steelseries Arctis 7 USB headset microphone path. Works also with Arctis Pro --; Wireless. -+; USB gaming headset microphone input path. These headsets usually have two -+; output devices. The first one is mono, meant for voice audio, and the second -+; one is stereo, meant for everything else. The purpose of this unusual design -+; is to provide separate volume controls for voice and other audio, which can -+; be useful in gaming. -+; -+; Works with: -+; Steelseries Arctis 7 -+; Steelseries Arctis Pro Wireless. -+; Lucidsound LS31 - - [General] - description-key = analog-input-microphone-headset -diff --git a/src/modules/alsa/mixer/paths/steelseries-arctis-7-output-mono.conf b/src/modules/alsa/mixer/paths/usb-gaming-headset-output-mono.conf -similarity index 66% -rename from src/modules/alsa/mixer/paths/steelseries-arctis-7-output-mono.conf -rename to src/modules/alsa/mixer/paths/usb-gaming-headset-output-mono.conf -index d8b24a2fbdf2..6df662f069e5 100644 ---- a/src/modules/alsa/mixer/paths/steelseries-arctis-7-output-mono.conf -+++ b/src/modules/alsa/mixer/paths/usb-gaming-headset-output-mono.conf -@@ -13,11 +13,16 @@ - # You should have received a copy of the GNU Lesser General Public License - # along with PulseAudio; if not, see . - --; Steelseries Arctis 7 USB headset mono output path. Works also with Arctis Pro --; Wireless. The headset has two output devices. The first one is mono, meant --; for voice audio, and the second one is stereo, meant for everything else. The --; purpose of this unusual design is to provide separate volume controls for --; voice and other audio, which can be useful in gaming. -+; USB gaming headset mono output path. These headsets usually have two -+; output devices. The first one is mono, meant for voice audio, and the second -+; one is stereo, meant for everything else. The purpose of this unusual design -+; is to provide separate volume controls for voice and other audio, which can -+; be useful in gaming. -+; -+; Works with: -+; Steelseries Arctis 7 -+; Steelseries Arctis Pro Wireless. -+; Lucidsound LS31 - - [General] - description-key = analog-output-headphones-mono -diff --git a/src/modules/alsa/mixer/paths/steelseries-arctis-7-output-stereo.conf b/src/modules/alsa/mixer/paths/usb-gaming-headset-output-stereo.conf -similarity index 68% -rename from src/modules/alsa/mixer/paths/steelseries-arctis-7-output-stereo.conf -rename to src/modules/alsa/mixer/paths/usb-gaming-headset-output-stereo.conf -index fcc58a033e2f..e3f91cd6cd2e 100644 ---- a/src/modules/alsa/mixer/paths/steelseries-arctis-7-output-stereo.conf -+++ b/src/modules/alsa/mixer/paths/usb-gaming-headset-output-stereo.conf -@@ -13,11 +13,16 @@ - # You should have received a copy of the GNU Lesser General Public License - # along with PulseAudio; if not, see . - --; Steelseries Arctis 7 USB headset stereo output path. Works also with Arctis --; Pro Wireless. The headset has two output devices. The first one is mono, --; meant for voice audio, and the second one is stereo, meant for everything --; else. The purpose of this unusual design is to provide separate volume --; controls for voice and other audio, which can be useful in gaming. -+; USB gaming headset mono output path. These headsets usually have two -+; output devices. The first one is mono, meant for voice audio, and the second -+; one is stereo, meant for everything else. The purpose of this unusual design -+; is to provide separate volume controls for voice and other audio, which can -+; be useful in gaming. -+; -+; Works with: -+; Steelseries Arctis 7 -+; Steelseries Arctis Pro Wireless. -+; Lucidsound LS31 - ; - ; This path doesn't provide hardware volume control, because the stereo - ; output is controlled by the PCM element with index 1, and currently -diff --git a/src/modules/alsa/mixer/profile-sets/steelseries-arctis-7-usb-audio.conf b/src/modules/alsa/mixer/profile-sets/usb-gaming-headset.conf -similarity index 79% -rename from src/modules/alsa/mixer/profile-sets/steelseries-arctis-7-usb-audio.conf -rename to src/modules/alsa/mixer/profile-sets/usb-gaming-headset.conf -index e1394dcfcc3b..01ecf864bcf2 100644 ---- a/src/modules/alsa/mixer/profile-sets/steelseries-arctis-7-usb-audio.conf -+++ b/src/modules/alsa/mixer/profile-sets/usb-gaming-headset.conf -@@ -13,12 +13,17 @@ - # You should have received a copy of the GNU Lesser General Public License - # along with PulseAudio; if not, see . - --; Steelseries Arctis 7 USB and Arctis Pro Wireless USB headset. These headsets --; have a microphone and two output devices. The first output device is mono, --; meant for voice audio, and the second one is stereo, meant for everything --; else. The purpose of this unusual design is to provide separate volume -+; USB gaming headset. -+; These headsets usually have two output devices. The first one is mono, -+; meant for voice audio, and the second one is stereo, meant for everything -+; else. The purpose of this unusual design is to provide separate volume - ; controls for voice and other audio, which can be useful in gaming. - ; -+; Works with: -+; Steelseries Arctis 7 -+; Steelseries Arctis Pro Wireless. -+; Lucidsound LS31 -+; - ; See default.conf for an explanation on the directives used here. - - [General] -@@ -27,13 +32,13 @@ auto-profiles = yes - [Mapping analog-mono] - device-strings = hw:%f,0,0 - channel-map = mono --paths-output = steelseries-arctis-7-output-mono --paths-input = steelseries-arctis-7-input -+paths-output = usb-gaming-headset-output-mono -+paths-input = usb-gaming-headset-input - - [Mapping analog-stereo] - device-strings = hw:%f,1,0 - channel-map = left,right --paths-output = steelseries-arctis-7-output-stereo -+paths-output = usb-gaming-headset-output-stereo - direction = output - - [Profile output:analog-mono+output:analog-stereo+input:analog-mono] --- -2.16.4 - diff --git a/0006-alsa-ucm-use-ucm2-name-for-the-direct-card-index-ope.patch b/0006-alsa-ucm-use-ucm2-name-for-the-direct-card-index-ope.patch deleted file mode 100644 index 63e6cc4..0000000 --- a/0006-alsa-ucm-use-ucm2-name-for-the-direct-card-index-ope.patch +++ /dev/null @@ -1,61 +0,0 @@ -From c8f065250dde966825f171ff817f7301f423a42e Mon Sep 17 00:00:00 2001 -From: Jaroslav Kysela -Date: Sat, 23 Nov 2019 15:17:30 +0100 -Subject: [PATCH] alsa-ucm: use ucm2 name for the direct card index open - -Signed-off-by: Jaroslav Kysela ---- - src/modules/alsa/alsa-ucm.c | 28 ++++++++++++++++++---------- - 1 file changed, 18 insertions(+), 10 deletions(-) - -diff --git a/src/modules/alsa/alsa-ucm.c b/src/modules/alsa/alsa-ucm.c -index 0a40ca8fe654..aeb4e59e323c 100644 ---- a/src/modules/alsa/alsa-ucm.c -+++ b/src/modules/alsa/alsa-ucm.c -@@ -576,17 +576,25 @@ int pa_alsa_ucm_query_profiles(pa_alsa_ucm_config *ucm, int card_index) { - const char **verb_list; - int num_verbs, i, err = 0; - -- /* is UCM available for this card ? */ -- err = snd_card_get_name(card_index, &card_name); -- if (err < 0) { -- pa_log("Card can't get card_name from card_index %d", card_index); -- goto name_fail; -- } -- -+ /* support multiple card instances, address card directly by index */ -+ card_name = pa_sprintf_malloc("hw:%i", card_index); -+ if (card_name == NULL) -+ return -ENOMEM; - err = snd_use_case_mgr_open(&ucm->ucm_mgr, card_name); - if (err < 0) { -- pa_log_info("UCM not available for card %s", card_name); -- goto ucm_mgr_fail; -+ /* fallback longname: is UCM available for this card ? */ -+ pa_xfree(card_name); -+ err = snd_card_get_name(card_index, &card_name); -+ if (err < 0) { -+ pa_log("Card can't get card_name from card_index %d", card_index); -+ goto name_fail; -+ } -+ -+ err = snd_use_case_mgr_open(&ucm->ucm_mgr, card_name); -+ if (err < 0) { -+ pa_log_info("UCM not available for card %s", card_name); -+ goto ucm_mgr_fail; -+ } - } - - pa_log_info("UCM available for card %s", card_name); -@@ -626,7 +634,7 @@ ucm_verb_fail: - } - - ucm_mgr_fail: -- free(card_name); -+ pa_xfree(card_name); - - name_fail: - return err; --- -2.16.4 - diff --git a/0007-alsa-ucm-add-mixer-IDs-to-ucm_items.patch b/0007-alsa-ucm-add-mixer-IDs-to-ucm_items.patch deleted file mode 100644 index 8a0005f..0000000 --- a/0007-alsa-ucm-add-mixer-IDs-to-ucm_items.patch +++ /dev/null @@ -1,72 +0,0 @@ -From ab5be56a10a83bfdfd7f40c02245db039e6eb730 Mon Sep 17 00:00:00 2001 -From: Jaroslav Kysela -Date: Sat, 23 Nov 2019 15:50:29 +0100 -Subject: [PATCH] alsa-ucm: add mixer IDs to ucm_items - -Signed-off-by: Jaroslav Kysela ---- - src/modules/alsa/alsa-ucm.c | 6 ++++++ - src/modules/alsa/alsa-ucm.h | 18 ++++++++++++++++++ - 2 files changed, 24 insertions(+) - -diff --git a/src/modules/alsa/alsa-ucm.c b/src/modules/alsa/alsa-ucm.c -index aeb4e59e323c..14056825a25f 100644 ---- a/src/modules/alsa/alsa-ucm.c -+++ b/src/modules/alsa/alsa-ucm.c -@@ -100,11 +100,17 @@ static struct ucm_items item[] = { - {"CapturePCM", PA_ALSA_PROP_UCM_SOURCE}, - {"PlaybackVolume", PA_ALSA_PROP_UCM_PLAYBACK_VOLUME}, - {"PlaybackSwitch", PA_ALSA_PROP_UCM_PLAYBACK_SWITCH}, -+ {"PlaybackMixerElem", PA_ALSA_PROP_UCM_PLAYBACK_MIXER_ELEM}, -+ {"PlaybackMasterElem", PA_ALSA_PROP_UCM_PLAYBACK_MASTER_ELEM}, -+ {"PlaybackMasterType", PA_ALSA_PROP_UCM_PLAYBACK_MASTER_TYPE}, - {"PlaybackPriority", PA_ALSA_PROP_UCM_PLAYBACK_PRIORITY}, - {"PlaybackRate", PA_ALSA_PROP_UCM_PLAYBACK_RATE}, - {"PlaybackChannels", PA_ALSA_PROP_UCM_PLAYBACK_CHANNELS}, - {"CaptureVolume", PA_ALSA_PROP_UCM_CAPTURE_VOLUME}, - {"CaptureSwitch", PA_ALSA_PROP_UCM_CAPTURE_SWITCH}, -+ {"CaptureMixerElem", PA_ALSA_PROP_UCM_CAPTURE_MIXER_ELEM}, -+ {"CaptureMasterElem", PA_ALSA_PROP_UCM_CAPTURE_MASTER_ELEM}, -+ {"CaptureMasterType", PA_ALSA_PROP_UCM_CAPTURE_MASTER_TYPE}, - {"CapturePriority", PA_ALSA_PROP_UCM_CAPTURE_PRIORITY}, - {"CaptureRate", PA_ALSA_PROP_UCM_CAPTURE_RATE}, - {"CaptureChannels", PA_ALSA_PROP_UCM_CAPTURE_CHANNELS}, -diff --git a/src/modules/alsa/alsa-ucm.h b/src/modules/alsa/alsa-ucm.h -index c926f3cc39a6..4feb8c0bfc3f 100644 ---- a/src/modules/alsa/alsa-ucm.h -+++ b/src/modules/alsa/alsa-ucm.h -@@ -51,6 +51,15 @@ typedef void snd_use_case_mgr_t; - /** For devices: Playback switch e.g PlaybackSwitch */ - #define PA_ALSA_PROP_UCM_PLAYBACK_SWITCH "alsa.ucm.playback.switch" - -+/** For devices: Playback mixer identifier */ -+#define PA_ALSA_PROP_UCM_PLAYBACK_MIXER_ELEM "alsa.ucm.playback.mixer.element" -+ -+/** For devices: Playback mixer master identifier */ -+#define PA_ALSA_PROP_UCM_PLAYBACK_MASTER_ELEM "alsa.ucm.playback.master.element" -+ -+/** For devices: Playback mixer master type */ -+#define PA_ALSA_PROP_UCM_PLAYBACK_MASTER_TYPE "alsa.ucm.playback.master.type" -+ - /** For devices: Playback priority */ - #define PA_ALSA_PROP_UCM_PLAYBACK_PRIORITY "alsa.ucm.playback.priority" - -@@ -69,6 +78,15 @@ typedef void snd_use_case_mgr_t; - /** For devices: Capture switch e.g CaptureSwitch */ - #define PA_ALSA_PROP_UCM_CAPTURE_SWITCH "alsa.ucm.capture.switch" - -+/** For devices: Capture mixer identifier */ -+#define PA_ALSA_PROP_UCM_CAPTURE_MIXER_ELEM "alsa.ucm.capture.mixer.element" -+ -+/** For devices: Capture mixer identifier */ -+#define PA_ALSA_PROP_UCM_CAPTURE_MASTER_ELEM "alsa.ucm.capture.master.element" -+ -+/** For devices: Capture mixer identifier */ -+#define PA_ALSA_PROP_UCM_CAPTURE_MASTER_TYPE "alsa.ucm.capture.master.type" -+ - /** For devices: Capture priority */ - #define PA_ALSA_PROP_UCM_CAPTURE_PRIORITY "alsa.ucm.capture.priority" - --- -2.16.4 - diff --git a/0008-alsa-mixer-handle-the-index-for-ALSA-mixer-element-i.patch b/0008-alsa-mixer-handle-the-index-for-ALSA-mixer-element-i.patch deleted file mode 100644 index 27a664e..0000000 --- a/0008-alsa-mixer-handle-the-index-for-ALSA-mixer-element-i.patch +++ /dev/null @@ -1,820 +0,0 @@ -From 7f4b8e1a7c2c6a873ddb0207d9b407605bd3e7d6 Mon Sep 17 00:00:00 2001 -From: Jaroslav Kysela -Date: Sat, 23 Nov 2019 20:59:24 +0100 -Subject: [PATCH] alsa-mixer: handle the index for ALSA mixer element - identifiers - -Signed-off-by: Jaroslav Kysela ---- - src/modules/alsa/alsa-mixer.c | 286 ++++++++++++++++++++++++++++++------------ - src/modules/alsa/alsa-mixer.h | 12 +- - 2 files changed, 217 insertions(+), 81 deletions(-) - -diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c -index 1309cec5d8f8..38ace783a997 100644 ---- a/src/modules/alsa/alsa-mixer.c -+++ b/src/modules/alsa/alsa-mixer.c -@@ -107,6 +107,33 @@ struct description_map { - const char *description; - }; - -+static char *alsa_id_str(char *dst, size_t dst_len, pa_alsa_mixer_id *id) { -+ if (id->index > 0) { -+ snprintf(dst, dst_len, "'%s',%d", id->name, id->index); -+ } else { -+ snprintf(dst, dst_len, "'%s'", id->name); -+ } -+ return dst; -+} -+ -+static int alsa_id_decode(const char *src, char *name, int *index) { -+ char *idx; -+ -+ *index = 0; -+ strcpy(name, src); -+ idx = strchr(name, ','); -+ if (idx == NULL) -+ return 0; -+ *idx = '\0'; -+ idx++; -+ if (*idx < '0' || *idx > '9') { -+ pa_log("Element %s: index value is invalid", src); -+ return 1; -+ } -+ *index = atoi(idx); -+ return 0; -+} -+ - pa_alsa_jack *pa_alsa_jack_new(pa_alsa_path *path, const char *name) { - pa_alsa_jack *jack; - -@@ -641,6 +668,7 @@ static void decibel_fix_free(pa_alsa_decibel_fix *db_fix) { - pa_xfree(db_fix->name); - pa_xfree(db_fix->db_values); - -+ pa_xfree(db_fix->key); - pa_xfree(db_fix); - } - -@@ -656,7 +684,7 @@ static void element_free(pa_alsa_element *e) { - if (e->db_fix) - decibel_fix_free(e->db_fix); - -- pa_xfree(e->alsa_name); -+ pa_xfree(e->alsa_id.name); - pa_xfree(e); - } - -@@ -717,11 +745,11 @@ static pa_volume_t from_alsa_volume(long v, long min, long max) { - return (pa_volume_t) round(((double) (v - min) * PA_VOLUME_NORM) / (double) (max - min)); - } - --#define SELEM_INIT(sid, name) \ -- do { \ -- snd_mixer_selem_id_alloca(&(sid)); \ -- snd_mixer_selem_id_set_name((sid), (name)); \ -- snd_mixer_selem_id_set_index((sid), 0); \ -+#define SELEM_INIT(sid, aid) \ -+ do { \ -+ snd_mixer_selem_id_alloca(&(sid)); \ -+ snd_mixer_selem_id_set_name((sid), (aid)->name); \ -+ snd_mixer_selem_id_set_index((sid), (aid)->index); \ - } while(false) - - static int element_get_volume(pa_alsa_element *e, snd_mixer_t *m, const pa_channel_map *cm, pa_cvolume *v) { -@@ -729,6 +757,7 @@ static int element_get_volume(pa_alsa_element *e, snd_mixer_t *m, const pa_chann - snd_mixer_elem_t *me; - snd_mixer_selem_channel_id_t c; - pa_channel_position_mask_t mask = 0; -+ char buf[64]; - unsigned k; - - pa_assert(m); -@@ -736,9 +765,10 @@ static int element_get_volume(pa_alsa_element *e, snd_mixer_t *m, const pa_chann - pa_assert(cm); - pa_assert(v); - -- SELEM_INIT(sid, e->alsa_name); -+ SELEM_INIT(sid, &e->alsa_id); - if (!(me = snd_mixer_find_selem(m, sid))) { -- pa_log_warn("Element %s seems to have disappeared.", e->alsa_name); -+ alsa_id_str(buf, sizeof(buf), &e->alsa_id); -+ pa_log_warn("Element %s seems to have disappeared.", buf); - return -1; - } - -@@ -763,14 +793,16 @@ static int element_get_volume(pa_alsa_element *e, snd_mixer_t *m, const pa_chann - if (value < e->db_fix->min_step) { - value = e->db_fix->min_step; - snd_mixer_selem_set_playback_volume(me, c, value); -+ alsa_id_str(buf, sizeof(buf), &e->alsa_id); - pa_log_debug("Playback volume for element %s channel %i was below the dB fix limit. " -- "Volume reset to %0.2f dB.", e->alsa_name, c, -+ "Volume reset to %0.2f dB.", buf, c, - e->db_fix->db_values[value - e->db_fix->min_step] / 100.0); - } else if (value > e->db_fix->max_step) { - value = e->db_fix->max_step; - snd_mixer_selem_set_playback_volume(me, c, value); -+ alsa_id_str(buf, sizeof(buf), &e->alsa_id); - pa_log_debug("Playback volume for element %s channel %i was over the dB fix limit. " -- "Volume reset to %0.2f dB.", e->alsa_name, c, -+ "Volume reset to %0.2f dB.", buf, c, - e->db_fix->db_values[value - e->db_fix->min_step] / 100.0); - } - -@@ -791,14 +823,16 @@ static int element_get_volume(pa_alsa_element *e, snd_mixer_t *m, const pa_chann - if (value < e->db_fix->min_step) { - value = e->db_fix->min_step; - snd_mixer_selem_set_capture_volume(me, c, value); -+ alsa_id_str(buf, sizeof(buf), &e->alsa_id); - pa_log_debug("Capture volume for element %s channel %i was below the dB fix limit. " -- "Volume reset to %0.2f dB.", e->alsa_name, c, -+ "Volume reset to %0.2f dB.", buf, c, - e->db_fix->db_values[value - e->db_fix->min_step] / 100.0); - } else if (value > e->db_fix->max_step) { - value = e->db_fix->max_step; - snd_mixer_selem_set_capture_volume(me, c, value); -+ alsa_id_str(buf, sizeof(buf), &e->alsa_id); - pa_log_debug("Capture volume for element %s channel %i was over the dB fix limit. " -- "Volume reset to %0.2f dB.", e->alsa_name, c, -+ "Volume reset to %0.2f dB.", buf, c, - e->db_fix->db_values[value - e->db_fix->min_step] / 100.0); - } - -@@ -896,14 +930,16 @@ static int element_get_switch(pa_alsa_element *e, snd_mixer_t *m, bool *b) { - snd_mixer_selem_id_t *sid; - snd_mixer_elem_t *me; - snd_mixer_selem_channel_id_t c; -+ char buf[64]; - - pa_assert(m); - pa_assert(e); - pa_assert(b); - -- SELEM_INIT(sid, e->alsa_name); -+ SELEM_INIT(sid, &e->alsa_id); - if (!(me = snd_mixer_find_selem(m, sid))) { -- pa_log_warn("Element %s seems to have disappeared.", e->alsa_name); -+ alsa_id_str(buf, sizeof(buf), &e->alsa_id); -+ pa_log_warn("Element %s seems to have disappeared.", buf); - return -1; - } - -@@ -1057,6 +1093,7 @@ static int element_set_volume(pa_alsa_element *e, snd_mixer_t *m, const pa_chann - snd_mixer_elem_t *me; - snd_mixer_selem_channel_id_t c; - pa_channel_position_mask_t mask = 0; -+ char buf[64]; - unsigned k; - - pa_assert(m); -@@ -1065,9 +1102,10 @@ static int element_set_volume(pa_alsa_element *e, snd_mixer_t *m, const pa_chann - pa_assert(v); - pa_assert(pa_cvolume_compatible_with_channel_map(v, cm)); - -- SELEM_INIT(sid, e->alsa_name); -+ SELEM_INIT(sid, &e->alsa_id); - if (!(me = snd_mixer_find_selem(m, sid))) { -- pa_log_warn("Element %s seems to have disappeared.", e->alsa_name); -+ alsa_id_str(buf, sizeof(buf), &e->alsa_id); -+ pa_log_warn("Element %s seems to have disappeared.", buf); - return -1; - } - -@@ -1250,14 +1288,16 @@ int pa_alsa_path_set_volume(pa_alsa_path *p, snd_mixer_t *m, const pa_channel_ma - static int element_set_switch(pa_alsa_element *e, snd_mixer_t *m, bool b) { - snd_mixer_elem_t *me; - snd_mixer_selem_id_t *sid; -+ char buf[64]; - int r; - - pa_assert(m); - pa_assert(e); - -- SELEM_INIT(sid, e->alsa_name); -+ SELEM_INIT(sid, &e->alsa_id); - if (!(me = snd_mixer_find_selem(m, sid))) { -- pa_log_warn("Element %s seems to have disappeared.", e->alsa_name); -+ alsa_id_str(buf, sizeof(buf), &e->alsa_id); -+ pa_log_warn("Element %s seems to have disappeared.", buf); - return -1; - } - -@@ -1266,8 +1306,10 @@ static int element_set_switch(pa_alsa_element *e, snd_mixer_t *m, bool b) { - else - r = snd_mixer_selem_set_capture_switch_all(me, b); - -- if (r < 0) -- pa_log_warn("Failed to set switch of %s: %s", e->alsa_name, pa_alsa_strerror(errno)); -+ if (r < 0) { -+ alsa_id_str(buf, sizeof(buf), &e->alsa_id); -+ pa_log_warn("Failed to set switch of %s: %s", buf, pa_alsa_strerror(errno)); -+ } - - return r; - } -@@ -1302,13 +1344,15 @@ static int element_set_constant_volume(pa_alsa_element *e, snd_mixer_t *m) { - int r = 0; - long volume = -1; - bool volume_set = false; -+ char buf[64]; - - pa_assert(m); - pa_assert(e); - -- SELEM_INIT(sid, e->alsa_name); -+ SELEM_INIT(sid, &e->alsa_id); - if (!(me = snd_mixer_find_selem(m, sid))) { -- pa_log_warn("Element %s seems to have disappeared.", e->alsa_name); -+ alsa_id_str(buf, sizeof(buf), &e->alsa_id); -+ pa_log_warn("Element %s seems to have disappeared.", buf); - return -1; - } - -@@ -1351,8 +1395,10 @@ static int element_set_constant_volume(pa_alsa_element *e, snd_mixer_t *m) { - r = snd_mixer_selem_set_capture_dB_all(me, 0, -1); - } - -- if (r < 0) -- pa_log_warn("Failed to set volume of %s: %s", e->alsa_name, pa_alsa_strerror(errno)); -+ if (r < 0) { -+ alsa_id_str(buf, sizeof(buf), &e->alsa_id); -+ pa_log_warn("Failed to set volume of %s: %s", buf, pa_alsa_strerror(errno)); -+ } - - return r; - } -@@ -1530,6 +1576,7 @@ static bool element_probe_volume(pa_alsa_element *e, snd_mixer_elem_t *me) { - int r; - bool is_mono; - pa_channel_position_t p; -+ char buf[64]; - - if (e->direction == PA_ALSA_DIRECTION_OUTPUT) { - if (!snd_mixer_selem_has_playback_volume(me)) { -@@ -1555,29 +1602,33 @@ static bool element_probe_volume(pa_alsa_element *e, snd_mixer_elem_t *me) { - r = snd_mixer_selem_get_capture_volume_range(me, &e->min_volume, &e->max_volume); - - if (r < 0) { -- pa_log_warn("Failed to get volume range of %s: %s", e->alsa_name, pa_alsa_strerror(r)); -+ alsa_id_str(buf, sizeof(buf), &e->alsa_id); -+ pa_log_warn("Failed to get volume range of %s: %s", buf, pa_alsa_strerror(r)); - return false; - } - - if (e->min_volume >= e->max_volume) { -- pa_log_warn("Your kernel driver is broken: it reports a volume range from %li to %li which makes no sense.", -- e->min_volume, e->max_volume); -+ alsa_id_str(buf, sizeof(buf), &e->alsa_id); -+ pa_log_warn("Your kernel driver is broken for element %s: it reports a volume range from %li to %li which makes no sense.", -+ buf, e->min_volume, e->max_volume); - return false; - } - if (e->volume_use == PA_ALSA_VOLUME_CONSTANT && (e->min_volume > e->constant_volume || e->max_volume < e->constant_volume)) { -+ alsa_id_str(buf, sizeof(buf), &e->alsa_id); - pa_log_warn("Constant volume %li configured for element %s, but the available range is from %li to %li.", -- e->constant_volume, e->alsa_name, e->min_volume, e->max_volume); -+ e->constant_volume, buf, e->min_volume, e->max_volume); - return false; - } - - - if (e->db_fix && ((e->min_volume > e->db_fix->min_step) || (e->max_volume < e->db_fix->max_step))) { -- pa_log_warn("The step range of the decibel fix for element %s (%li-%li) doesn't fit to the " -- "real hardware range (%li-%li). Disabling the decibel fix.", e->alsa_name, -- e->db_fix->min_step, e->db_fix->max_step, e->min_volume, e->max_volume); -+ alsa_id_str(buf, sizeof(buf), &e->alsa_id); -+ pa_log_warn("The step range of the decibel fix for element %s (%li-%li) doesn't fit to the " -+ "real hardware range (%li-%li). Disabling the decibel fix.", buf, -+ e->db_fix->min_step, e->db_fix->max_step, e->min_volume, e->max_volume); - -- decibel_fix_free(e->db_fix); -- e->db_fix = NULL; -+ decibel_fix_free(e->db_fix); -+ e->db_fix = NULL; - } - - if (e->db_fix) { -@@ -1598,19 +1649,22 @@ static bool element_probe_volume(pa_alsa_element *e, snd_mixer_elem_t *me) { - long max_dB_checked = 0; - - if (element_ask_vol_dB(me, e->direction, e->min_volume, &min_dB_checked) < 0) { -- pa_log_warn("Failed to query the dB value for %s at volume level %li", e->alsa_name, e->min_volume); -+ alsa_id_str(buf, sizeof(buf), &e->alsa_id); -+ pa_log_warn("Failed to query the dB value for %s at volume level %li", buf, e->min_volume); - return false; - } - - if (element_ask_vol_dB(me, e->direction, e->max_volume, &max_dB_checked) < 0) { -- pa_log_warn("Failed to query the dB value for %s at volume level %li", e->alsa_name, e->max_volume); -+ alsa_id_str(buf, sizeof(buf), &e->alsa_id); -+ pa_log_warn("Failed to query the dB value for %s at volume level %li", buf, e->max_volume); - return false; - } - - if (min_dB != min_dB_checked || max_dB != max_dB_checked) { -+ alsa_id_str(buf, sizeof(buf), &e->alsa_id); - pa_log_warn("Your kernel driver is broken: the reported dB range for %s (from %0.2f dB to %0.2f dB) " - "doesn't match the dB values at minimum and maximum volume levels: %0.2f dB at level %li, " -- "%0.2f dB at level %li.", e->alsa_name, min_dB / 100.0, max_dB / 100.0, -+ "%0.2f dB at level %li.", buf, min_dB / 100.0, max_dB / 100.0, - min_dB_checked / 100.0, e->min_volume, max_dB_checked / 100.0, e->max_volume); - return false; - } -@@ -1629,11 +1683,12 @@ static bool element_probe_volume(pa_alsa_element *e, snd_mixer_elem_t *me) { - } - - if (e->volume_limit >= 0) { -- if (e->volume_limit <= e->min_volume || e->volume_limit > e->max_volume) -+ if (e->volume_limit <= e->min_volume || e->volume_limit > e->max_volume) { -+ alsa_id_str(buf, sizeof(buf), &e->alsa_id); - pa_log_warn("Volume limit for element %s of path %s is invalid: %li isn't within the valid range " - "%li-%li. The volume limit is ignored.", -- e->alsa_name, e->path->name, e->volume_limit, e->min_volume + 1, e->max_volume); -- else { -+ buf, e->path->name, e->volume_limit, e->min_volume + 1, e->max_volume); -+ } else { - e->max_volume = e->volume_limit; - - if (e->has_dB) { -@@ -1641,7 +1696,8 @@ static bool element_probe_volume(pa_alsa_element *e, snd_mixer_elem_t *me) { - e->db_fix->max_step = e->max_volume; - e->max_dB = ((double) e->db_fix->db_values[e->db_fix->max_step - e->db_fix->min_step]) / 100.0; - } else if (element_ask_vol_dB(me, e->direction, e->max_volume, &max_dB) < 0) { -- pa_log_warn("Failed to get dB value of %s: %s", e->alsa_name, pa_alsa_strerror(r)); -+ alsa_id_str(buf, sizeof(buf), &e->alsa_id); -+ pa_log_warn("Failed to get dB value of %s: %s", buf, pa_alsa_strerror(r)); - e->has_dB = false; - } else - e->max_dB = ((double) max_dB) / 100.0; -@@ -1681,7 +1737,8 @@ static bool element_probe_volume(pa_alsa_element *e, snd_mixer_elem_t *me) { - } - - if (e->n_channels <= 0) { -- pa_log_warn("Volume element %s with no channels?", e->alsa_name); -+ alsa_id_str(buf, sizeof(buf), &e->alsa_id); -+ pa_log_warn("Volume element %s with no channels?", buf); - return false; - } else if (e->n_channels > 2) { - /* FIXME: In some places code like this is used: -@@ -1695,7 +1752,8 @@ static bool element_probe_volume(pa_alsa_element *e, snd_mixer_elem_t *me) { - * Since the array size is fixed at 2, we obviously - * don't support elements with more than two - * channels... */ -- pa_log_warn("Volume element %s has %u channels. That's too much! I can't handle that!", e->alsa_name, e->n_channels); -+ alsa_id_str(buf, sizeof(buf), &e->alsa_id); -+ pa_log_warn("Volume element %s has %u channels. That's too much! I can't handle that!", buf, e->n_channels); - return false; - } - -@@ -1733,7 +1791,7 @@ static int element_probe(pa_alsa_element *e, snd_mixer_t *m) { - pa_assert(e); - pa_assert(e->path); - -- SELEM_INIT(sid, e->alsa_name); -+ SELEM_INIT(sid, &e->alsa_id); - - if (!(me = snd_mixer_find_selem(m, sid))) { - -@@ -1854,6 +1912,8 @@ static int jack_probe(pa_alsa_jack *j, pa_alsa_mapping *mapping, snd_mixer_t *m) - - static pa_alsa_element* element_get(pa_alsa_path *p, const char *section, bool prefixed) { - pa_alsa_element *e; -+ char *name; -+ int index; - - pa_assert(p); - pa_assert(section); -@@ -1869,16 +1929,22 @@ static pa_alsa_element* element_get(pa_alsa_path *p, const char *section, bool p - if (strchr(section, ':')) - return NULL; - -- if (p->last_element && pa_streq(p->last_element->alsa_name, section)) -+ name = alloca(strlen(section) + 1); -+ if (alsa_id_decode(section, name, &index)) -+ return NULL; -+ -+ if (p->last_element && pa_streq(p->last_element->alsa_id.name, name) && -+ p->last_element->alsa_id.index == index) - return p->last_element; - - PA_LLIST_FOREACH(e, p->elements) -- if (pa_streq(e->alsa_name, section)) -+ if (pa_streq(e->alsa_id.name, name) && e->alsa_id.index == index) - goto finish; - - e = pa_xnew0(pa_alsa_element, 1); - e->path = p; -- e->alsa_name = pa_xstrdup(section); -+ e->alsa_id.name = pa_xstrdup(name); -+ e->alsa_id.index = index; - e->direction = p->direction; - e->volume_limit = -1; - -@@ -1912,10 +1978,12 @@ finish: - } - - static pa_alsa_option* option_get(pa_alsa_path *p, const char *section) { -- char *en; -+ char *en, *name; - const char *on; - pa_alsa_option *o; - pa_alsa_element *e; -+ size_t len; -+ int index; - - if (!pa_startswith(section, "Option ")) - return NULL; -@@ -1926,18 +1994,25 @@ static pa_alsa_option* option_get(pa_alsa_path *p, const char *section) { - if (!(on = strchr(section, ':'))) - return NULL; - -- en = pa_xstrndup(section, on - section); -+ len = on - section; -+ en = alloca(len + 1); -+ strncpy(en, section, len); -+ en[len] = '\0'; -+ -+ name = alloca(strlen(en) + 1); -+ if (alsa_id_decode(en, name, &index)) -+ return NULL; -+ - on++; - - if (p->last_option && -- pa_streq(p->last_option->element->alsa_name, en) && -+ pa_streq(p->last_option->element->alsa_id.name, name) && -+ p->last_option->element->alsa_id.index == index && - pa_streq(p->last_option->alsa_name, on)) { -- pa_xfree(en); - return p->last_option; - } - - pa_assert_se(e = element_get(p, en, false)); -- pa_xfree(en); - - PA_LLIST_FOREACH(o, e->options) - if (pa_streq(o->alsa_name, on)) -@@ -2393,14 +2468,16 @@ static int jack_parse_append_pcm_to_name(pa_config_parser_state *state) { - static int element_set_option(pa_alsa_element *e, snd_mixer_t *m, int alsa_idx) { - snd_mixer_selem_id_t *sid; - snd_mixer_elem_t *me; -+ char buf[64]; - int r; - - pa_assert(e); - pa_assert(m); - -- SELEM_INIT(sid, e->alsa_name); -+ SELEM_INIT(sid, &e->alsa_id); - if (!(me = snd_mixer_find_selem(m, sid))) { -- pa_log_warn("Element %s seems to have disappeared.", e->alsa_name); -+ alsa_id_str(buf, sizeof(buf), &e->alsa_id); -+ pa_log_warn("Element %s seems to have disappeared.", buf); - return -1; - } - -@@ -2411,14 +2488,18 @@ static int element_set_option(pa_alsa_element *e, snd_mixer_t *m, int alsa_idx) - else - r = snd_mixer_selem_set_capture_switch_all(me, alsa_idx); - -- if (r < 0) -- pa_log_warn("Failed to set switch of %s: %s", e->alsa_name, pa_alsa_strerror(errno)); -+ if (r < 0) { -+ alsa_id_str(buf, sizeof(buf), &e->alsa_id); -+ pa_log_warn("Failed to set switch of %s: %s", buf, pa_alsa_strerror(errno)); -+ } - - } else { - pa_assert(e->enumeration_use == PA_ALSA_ENUMERATION_SELECT); - -- if ((r = snd_mixer_selem_set_enum_item(me, 0, alsa_idx)) < 0) -- pa_log_warn("Failed to set enumeration of %s: %s", e->alsa_name, pa_alsa_strerror(errno)); -+ if ((r = snd_mixer_selem_set_enum_item(me, 0, alsa_idx)) < 0) { -+ alsa_id_str(buf, sizeof(buf), &e->alsa_id); -+ pa_log_warn("Failed to set enumeration of %s: %s", buf, pa_alsa_strerror(errno)); -+ } - } - - return r; -@@ -2462,6 +2543,7 @@ static int option_verify(pa_alsa_option *o) { - { "output-speaker", N_("Speaker") }, - { "output-headphones", N_("Headphones") } - }; -+ char buf[64]; - - pa_assert(o); - -@@ -2472,14 +2554,16 @@ static int option_verify(pa_alsa_option *o) { - - if (o->element->enumeration_use != PA_ALSA_ENUMERATION_SELECT && - o->element->switch_use != PA_ALSA_SWITCH_SELECT) { -- pa_log("Element %s of option %s not set for select.", o->element->alsa_name, o->name); -+ alsa_id_str(buf, sizeof(buf), &o->element->alsa_id); -+ pa_log("Element %s of option %s not set for select.", buf, o->name); - return -1; - } - - if (o->element->switch_use == PA_ALSA_SWITCH_SELECT && - !pa_streq(o->alsa_name, "on") && - !pa_streq(o->alsa_name, "off")) { -- pa_log("Switch %s options need be named off or on ", o->element->alsa_name); -+ alsa_id_str(buf, sizeof(buf), &o->element->alsa_id); -+ pa_log("Switch %s options need be named off or on ", buf); - return -1; - } - -@@ -2495,6 +2579,7 @@ static int option_verify(pa_alsa_option *o) { - - static int element_verify(pa_alsa_element *e) { - pa_alsa_option *o; -+ char buf[64]; - - pa_assert(e); - -@@ -2503,12 +2588,14 @@ static int element_verify(pa_alsa_element *e) { - (e->required_any != PA_ALSA_REQUIRED_IGNORE && e->required_any == e->required_absent) || - (e->required_absent == PA_ALSA_REQUIRED_ANY && e->required_any != PA_ALSA_REQUIRED_IGNORE) || - (e->required_absent == PA_ALSA_REQUIRED_ANY && e->required != PA_ALSA_REQUIRED_IGNORE)) { -- pa_log("Element %s cannot be required and absent at the same time.", e->alsa_name); -+ alsa_id_str(buf, sizeof(buf), &e->alsa_id); -+ pa_log("Element %s cannot be required and absent at the same time.", buf); - return -1; - } - - if (e->switch_use == PA_ALSA_SWITCH_SELECT && e->enumeration_use == PA_ALSA_ENUMERATION_SELECT) { -- pa_log("Element %s cannot set select for both switch and enumeration.", e->alsa_name); -+ alsa_id_str(buf, sizeof(buf), &e->alsa_id); -+ pa_log("Element %s cannot set select for both switch and enumeration.", buf); - return -1; - } - -@@ -2660,9 +2747,15 @@ fail: - pa_alsa_path *pa_alsa_path_synthesize(const char *element, pa_alsa_direction_t direction) { - pa_alsa_path *p; - pa_alsa_element *e; -+ char *name; -+ int index; - - pa_assert(element); - -+ name = alloca(strlen(element) + 1); -+ if (alsa_id_decode(element, name, &index)) -+ return NULL; -+ - p = pa_xnew0(pa_alsa_path, 1); - p->name = pa_xstrdup(element); - p->direction = direction; -@@ -2670,7 +2763,8 @@ pa_alsa_path *pa_alsa_path_synthesize(const char *element, pa_alsa_direction_t d - - e = pa_xnew0(pa_alsa_element, 1); - e->path = p; -- e->alsa_name = pa_xstrdup(element); -+ e->alsa_id.name = pa_xstrdup(name); -+ e->alsa_id.index = index; - e->direction = direction; - e->volume_limit = -1; - -@@ -2820,6 +2914,7 @@ int pa_alsa_path_probe(pa_alsa_path *p, pa_alsa_mapping *mapping, snd_mixer_t *m - double min_dB[PA_CHANNEL_POSITION_MAX], max_dB[PA_CHANNEL_POSITION_MAX]; - pa_channel_position_t t; - pa_channel_position_mask_t path_volume_channels = 0; -+ char buf[64]; - - pa_assert(p); - pa_assert(m); -@@ -2843,12 +2938,13 @@ int pa_alsa_path_probe(pa_alsa_path *p, pa_alsa_mapping *mapping, snd_mixer_t *m - } - - PA_LLIST_FOREACH(e, p->elements) { -+ alsa_id_str(buf, sizeof(buf), &e->alsa_id); - if (element_probe(e, m) < 0) { - p->supported = false; -- pa_log_debug("Probe of element '%s' failed.", e->alsa_name); -+ pa_log_debug("Probe of element %s failed.", buf); - return -1; - } -- pa_log_debug("Probe of element '%s' succeeded (volume=%d, switch=%d, enumeration=%d).", e->alsa_name, e->volume_use, e->switch_use, e->enumeration_use); -+ pa_log_debug("Probe of element %s succeeded (volume=%d, switch=%d, enumeration=%d).", buf, e->volume_use, e->switch_use, e->enumeration_use); - - if (ignore_dB) - e->has_dB = false; -@@ -2884,13 +2980,13 @@ int pa_alsa_path_probe(pa_alsa_path *p, pa_alsa_mapping *mapping, snd_mixer_t *m - * which cannot do dB volumes, so we we need - * to 'neutralize' this slider */ - e->volume_use = PA_ALSA_VOLUME_ZERO; -- pa_log_info("Zeroing volume of '%s' on path '%s'", e->alsa_name, p->name); -+ pa_log_info("Zeroing volume of %s on path '%s'", buf, p->name); - } - } - } else if (p->has_volume) { - /* We can't use this volume, so let's ignore it */ - e->volume_use = PA_ALSA_VOLUME_IGNORE; -- pa_log_info("Ignoring volume of '%s' on path '%s' (missing dB info)", e->alsa_name, p->name); -+ pa_log_info("Ignoring volume of %s on path '%s' (missing dB info)", buf, p->name); - } - p->has_volume = true; - } -@@ -2954,11 +3050,14 @@ void pa_alsa_option_dump(pa_alsa_option *o) { - } - - void pa_alsa_element_dump(pa_alsa_element *e) { -+ char buf[64]; -+ - pa_alsa_option *o; - pa_assert(e); - -+ alsa_id_str(buf, sizeof(buf), &e->alsa_id); - pa_log_debug("Element %s, direction=%i, switch=%i, volume=%i, volume_limit=%li, enumeration=%i, required=%i, required_any=%i, required_absent=%i, mask=0x%llx, n_channels=%u, override_map=%s", -- e->alsa_name, -+ buf, - e->direction, - e->switch_use, - e->volume_use, -@@ -3008,14 +3107,16 @@ void pa_alsa_path_dump(pa_alsa_path *p) { - static void element_set_callback(pa_alsa_element *e, snd_mixer_t *m, snd_mixer_elem_callback_t cb, void *userdata) { - snd_mixer_selem_id_t *sid; - snd_mixer_elem_t *me; -+ char buf[64]; - - pa_assert(e); - pa_assert(m); - pa_assert(cb); - -- SELEM_INIT(sid, e->alsa_name); -+ SELEM_INIT(sid, &e->alsa_id); - if (!(me = snd_mixer_find_selem(m, sid))) { -- pa_log_warn("Element %s seems to have disappeared.", e->alsa_name); -+ alsa_id_str(buf, sizeof(buf), &e->alsa_id); -+ pa_log_warn("Element %s seems to have disappeared.", buf); - return; - } - -@@ -3081,6 +3182,8 @@ pa_alsa_path_set *pa_alsa_path_set_new(pa_alsa_mapping *m, pa_alsa_direction_t d - char **pn = NULL, **en = NULL, **ie; - pa_alsa_decibel_fix *db_fix; - void *state, *state2; -+ char name[64]; -+ int index; - - pa_assert(m); - pa_assert(m->profile_set); -@@ -3160,9 +3263,18 @@ pa_alsa_path_set *pa_alsa_path_set_new(pa_alsa_mapping *m, pa_alsa_direction_t d - if (je == ie) - continue; - -+ if (strlen(*je) + 1 >= sizeof(name)) { -+ pa_log("Element identifier %s is too long!", *je); -+ continue; -+ } -+ -+ if (alsa_id_decode(*je, name, &index)) -+ continue; -+ - e = pa_xnew0(pa_alsa_element, 1); - e->path = p; -- e->alsa_name = pa_xstrdup(*je); -+ e->alsa_id.name = pa_xstrdup(name); -+ e->alsa_id.index = index; - e->direction = direction; - e->required_absent = PA_ALSA_REQUIRED_ANY; - e->volume_limit = -1; -@@ -3183,7 +3295,8 @@ finish: - pa_alsa_element *e; - - PA_LLIST_FOREACH(e, p->elements) { -- if (e->volume_use != PA_ALSA_VOLUME_IGNORE && pa_streq(db_fix->name, e->alsa_name)) { -+ if (e->volume_use != PA_ALSA_VOLUME_IGNORE && pa_streq(db_fix->name, e->alsa_id.name) && -+ db_fix->index == e->alsa_id.index) { - /* The profile set that contains the dB fix may be freed - * before the element, so we have to copy the dB fix - * object. */ -@@ -3256,6 +3369,8 @@ static bool enumeration_is_subset(pa_alsa_option *a_options, pa_alsa_option *b_o - * Compares two elements to see if a is a subset of b - */ - static bool element_is_subset(pa_alsa_element *a, pa_alsa_element *b, snd_mixer_t *m) { -+ char buf[64]; -+ - pa_assert(a); - pa_assert(b); - pa_assert(m); -@@ -3293,9 +3408,10 @@ static bool element_is_subset(pa_alsa_element *a, pa_alsa_element *b, snd_mixer_ - snd_mixer_selem_id_t *sid; - snd_mixer_elem_t *me; - -- SELEM_INIT(sid, a->alsa_name); -+ SELEM_INIT(sid, &a->alsa_id); - if (!(me = snd_mixer_find_selem(m, sid))) { -- pa_log_warn("Element %s seems to have disappeared.", a->alsa_name); -+ alsa_id_str(buf, sizeof(buf), &a->alsa_id); -+ pa_log_warn("Element %s seems to have disappeared.", buf); - return false; - } - -@@ -3325,8 +3441,9 @@ static bool element_is_subset(pa_alsa_element *a, pa_alsa_element *b, snd_mixer_ - return false; - for (s = 0; s <= SND_MIXER_SCHN_LAST; s++) - if (a->masks[s][a->n_channels-1] != b->masks[s][b->n_channels-1]) { -+ alsa_id_str(buf, sizeof(buf), &a->alsa_id); - pa_log_debug("Element %s is not a subset - mask a: 0x%" PRIx64 ", mask b: 0x%" PRIx64 ", at channel %d", -- a->alsa_name, a->masks[s][a->n_channels-1], b->masks[s][b->n_channels-1], s); -+ buf, a->masks[s][a->n_channels-1], b->masks[s][b->n_channels-1], s); - return false; - } - } -@@ -3423,7 +3540,8 @@ static void path_set_condense(pa_alsa_path_set *ps, snd_mixer_t *m) { - break; - - PA_LLIST_FOREACH(eb, p2->elements) { -- if (pa_streq(ea->alsa_name, eb->alsa_name)) { -+ if (pa_streq(ea->alsa_id.name, eb->alsa_id.name) && -+ ea->alsa_id.index == eb->alsa_id.index) { - found_matching_element = true; - is_subset = element_is_subset(ea, eb, m); - break; -@@ -3600,22 +3718,30 @@ static pa_alsa_profile *profile_get(pa_alsa_profile_set *ps, const char *name) { - return p; - } - --static pa_alsa_decibel_fix *decibel_fix_get(pa_alsa_profile_set *ps, const char *name) { -+static pa_alsa_decibel_fix *decibel_fix_get(pa_alsa_profile_set *ps, const char *alsa_id) { - pa_alsa_decibel_fix *db_fix; -+ char *name; -+ int index; - -- if (!pa_startswith(name, "DecibelFix ")) -+ if (!pa_startswith(alsa_id, "DecibelFix ")) - return NULL; - -- name += 11; -+ alsa_id += 11; - -- if ((db_fix = pa_hashmap_get(ps->decibel_fixes, name))) -+ if ((db_fix = pa_hashmap_get(ps->decibel_fixes, alsa_id))) - return db_fix; - -+ name = alloca(strlen(alsa_id) + 1); -+ if (alsa_id_decode(alsa_id, name, &index)) -+ return NULL; -+ - db_fix = pa_xnew0(pa_alsa_decibel_fix, 1); - db_fix->profile_set = ps; - db_fix->name = pa_xstrdup(name); -+ db_fix->index = index; -+ db_fix->key = pa_xstrdup(alsa_id); - -- pa_hashmap_put(ps->decibel_fixes, db_fix->name, db_fix); -+ pa_hashmap_put(ps->decibel_fixes, db_fix->key, db_fix); - - return db_fix; - } -diff --git a/src/modules/alsa/alsa-mixer.h b/src/modules/alsa/alsa-mixer.h -index 65b071165c6b..709f270fbfa5 100644 ---- a/src/modules/alsa/alsa-mixer.h -+++ b/src/modules/alsa/alsa-mixer.h -@@ -34,6 +34,7 @@ - typedef struct pa_alsa_fdlist pa_alsa_fdlist; - typedef struct pa_alsa_mixer_pdata pa_alsa_mixer_pdata; - typedef struct pa_alsa_setting pa_alsa_setting; -+typedef struct pa_alsa_mixer_id pa_alsa_mixer_id; - typedef struct pa_alsa_option pa_alsa_option; - typedef struct pa_alsa_element pa_alsa_element; - typedef struct pa_alsa_jack pa_alsa_jack; -@@ -97,6 +98,12 @@ struct pa_alsa_setting { - unsigned priority; - }; - -+/* ALSA mixer element identifier */ -+struct pa_alsa_mixer_id { -+ char *name; -+ int index; -+}; -+ - /* An option belongs to an element and refers to one enumeration item - * of the element is an enumeration item, or a switch status if the - * element is a switch item. */ -@@ -123,7 +130,7 @@ struct pa_alsa_element { - pa_alsa_path *path; - PA_LLIST_FIELDS(pa_alsa_element); - -- char *alsa_name; -+ struct pa_alsa_mixer_id alsa_id; - pa_alsa_direction_t direction; - - pa_alsa_switch_use_t switch_use; -@@ -315,9 +322,12 @@ struct pa_alsa_profile { - }; - - struct pa_alsa_decibel_fix { -+ char *key; -+ - pa_alsa_profile_set *profile_set; - - char *name; /* Alsa volume element name. */ -+ int index; /* Alsa volume element index. */ - long min_step; - long max_step; - --- -2.16.4 - diff --git a/0009-alsa-mixer-improve-alsa_id_decode-function.patch b/0009-alsa-mixer-improve-alsa_id_decode-function.patch deleted file mode 100644 index 048a2ed..0000000 --- a/0009-alsa-mixer-improve-alsa_id_decode-function.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 1c240b7a12e9e2f7c2266d18cbb74130bb81277e Mon Sep 17 00:00:00 2001 -From: Jaroslav Kysela -Date: Tue, 26 Nov 2019 10:35:14 +0100 -Subject: [PATCH] alsa-mixer: improve alsa_id_decode() function - -Accept those identifiers: - - Speaker,1 - 'Speaker',1 - "Speaker",1 - -Signed-off-by: Jaroslav Kysela ---- - src/modules/alsa/alsa-mixer.c | 19 ++++++++++++++++--- - 1 file changed, 16 insertions(+), 3 deletions(-) - -diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c -index 38ace783a997..f57aabe5d885 100644 ---- a/src/modules/alsa/alsa-mixer.c -+++ b/src/modules/alsa/alsa-mixer.c -@@ -117,11 +117,24 @@ static char *alsa_id_str(char *dst, size_t dst_len, pa_alsa_mixer_id *id) { - } - - static int alsa_id_decode(const char *src, char *name, int *index) { -- char *idx; -+ char *idx, c; -+ int i; - - *index = 0; -- strcpy(name, src); -- idx = strchr(name, ','); -+ c = src[0]; -+ /* Strip quotes in entries such as 'Speaker',1 or "Speaker",1 */ -+ if (c == '\'' || c == '"') { -+ strcpy(name, src + 1); -+ for (i = 0; name[i] != '\0' && name[i] != c; i++); -+ idx = NULL; -+ if (name[i]) { -+ name[i] = '\0'; -+ idx = strchr(name + i + 1, ','); -+ } -+ } else { -+ strcpy(name, src); -+ idx = strchr(name, ','); -+ } - if (idx == NULL) - return 0; - *idx = '\0'; --- -2.16.4 - diff --git a/0010-alsa-ucm-Support-Playback-CaptureVolume.patch b/0010-alsa-ucm-Support-Playback-CaptureVolume.patch deleted file mode 100644 index debf743..0000000 --- a/0010-alsa-ucm-Support-Playback-CaptureVolume.patch +++ /dev/null @@ -1,795 +0,0 @@ -From 3dfccada466bef64f73ef9be3d94eaee7b6f9a60 Mon Sep 17 00:00:00 2001 -From: Arun Raghavan -Date: Tue, 3 May 2016 18:22:10 +0530 -Subject: [PATCH] alsa-ucm: Support Playback/CaptureVolume - -This allows us to support the PlaybackVolume and CaptureVolume commands -in UCM, specifying a mixer control to use for hardware volume control. -This only works with ports corresponding to single devices at the -moment, and doesn't support stacking controls for combination ports. - -The configuration is intended to provide a control (like Headphone -Playback Volume), but we try to resolve to a simple mixer control -(Headphone) to reuse existing volume paths. - -On the UCM side, this also requires that when disabling the device for -the port, the volume should be reset to some default. - -When enabling/disabling combination devices, things are a bit iffy since -we have no way to reset the volume before switching to a combination -device. It would be nice to have a combination-transition-sequence -command in UCM to handle this and other similar cases. - -PlaybackSwitch and CaptureSwitch are yet to be implemented. ---- - src/modules/alsa/alsa-sink.c | 70 +++++++++++---- - src/modules/alsa/alsa-source.c | 68 +++++++++++---- - src/modules/alsa/alsa-ucm.c | 165 +++++++++++++++++++++++++++++------- - src/modules/alsa/alsa-ucm.h | 26 +++++- - src/modules/alsa/module-alsa-card.c | 4 +- - src/pulsecore/core-util.c | 26 ++++++ - src/pulsecore/core-util.h | 2 + - 7 files changed, 295 insertions(+), 66 deletions(-) - -diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c -index 4b46708ce4a3..08d4d1f38b80 100644 ---- a/src/modules/alsa/alsa-sink.c -+++ b/src/modules/alsa/alsa-sink.c -@@ -1598,7 +1598,7 @@ static void sink_set_mute_cb(pa_sink *s) { - static void mixer_volume_init(struct userdata *u) { - pa_assert(u); - -- if (!u->mixer_path->has_volume) { -+ if (!u->mixer_path || !u->mixer_path->has_volume) { - pa_sink_set_write_volume_callback(u->sink, NULL); - pa_sink_set_get_volume_callback(u->sink, NULL); - pa_sink_set_set_volume_callback(u->sink, NULL); -@@ -1633,7 +1633,7 @@ static void mixer_volume_init(struct userdata *u) { - pa_log_info("Using hardware volume control. Hardware dB scale %s.", u->mixer_path->has_dB ? "supported" : "not supported"); - } - -- if (!u->mixer_path->has_mute) { -+ if (!u->mixer_path || !u->mixer_path->has_mute) { - pa_sink_set_get_mute_callback(u->sink, NULL); - pa_sink_set_set_mute_callback(u->sink, NULL); - pa_log_info("Driver does not support hardware mute control, falling back to software mute control."); -@@ -1646,11 +1646,31 @@ static void mixer_volume_init(struct userdata *u) { - - static int sink_set_port_ucm_cb(pa_sink *s, pa_device_port *p) { - struct userdata *u = s->userdata; -+ pa_alsa_ucm_port_data *data; -+ -+ data = PA_DEVICE_PORT_DATA(p); - - pa_assert(u); - pa_assert(p); - pa_assert(u->ucm_context); - -+ u->mixer_path = data->path; -+ mixer_volume_init(u); -+ -+ if (u->mixer_path) { -+ pa_alsa_path_select(u->mixer_path, NULL, u->mixer_handle, s->muted); -+ -+ if (s->set_mute) -+ s->set_mute(s); -+ if (s->flags & PA_SINK_DEFERRED_VOLUME) { -+ if (s->write_volume) -+ s->write_volume(s); -+ } else { -+ if (s->set_volume) -+ s->set_volume(s); -+ } -+ } -+ - return pa_alsa_ucm_set_port(u->ucm_context, p, true); - } - -@@ -2079,6 +2099,11 @@ static void find_mixer(struct userdata *u, pa_alsa_mapping *mapping, const char - return; - } - -+ if (u->ucm_context) { -+ /* We just want to open the device */ -+ return; -+ } -+ - if (element) { - - if (!(u->mixer_path = pa_alsa_path_synthesize(element, PA_ALSA_DIRECTION_OUTPUT))) -@@ -2116,16 +2141,31 @@ static int setup_mixer(struct userdata *u, bool ignore_dB) { - return 0; - - if (u->sink->active_port) { -- pa_alsa_port_data *data; -+ if (!u->ucm_context) { -+ pa_alsa_port_data *data; - -- /* We have a list of supported paths, so let's activate the -- * one that has been chosen as active */ -+ /* We have a list of supported paths, so let's activate the -+ * one that has been chosen as active */ -+ -+ data = PA_DEVICE_PORT_DATA(u->sink->active_port); -+ u->mixer_path = data->path; -+ -+ pa_alsa_path_select(data->path, data->setting, u->mixer_handle, u->sink->muted); -+ } else { -+ pa_alsa_ucm_port_data *data; - -- data = PA_DEVICE_PORT_DATA(u->sink->active_port); -- u->mixer_path = data->path; -+ /* First activate the port on the UCM side */ -+ if (pa_alsa_ucm_set_port(u->ucm_context, u->sink->active_port, true) < 0) -+ return -1; - -- pa_alsa_path_select(data->path, data->setting, u->mixer_handle, u->sink->muted); -+ data = PA_DEVICE_PORT_DATA(u->sink->active_port); - -+ /* Now activate volume controls, if any */ -+ if (data->path) { -+ u->mixer_path = data->path; -+ pa_alsa_path_select(u->mixer_path, NULL, u->mixer_handle, u->sink->muted); -+ } -+ } - } else { - - if (!u->mixer_path && u->mixer_path_set) -@@ -2135,7 +2175,6 @@ static int setup_mixer(struct userdata *u, bool ignore_dB) { - /* Hmm, we have only a single path, then let's activate it */ - - pa_alsa_path_select(u->mixer_path, u->mixer_path->settings, u->mixer_handle, u->sink->muted); -- - } else - return 0; - } -@@ -2466,8 +2505,7 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca - /* ALSA might tweak the sample spec, so recalculate the frame size */ - frame_size = pa_frame_size(&ss); - -- if (!u->ucm_context) -- find_mixer(u, mapping, pa_modargs_get_value(ma, "control", NULL), ignore_dB); -+ find_mixer(u, mapping, pa_modargs_get_value(ma, "control", NULL), ignore_dB); - - pa_sink_new_data_init(&data); - data.driver = driver; -@@ -2524,7 +2562,7 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca - } - - if (u->ucm_context) -- pa_alsa_ucm_add_ports(&data.ports, data.proplist, u->ucm_context, true, card); -+ pa_alsa_ucm_add_ports(&data.ports, data.proplist, u->ucm_context, true, card, u->pcm_handle, ignore_dB); - else if (u->mixer_path_set) - pa_alsa_add_ports(&data, u->mixer_path_set, card); - -@@ -2598,10 +2636,7 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca - if (update_sw_params(u, false) < 0) - goto fail; - -- if (u->ucm_context) { -- if (u->sink->active_port && pa_alsa_ucm_set_port(u->ucm_context, u->sink->active_port, true) < 0) -- goto fail; -- } else if (setup_mixer(u, ignore_dB) < 0) -+ if (setup_mixer(u, ignore_dB) < 0) - goto fail; - - pa_alsa_dump(PA_LOG_DEBUG, u->pcm_handle); -@@ -2725,7 +2760,8 @@ static void userdata_free(struct userdata *u) { - if (u->mixer_fdl) - pa_alsa_fdlist_free(u->mixer_fdl); - -- if (u->mixer_path && !u->mixer_path_set) -+ /* Only free the mixer_path if the sink owns it */ -+ if (u->mixer_path && !u->mixer_path_set && !u->ucm_context) - pa_alsa_path_free(u->mixer_path); - - if (u->mixer_handle) -diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c -index c8bf649e1730..657ed5aeda11 100644 ---- a/src/modules/alsa/alsa-source.c -+++ b/src/modules/alsa/alsa-source.c -@@ -1469,7 +1469,7 @@ static void source_set_mute_cb(pa_source *s) { - static void mixer_volume_init(struct userdata *u) { - pa_assert(u); - -- if (!u->mixer_path->has_volume) { -+ if (!u->mixer_path || !u->mixer_path->has_volume) { - pa_source_set_write_volume_callback(u->source, NULL); - pa_source_set_get_volume_callback(u->source, NULL); - pa_source_set_set_volume_callback(u->source, NULL); -@@ -1504,7 +1504,7 @@ static void mixer_volume_init(struct userdata *u) { - pa_log_info("Using hardware volume control. Hardware dB scale %s.", u->mixer_path->has_dB ? "supported" : "not supported"); - } - -- if (!u->mixer_path->has_mute) { -+ if (!u->mixer_path || !u->mixer_path->has_mute) { - pa_source_set_get_mute_callback(u->source, NULL); - pa_source_set_set_mute_callback(u->source, NULL); - pa_log_info("Driver does not support hardware mute control, falling back to software mute control."); -@@ -1517,11 +1517,31 @@ static void mixer_volume_init(struct userdata *u) { - - static int source_set_port_ucm_cb(pa_source *s, pa_device_port *p) { - struct userdata *u = s->userdata; -+ pa_alsa_ucm_port_data *data; -+ -+ data = PA_DEVICE_PORT_DATA(p); - - pa_assert(u); - pa_assert(p); - pa_assert(u->ucm_context); - -+ u->mixer_path = data->path; -+ mixer_volume_init(u); -+ -+ if (u->mixer_path) { -+ pa_alsa_path_select(u->mixer_path, NULL, u->mixer_handle, s->muted); -+ -+ if (s->set_mute) -+ s->set_mute(s); -+ if (s->flags & PA_SOURCE_DEFERRED_VOLUME) { -+ if (s->write_volume) -+ s->write_volume(s); -+ } else { -+ if (s->set_volume) -+ s->set_volume(s); -+ } -+ } -+ - return pa_alsa_ucm_set_port(u->ucm_context, p, false); - } - -@@ -1785,6 +1805,11 @@ static void find_mixer(struct userdata *u, pa_alsa_mapping *mapping, const char - return; - } - -+ if (u->ucm_context) { -+ /* We just want to open the device */ -+ return; -+ } -+ - if (element) { - - if (!(u->mixer_path = pa_alsa_path_synthesize(element, PA_ALSA_DIRECTION_INPUT))) -@@ -1822,16 +1847,31 @@ static int setup_mixer(struct userdata *u, bool ignore_dB) { - return 0; - - if (u->source->active_port) { -- pa_alsa_port_data *data; -+ if (!u->ucm_context) { -+ pa_alsa_port_data *data; - -- /* We have a list of supported paths, so let's activate the -- * one that has been chosen as active */ -+ /* We have a list of supported paths, so let's activate the -+ * one that has been chosen as active */ - -- data = PA_DEVICE_PORT_DATA(u->source->active_port); -- u->mixer_path = data->path; -+ data = PA_DEVICE_PORT_DATA(u->source->active_port); -+ u->mixer_path = data->path; - -- pa_alsa_path_select(data->path, data->setting, u->mixer_handle, u->source->muted); -+ pa_alsa_path_select(data->path, data->setting, u->mixer_handle, u->source->muted); -+ } else { -+ pa_alsa_ucm_port_data *data; -+ -+ /* First activate the port on the UCM side */ -+ if (pa_alsa_ucm_set_port(u->ucm_context, u->source->active_port, false) < 0) -+ return -1; - -+ data = PA_DEVICE_PORT_DATA(u->source->active_port); -+ -+ /* Now activate volume controls, if any */ -+ if (data->path) { -+ u->mixer_path = data->path; -+ pa_alsa_path_select(u->mixer_path, NULL, u->mixer_handle, u->source->muted); -+ } -+ } - } else { - - if (!u->mixer_path && u->mixer_path_set) -@@ -2152,8 +2192,7 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p - /* ALSA might tweak the sample spec, so recalculate the frame size */ - frame_size = pa_frame_size(&ss); - -- if (!u->ucm_context) -- find_mixer(u, mapping, pa_modargs_get_value(ma, "control", NULL), ignore_dB); -+ find_mixer(u, mapping, pa_modargs_get_value(ma, "control", NULL), ignore_dB); - - pa_source_new_data_init(&data); - data.driver = driver; -@@ -2210,7 +2249,7 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p - } - - if (u->ucm_context) -- pa_alsa_ucm_add_ports(&data.ports, data.proplist, u->ucm_context, false, card); -+ pa_alsa_ucm_add_ports(&data.ports, data.proplist, u->ucm_context, false, card, u->pcm_handle, ignore_dB); - else if (u->mixer_path_set) - pa_alsa_add_ports(&data, u->mixer_path_set, card); - -@@ -2276,10 +2315,7 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p - if (update_sw_params(u) < 0) - goto fail; - -- if (u->ucm_context) { -- if (u->source->active_port && pa_alsa_ucm_set_port(u->ucm_context, u->source->active_port, false) < 0) -- goto fail; -- } else if (setup_mixer(u, ignore_dB) < 0) -+ if (setup_mixer(u, ignore_dB) < 0) - goto fail; - - pa_alsa_dump(PA_LOG_DEBUG, u->pcm_handle); -@@ -2368,7 +2404,7 @@ static void userdata_free(struct userdata *u) { - if (u->mixer_fdl) - pa_alsa_fdlist_free(u->mixer_fdl); - -- if (u->mixer_path && !u->mixer_path_set) -+ if (u->mixer_path && !u->mixer_path_set && !u->ucm_context) - pa_alsa_path_free(u->mixer_path); - - if (u->mixer_handle) -diff --git a/src/modules/alsa/alsa-ucm.c b/src/modules/alsa/alsa-ucm.c -index 14056825a25f..349a59566200 100644 ---- a/src/modules/alsa/alsa-ucm.c -+++ b/src/modules/alsa/alsa-ucm.c -@@ -81,19 +81,11 @@ static void device_add_hw_mute_jack(pa_alsa_ucm_device *device, pa_alsa_jack *ja - - static pa_alsa_ucm_device *verb_find_device(pa_alsa_ucm_verb *verb, const char *device_name); - --struct ucm_port { -- pa_alsa_ucm_config *ucm; -- pa_device_port *core_port; -- -- /* A single port will be associated with multiple devices if it represents -- * a combination of devices. */ -- pa_dynarray *devices; /* pa_alsa_ucm_device */ --}; - --static void ucm_port_init(struct ucm_port *port, pa_alsa_ucm_config *ucm, pa_device_port *core_port, -- pa_alsa_ucm_device **devices, unsigned n_devices); --static void ucm_port_free(pa_device_port *port); --static void ucm_port_update_available(struct ucm_port *port); -+static void ucm_port_data_init(pa_alsa_ucm_port_data *port, pa_alsa_ucm_config *ucm, pa_device_port *core_port, -+ pa_alsa_ucm_device **devices, unsigned n_devices); -+static void ucm_port_data_free(pa_device_port *port); -+static void ucm_port_update_available(pa_alsa_ucm_port_data *port); - - static struct ucm_items item[] = { - {"PlaybackPCM", PA_ALSA_PROP_UCM_SINK}, -@@ -303,6 +295,18 @@ static int ucm_get_device_property( - else - pa_log_debug("UCM playback priority %s for device %s error", value, device_name); - } -+ -+ value = pa_proplist_gets(device->proplist, PA_ALSA_PROP_UCM_PLAYBACK_VOLUME); -+ if (value) { -+ /* Try to get the simple control name, and failing that, just use the name as is */ -+ char *selem; -+ -+ if (!(selem = pa_str_strip_suffix(value, " Playback Volume"))) -+ if (!(selem = pa_str_strip_suffix(value, " Volume"))) -+ selem = pa_xstrdup(value); -+ -+ pa_hashmap_put(device->playback_volumes, pa_xstrdup(pa_proplist_gets(verb->proplist, PA_ALSA_PROP_UCM_NAME)), selem); -+ } - } - - if (device->capture_channels) { /* source device */ -@@ -324,6 +328,18 @@ static int ucm_get_device_property( - else - pa_log_debug("UCM capture priority %s for device %s error", value, device_name); - } -+ -+ value = pa_proplist_gets(device->proplist, PA_ALSA_PROP_UCM_CAPTURE_VOLUME); -+ if (value) { -+ /* Try to get the simple control name, and failing that, just use the name as is */ -+ char *selem; -+ -+ if (!(selem = pa_str_strip_suffix(value, " Capture Volume"))) -+ if (!(selem = pa_str_strip_suffix(value, " Volume"))) -+ selem = pa_xstrdup(value); -+ -+ pa_hashmap_put(device->capture_volumes, pa_xstrdup(pa_proplist_gets(verb->proplist, PA_ALSA_PROP_UCM_NAME)), selem); -+ } - } - - if (PA_UCM_PLAYBACK_PRIORITY_UNSET(device) || PA_UCM_CAPTURE_PRIORITY_UNSET(device)) { -@@ -427,6 +443,11 @@ static int ucm_get_devices(pa_alsa_ucm_verb *verb, snd_use_case_mgr_t *uc_mgr) { - d->hw_mute_jacks = pa_dynarray_new(NULL); - d->available = PA_AVAILABLE_UNKNOWN; - -+ d->playback_volumes = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, pa_xfree, -+ pa_xfree); -+ d->capture_volumes = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, pa_xfree, -+ pa_xfree); -+ - PA_LLIST_PREPEND(pa_alsa_ucm_device, verb->devices, d); - } - -@@ -707,6 +728,46 @@ static int pa_alsa_ucm_device_cmp(const void *a, const void *b) { - return strcmp(pa_proplist_gets(d1->proplist, PA_ALSA_PROP_UCM_NAME), pa_proplist_gets(d2->proplist, PA_ALSA_PROP_UCM_NAME)); - } - -+static void probe_volumes(pa_hashmap *hash, snd_pcm_t *pcm_handle, bool ignore_dB) { -+ pa_device_port *port; -+ pa_alsa_path *path; -+ pa_alsa_ucm_port_data *data; -+ snd_mixer_t *mixer_handle; -+ const char *profile; -+ void *state, *state2; -+ -+ if (!(mixer_handle = pa_alsa_open_mixer_for_pcm(pcm_handle, NULL))) { -+ pa_log_error("Failed to find a working mixer device."); -+ goto fail; -+ } -+ -+ PA_HASHMAP_FOREACH(port, hash, state) { -+ data = PA_DEVICE_PORT_DATA(port); -+ -+ PA_HASHMAP_FOREACH_KV(profile, path, data->paths, state2) { -+ if (pa_alsa_path_probe(path, NULL, mixer_handle, ignore_dB) < 0) { -+ pa_log_warn("Could not probe path: %s, using s/w volume", data->path->name); -+ pa_hashmap_remove(data->paths, profile); -+ } else if (!path->has_volume) { -+ pa_log_warn("Path %s is not a volume control", data->path->name); -+ pa_hashmap_remove(data->paths, profile); -+ } else -+ pa_log_debug("Set up h/w volume using '%s' for %s:%s", path->name, profile, port->name); -+ } -+ } -+ -+ snd_mixer_close(mixer_handle); -+ -+ return; -+ -+fail: -+ /* We could not probe the paths we created. Free them and revert to software volumes. */ -+ PA_HASHMAP_FOREACH(port, hash, state) { -+ data = PA_DEVICE_PORT_DATA(port); -+ pa_hashmap_remove_all(data->paths); -+ } -+} -+ - static void ucm_add_port_combination( - pa_hashmap *hash, - pa_alsa_ucm_mapping_context *context, -@@ -724,7 +785,10 @@ static void ucm_add_port_combination( - char *name, *desc; - const char *dev_name; - const char *direction; -+ const char *profile, *volume_element; - pa_alsa_ucm_device *sorted[num], *dev; -+ pa_alsa_ucm_port_data *data; -+ void *state; - - for (i = 0; i < num; i++) - sorted[i] = pdevices[i]; -@@ -772,8 +836,6 @@ static void ucm_add_port_combination( - - port = pa_hashmap_get(ports, name); - if (!port) { -- struct ucm_port *ucm_port; -- - pa_device_port_new_data port_data; - - pa_device_port_new_data_init(&port_data); -@@ -781,17 +843,33 @@ static void ucm_add_port_combination( - pa_device_port_new_data_set_description(&port_data, desc); - pa_device_port_new_data_set_direction(&port_data, is_sink ? PA_DIRECTION_OUTPUT : PA_DIRECTION_INPUT); - -- port = pa_device_port_new(core, &port_data, sizeof(struct ucm_port)); -- port->impl_free = ucm_port_free; -+ port = pa_device_port_new(core, &port_data, sizeof(pa_alsa_ucm_port_data)); - pa_device_port_new_data_done(&port_data); - -- ucm_port = PA_DEVICE_PORT_DATA(port); -- ucm_port_init(ucm_port, context->ucm, port, pdevices, num); -+ data = PA_DEVICE_PORT_DATA(port); -+ ucm_port_data_init(data, context->ucm, port, pdevices, num); -+ port->impl_free = ucm_port_data_free; - - pa_hashmap_put(ports, port->name, port); - pa_log_debug("Add port %s: %s", port->name, port->description); - } - -+ if (num == 1) { -+ /* To keep things simple and not worry about stacking controls, we only support hardware volumes on non-combination -+ * ports. */ -+ data = PA_DEVICE_PORT_DATA(port); -+ -+ PA_HASHMAP_FOREACH_KV(profile, volume_element, is_sink ? dev->playback_volumes : dev->capture_volumes, state) { -+ pa_alsa_path *path = pa_alsa_path_synthesize(volume_element, -+ is_sink ? PA_ALSA_DIRECTION_OUTPUT : PA_ALSA_DIRECTION_INPUT); -+ -+ if (!path) -+ pa_log_warn("Failed to set up volume control: %s", volume_element); -+ else -+ pa_hashmap_put(data->paths, pa_xstrdup(profile), path); -+ } -+ } -+ - port->priority = priority; - - pa_xfree(name); -@@ -971,7 +1049,9 @@ void pa_alsa_ucm_add_ports( - pa_proplist *proplist, - pa_alsa_ucm_mapping_context *context, - bool is_sink, -- pa_card *card) { -+ pa_card *card, -+ snd_pcm_t *pcm_handle, -+ bool ignore_dB) { - - uint32_t idx; - char *merged_roles; -@@ -986,6 +1066,9 @@ void pa_alsa_ucm_add_ports( - /* add ports first */ - pa_alsa_ucm_add_ports_combination(*p, context, is_sink, card->ports, NULL, card->core); - -+ /* now set up volume paths if any */ -+ probe_volumes(*p, pcm_handle, ignore_dB); -+ - /* then set property PA_PROP_DEVICE_INTENDED_ROLES */ - merged_roles = pa_xstrdup(pa_proplist_gets(proplist, PA_PROP_DEVICE_INTENDED_ROLES)); - PA_IDXSET_FOREACH(dev, context->ucm_devices, idx) { -@@ -1010,10 +1093,13 @@ void pa_alsa_ucm_add_ports( - } - - /* Change UCM verb and device to match selected card profile */ --int pa_alsa_ucm_set_profile(pa_alsa_ucm_config *ucm, const char *new_profile, const char *old_profile) { -+int pa_alsa_ucm_set_profile(pa_alsa_ucm_config *ucm, pa_card *card, const char *new_profile, const char *old_profile) { - int ret = 0; - const char *profile; - pa_alsa_ucm_verb *verb; -+ pa_device_port *port; -+ pa_alsa_ucm_port_data *data; -+ void *state; - - if (new_profile == old_profile) - return ret; -@@ -1042,6 +1128,12 @@ int pa_alsa_ucm_set_profile(pa_alsa_ucm_config *ucm, const char *new_profile, co - } - } - -+ /* select volume controls on ports */ -+ PA_HASHMAP_FOREACH(port, card->ports, state) { -+ data = PA_DEVICE_PORT_DATA(port); -+ data->path = pa_hashmap_get(data->paths, new_profile); -+ } -+ - return ret; - } - -@@ -1650,11 +1742,18 @@ static void free_verb(pa_alsa_ucm_verb *verb) { - if (di->ucm_ports) - pa_dynarray_free(di->ucm_ports); - -+ if (di->playback_volumes) -+ pa_hashmap_free(di->playback_volumes); -+ if (di->capture_volumes) -+ pa_hashmap_free(di->capture_volumes); -+ - pa_proplist_free(di->proplist); -+ - if (di->conflicting_devices) - pa_idxset_free(di->conflicting_devices, NULL); - if (di->supported_devices) - pa_idxset_free(di->supported_devices, NULL); -+ - pa_xfree(di); - } - -@@ -1785,7 +1884,7 @@ void pa_alsa_ucm_roled_stream_end(pa_alsa_ucm_config *ucm, const char *role, pa_ - } - } - --static void device_add_ucm_port(pa_alsa_ucm_device *device, struct ucm_port *port) { -+static void device_add_ucm_port(pa_alsa_ucm_device *device, pa_alsa_ucm_port_data *port) { - pa_assert(device); - pa_assert(port); - -@@ -1813,7 +1912,7 @@ static void device_add_hw_mute_jack(pa_alsa_ucm_device *device, pa_alsa_jack *ja - } - - static void device_set_available(pa_alsa_ucm_device *device, pa_available_t available) { -- struct ucm_port *port; -+ pa_alsa_ucm_port_data *port; - unsigned idx; - - pa_assert(device); -@@ -1847,8 +1946,8 @@ void pa_alsa_ucm_device_update_available(pa_alsa_ucm_device *device) { - device_set_available(device, available); - } - --static void ucm_port_init(struct ucm_port *port, pa_alsa_ucm_config *ucm, pa_device_port *core_port, -- pa_alsa_ucm_device **devices, unsigned n_devices) { -+static void ucm_port_data_init(pa_alsa_ucm_port_data *port, pa_alsa_ucm_config *ucm, pa_device_port *core_port, -+ pa_alsa_ucm_device **devices, unsigned n_devices) { - unsigned i; - - pa_assert(ucm); -@@ -1864,11 +1963,14 @@ static void ucm_port_init(struct ucm_port *port, pa_alsa_ucm_config *ucm, pa_dev - device_add_ucm_port(devices[i], port); - } - -+ port->paths = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, pa_xfree, -+ (pa_free_cb_t) pa_alsa_path_free); -+ - ucm_port_update_available(port); - } - --static void ucm_port_free(pa_device_port *port) { -- struct ucm_port *ucm_port; -+static void ucm_port_data_free(pa_device_port *port) { -+ pa_alsa_ucm_port_data *ucm_port; - - pa_assert(port); - -@@ -1876,9 +1978,12 @@ static void ucm_port_free(pa_device_port *port) { - - if (ucm_port->devices) - pa_dynarray_free(ucm_port->devices); -+ -+ if (ucm_port->paths) -+ pa_hashmap_free(ucm_port->paths); - } - --static void ucm_port_update_available(struct ucm_port *port) { -+static void ucm_port_update_available(pa_alsa_ucm_port_data *port) { - pa_alsa_ucm_device *device; - unsigned idx; - pa_available_t available = PA_AVAILABLE_YES; -@@ -1910,7 +2015,7 @@ pa_alsa_profile_set* pa_alsa_ucm_add_profile_set(pa_alsa_ucm_config *ucm, pa_cha - return NULL; - } - --int pa_alsa_ucm_set_profile(pa_alsa_ucm_config *ucm, const char *new_profile, const char *old_profile) { -+int pa_alsa_ucm_set_profile(pa_alsa_ucm_config *ucm, pa_card *card, const char *new_profile, const char *old_profile) { - return -1; - } - -@@ -1923,7 +2028,9 @@ void pa_alsa_ucm_add_ports( - pa_proplist *proplist, - pa_alsa_ucm_mapping_context *context, - bool is_sink, -- pa_card *card) { -+ pa_card *card, -+ snd_pcm_t *pcm_handle, -+ bool ignore_dB) { - } - - void pa_alsa_ucm_add_ports_combination( -diff --git a/src/modules/alsa/alsa-ucm.h b/src/modules/alsa/alsa-ucm.h -index 4feb8c0bfc3f..2e39a09a51f3 100644 ---- a/src/modules/alsa/alsa-ucm.h -+++ b/src/modules/alsa/alsa-ucm.h -@@ -113,10 +113,11 @@ typedef struct pa_alsa_ucm_modifier pa_alsa_ucm_modifier; - typedef struct pa_alsa_ucm_device pa_alsa_ucm_device; - typedef struct pa_alsa_ucm_config pa_alsa_ucm_config; - typedef struct pa_alsa_ucm_mapping_context pa_alsa_ucm_mapping_context; -+typedef struct pa_alsa_ucm_port_data pa_alsa_ucm_port_data; - - int pa_alsa_ucm_query_profiles(pa_alsa_ucm_config *ucm, int card_index); - pa_alsa_profile_set* pa_alsa_ucm_add_profile_set(pa_alsa_ucm_config *ucm, pa_channel_map *default_channel_map); --int pa_alsa_ucm_set_profile(pa_alsa_ucm_config *ucm, const char *new_profile, const char *old_profile); -+int pa_alsa_ucm_set_profile(pa_alsa_ucm_config *ucm, pa_card *card, const char *new_profile, const char *old_profile); - - int pa_alsa_ucm_get_verb(snd_use_case_mgr_t *uc_mgr, const char *verb_name, const char *verb_desc, pa_alsa_ucm_verb **p_verb); - -@@ -125,7 +126,9 @@ void pa_alsa_ucm_add_ports( - pa_proplist *proplist, - pa_alsa_ucm_mapping_context *context, - bool is_sink, -- pa_card *card); -+ pa_card *card, -+ snd_pcm_t *pcm_handle, -+ bool ignore_dB); - void pa_alsa_ucm_add_ports_combination( - pa_hashmap *hash, - pa_alsa_ucm_mapping_context *context, -@@ -157,6 +160,11 @@ struct pa_alsa_ucm_device { - unsigned playback_channels; - unsigned capture_channels; - -+ /* These may be different per verb, so we store this as a hashmap of verb -> volume_control. We might eventually want to -+ * make this a hashmap of verb -> per-verb-device-properties-struct. */ -+ pa_hashmap *playback_volumes; -+ pa_hashmap *capture_volumes; -+ - pa_alsa_mapping *playback_mapping; - pa_alsa_mapping *capture_mapping; - -@@ -224,4 +232,18 @@ struct pa_alsa_ucm_mapping_context { - pa_idxset *ucm_modifiers; - }; - -+struct pa_alsa_ucm_port_data { -+ pa_alsa_ucm_config *ucm; -+ pa_device_port *core_port; -+ -+ /* A single port will be associated with multiple devices if it represents -+ * a combination of devices. */ -+ pa_dynarray *devices; /* pa_alsa_ucm_device */ -+ -+ /* profile -> pa_alsa_path for volume control */ -+ pa_hashmap *paths; -+ /* Current path, set when activating profile */ -+ pa_alsa_path *path; -+}; -+ - #endif -diff --git a/src/modules/alsa/module-alsa-card.c b/src/modules/alsa/module-alsa-card.c -index 1e1090fe024e..e2a86bc1c68d 100644 ---- a/src/modules/alsa/module-alsa-card.c -+++ b/src/modules/alsa/module-alsa-card.c -@@ -241,7 +241,7 @@ static int card_set_profile(pa_card *c, pa_card_profile *new_profile) { - - /* if UCM is available for this card then update the verb */ - if (u->use_ucm) { -- if (pa_alsa_ucm_set_profile(&u->ucm, nd->profile ? nd->profile->name : NULL, -+ if (pa_alsa_ucm_set_profile(&u->ucm, c, nd->profile ? nd->profile->name : NULL, - od->profile ? od->profile->name : NULL) < 0) { - ret = -1; - goto finish; -@@ -294,7 +294,7 @@ static void init_profile(struct userdata *u) { - - if (d->profile && u->use_ucm) { - /* Set initial verb */ -- if (pa_alsa_ucm_set_profile(ucm, d->profile->name, NULL) < 0) { -+ if (pa_alsa_ucm_set_profile(ucm, u->card, d->profile->name, NULL) < 0) { - pa_log("Failed to set ucm profile %s", d->profile->name); - return; - } -diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c -index f5ec67b8f3fc..174987e4afda 100644 ---- a/src/pulsecore/core-util.c -+++ b/src/pulsecore/core-util.c -@@ -2893,6 +2893,32 @@ bool pa_str_in_list_spaces(const char *haystack, const char *needle) { - return false; - } - -+char* pa_str_strip_suffix(const char *str, const char *suffix) { -+ size_t str_l, suf_l, prefix; -+ char *ret; -+ -+ pa_assert(str); -+ pa_assert(suffix); -+ -+ str_l = strlen(str); -+ suf_l = strlen(suffix); -+ -+ if (str_l < suf_l) -+ return NULL; -+ -+ prefix = str_l - suf_l; -+ -+ if (!pa_streq(&str[prefix], suffix)) -+ return NULL; -+ -+ ret = pa_xmalloc(prefix + 1); -+ -+ strncpy(ret, str, prefix); -+ ret[prefix] = '\0'; -+ -+ return ret; -+} -+ - char *pa_get_user_name_malloc(void) { - ssize_t k; - char *u; -diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h -index d1c4ae1c49aa..9440af9172ca 100644 ---- a/src/pulsecore/core-util.h -+++ b/src/pulsecore/core-util.h -@@ -232,6 +232,8 @@ static inline bool pa_safe_streq(const char *a, const char *b) { - bool pa_str_in_list_spaces(const char *needle, const char *haystack); - bool pa_str_in_list(const char *haystack, const char *delimiters, const char *needle); - -+char* pa_str_strip_suffix(const char *str, const char *suffix); -+ - char *pa_get_host_name_malloc(void); - char *pa_get_user_name_malloc(void); - --- -2.16.4 - diff --git a/0011-alsa-ucm-Fix-volume-control-based-on-review.patch b/0011-alsa-ucm-Fix-volume-control-based-on-review.patch deleted file mode 100644 index e4f912b..0000000 --- a/0011-alsa-ucm-Fix-volume-control-based-on-review.patch +++ /dev/null @@ -1,242 +0,0 @@ -From 9acacd9ba3b9f4df0957e9ddaacbcee00396175c Mon Sep 17 00:00:00 2001 -From: Jaska Uimonen -Date: Tue, 1 Oct 2019 18:34:17 +0300 -Subject: [PATCH] alsa-ucm: Fix volume control based on review - -- sync mixer logic added -- mixer path creation, empty set in mapping creation, paths added in path creation -- path creation moved inside new port creation as it might be called twice otherwise -- some comments added ---- - src/modules/alsa/alsa-sink.c | 31 ++++++++-------------------- - src/modules/alsa/alsa-source.c | 29 ++++++++------------------ - src/modules/alsa/alsa-ucm.c | 47 +++++++++++++++++++++++++++++------------- - src/modules/alsa/alsa-ucm.h | 2 +- - 4 files changed, 52 insertions(+), 57 deletions(-) - -diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c -index 08d4d1f38b80..0a5c92529af3 100644 ---- a/src/modules/alsa/alsa-sink.c -+++ b/src/modules/alsa/alsa-sink.c -@@ -1266,7 +1266,7 @@ static void sync_mixer(struct userdata *u, pa_device_port *port) { - - /* port may be NULL, because if we use a synthesized mixer path, then the - * sink has no ports. */ -- if (port) { -+ if (port && !u->ucm_context) { - pa_alsa_port_data *data; - - data = PA_DEVICE_PORT_DATA(port); -@@ -1648,28 +1648,19 @@ static int sink_set_port_ucm_cb(pa_sink *s, pa_device_port *p) { - struct userdata *u = s->userdata; - pa_alsa_ucm_port_data *data; - -- data = PA_DEVICE_PORT_DATA(p); -- - pa_assert(u); - pa_assert(p); -+ pa_assert(u->mixer_handle); - pa_assert(u->ucm_context); - -- u->mixer_path = data->path; -+ data = PA_DEVICE_PORT_DATA(p); -+ pa_assert_se(u->mixer_path = data->path); - mixer_volume_init(u); - -- if (u->mixer_path) { -- pa_alsa_path_select(u->mixer_path, NULL, u->mixer_handle, s->muted); -- -- if (s->set_mute) -- s->set_mute(s); -- if (s->flags & PA_SINK_DEFERRED_VOLUME) { -- if (s->write_volume) -- s->write_volume(s); -- } else { -- if (s->set_volume) -- s->set_volume(s); -- } -- } -+ if (s->flags & PA_SINK_DEFERRED_VOLUME) -+ pa_asyncmsgq_send(u->sink->asyncmsgq, PA_MSGOBJECT(u->sink), SINK_MESSAGE_SYNC_MIXER, p, 0, NULL); -+ else -+ sync_mixer(u, p); - - return pa_alsa_ucm_set_port(u->ucm_context, p, true); - } -@@ -2091,6 +2082,7 @@ static void set_sink_name(pa_sink_new_data *data, pa_modargs *ma, const char *de - } - - static void find_mixer(struct userdata *u, pa_alsa_mapping *mapping, const char *element, bool ignore_dB) { -+ - if (!mapping && !element) - return; - -@@ -2099,11 +2091,6 @@ static void find_mixer(struct userdata *u, pa_alsa_mapping *mapping, const char - return; - } - -- if (u->ucm_context) { -- /* We just want to open the device */ -- return; -- } -- - if (element) { - - if (!(u->mixer_path = pa_alsa_path_synthesize(element, PA_ALSA_DIRECTION_OUTPUT))) -diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c -index 657ed5aeda11..d186101720b8 100644 ---- a/src/modules/alsa/alsa-source.c -+++ b/src/modules/alsa/alsa-source.c -@@ -1137,7 +1137,7 @@ static void sync_mixer(struct userdata *u, pa_device_port *port) { - - /* port may be NULL, because if we use a synthesized mixer path, then the - * source has no ports. */ -- if (port) { -+ if (port && !u->ucm_context) { - pa_alsa_port_data *data; - - data = PA_DEVICE_PORT_DATA(port); -@@ -1523,24 +1523,17 @@ static int source_set_port_ucm_cb(pa_source *s, pa_device_port *p) { - - pa_assert(u); - pa_assert(p); -+ pa_assert(u->mixer_handle); - pa_assert(u->ucm_context); - -- u->mixer_path = data->path; -+ data = PA_DEVICE_PORT_DATA(p); -+ pa_assert_se(u->mixer_path = data->path); - mixer_volume_init(u); - -- if (u->mixer_path) { -- pa_alsa_path_select(u->mixer_path, NULL, u->mixer_handle, s->muted); -- -- if (s->set_mute) -- s->set_mute(s); -- if (s->flags & PA_SOURCE_DEFERRED_VOLUME) { -- if (s->write_volume) -- s->write_volume(s); -- } else { -- if (s->set_volume) -- s->set_volume(s); -- } -- } -+ if (s->flags & PA_SOURCE_DEFERRED_VOLUME) -+ pa_asyncmsgq_send(u->source->asyncmsgq, PA_MSGOBJECT(u->source), SOURCE_MESSAGE_SYNC_MIXER, p, 0, NULL); -+ else -+ sync_mixer(u, p); - - return pa_alsa_ucm_set_port(u->ucm_context, p, false); - } -@@ -1805,11 +1798,6 @@ static void find_mixer(struct userdata *u, pa_alsa_mapping *mapping, const char - return; - } - -- if (u->ucm_context) { -- /* We just want to open the device */ -- return; -- } -- - if (element) { - - if (!(u->mixer_path = pa_alsa_path_synthesize(element, PA_ALSA_DIRECTION_INPUT))) -@@ -2404,6 +2392,7 @@ static void userdata_free(struct userdata *u) { - if (u->mixer_fdl) - pa_alsa_fdlist_free(u->mixer_fdl); - -+ /* Only free the mixer_path if the sink owns it */ - if (u->mixer_path && !u->mixer_path_set && !u->ucm_context) - pa_alsa_path_free(u->mixer_path); - -diff --git a/src/modules/alsa/alsa-ucm.c b/src/modules/alsa/alsa-ucm.c -index 349a59566200..a812b52f449e 100644 ---- a/src/modules/alsa/alsa-ucm.c -+++ b/src/modules/alsa/alsa-ucm.c -@@ -852,21 +852,29 @@ static void ucm_add_port_combination( - - pa_hashmap_put(ports, port->name, port); - pa_log_debug("Add port %s: %s", port->name, port->description); -- } -- -- if (num == 1) { -- /* To keep things simple and not worry about stacking controls, we only support hardware volumes on non-combination -- * ports. */ -- data = PA_DEVICE_PORT_DATA(port); - -- PA_HASHMAP_FOREACH_KV(profile, volume_element, is_sink ? dev->playback_volumes : dev->capture_volumes, state) { -- pa_alsa_path *path = pa_alsa_path_synthesize(volume_element, -- is_sink ? PA_ALSA_DIRECTION_OUTPUT : PA_ALSA_DIRECTION_INPUT); -- -- if (!path) -- pa_log_warn("Failed to set up volume control: %s", volume_element); -- else -- pa_hashmap_put(data->paths, pa_xstrdup(profile), path); -+ if (num == 1) { -+ /* To keep things simple and not worry about stacking controls, we only support hardware volumes on non-combination -+ * ports. */ -+ data = PA_DEVICE_PORT_DATA(port); -+ -+ PA_HASHMAP_FOREACH_KV(profile, volume_element, is_sink ? dev->playback_volumes : dev->capture_volumes, state) { -+ pa_alsa_path *path = pa_alsa_path_synthesize(volume_element, -+ is_sink ? PA_ALSA_DIRECTION_OUTPUT : PA_ALSA_DIRECTION_INPUT); -+ -+ if (!path) -+ pa_log_warn("Failed to set up volume control: %s", volume_element); -+ else { -+ pa_hashmap_put(data->paths, pa_xstrdup(profile), path); -+ -+ /* Add path also to already created empty path set */ -+ dev = sorted[0]; -+ if (is_sink) -+ pa_hashmap_put(dev->playback_mapping->output_path_set->paths, pa_xstrdup(volume_element), path); -+ else -+ pa_hashmap_put(dev->capture_mapping->input_path_set->paths, pa_xstrdup(volume_element), path); -+ } -+ } - } - } - -@@ -1185,16 +1193,27 @@ int pa_alsa_ucm_set_port(pa_alsa_ucm_mapping_context *context, pa_device_port *p - - static void ucm_add_mapping(pa_alsa_profile *p, pa_alsa_mapping *m) { - -+ pa_alsa_path_set *ps; -+ -+ /* create empty path set for the future path additions */ -+ ps = pa_xnew0(pa_alsa_path_set, 1); -+ ps->direction = m->direction; -+ ps->paths = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); -+ - switch (m->direction) { - case PA_ALSA_DIRECTION_ANY: - pa_idxset_put(p->output_mappings, m, NULL); - pa_idxset_put(p->input_mappings, m, NULL); -+ m->output_path_set = ps; -+ m->input_path_set = ps; - break; - case PA_ALSA_DIRECTION_OUTPUT: - pa_idxset_put(p->output_mappings, m, NULL); -+ m->output_path_set = ps; - break; - case PA_ALSA_DIRECTION_INPUT: - pa_idxset_put(p->input_mappings, m, NULL); -+ m->input_path_set = ps; - break; - } - } -diff --git a/src/modules/alsa/alsa-ucm.h b/src/modules/alsa/alsa-ucm.h -index 2e39a09a51f3..d8507a83615c 100644 ---- a/src/modules/alsa/alsa-ucm.h -+++ b/src/modules/alsa/alsa-ucm.h -@@ -240,7 +240,7 @@ struct pa_alsa_ucm_port_data { - * a combination of devices. */ - pa_dynarray *devices; /* pa_alsa_ucm_device */ - -- /* profile -> pa_alsa_path for volume control */ -+ /* profile name -> pa_alsa_path for volume control */ - pa_hashmap *paths; - /* Current path, set when activating profile */ - pa_alsa_path *path; --- -2.16.4 - diff --git a/0012-alsa-ucm-use-the-correct-mixer-identifiers-as-first.patch b/0012-alsa-ucm-use-the-correct-mixer-identifiers-as-first.patch deleted file mode 100644 index 7edbdde..0000000 --- a/0012-alsa-ucm-use-the-correct-mixer-identifiers-as-first.patch +++ /dev/null @@ -1,120 +0,0 @@ -From dc9dc70fcc1b06788d08b5e7997c9053a13cbce2 Mon Sep 17 00:00:00 2001 -From: Jaroslav Kysela -Date: Tue, 26 Nov 2019 10:54:15 +0100 -Subject: [PATCH] alsa-ucm: use the correct mixer identifiers as first - -The mixer identifiers should be used for snd_mixer_selem API. -Use them as first, then try to fallback to the raw control -identifiers. - -Signed-off-by: Jaroslav Kysela ---- - src/modules/alsa/alsa-ucm.c | 78 ++++++++++++++++++++++++++++++++------------- - 1 file changed, 56 insertions(+), 22 deletions(-) - -diff --git a/src/modules/alsa/alsa-ucm.c b/src/modules/alsa/alsa-ucm.c -index a812b52f449e..65ec6941e8de 100644 ---- a/src/modules/alsa/alsa-ucm.c -+++ b/src/modules/alsa/alsa-ucm.c -@@ -200,6 +200,50 @@ static void ucm_add_devices_to_idxset( - } - } - -+/* Get the volume identifier */ -+static char *ucm_get_mixer_id( -+ pa_alsa_ucm_device *device, -+ const char *mprop, -+ const char *cprop, -+ const char *cid) -+{ -+#if SND_LIB_VERSION >= 0x10201 -+ snd_ctl_elem_id_t *ctl; -+ int err; -+#endif -+ const char *value; -+ char *value2; -+ int index; -+ -+ value = pa_proplist_gets(device->proplist, mprop); -+ if (value) -+ return pa_xstrdup(value); -+ value = pa_proplist_gets(device->proplist, cprop); -+ if (value == NULL) -+ return NULL; -+#if SND_LIB_VERSION >= 0x10201 -+ snd_ctl_elem_id_alloca(&ctl); -+ err = snd_use_case_parse_ctl_elem_id(ctl, cid, value); -+ if (err < 0) -+ return NULL; -+ value = snd_ctl_elem_id_get_name(ctl); -+ index = snd_ctl_elem_id_get_index(ctl); -+#else -+#warning "Upgrade to alsa-lib 1.2.1!" -+ index = 0; -+#endif -+ if (!(value2 = pa_str_strip_suffix(value, " Playback Volume"))) -+ if (!(value2 = pa_str_strip_suffix(value, " Capture Volume"))) -+ if (!(value2 = pa_str_strip_suffix(value, " Volume"))) -+ value2 = pa_xstrdup(value); -+ if (index > 0) { -+ char *mix = pa_sprintf_malloc("'%s',%d", value2, index); -+ pa_xfree(value2); -+ return mix; -+ } -+ return value2; -+} -+ - /* Create a property list for this ucm device */ - static int ucm_get_device_property( - pa_alsa_ucm_device *device, -@@ -296,17 +340,12 @@ static int ucm_get_device_property( - pa_log_debug("UCM playback priority %s for device %s error", value, device_name); - } - -- value = pa_proplist_gets(device->proplist, PA_ALSA_PROP_UCM_PLAYBACK_VOLUME); -- if (value) { -- /* Try to get the simple control name, and failing that, just use the name as is */ -- char *selem; -- -- if (!(selem = pa_str_strip_suffix(value, " Playback Volume"))) -- if (!(selem = pa_str_strip_suffix(value, " Volume"))) -- selem = pa_xstrdup(value); -- -- pa_hashmap_put(device->playback_volumes, pa_xstrdup(pa_proplist_gets(verb->proplist, PA_ALSA_PROP_UCM_NAME)), selem); -- } -+ value = ucm_get_mixer_id(device, -+ PA_ALSA_PROP_UCM_PLAYBACK_MIXER_ELEM, -+ PA_ALSA_PROP_UCM_PLAYBACK_VOLUME, -+ "PlaybackVolume"); -+ if (value) -+ pa_hashmap_put(device->playback_volumes, pa_xstrdup(pa_proplist_gets(verb->proplist, PA_ALSA_PROP_UCM_NAME)), (void *)value); - } - - if (device->capture_channels) { /* source device */ -@@ -329,17 +368,12 @@ static int ucm_get_device_property( - pa_log_debug("UCM capture priority %s for device %s error", value, device_name); - } - -- value = pa_proplist_gets(device->proplist, PA_ALSA_PROP_UCM_CAPTURE_VOLUME); -- if (value) { -- /* Try to get the simple control name, and failing that, just use the name as is */ -- char *selem; -- -- if (!(selem = pa_str_strip_suffix(value, " Capture Volume"))) -- if (!(selem = pa_str_strip_suffix(value, " Volume"))) -- selem = pa_xstrdup(value); -- -- pa_hashmap_put(device->capture_volumes, pa_xstrdup(pa_proplist_gets(verb->proplist, PA_ALSA_PROP_UCM_NAME)), selem); -- } -+ value = ucm_get_mixer_id(device, -+ PA_ALSA_PROP_UCM_CAPTURE_MIXER_ELEM, -+ PA_ALSA_PROP_UCM_CAPTURE_VOLUME, -+ "CaptureVolume"); -+ if (value) -+ pa_hashmap_put(device->capture_volumes, pa_xstrdup(pa_proplist_gets(verb->proplist, PA_ALSA_PROP_UCM_NAME)), (void *)value); - } - - if (PA_UCM_PLAYBACK_PRIORITY_UNSET(device) || PA_UCM_CAPTURE_PRIORITY_UNSET(device)) { --- -2.16.4 - diff --git a/0013-alsa-ucm-add-support-for-master-volume.patch b/0013-alsa-ucm-add-support-for-master-volume.patch deleted file mode 100644 index 01df5ed..0000000 --- a/0013-alsa-ucm-add-support-for-master-volume.patch +++ /dev/null @@ -1,330 +0,0 @@ -From 6d830bf0f08c7f92418c2d8b0e73c0415dca03c8 Mon Sep 17 00:00:00 2001 -From: Jaroslav Kysela -Date: Wed, 27 Nov 2019 11:34:49 +0100 -Subject: [PATCH] alsa-ucm: add support for master volume - -Signed-off-by: Jaroslav Kysela ---- - src/modules/alsa/alsa-mixer.c | 20 +++++----- - src/modules/alsa/alsa-mixer.h | 1 + - src/modules/alsa/alsa-ucm.c | 86 +++++++++++++++++++++++++++++++++---------- - src/modules/alsa/alsa-ucm.h | 19 ++++++++++ - 4 files changed, 96 insertions(+), 30 deletions(-) - -diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c -index f57aabe5d885..ed06f42d86da 100644 ---- a/src/modules/alsa/alsa-mixer.c -+++ b/src/modules/alsa/alsa-mixer.c -@@ -1923,7 +1923,7 @@ static int jack_probe(pa_alsa_jack *j, pa_alsa_mapping *mapping, snd_mixer_t *m) - return 0; - } - --static pa_alsa_element* element_get(pa_alsa_path *p, const char *section, bool prefixed) { -+pa_alsa_element * pa_alsa_element_get(pa_alsa_path *p, const char *section, bool prefixed) { - pa_alsa_element *e; - char *name; - int index; -@@ -2025,7 +2025,7 @@ static pa_alsa_option* option_get(pa_alsa_path *p, const char *section) { - return p->last_option; - } - -- pa_assert_se(e = element_get(p, en, false)); -+ pa_assert_se(e = pa_alsa_element_get(p, en, false)); - - PA_LLIST_FOREACH(o, e->options) - if (pa_streq(o->alsa_name, on)) -@@ -2054,7 +2054,7 @@ static int element_parse_switch(pa_config_parser_state *state) { - - p = state->userdata; - -- if (!(e = element_get(p, state->section, true))) { -+ if (!(e = pa_alsa_element_get(p, state->section, true))) { - pa_log("[%s:%u] Switch makes no sense in '%s'", state->filename, state->lineno, state->section); - return -1; - } -@@ -2085,7 +2085,7 @@ static int element_parse_volume(pa_config_parser_state *state) { - - p = state->userdata; - -- if (!(e = element_get(p, state->section, true))) { -+ if (!(e = pa_alsa_element_get(p, state->section, true))) { - pa_log("[%s:%u] Volume makes no sense in '%s'", state->filename, state->lineno, state->section); - return -1; - } -@@ -2121,7 +2121,7 @@ static int element_parse_enumeration(pa_config_parser_state *state) { - - p = state->userdata; - -- if (!(e = element_get(p, state->section, true))) { -+ if (!(e = pa_alsa_element_get(p, state->section, true))) { - pa_log("[%s:%u] Enumeration makes no sense in '%s'", state->filename, state->lineno, state->section); - return -1; - } -@@ -2213,7 +2213,7 @@ static int element_parse_required(pa_config_parser_state *state) { - - p = state->userdata; - -- e = element_get(p, state->section, true); -+ e = pa_alsa_element_get(p, state->section, true); - o = option_get(p, state->section); - j = jack_get(p, state->section); - if (!e && !o && !j) { -@@ -2279,7 +2279,7 @@ static int element_parse_direction(pa_config_parser_state *state) { - - p = state->userdata; - -- if (!(e = element_get(p, state->section, true))) { -+ if (!(e = pa_alsa_element_get(p, state->section, true))) { - pa_log("[%s:%u] Direction makes no sense in '%s'", state->filename, state->lineno, state->section); - return -1; - } -@@ -2305,7 +2305,7 @@ static int element_parse_direction_try_other(pa_config_parser_state *state) { - - p = state->userdata; - -- if (!(e = element_get(p, state->section, true))) { -+ if (!(e = pa_alsa_element_get(p, state->section, true))) { - pa_log("[%s:%u] Direction makes no sense in '%s'", state->filename, state->lineno, state->section); - return -1; - } -@@ -2328,7 +2328,7 @@ static int element_parse_volume_limit(pa_config_parser_state *state) { - - p = state->userdata; - -- if (!(e = element_get(p, state->section, true))) { -+ if (!(e = pa_alsa_element_get(p, state->section, true))) { - pa_log("[%s:%u] volume-limit makes no sense in '%s'", state->filename, state->lineno, state->section); - return -1; - } -@@ -2386,7 +2386,7 @@ static int element_parse_override_map(pa_config_parser_state *state) { - - p = state->userdata; - -- if (!(e = element_get(p, state->section, true))) { -+ if (!(e = pa_alsa_element_get(p, state->section, true))) { - pa_log("[%s:%u] Override map makes no sense in '%s'", state->filename, state->lineno, state->section); - return -1; - } -diff --git a/src/modules/alsa/alsa-mixer.h b/src/modules/alsa/alsa-mixer.h -index 709f270fbfa5..0b634f2f2be1 100644 ---- a/src/modules/alsa/alsa-mixer.h -+++ b/src/modules/alsa/alsa-mixer.h -@@ -244,6 +244,7 @@ void pa_alsa_element_dump(pa_alsa_element *e); - - pa_alsa_path *pa_alsa_path_new(const char *paths_dir, const char *fname, pa_alsa_direction_t direction); - pa_alsa_path *pa_alsa_path_synthesize(const char *element, pa_alsa_direction_t direction); -+pa_alsa_element *pa_alsa_element_get(pa_alsa_path *p, const char *section, bool prefixed); - int pa_alsa_path_probe(pa_alsa_path *p, pa_alsa_mapping *mapping, snd_mixer_t *m, bool ignore_dB); - void pa_alsa_path_dump(pa_alsa_path *p); - int pa_alsa_path_get_volume(pa_alsa_path *p, snd_mixer_t *m, const pa_channel_map *cm, pa_cvolume *v); -diff --git a/src/modules/alsa/alsa-ucm.c b/src/modules/alsa/alsa-ucm.c -index 65ec6941e8de..46d016541ddf 100644 ---- a/src/modules/alsa/alsa-ucm.c -+++ b/src/modules/alsa/alsa-ucm.c -@@ -200,6 +200,14 @@ static void ucm_add_devices_to_idxset( - } - } - -+static void ucm_volume_free(pa_alsa_ucm_volume *vol) { -+ pa_assert(vol); -+ pa_xfree(vol->mixer_elem); -+ pa_xfree(vol->master_elem); -+ pa_xfree(vol->master_type); -+ pa_xfree(vol); -+} -+ - /* Get the volume identifier */ - static char *ucm_get_mixer_id( - pa_alsa_ucm_device *device, -@@ -244,6 +252,32 @@ static char *ucm_get_mixer_id( - return value2; - } - -+/* Get the volume identifier */ -+static pa_alsa_ucm_volume *ucm_get_mixer_volume( -+ pa_alsa_ucm_device *device, -+ const char *mprop, -+ const char *cprop, -+ const char *cid, -+ const char *masterid, -+ const char *mastertype) -+{ -+ pa_alsa_ucm_volume *vol; -+ char *mixer_elem; -+ -+ mixer_elem = ucm_get_mixer_id(device, mprop, cprop, cid); -+ if (mixer_elem == NULL) -+ return NULL; -+ vol = pa_xnew0(pa_alsa_ucm_volume, 1); -+ if (vol == NULL) { -+ pa_xfree(mixer_elem); -+ return NULL; -+ } -+ vol->mixer_elem = mixer_elem; -+ vol->master_elem = pa_xstrdup(pa_proplist_gets(device->proplist, masterid)); -+ vol->master_type = pa_xstrdup(pa_proplist_gets(device->proplist, mastertype)); -+ return vol; -+} -+ - /* Create a property list for this ucm device */ - static int ucm_get_device_property( - pa_alsa_ucm_device *device, -@@ -258,6 +292,7 @@ static int ucm_get_device_property( - int err; - uint32_t ui; - int n_confdev, n_suppdev; -+ pa_alsa_ucm_volume *vol; - - for (i = 0; item[i].id; i++) { - id = pa_sprintf_malloc("=%s/%s", item[i].id, device_name); -@@ -340,12 +375,14 @@ static int ucm_get_device_property( - pa_log_debug("UCM playback priority %s for device %s error", value, device_name); - } - -- value = ucm_get_mixer_id(device, -- PA_ALSA_PROP_UCM_PLAYBACK_MIXER_ELEM, -- PA_ALSA_PROP_UCM_PLAYBACK_VOLUME, -- "PlaybackVolume"); -- if (value) -- pa_hashmap_put(device->playback_volumes, pa_xstrdup(pa_proplist_gets(verb->proplist, PA_ALSA_PROP_UCM_NAME)), (void *)value); -+ vol = ucm_get_mixer_volume(device, -+ PA_ALSA_PROP_UCM_PLAYBACK_MIXER_ELEM, -+ PA_ALSA_PROP_UCM_PLAYBACK_VOLUME, -+ "PlaybackVolume", -+ PA_ALSA_PROP_UCM_PLAYBACK_MASTER_ELEM, -+ PA_ALSA_PROP_UCM_PLAYBACK_MASTER_TYPE); -+ if (vol) -+ pa_hashmap_put(device->playback_volumes, pa_xstrdup(pa_proplist_gets(verb->proplist, PA_ALSA_PROP_UCM_NAME)), vol); - } - - if (device->capture_channels) { /* source device */ -@@ -368,12 +405,14 @@ static int ucm_get_device_property( - pa_log_debug("UCM capture priority %s for device %s error", value, device_name); - } - -- value = ucm_get_mixer_id(device, -- PA_ALSA_PROP_UCM_CAPTURE_MIXER_ELEM, -- PA_ALSA_PROP_UCM_CAPTURE_VOLUME, -- "CaptureVolume"); -- if (value) -- pa_hashmap_put(device->capture_volumes, pa_xstrdup(pa_proplist_gets(verb->proplist, PA_ALSA_PROP_UCM_NAME)), (void *)value); -+ vol = ucm_get_mixer_volume(device, -+ PA_ALSA_PROP_UCM_CAPTURE_MIXER_ELEM, -+ PA_ALSA_PROP_UCM_CAPTURE_VOLUME, -+ "CaptureVolume", -+ PA_ALSA_PROP_UCM_CAPTURE_MASTER_ELEM, -+ PA_ALSA_PROP_UCM_CAPTURE_MASTER_TYPE); -+ if (vol) -+ pa_hashmap_put(device->capture_volumes, pa_xstrdup(pa_proplist_gets(verb->proplist, PA_ALSA_PROP_UCM_NAME)), vol); - } - - if (PA_UCM_PLAYBACK_PRIORITY_UNSET(device) || PA_UCM_CAPTURE_PRIORITY_UNSET(device)) { -@@ -478,9 +517,9 @@ static int ucm_get_devices(pa_alsa_ucm_verb *verb, snd_use_case_mgr_t *uc_mgr) { - d->available = PA_AVAILABLE_UNKNOWN; - - d->playback_volumes = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, pa_xfree, -- pa_xfree); -+ (pa_free_cb_t) ucm_volume_free); - d->capture_volumes = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, pa_xfree, -- pa_xfree); -+ (pa_free_cb_t) ucm_volume_free); - - PA_LLIST_PREPEND(pa_alsa_ucm_device, verb->devices, d); - } -@@ -819,9 +858,10 @@ static void ucm_add_port_combination( - char *name, *desc; - const char *dev_name; - const char *direction; -- const char *profile, *volume_element; -+ const char *profile; - pa_alsa_ucm_device *sorted[num], *dev; - pa_alsa_ucm_port_data *data; -+ pa_alsa_ucm_volume *vol; - void *state; - - for (i = 0; i < num; i++) -@@ -892,21 +932,27 @@ static void ucm_add_port_combination( - * ports. */ - data = PA_DEVICE_PORT_DATA(port); - -- PA_HASHMAP_FOREACH_KV(profile, volume_element, is_sink ? dev->playback_volumes : dev->capture_volumes, state) { -- pa_alsa_path *path = pa_alsa_path_synthesize(volume_element, -+ PA_HASHMAP_FOREACH_KV(profile, vol, is_sink ? dev->playback_volumes : dev->capture_volumes, state) { -+ pa_alsa_path *path = pa_alsa_path_synthesize(vol->mixer_elem, - is_sink ? PA_ALSA_DIRECTION_OUTPUT : PA_ALSA_DIRECTION_INPUT); - - if (!path) -- pa_log_warn("Failed to set up volume control: %s", volume_element); -+ pa_log_warn("Failed to set up volume control: %s", vol->mixer_elem); - else { -+ if (vol->master_elem) { -+ pa_alsa_element *e = pa_alsa_element_get(path, vol->master_elem, false); -+ e->switch_use = PA_ALSA_SWITCH_MUTE; -+ e->volume_use = PA_ALSA_VOLUME_MERGE; -+ } -+ - pa_hashmap_put(data->paths, pa_xstrdup(profile), path); - - /* Add path also to already created empty path set */ - dev = sorted[0]; - if (is_sink) -- pa_hashmap_put(dev->playback_mapping->output_path_set->paths, pa_xstrdup(volume_element), path); -+ pa_hashmap_put(dev->playback_mapping->output_path_set->paths, pa_xstrdup(vol->mixer_elem), path); - else -- pa_hashmap_put(dev->capture_mapping->input_path_set->paths, pa_xstrdup(volume_element), path); -+ pa_hashmap_put(dev->capture_mapping->input_path_set->paths, pa_xstrdup(vol->mixer_elem), path); - } - } - } -diff --git a/src/modules/alsa/alsa-ucm.h b/src/modules/alsa/alsa-ucm.h -index d8507a83615c..a6863abc05a6 100644 ---- a/src/modules/alsa/alsa-ucm.h -+++ b/src/modules/alsa/alsa-ucm.h -@@ -60,6 +60,12 @@ typedef void snd_use_case_mgr_t; - /** For devices: Playback mixer master type */ - #define PA_ALSA_PROP_UCM_PLAYBACK_MASTER_TYPE "alsa.ucm.playback.master.type" - -+/** For devices: Playback mixer master identifier */ -+#define PA_ALSA_PROP_UCM_PLAYBACK_MASTER_ID "alsa.ucm.playback.master.id" -+ -+/** For devices: Playback mixer master type */ -+#define PA_ALSA_PROP_UCM_PLAYBACK_MASTER_TYPE "alsa.ucm.playback.master.type" -+ - /** For devices: Playback priority */ - #define PA_ALSA_PROP_UCM_PLAYBACK_PRIORITY "alsa.ucm.playback.priority" - -@@ -87,6 +93,12 @@ typedef void snd_use_case_mgr_t; - /** For devices: Capture mixer identifier */ - #define PA_ALSA_PROP_UCM_CAPTURE_MASTER_TYPE "alsa.ucm.capture.master.type" - -+/** For devices: Capture mixer identifier */ -+#define PA_ALSA_PROP_UCM_CAPTURE_MASTER_ID "alsa.ucm.capture.master.id" -+ -+/** For devices: Capture mixer identifier */ -+#define PA_ALSA_PROP_UCM_CAPTURE_MASTER_TYPE "alsa.ucm.capture.master.type" -+ - /** For devices: Capture priority */ - #define PA_ALSA_PROP_UCM_CAPTURE_PRIORITY "alsa.ucm.capture.priority" - -@@ -114,6 +126,7 @@ typedef struct pa_alsa_ucm_device pa_alsa_ucm_device; - typedef struct pa_alsa_ucm_config pa_alsa_ucm_config; - typedef struct pa_alsa_ucm_mapping_context pa_alsa_ucm_mapping_context; - typedef struct pa_alsa_ucm_port_data pa_alsa_ucm_port_data; -+typedef struct pa_alsa_ucm_volume pa_alsa_ucm_volume; - - int pa_alsa_ucm_query_profiles(pa_alsa_ucm_config *ucm, int card_index); - pa_alsa_profile_set* pa_alsa_ucm_add_profile_set(pa_alsa_ucm_config *ucm, pa_channel_map *default_channel_map); -@@ -246,4 +259,10 @@ struct pa_alsa_ucm_port_data { - pa_alsa_path *path; - }; - -+struct pa_alsa_ucm_volume { -+ char *mixer_elem; /* mixer element identifier */ -+ char *master_elem; /* master mixer element identifier */ -+ char *master_type; -+}; -+ - #endif --- -2.16.4 - diff --git a/0014-alsa-ucm-split-correctly-JackHWMute-device-names.patch b/0014-alsa-ucm-split-correctly-JackHWMute-device-names.patch deleted file mode 100644 index e16ce07..0000000 --- a/0014-alsa-ucm-split-correctly-JackHWMute-device-names.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 156bd7742490d68701688572ec06f2c608f33db6 Mon Sep 17 00:00:00 2001 -From: Jaroslav Kysela -Date: Tue, 3 Dec 2019 14:52:08 +0100 -Subject: [PATCH] alsa-ucm: split correctly JackHWMute device names - -Signed-off-by: Jaroslav Kysela ---- - src/modules/alsa/alsa-ucm.c | 28 +++++++++++++++++++++++++++- - 1 file changed, 27 insertions(+), 1 deletion(-) - -diff --git a/src/modules/alsa/alsa-ucm.c b/src/modules/alsa/alsa-ucm.c -index 46d016541ddf..65b786caf95e 100644 ---- a/src/modules/alsa/alsa-ucm.c -+++ b/src/modules/alsa/alsa-ucm.c -@@ -200,6 +200,32 @@ static void ucm_add_devices_to_idxset( - } - } - -+/* Split a string into words. Like pa_split_spaces() but handle '' and "". */ -+static char *ucm_split_devnames(const char *c, const char **state) { -+ const char *current = *state ? *state : c; -+ char h; -+ size_t l; -+ -+ if (!*current || *c == 0) -+ return NULL; -+ -+ current += strspn(current, "\n\r \t"); -+ h = *current; -+ if (h == '\'' || h =='"') { -+ c = ++current; -+ for (l = 0; *c && *c != h; l++) c++; -+ if (*c != h) -+ return NULL; -+ *state = c + 1; -+ } else { -+ l = strcspn(current, "\n\r \t"); -+ *state = current+l; -+ } -+ -+ return pa_xstrndup(current, l); -+} -+ -+ - static void ucm_volume_free(pa_alsa_ucm_volume *vol) { - pa_assert(vol); - pa_xfree(vol->mixer_elem); -@@ -1607,7 +1633,7 @@ static int ucm_create_profile( - char *hw_mute_device_name; - const char *state = NULL; - -- while ((hw_mute_device_name = pa_split_spaces(jack_hw_mute, &state))) { -+ while ((hw_mute_device_name = ucm_split_devnames(jack_hw_mute, &state))) { - pa_alsa_ucm_verb *verb2; - bool device_found = false; - --- -2.16.4 - diff --git a/0015-alsa-ucm-fix-parsing-for-JackControl.patch b/0015-alsa-ucm-fix-parsing-for-JackControl.patch deleted file mode 100644 index b73ac9f..0000000 --- a/0015-alsa-ucm-fix-parsing-for-JackControl.patch +++ /dev/null @@ -1,40 +0,0 @@ -From e04f14ebf3a0898dd2f665434524cc34cb267ddd Mon Sep 17 00:00:00 2001 -From: Jaroslav Kysela -Date: Tue, 3 Dec 2019 15:13:48 +0100 -Subject: [PATCH] alsa-ucm: fix parsing for JackControl - -Signed-off-by: Jaroslav Kysela ---- - src/modules/alsa/alsa-ucm.c | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - -diff --git a/src/modules/alsa/alsa-ucm.c b/src/modules/alsa/alsa-ucm.c -index 65b786caf95e..221fed719284 100644 ---- a/src/modules/alsa/alsa-ucm.c -+++ b/src/modules/alsa/alsa-ucm.c -@@ -1534,6 +1534,22 @@ static pa_alsa_jack* ucm_get_jack(pa_alsa_ucm_config *ucm, pa_alsa_ucm_device *d - - jack_control = pa_proplist_gets(device->proplist, PA_ALSA_PROP_UCM_JACK_CONTROL); - if (jack_control) { -+#if SND_LIB_VERSION >= 0x10201 -+ snd_ctl_elem_id_t *ctl; -+ int err, index; -+ snd_ctl_elem_id_alloca(&ctl); -+ err = snd_use_case_parse_ctl_elem_id(ctl, "JackControl", jack_control); -+ if (err < 0) -+ return NULL; -+ jack_control = snd_ctl_elem_id_get_name(ctl); -+ index = snd_ctl_elem_id_get_index(ctl); -+ if (index > 0) { -+ pa_log("[%s] Invalid JackControl index value: \"%s\",%d", device_name, jack_control, index); -+ return NULL; -+ } -+#else -+#warning "Upgrade to alsa-lib 1.2.1!" -+#endif - if (!pa_endswith(jack_control, " Jack")) { - pa_log("[%s] Invalid JackControl value: \"%s\"", device_name, jack_control); - return NULL; --- -2.16.4 - diff --git a/0016-alsa-ucm-add-comments-to-ucm_get_mixer_id.patch b/0016-alsa-ucm-add-comments-to-ucm_get_mixer_id.patch deleted file mode 100644 index e7f57bc..0000000 --- a/0016-alsa-ucm-add-comments-to-ucm_get_mixer_id.patch +++ /dev/null @@ -1,45 +0,0 @@ -From f5c02dfcd821ab77fc7f91da985254a7bdb658ad Mon Sep 17 00:00:00 2001 -From: Jaroslav Kysela -Date: Wed, 4 Dec 2019 16:29:51 +0100 -Subject: [PATCH] alsa-ucm: add comments to ucm_get_mixer_id() - -Signed-off-by: Jaroslav Kysela ---- - src/modules/alsa/alsa-ucm.c | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - -diff --git a/src/modules/alsa/alsa-ucm.c b/src/modules/alsa/alsa-ucm.c -index 221fed719284..3ee271845c19 100644 ---- a/src/modules/alsa/alsa-ucm.c -+++ b/src/modules/alsa/alsa-ucm.c -@@ -241,7 +241,7 @@ static char *ucm_get_mixer_id( - const char *cprop, - const char *cid) - { --#if SND_LIB_VERSION >= 0x10201 -+#if SND_LIB_VERSION >= 0x10201 /* alsa-lib-1.2.1+ check */ - snd_ctl_elem_id_t *ctl; - int err; - #endif -@@ -249,13 +249,17 @@ static char *ucm_get_mixer_id( - char *value2; - int index; - -+ /* mixer element as first, if it's found, return it without modifications */ - value = pa_proplist_gets(device->proplist, mprop); - if (value) - return pa_xstrdup(value); -+ /* fallback, get the control element identifier */ -+ /* and try to do some heuristic to determine the mixer element name */ - value = pa_proplist_gets(device->proplist, cprop); - if (value == NULL) - return NULL; --#if SND_LIB_VERSION >= 0x10201 -+#if SND_LIB_VERSION >= 0x10201 /* alsa-lib-1.2.1+ check */ -+ /* The new parser may return also element index. */ - snd_ctl_elem_id_alloca(&ctl); - err = snd_use_case_parse_ctl_elem_id(ctl, cid, value); - if (err < 0) --- -2.16.4 - diff --git a/0017-alsa-ucm-validate-access-to-PA_DEVICE_PORT_DATA.patch b/0017-alsa-ucm-validate-access-to-PA_DEVICE_PORT_DATA.patch deleted file mode 100644 index cbc674d..0000000 --- a/0017-alsa-ucm-validate-access-to-PA_DEVICE_PORT_DATA.patch +++ /dev/null @@ -1,81 +0,0 @@ -From e6779ad229d5858f90f5f10c3796c9778f05c3fa Mon Sep 17 00:00:00 2001 -From: Jaroslav Kysela -Date: Wed, 4 Dec 2019 19:33:01 +0100 -Subject: [PATCH] alsa-ucm: validate access to PA_DEVICE_PORT_DATA() - -Signed-off-by: Jaroslav Kysela ---- - src/modules/alsa/alsa-sink.c | 3 ++- - src/modules/alsa/alsa-source.c | 3 +-- - src/modules/alsa/module-alsa-card.c | 6 +++++- - 3 files changed, 8 insertions(+), 4 deletions(-) - -diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c -index 0a5c92529af3..19e9efc3674b 100644 ---- a/src/modules/alsa/alsa-sink.c -+++ b/src/modules/alsa/alsa-sink.c -@@ -1672,6 +1672,7 @@ static int sink_set_port_cb(pa_sink *s, pa_device_port *p) { - pa_assert(u); - pa_assert(p); - pa_assert(u->mixer_handle); -+ pa_assert(!u->ucm_context); - - data = PA_DEVICE_PORT_DATA(p); - pa_assert_se(u->mixer_path = data->path); -@@ -2688,7 +2689,7 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca - * pa_sink_suspend() between pa_sink_new() and pa_sink_put() would - * otherwise work, but currently pa_sink_suspend() will crash if - * pa_sink_put() hasn't been called. */ -- if (u->sink->active_port) { -+ if (u->sink->active_port && !u->ucm_context) { - pa_alsa_port_data *port_data; - - port_data = PA_DEVICE_PORT_DATA(u->sink->active_port); -diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c -index d186101720b8..34946b74c77f 100644 ---- a/src/modules/alsa/alsa-source.c -+++ b/src/modules/alsa/alsa-source.c -@@ -1519,8 +1519,6 @@ static int source_set_port_ucm_cb(pa_source *s, pa_device_port *p) { - struct userdata *u = s->userdata; - pa_alsa_ucm_port_data *data; - -- data = PA_DEVICE_PORT_DATA(p); -- - pa_assert(u); - pa_assert(p); - pa_assert(u->mixer_handle); -@@ -1545,6 +1543,7 @@ static int source_set_port_cb(pa_source *s, pa_device_port *p) { - pa_assert(u); - pa_assert(p); - pa_assert(u->mixer_handle); -+ pa_assert(!u->ucm_context); - - data = PA_DEVICE_PORT_DATA(p); - pa_assert_se(u->mixer_path = data->path); -diff --git a/src/modules/alsa/module-alsa-card.c b/src/modules/alsa/module-alsa-card.c -index e2a86bc1c68d..be260e4badab 100644 ---- a/src/modules/alsa/module-alsa-card.c -+++ b/src/modules/alsa/module-alsa-card.c -@@ -538,6 +538,9 @@ static int hdmi_eld_changed(snd_mixer_elem_t *melem, unsigned int mask) { - if (mask == SND_CTL_EVENT_MASK_REMOVE) - return 0; - -+ if (u->use_ucm) -+ return 0; -+ - p = find_port_with_eld_device(u->card->ports, device); - if (p == NULL) { - pa_log_error("Invalid device changed in ALSA: %d", device); -@@ -900,7 +903,8 @@ int pa__init(pa_module *m) { - * results in an infinite loop of "fill buffer, handle underrun". To work - * around this issue, the suspend_when_unavailable flag is used to stop - * playback when the HDMI cable is unplugged. */ -- if (pa_safe_streq(pa_proplist_gets(data.proplist, "alsa.driver_name"), "snd_hdmi_lpe_audio")) { -+ if (!u->use_ucm && -+ pa_safe_streq(pa_proplist_gets(data.proplist, "alsa.driver_name"), "snd_hdmi_lpe_audio")) { - pa_device_port *port; - void *state; - --- -2.16.4 - diff --git a/0018-alsa-Skip-resume-PCM-if-hardware-doesn-t-support-it.patch b/0018-alsa-Skip-resume-PCM-if-hardware-doesn-t-support-it.patch deleted file mode 100644 index 7df8880..0000000 --- a/0018-alsa-Skip-resume-PCM-if-hardware-doesn-t-support-it.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 734a00c849815a45697970d593068c301a04ebbb Mon Sep 17 00:00:00 2001 -From: Kai-Heng Feng -Date: Tue, 10 Dec 2019 16:16:18 +0800 -Subject: [PATCH] alsa: Skip resume PCM if hardware doesn't support it - -Hardwares without SNDRV_PCM_INFO_RESUME capability, like USB Audio, -don't support snd_pcm_resume() when it's in suspended state. - -Let's use snd_pcm_hw_params_can_resume() to check hardware's capability -before snd_pcm_resume() attempt. If it doesn't support resume, just go -to snd_pcm_drop() to leave suspended state directly. ---- - src/modules/alsa/alsa-util.c | 28 +++++++++++++++++++--------- - 1 file changed, 19 insertions(+), 9 deletions(-) - -diff --git a/src/modules/alsa/alsa-util.c b/src/modules/alsa/alsa-util.c -index bd0a47e5072c..a14b061118e6 100644 ---- a/src/modules/alsa/alsa-util.c -+++ b/src/modules/alsa/alsa-util.c -@@ -1066,6 +1066,7 @@ void pa_alsa_init_proplist_ctl(pa_proplist *p, const char *name) { - - int pa_alsa_recover_from_poll(snd_pcm_t *pcm, int revents) { - snd_pcm_state_t state; -+ snd_pcm_hw_params_t *hwparams; - int err; - - pa_assert(pcm); -@@ -1103,16 +1104,25 @@ int pa_alsa_recover_from_poll(snd_pcm_t *pcm, int revents) { - break; - - case SND_PCM_STATE_SUSPENDED: -- /* Retry resume 3 times before giving up, then fallback to restarting the stream. */ -- for (int i = 0; i < 3; i++) { -- if ((err = snd_pcm_resume(pcm)) == 0) -- return 0; -- if (err != -EAGAIN) -- break; -- pa_msleep(25); -+ snd_pcm_hw_params_alloca(&hwparams); -+ -+ if ((err = snd_pcm_hw_params_any(pcm, hwparams)) < 0) { -+ pa_log_debug("snd_pcm_hw_params_any() failed: %s", pa_alsa_strerror(err)); -+ return -1; - } -- pa_log_warn("Could not recover alsa device from SUSPENDED state, trying to restart PCM"); -- /* Fall through */ -+ -+ if (snd_pcm_hw_params_can_resume(hwparams)) { -+ /* Retry resume 3 times before giving up, then fallback to restarting the stream. */ -+ for (int i = 0; i < 3; i++) { -+ if ((err = snd_pcm_resume(pcm)) == 0) -+ return 0; -+ if (err != -EAGAIN) -+ break; -+ pa_msleep(25); -+ } -+ pa_log_warn("Could not recover alsa device from SUSPENDED state, trying to restart PCM"); -+ } -+ /* Fall through */ - - default: - --- -2.16.4 - diff --git a/0019-alsa-ucm-parse-correctly-the-device-values.patch b/0019-alsa-ucm-parse-correctly-the-device-values.patch deleted file mode 100644 index 8b761a4..0000000 --- a/0019-alsa-ucm-parse-correctly-the-device-values.patch +++ /dev/null @@ -1,125 +0,0 @@ -From 4c64f73c97c7f77426ee838f47fc7bad6a4563b6 Mon Sep 17 00:00:00 2001 -From: Jaroslav Kysela -Date: Fri, 6 Dec 2019 21:51:47 +0100 -Subject: [PATCH] alsa-ucm: parse correctly the device values - -The UCM library is used to get the fallback values from the verbs -and the defaults section. There is no reason to duplicate this code -inside application. - -Signed-off-by: Jaroslav Kysela ---- - src/modules/alsa/alsa-ucm.c | 55 ++++++--------------------------------------- - 1 file changed, 7 insertions(+), 48 deletions(-) - -diff --git a/src/modules/alsa/alsa-ucm.c b/src/modules/alsa/alsa-ucm.c -index 3ee271845c19..ac1b71e94022 100644 ---- a/src/modules/alsa/alsa-ucm.c -+++ b/src/modules/alsa/alsa-ucm.c -@@ -141,30 +141,6 @@ static struct ucm_info dev_info[] = { - {NULL, 0} - }; - --/* UCM profile properties - The verb data is store so it can be used to fill -- * the new profiles properties */ --static int ucm_get_property(pa_alsa_ucm_verb *verb, snd_use_case_mgr_t *uc_mgr, const char *verb_name) { -- const char *value; -- char *id; -- int i; -- -- for (i = 0; item[i].id; i++) { -- int err; -- -- id = pa_sprintf_malloc("=%s//%s", item[i].id, verb_name); -- err = snd_use_case_get(uc_mgr, id, &value); -- pa_xfree(id); -- if (err < 0) -- continue; -- -- pa_log_debug("Got %s for verb %s: %s", item[i].id, verb_name, value); -- pa_proplist_sets(verb->proplist, item[i].property, value); -- free((void*)value); -- } -- -- return 0; --}; -- - static int ucm_device_exists(pa_idxset *idxset, pa_alsa_ucm_device *dev) { - pa_alsa_ucm_device *d; - uint32_t idx; -@@ -325,7 +301,7 @@ static int ucm_get_device_property( - pa_alsa_ucm_volume *vol; - - for (i = 0; item[i].id; i++) { -- id = pa_sprintf_malloc("=%s/%s", item[i].id, device_name); -+ id = pa_sprintf_malloc("%s/%s", item[i].id, device_name); - err = snd_use_case_get(uc_mgr, id, &value); - pa_xfree(id); - if (err < 0) -@@ -347,14 +323,8 @@ static int ucm_get_device_property( - - /* get pcm */ - value = pa_proplist_gets(device->proplist, PA_ALSA_PROP_UCM_SINK); -- if (!value) { /* take pcm from verb playback default */ -- value = pa_proplist_gets(verb->proplist, PA_ALSA_PROP_UCM_SINK); -- if (value) { -- pa_log_debug("UCM playback device %s fetch pcm from verb default %s", device_name, value); -- pa_proplist_sets(device->proplist, PA_ALSA_PROP_UCM_SINK, value); -- } else -- pa_log("UCM playback device %s fetch pcm failed", device_name); -- } -+ if (!value) /* take pcm from verb playback default */ -+ pa_log("UCM playback device %s fetch pcm failed", device_name); - } - - value = pa_proplist_gets(device->proplist, PA_ALSA_PROP_UCM_CAPTURE_CHANNELS); -@@ -367,14 +337,8 @@ static int ucm_get_device_property( - - /* get pcm */ - value = pa_proplist_gets(device->proplist, PA_ALSA_PROP_UCM_SOURCE); -- if (!value) { /* take pcm from verb capture default */ -- value = pa_proplist_gets(verb->proplist, PA_ALSA_PROP_UCM_SOURCE); -- if (value) { -- pa_log_debug("UCM capture device %s fetch pcm from verb default %s", device_name, value); -- pa_proplist_sets(device->proplist, PA_ALSA_PROP_UCM_SOURCE, value); -- } else -- pa_log("UCM capture device %s fetch pcm failed", device_name); -- } -+ if (!value) /* take pcm from verb capture default */ -+ pa_log("UCM capture device %s fetch pcm failed", device_name); - } - - if (device->playback_channels == 0 && device->capture_channels == 0) { -@@ -387,8 +351,7 @@ static int ucm_get_device_property( - /* get rate and priority of device */ - if (device->playback_channels) { /* sink device */ - /* get rate */ -- if ((value = pa_proplist_gets(device->proplist, PA_ALSA_PROP_UCM_PLAYBACK_RATE)) || -- (value = pa_proplist_gets(verb->proplist, PA_ALSA_PROP_UCM_PLAYBACK_RATE))) { -+ if ((value = pa_proplist_gets(device->proplist, PA_ALSA_PROP_UCM_PLAYBACK_RATE))) { - if (pa_atou(value, &ui) == 0 && pa_sample_rate_valid(ui)) { - pa_log_debug("UCM playback device %s rate %d", device_name, ui); - device->playback_rate = ui; -@@ -417,8 +380,7 @@ static int ucm_get_device_property( - - if (device->capture_channels) { /* source device */ - /* get rate */ -- if ((value = pa_proplist_gets(device->proplist, PA_ALSA_PROP_UCM_CAPTURE_RATE)) || -- (value = pa_proplist_gets(verb->proplist, PA_ALSA_PROP_UCM_CAPTURE_RATE))) { -+ if ((value = pa_proplist_gets(device->proplist, PA_ALSA_PROP_UCM_CAPTURE_RATE))) { - if (pa_atou(value, &ui) == 0 && pa_sample_rate_valid(ui)) { - pa_log_debug("UCM capture device %s rate %d", device_name, ui); - device->capture_rate = ui; -@@ -796,9 +758,6 @@ int pa_alsa_ucm_get_verb(snd_use_case_mgr_t *uc_mgr, const char *verb_name, cons - if (err < 0) - pa_log("No UCM modifiers for verb %s", verb_name); - -- /* Verb properties */ -- ucm_get_property(verb, uc_mgr, verb_name); -- - PA_LLIST_FOREACH(d, verb->devices) { - const char *dev_name = pa_proplist_gets(d->proplist, PA_ALSA_PROP_UCM_NAME); - --- -2.16.4 - diff --git a/0020-alsa-ucm-do-not-try-to-use-UCM-device-name-as-jack-n.patch b/0020-alsa-ucm-do-not-try-to-use-UCM-device-name-as-jack-n.patch deleted file mode 100644 index 8ecddf0..0000000 --- a/0020-alsa-ucm-do-not-try-to-use-UCM-device-name-as-jack-n.patch +++ /dev/null @@ -1,44 +0,0 @@ -From ef1df946274a0499e1fa631a8b6680c23c4eb723 Mon Sep 17 00:00:00 2001 -From: Jaroslav Kysela -Date: Fri, 6 Dec 2019 15:43:04 +0100 -Subject: [PATCH] alsa-ucm: do not try to use UCM device name as jack name by - default - -Remove the implicit rule. It is perfectly ok to have the jack with -the same name for another I/O in the driver. Trust only the -value obtained from UCM. - -Signed-off-by: Jaroslav Kysela ---- - src/modules/alsa/alsa-ucm.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/src/modules/alsa/alsa-ucm.c b/src/modules/alsa/alsa-ucm.c -index ac1b71e94022..95f1a47f8b61 100644 ---- a/src/modules/alsa/alsa-ucm.c -+++ b/src/modules/alsa/alsa-ucm.c -@@ -1522,9 +1522,8 @@ static pa_alsa_jack* ucm_get_jack(pa_alsa_ucm_config *ucm, pa_alsa_ucm_device *d - * end, so drop the trailing " Jack". */ - name = pa_xstrndup(jack_control, strlen(jack_control) - 5); - } else { -- /* The jack control hasn't been explicitly configured - try a jack name -- * that is the same as the device name. */ -- name = pa_xstrdup(device_name); -+ /* The jack control hasn't been explicitly configured, fail. */ -+ return NULL; - } - - PA_LLIST_FOREACH(j, ucm->jacks) -@@ -1603,7 +1602,8 @@ static int ucm_create_profile( - ucm_create_mapping(ucm, ps, p, dev, verb_name, name, sink, source); - - jack = ucm_get_jack(ucm, dev); -- device_set_jack(dev, jack); -+ if (jack) -+ device_set_jack(dev, jack); - - /* JackHWMute contains a list of device names. Each listed device must - * be associated with the jack object that we just created. */ --- -2.16.4 - diff --git a/0021-alsa-util-do-not-try-to-guess-the-mixer-name-from-th.patch b/0021-alsa-util-do-not-try-to-guess-the-mixer-name-from-th.patch deleted file mode 100644 index bdd39bf..0000000 --- a/0021-alsa-util-do-not-try-to-guess-the-mixer-name-from-th.patch +++ /dev/null @@ -1,84 +0,0 @@ -From d8200ee805ed6b508a8174031080b1d98a7c27b3 Mon Sep 17 00:00:00 2001 -From: Jaroslav Kysela -Date: Fri, 6 Dec 2019 16:05:07 +0100 -Subject: [PATCH] alsa-util: do not try to guess the mixer name from the PCM - name - -This is just invalid. It results to an error in almost all cases. -The hw: scheme is sufficient to get the right card mixer. - -Signed-off-by: Jaroslav Kysela ---- - src/modules/alsa/alsa-ucm.c | 2 ++ - src/modules/alsa/alsa-util.c | 26 +++++++------------------- - 2 files changed, 9 insertions(+), 19 deletions(-) - -diff --git a/src/modules/alsa/alsa-ucm.c b/src/modules/alsa/alsa-ucm.c -index 95f1a47f8b61..45eb83085b38 100644 ---- a/src/modules/alsa/alsa-ucm.c -+++ b/src/modules/alsa/alsa-ucm.c -@@ -1725,6 +1725,8 @@ static void ucm_mapping_jack_probe(pa_alsa_mapping *m) { - PA_IDXSET_FOREACH(dev, context->ucm_devices, idx) { - bool has_control; - -+ if (!dev->jack) -+ continue; - has_control = pa_alsa_mixer_find(mixer_handle, dev->jack->alsa_name, 0) != NULL; - pa_alsa_jack_set_has_control(dev->jack, has_control); - pa_log_info("UCM jack %s has_control=%d", dev->jack->name, dev->jack->has_control); -diff --git a/src/modules/alsa/alsa-util.c b/src/modules/alsa/alsa-util.c -index a14b061118e6..54fe1361148a 100644 ---- a/src/modules/alsa/alsa-util.c -+++ b/src/modules/alsa/alsa-util.c -@@ -1743,7 +1743,6 @@ snd_mixer_t *pa_alsa_open_mixer(int alsa_card_index, char **ctl_device) { - snd_mixer_t *pa_alsa_open_mixer_for_pcm(snd_pcm_t *pcm, char **ctl_device) { - int err; - snd_mixer_t *m; -- const char *dev; - snd_pcm_info_t* info; - snd_pcm_info_alloca(&info); - -@@ -1754,15 +1753,6 @@ snd_mixer_t *pa_alsa_open_mixer_for_pcm(snd_pcm_t *pcm, char **ctl_device) { - return NULL; - } - -- /* First, try by name */ -- if ((dev = snd_pcm_name(pcm))) -- if (prepare_mixer(m, dev) >= 0) { -- if (ctl_device) -- *ctl_device = pa_xstrdup(dev); -- -- return m; -- } -- - /* Then, try by card index */ - if (snd_pcm_info(pcm, info) >= 0) { - char *md; -@@ -1771,17 +1761,15 @@ snd_mixer_t *pa_alsa_open_mixer_for_pcm(snd_pcm_t *pcm, char **ctl_device) { - if ((card_idx = snd_pcm_info_get_card(info)) >= 0) { - - md = pa_sprintf_malloc("hw:%i", card_idx); -+ if (prepare_mixer(m, md) >= 0) { - -- if (!dev || !pa_streq(dev, md)) -- if (prepare_mixer(m, md) >= 0) { -+ if (ctl_device) -+ *ctl_device = md; -+ else -+ pa_xfree(md); - -- if (ctl_device) -- *ctl_device = md; -- else -- pa_xfree(md); -- -- return m; -- } -+ return m; -+ } - - pa_xfree(md); - } --- -2.16.4 - diff --git a/0022-alsa-ucm-add-control-and-mixer-device-items.patch b/0022-alsa-ucm-add-control-and-mixer-device-items.patch deleted file mode 100644 index cfbfaeb..0000000 --- a/0022-alsa-ucm-add-control-and-mixer-device-items.patch +++ /dev/null @@ -1,99 +0,0 @@ -From ddd0fdb9970b920ef95e33cfe50a1e492be9d60b Mon Sep 17 00:00:00 2001 -From: Jaroslav Kysela -Date: Fri, 6 Dec 2019 20:33:45 +0100 -Subject: [PATCH] alsa-ucm: add control and mixer device items - -Signed-off-by: Jaroslav Kysela ---- - src/modules/alsa/alsa-ucm.c | 5 +++++ - src/modules/alsa/alsa-ucm.h | 15 +++++++++++++++ - 2 files changed, 20 insertions(+) - -diff --git a/src/modules/alsa/alsa-ucm.c b/src/modules/alsa/alsa-ucm.c -index 45eb83085b38..2a594b4df546 100644 ---- a/src/modules/alsa/alsa-ucm.c -+++ b/src/modules/alsa/alsa-ucm.c -@@ -90,16 +90,20 @@ static void ucm_port_update_available(pa_alsa_ucm_port_data *port); - static struct ucm_items item[] = { - {"PlaybackPCM", PA_ALSA_PROP_UCM_SINK}, - {"CapturePCM", PA_ALSA_PROP_UCM_SOURCE}, -+ {"PlaybackCTL", PA_ALSA_PROP_UCM_PLAYBACK_CTL_DEVICE}, - {"PlaybackVolume", PA_ALSA_PROP_UCM_PLAYBACK_VOLUME}, - {"PlaybackSwitch", PA_ALSA_PROP_UCM_PLAYBACK_SWITCH}, -+ {"PlaybackMixer", PA_ALSA_PROP_UCM_PLAYBACK_MIXER_DEVICE}, - {"PlaybackMixerElem", PA_ALSA_PROP_UCM_PLAYBACK_MIXER_ELEM}, - {"PlaybackMasterElem", PA_ALSA_PROP_UCM_PLAYBACK_MASTER_ELEM}, - {"PlaybackMasterType", PA_ALSA_PROP_UCM_PLAYBACK_MASTER_TYPE}, - {"PlaybackPriority", PA_ALSA_PROP_UCM_PLAYBACK_PRIORITY}, - {"PlaybackRate", PA_ALSA_PROP_UCM_PLAYBACK_RATE}, - {"PlaybackChannels", PA_ALSA_PROP_UCM_PLAYBACK_CHANNELS}, -+ {"CaptureCTL", PA_ALSA_PROP_UCM_CAPTURE_CTL_DEVICE}, - {"CaptureVolume", PA_ALSA_PROP_UCM_CAPTURE_VOLUME}, - {"CaptureSwitch", PA_ALSA_PROP_UCM_CAPTURE_SWITCH}, -+ {"CaptureMixer", PA_ALSA_PROP_UCM_CAPTURE_MIXER_DEVICE}, - {"CaptureMixerElem", PA_ALSA_PROP_UCM_CAPTURE_MIXER_ELEM}, - {"CaptureMasterElem", PA_ALSA_PROP_UCM_CAPTURE_MASTER_ELEM}, - {"CaptureMasterType", PA_ALSA_PROP_UCM_CAPTURE_MASTER_TYPE}, -@@ -107,6 +111,7 @@ static struct ucm_items item[] = { - {"CaptureRate", PA_ALSA_PROP_UCM_CAPTURE_RATE}, - {"CaptureChannels", PA_ALSA_PROP_UCM_CAPTURE_CHANNELS}, - {"TQ", PA_ALSA_PROP_UCM_QOS}, -+ {"JackCTL", PA_ALSA_PROP_UCM_JACK_DEVICE}, - {"JackControl", PA_ALSA_PROP_UCM_JACK_CONTROL}, - {"JackHWMute", PA_ALSA_PROP_UCM_JACK_HW_MUTE}, - {NULL, NULL}, -diff --git a/src/modules/alsa/alsa-ucm.h b/src/modules/alsa/alsa-ucm.h -index a6863abc05a6..014bc334ad67 100644 ---- a/src/modules/alsa/alsa-ucm.h -+++ b/src/modules/alsa/alsa-ucm.h -@@ -45,12 +45,18 @@ typedef void snd_use_case_mgr_t; - /** For devices: Playback roles */ - #define PA_ALSA_PROP_UCM_PLAYBACK_ROLES "alsa.ucm.playback.roles" - -+/** For devices: Playback control device name */ -+#define PA_ALSA_PROP_UCM_PLAYBACK_CTL_DEVICE "alsa.ucm.playback.ctldev" -+ - /** For devices: Playback control volume ID string. e.g PlaybackVolume */ - #define PA_ALSA_PROP_UCM_PLAYBACK_VOLUME "alsa.ucm.playback.volume" - - /** For devices: Playback switch e.g PlaybackSwitch */ - #define PA_ALSA_PROP_UCM_PLAYBACK_SWITCH "alsa.ucm.playback.switch" - -+/** For devices: Playback mixer device name */ -+#define PA_ALSA_PROP_UCM_PLAYBACK_MIXER_DEVICE "alsa.ucm.playback.mixer.device" -+ - /** For devices: Playback mixer identifier */ - #define PA_ALSA_PROP_UCM_PLAYBACK_MIXER_ELEM "alsa.ucm.playback.mixer.element" - -@@ -78,12 +84,18 @@ typedef void snd_use_case_mgr_t; - /** For devices: Capture roles */ - #define PA_ALSA_PROP_UCM_CAPTURE_ROLES "alsa.ucm.capture.roles" - -+/** For devices: Capture control device name */ -+#define PA_ALSA_PROP_UCM_CAPTURE_CTL_DEVICE "alsa.ucm.capture.ctldev" -+ - /** For devices: Capture controls volume ID string. e.g CaptureVolume */ - #define PA_ALSA_PROP_UCM_CAPTURE_VOLUME "alsa.ucm.capture.volume" - - /** For devices: Capture switch e.g CaptureSwitch */ - #define PA_ALSA_PROP_UCM_CAPTURE_SWITCH "alsa.ucm.capture.switch" - -+/** For devices: Capture mixer device name */ -+#define PA_ALSA_PROP_UCM_CAPTURE_MIXER_DEVICE "alsa.ucm.capture.mixer.device" -+ - /** For devices: Capture mixer identifier */ - #define PA_ALSA_PROP_UCM_CAPTURE_MIXER_ELEM "alsa.ucm.capture.mixer.element" - -@@ -114,6 +126,9 @@ typedef void snd_use_case_mgr_t; - /** For devices: The modifier (if any) that this device corresponds to */ - #define PA_ALSA_PROP_UCM_MODIFIER "alsa.ucm.modifier" - -+/* Corresponds to the "JackCTL" UCM value. */ -+#define PA_ALSA_PROP_UCM_JACK_DEVICE "alsa.ucm.jack_device" -+ - /* Corresponds to the "JackControl" UCM value. */ - #define PA_ALSA_PROP_UCM_JACK_CONTROL "alsa.ucm.jack_control" - --- -2.16.4 - diff --git a/0023-alsa-ucm-get-the-mixer-names-from-ucm-don-t-guess.patch b/0023-alsa-ucm-get-the-mixer-names-from-ucm-don-t-guess.patch deleted file mode 100644 index bbe539b..0000000 --- a/0023-alsa-ucm-get-the-mixer-names-from-ucm-don-t-guess.patch +++ /dev/null @@ -1,244 +0,0 @@ -From e438382a51f7e0d04fb9439da2f45c183e958e0f Mon Sep 17 00:00:00 2001 -From: Jaroslav Kysela -Date: Fri, 6 Dec 2019 21:32:21 +0100 -Subject: [PATCH] alsa-ucm: get the mixer names from ucm, don't guess - -Signed-off-by: Jaroslav Kysela ---- - src/modules/alsa/alsa-mixer.h | 1 + - src/modules/alsa/alsa-ucm.c | 96 +++++++++++++++++++++++++++++++++++-------- - src/modules/alsa/alsa-util.c | 26 ++++++++---- - 3 files changed, 97 insertions(+), 26 deletions(-) - -diff --git a/src/modules/alsa/alsa-mixer.h b/src/modules/alsa/alsa-mixer.h -index 0b634f2f2be1..7864a2c1252f 100644 ---- a/src/modules/alsa/alsa-mixer.h -+++ b/src/modules/alsa/alsa-mixer.h -@@ -364,6 +364,7 @@ void pa_alsa_profile_set_free(pa_alsa_profile_set *s); - void pa_alsa_profile_set_dump(pa_alsa_profile_set *s); - void pa_alsa_profile_set_drop_unsupported(pa_alsa_profile_set *s); - -+snd_mixer_t *pa_alsa_open_mixer_by_name(const char *dev); - snd_mixer_t *pa_alsa_open_mixer_for_pcm(snd_pcm_t *pcm, char **ctl_device); - - pa_alsa_fdlist *pa_alsa_fdlist_new(void); -diff --git a/src/modules/alsa/alsa-ucm.c b/src/modules/alsa/alsa-ucm.c -index 2a594b4df546..d02adab650fe 100644 ---- a/src/modules/alsa/alsa-ucm.c -+++ b/src/modules/alsa/alsa-ucm.c -@@ -289,6 +289,31 @@ static pa_alsa_ucm_volume *ucm_get_mixer_volume( - return vol; - } - -+/* Get the ALSA mixer device for the UCM device */ -+static const char *get_mixer_device(pa_alsa_ucm_device *dev, bool is_sink) -+{ -+ const char *dev_name; -+ -+ if (is_sink) { -+ dev_name = pa_proplist_gets(dev->proplist, PA_ALSA_PROP_UCM_PLAYBACK_MIXER_DEVICE); -+ if (!dev_name) -+ dev_name = pa_proplist_gets(dev->proplist, PA_ALSA_PROP_UCM_PLAYBACK_CTL_DEVICE); -+ } else { -+ dev_name = pa_proplist_gets(dev->proplist, PA_ALSA_PROP_UCM_CAPTURE_MIXER_DEVICE); -+ if (!dev_name) -+ dev_name = pa_proplist_gets(dev->proplist, PA_ALSA_PROP_UCM_CAPTURE_CTL_DEVICE); -+ } -+ return dev_name; -+} -+ -+/* Get the ALSA mixer device for the UCM jack */ -+static const char *get_jack_mixer_device(pa_alsa_ucm_device *dev, bool is_sink) { -+ const char *dev_name = pa_proplist_gets(dev->proplist, PA_ALSA_PROP_UCM_JACK_DEVICE); -+ if (!dev_name) -+ return get_mixer_device(dev, is_sink); -+ return dev_name; -+} -+ - /* Create a property list for this ucm device */ - static int ucm_get_device_property( - pa_alsa_ucm_device *device, -@@ -795,22 +820,41 @@ static int pa_alsa_ucm_device_cmp(const void *a, const void *b) { - return strcmp(pa_proplist_gets(d1->proplist, PA_ALSA_PROP_UCM_NAME), pa_proplist_gets(d2->proplist, PA_ALSA_PROP_UCM_NAME)); - } - --static void probe_volumes(pa_hashmap *hash, snd_pcm_t *pcm_handle, bool ignore_dB) { -+static void probe_volumes(pa_hashmap *hash, bool is_sink, snd_pcm_t *pcm_handle, bool ignore_dB) { - pa_device_port *port; - pa_alsa_path *path; - pa_alsa_ucm_port_data *data; -- snd_mixer_t *mixer_handle; -- const char *profile; -+ pa_alsa_ucm_device *dev; -+ snd_mixer_t *mixer_handle = NULL; -+ const char *profile, *mdev_opened = NULL, *mdev, *mdev2; - void *state, *state2; -- -- if (!(mixer_handle = pa_alsa_open_mixer_for_pcm(pcm_handle, NULL))) { -- pa_log_error("Failed to find a working mixer device."); -- goto fail; -- } -+ int idx; - - PA_HASHMAP_FOREACH(port, hash, state) { - data = PA_DEVICE_PORT_DATA(port); - -+ mdev = NULL; -+ PA_DYNARRAY_FOREACH(dev, data->devices, idx) { -+ mdev2 = get_mixer_device(dev, is_sink); -+ if (mdev && !pa_streq(mdev, mdev2)) { -+ pa_log_error("Two mixer device names found ('%s', '%s'), using s/w volume", mdev, mdev2); -+ goto fail; -+ } -+ mdev = mdev2; -+ } -+ -+ if (!mdev_opened || !pa_streq(mdev_opened, mdev)) { -+ if (mixer_handle) { -+ snd_mixer_close(mixer_handle); -+ mdev_opened = NULL; -+ } -+ if (!(mixer_handle = pa_alsa_open_mixer_by_name(mdev))) { -+ pa_log_error("Failed to find a working mixer device (%s).", mdev); -+ goto fail; -+ } -+ mdev_opened = mdev; -+ } -+ - PA_HASHMAP_FOREACH_KV(profile, path, data->paths, state2) { - if (pa_alsa_path_probe(path, NULL, mixer_handle, ignore_dB) < 0) { - pa_log_warn("Could not probe path: %s, using s/w volume", data->path->name); -@@ -823,7 +867,8 @@ static void probe_volumes(pa_hashmap *hash, snd_pcm_t *pcm_handle, bool ignore_d - } - } - -- snd_mixer_close(mixer_handle); -+ if (mixer_handle) -+ snd_mixer_close(mixer_handle); - - return; - -@@ -1149,7 +1194,7 @@ void pa_alsa_ucm_add_ports( - pa_alsa_ucm_add_ports_combination(*p, context, is_sink, card->ports, NULL, card->core); - - /* now set up volume paths if any */ -- probe_volumes(*p, pcm_handle, ignore_dB); -+ probe_volumes(*p, is_sink, pcm_handle, ignore_dB); - - /* then set property PA_PROP_DEVICE_INTENDED_ROLES */ - merged_roles = pa_xstrdup(pa_proplist_gets(proplist, PA_PROP_DEVICE_INTENDED_ROLES)); -@@ -1716,28 +1761,43 @@ static void profile_finalize_probing(pa_alsa_profile *p) { - } - - static void ucm_mapping_jack_probe(pa_alsa_mapping *m) { -- snd_pcm_t *pcm_handle; -- snd_mixer_t *mixer_handle; -+ snd_mixer_t *mixer_handle = NULL; - pa_alsa_ucm_mapping_context *context = &m->ucm_context; - pa_alsa_ucm_device *dev; -+ bool is_sink = m->direction == PA_ALSA_DIRECTION_OUTPUT; -+ const char *mdev_opened = NULL, *mdev; - uint32_t idx; - -- pcm_handle = m->direction == PA_ALSA_DIRECTION_OUTPUT ? m->output_pcm : m->input_pcm; -- mixer_handle = pa_alsa_open_mixer_for_pcm(pcm_handle, NULL); -- if (!mixer_handle) -- return; -- - PA_IDXSET_FOREACH(dev, context->ucm_devices, idx) { - bool has_control; - - if (!dev->jack) - continue; -+ -+ mdev = get_jack_mixer_device(dev, is_sink); -+ if (mdev == NULL) { -+ pa_log_error("Unable to determine mixer device for jack %s", dev->jack->name); -+ continue; -+ } -+ -+ if (!mdev_opened || !pa_streq(mdev_opened, mdev)) { -+ if (mixer_handle) { -+ snd_mixer_close(mixer_handle); -+ mdev_opened = NULL; -+ } -+ mixer_handle = pa_alsa_open_mixer_by_name(mdev); -+ if (!mixer_handle) -+ continue; -+ mdev_opened = mdev; -+ } -+ - has_control = pa_alsa_mixer_find(mixer_handle, dev->jack->alsa_name, 0) != NULL; - pa_alsa_jack_set_has_control(dev->jack, has_control); - pa_log_info("UCM jack %s has_control=%d", dev->jack->name, dev->jack->has_control); - } - -- snd_mixer_close(mixer_handle); -+ if (mixer_handle) -+ snd_mixer_close(mixer_handle); - } - - static void ucm_probe_profile_set(pa_alsa_ucm_config *ucm, pa_alsa_profile_set *ps) { -diff --git a/src/modules/alsa/alsa-util.c b/src/modules/alsa/alsa-util.c -index 54fe1361148a..2df2258d85af 100644 ---- a/src/modules/alsa/alsa-util.c -+++ b/src/modules/alsa/alsa-util.c -@@ -1740,20 +1740,31 @@ snd_mixer_t *pa_alsa_open_mixer(int alsa_card_index, char **ctl_device) { - return NULL; - } - --snd_mixer_t *pa_alsa_open_mixer_for_pcm(snd_pcm_t *pcm, char **ctl_device) { -+snd_mixer_t *pa_alsa_open_mixer_by_name(const char *dev) { - int err; - snd_mixer_t *m; -- snd_pcm_info_t* info; -- snd_pcm_info_alloca(&info); - -- pa_assert(pcm); -+ pa_assert(dev); - - if ((err = snd_mixer_open(&m, 0)) < 0) { - pa_log("Error opening mixer: %s", pa_alsa_strerror(err)); - return NULL; - } - -- /* Then, try by card index */ -+ if (prepare_mixer(m, dev) >= 0) -+ return m; -+ -+ snd_mixer_close(m); -+ return NULL; -+} -+ -+snd_mixer_t *pa_alsa_open_mixer_for_pcm(snd_pcm_t *pcm, char **ctl_device) { -+ snd_mixer_t *m; -+ snd_pcm_info_t* info; -+ snd_pcm_info_alloca(&info); -+ -+ pa_assert(pcm); -+ - if (snd_pcm_info(pcm, info) >= 0) { - char *md; - int card_idx; -@@ -1761,8 +1772,8 @@ snd_mixer_t *pa_alsa_open_mixer_for_pcm(snd_pcm_t *pcm, char **ctl_device) { - if ((card_idx = snd_pcm_info_get_card(info)) >= 0) { - - md = pa_sprintf_malloc("hw:%i", card_idx); -- if (prepare_mixer(m, md) >= 0) { -- -+ m = pa_alsa_open_mixer_by_name(md); -+ if (m) { - if (ctl_device) - *ctl_device = md; - else -@@ -1775,7 +1786,6 @@ snd_mixer_t *pa_alsa_open_mixer_for_pcm(snd_pcm_t *pcm, char **ctl_device) { - } - } - -- snd_mixer_close(m); - return NULL; - } - --- -2.16.4 - diff --git a/0024-alsa-ucm-use-the-proper-mixer-name-for-ucm-pcm-sink-.patch b/0024-alsa-ucm-use-the-proper-mixer-name-for-ucm-pcm-sink-.patch deleted file mode 100644 index 3765860..0000000 --- a/0024-alsa-ucm-use-the-proper-mixer-name-for-ucm-pcm-sink-.patch +++ /dev/null @@ -1,93 +0,0 @@ -From dacfcbb09c9d91ca20dedfa449da37f0f7e3953f Mon Sep 17 00:00:00 2001 -From: Jaroslav Kysela -Date: Sat, 7 Dec 2019 11:50:13 +0100 -Subject: [PATCH] alsa-ucm: use the proper mixer name for ucm pcm sink/source - -Signed-off-by: Jaroslav Kysela ---- - src/modules/alsa/alsa-sink.c | 9 ++++++++- - src/modules/alsa/alsa-source.c | 10 +++++++++- - src/modules/alsa/alsa-ucm.c | 9 +++++++-- - 3 files changed, 24 insertions(+), 4 deletions(-) - -diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c -index 19e9efc3674b..5ea4b2597449 100644 ---- a/src/modules/alsa/alsa-sink.c -+++ b/src/modules/alsa/alsa-sink.c -@@ -2083,11 +2083,18 @@ static void set_sink_name(pa_sink_new_data *data, pa_modargs *ma, const char *de - } - - static void find_mixer(struct userdata *u, pa_alsa_mapping *mapping, const char *element, bool ignore_dB) { -+ const char *mdev; - - if (!mapping && !element) - return; - -- if (!(u->mixer_handle = pa_alsa_open_mixer_for_pcm(u->pcm_handle, &u->control_device))) { -+ mdev = pa_proplist_gets(mapping->proplist, "alsa.mixer_device"); -+ if (mdev) { -+ u->mixer_handle = pa_alsa_open_mixer_by_name(mdev); -+ } else { -+ u->mixer_handle = pa_alsa_open_mixer_for_pcm(u->pcm_handle, &u->control_device); -+ } -+ if (!mdev) { - pa_log_info("Failed to find a working mixer device."); - return; - } -diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c -index 34946b74c77f..bd78d45e2a5b 100644 ---- a/src/modules/alsa/alsa-source.c -+++ b/src/modules/alsa/alsa-source.c -@@ -1789,10 +1789,18 @@ static void set_source_name(pa_source_new_data *data, pa_modargs *ma, const char - } - - static void find_mixer(struct userdata *u, pa_alsa_mapping *mapping, const char *element, bool ignore_dB) { -+ const char *mdev; -+ - if (!mapping && !element) - return; - -- if (!(u->mixer_handle = pa_alsa_open_mixer_for_pcm(u->pcm_handle, &u->control_device))) { -+ mdev = pa_proplist_gets(mapping->proplist, "alsa.mixer_device"); -+ if (mdev) { -+ u->mixer_handle = pa_alsa_open_mixer_by_name(mdev); -+ } else { -+ u->mixer_handle = pa_alsa_open_mixer_for_pcm(u->pcm_handle, &u->control_device); -+ } -+ if (!mdev) { - pa_log_info("Failed to find a working mixer device."); - return; - } -diff --git a/src/modules/alsa/alsa-ucm.c b/src/modules/alsa/alsa-ucm.c -index d02adab650fe..d1ca62d28619 100644 ---- a/src/modules/alsa/alsa-ucm.c -+++ b/src/modules/alsa/alsa-ucm.c -@@ -1339,7 +1339,8 @@ static void ucm_add_mapping(pa_alsa_profile *p, pa_alsa_mapping *m) { - - static void alsa_mapping_add_ucm_device(pa_alsa_mapping *m, pa_alsa_ucm_device *device) { - char *cur_desc; -- const char *new_desc; -+ const char *new_desc, *mdev; -+ bool is_sink = m->direction == PA_ALSA_DIRECTION_OUTPUT; - - pa_idxset_put(m->ucm_context.ucm_devices, device, NULL); - -@@ -1355,10 +1356,14 @@ static void alsa_mapping_add_ucm_device(pa_alsa_mapping *m, pa_alsa_ucm_device * - m->description = m->description ? m->description : pa_xstrdup(""); - - /* save mapping to ucm device */ -- if (m->direction == PA_ALSA_DIRECTION_OUTPUT) -+ if (is_sink) - device->playback_mapping = m; - else - device->capture_mapping = m; -+ -+ mdev = get_mixer_device(device, is_sink); -+ if (mdev) -+ pa_proplist_sets(m->proplist, "alsa.mixer_device", mdev); - } - - static void alsa_mapping_add_ucm_modifier(pa_alsa_mapping *m, pa_alsa_ucm_modifier *modifier) { --- -2.16.4 - diff --git a/0025-alsa-mixer-handle-interface-type-CARD-PCM-for-mixer-.patch b/0025-alsa-mixer-handle-interface-type-CARD-PCM-for-mixer-.patch deleted file mode 100644 index 953fc64..0000000 --- a/0025-alsa-mixer-handle-interface-type-CARD-PCM-for-mixer-.patch +++ /dev/null @@ -1,125 +0,0 @@ -From f18b0c3402f5e1f7db9d0a42c6e10cfe1f212da3 Mon Sep 17 00:00:00 2001 -From: Jaroslav Kysela -Date: Sat, 7 Dec 2019 17:54:04 +0100 -Subject: [PATCH] alsa-mixer: handle interface type (CARD,PCM) for mixer - element lookups - -Signed-off-by: Jaroslav Kysela ---- - src/modules/alsa/alsa-mixer.c | 2 +- - src/modules/alsa/alsa-ucm.c | 2 +- - src/modules/alsa/alsa-util.c | 18 +++++++++++++++++- - src/modules/alsa/alsa-util.h | 3 ++- - src/modules/alsa/module-alsa-card.c | 4 ++-- - 5 files changed, 23 insertions(+), 6 deletions(-) - -diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c -index ed06f42d86da..094cff817df7 100644 ---- a/src/modules/alsa/alsa-mixer.c -+++ b/src/modules/alsa/alsa-mixer.c -@@ -1907,7 +1907,7 @@ static int jack_probe(pa_alsa_jack *j, pa_alsa_mapping *mapping, snd_mixer_t *m) - j->append_pcm_to_name = false; - } - -- has_control = pa_alsa_mixer_find(m, j->alsa_name, 0) != NULL; -+ has_control = pa_alsa_mixer_find_card(m, j->alsa_name, 0) != NULL; - pa_alsa_jack_set_has_control(j, has_control); - - if (j->has_control) { -diff --git a/src/modules/alsa/alsa-ucm.c b/src/modules/alsa/alsa-ucm.c -index d1ca62d28619..a64505a0c781 100644 ---- a/src/modules/alsa/alsa-ucm.c -+++ b/src/modules/alsa/alsa-ucm.c -@@ -1796,7 +1796,7 @@ static void ucm_mapping_jack_probe(pa_alsa_mapping *m) { - mdev_opened = mdev; - } - -- has_control = pa_alsa_mixer_find(mixer_handle, dev->jack->alsa_name, 0) != NULL; -+ has_control = pa_alsa_mixer_find_card(mixer_handle, dev->jack->alsa_name, 0) != NULL; - pa_alsa_jack_set_has_control(dev->jack, has_control); - pa_log_info("UCM jack %s has_control=%d", dev->jack->name, dev->jack->has_control); - } -diff --git a/src/modules/alsa/alsa-util.c b/src/modules/alsa/alsa-util.c -index 2df2258d85af..08a144782394 100644 ---- a/src/modules/alsa/alsa-util.c -+++ b/src/modules/alsa/alsa-util.c -@@ -1610,7 +1610,11 @@ bool pa_alsa_may_tsched(bool want) { - - #define SND_MIXER_ELEM_PULSEAUDIO (SND_MIXER_ELEM_LAST + 10) - --snd_mixer_elem_t *pa_alsa_mixer_find(snd_mixer_t *mixer, const char *name, unsigned int device) { -+static snd_mixer_elem_t *pa_alsa_mixer_find(snd_mixer_t *mixer, -+ snd_ctl_elem_iface_t iface, -+ const char *name, -+ unsigned int index, -+ unsigned int device) { - snd_mixer_elem_t *elem; - - for (elem = snd_mixer_first_elem(mixer); elem; elem = snd_mixer_elem_next(elem)) { -@@ -1618,8 +1622,12 @@ snd_mixer_elem_t *pa_alsa_mixer_find(snd_mixer_t *mixer, const char *name, unsig - if (snd_mixer_elem_get_type(elem) != SND_MIXER_ELEM_PULSEAUDIO) - continue; - helem = snd_mixer_elem_get_private(elem); -+ if (snd_hctl_elem_get_interface(helem) != iface) -+ continue; - if (!pa_streq(snd_hctl_elem_get_name(helem), name)) - continue; -+ if (snd_hctl_elem_get_index(helem) != index) -+ continue; - if (snd_hctl_elem_get_device(helem) != device) - continue; - return elem; -@@ -1627,6 +1635,14 @@ snd_mixer_elem_t *pa_alsa_mixer_find(snd_mixer_t *mixer, const char *name, unsig - return NULL; - } - -+snd_mixer_elem_t *pa_alsa_mixer_find_card(snd_mixer_t *mixer, const char *name, unsigned int device) { -+ return pa_alsa_mixer_find(mixer, SND_CTL_ELEM_IFACE_CARD, name, 0, device); -+} -+ -+snd_mixer_elem_t *pa_alsa_mixer_find_pcm(snd_mixer_t *mixer, const char *name, unsigned int device) { -+ return pa_alsa_mixer_find(mixer, SND_CTL_ELEM_IFACE_PCM, name, 0, device); -+} -+ - static int mixer_class_compare(const snd_mixer_elem_t *c1, const snd_mixer_elem_t *c2) - { - /* Dummy compare function */ -diff --git a/src/modules/alsa/alsa-util.h b/src/modules/alsa/alsa-util.h -index 4ceaa06ee480..ceca48809400 100644 ---- a/src/modules/alsa/alsa-util.h -+++ b/src/modules/alsa/alsa-util.h -@@ -141,7 +141,8 @@ const char* pa_alsa_strerror(int errnum); - - bool pa_alsa_may_tsched(bool want); - --snd_mixer_elem_t *pa_alsa_mixer_find(snd_mixer_t *mixer, const char *name, unsigned int device); -+snd_mixer_elem_t *pa_alsa_mixer_find_card(snd_mixer_t *mixer, const char *name, unsigned int device); -+snd_mixer_elem_t *pa_alsa_mixer_find_pcm(snd_mixer_t *mixer, const char *name, unsigned int device); - - snd_mixer_t *pa_alsa_open_mixer(int alsa_card_index, char **ctl_device); - -diff --git a/src/modules/alsa/module-alsa-card.c b/src/modules/alsa/module-alsa-card.c -index be260e4badab..ba7a19a38983 100644 ---- a/src/modules/alsa/module-alsa-card.c -+++ b/src/modules/alsa/module-alsa-card.c -@@ -588,7 +588,7 @@ static void init_eld_ctls(struct userdata *u) { - if (device < 0) - continue; - -- melem = pa_alsa_mixer_find(u->mixer_handle, "ELD", device); -+ melem = pa_alsa_mixer_find_pcm(u->mixer_handle, "ELD", device); - if (melem) { - snd_mixer_elem_set_callback(melem, hdmi_eld_changed); - snd_mixer_elem_set_callback_private(melem, u); -@@ -635,7 +635,7 @@ static void init_jacks(struct userdata *u) { - u->mixer_handle = pa_alsa_open_mixer(u->alsa_card_index, NULL); - if (u->mixer_handle && pa_alsa_fdlist_set_handle(u->mixer_fdl, u->mixer_handle, NULL, u->core->mainloop) >= 0) { - PA_HASHMAP_FOREACH(jack, u->jacks, state) { -- jack->melem = pa_alsa_mixer_find(u->mixer_handle, jack->alsa_name, 0); -+ jack->melem = pa_alsa_mixer_find_card(u->mixer_handle, jack->alsa_name, 0); - if (!jack->melem) { - pa_log_warn("Jack '%s' seems to have disappeared.", jack->alsa_name); - pa_alsa_jack_set_has_control(jack, false); --- -2.16.4 - diff --git a/0026-alsa-mixer-Add-the-ability-to-pass-the-intended-role.patch b/0026-alsa-mixer-Add-the-ability-to-pass-the-intended-role.patch deleted file mode 100644 index 856fd86..0000000 --- a/0026-alsa-mixer-Add-the-ability-to-pass-the-intended-role.patch +++ /dev/null @@ -1,51 +0,0 @@ -From c6a0665618975eedc98bdf23e4140935a1af38c2 Mon Sep 17 00:00:00 2001 -From: Laurent Bigonville -Date: Thu, 7 Mar 2019 11:35:30 +0100 -Subject: [PATCH] alsa-mixer: Add the ability to pass the intended-role to the - mapping - -https://gitlab.freedesktop.org/pulseaudio/pulseaudio/issues/640 ---- - src/modules/alsa/alsa-mixer.c | 19 +++++++++++++++++++ - 1 file changed, 19 insertions(+) - -diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c -index 094cff817df7..7956371b604b 100644 ---- a/src/modules/alsa/alsa-mixer.c -+++ b/src/modules/alsa/alsa-mixer.c -@@ -3978,6 +3978,24 @@ static int mapping_parse_fallback(pa_config_parser_state *state) { - return 0; - } - -+static int mapping_parse_intended_roles(pa_config_parser_state *state) { -+ pa_alsa_profile_set *ps; -+ pa_alsa_mapping *m; -+ -+ pa_assert(state); -+ -+ ps = state->userdata; -+ -+ if (!(m = pa_alsa_mapping_get(ps, state->section))) { -+ pa_log("[%s:%u] %s invalid in section %s", state->filename, state->lineno, state->lvalue, state->section); -+ return -1; -+ } -+ -+ pa_proplist_sets(m->proplist, PA_PROP_DEVICE_INTENDED_ROLES, state->rvalue); -+ -+ return 0; -+} -+ - - static int profile_parse_mappings(pa_config_parser_state *state) { - pa_alsa_profile_set *ps; -@@ -4569,6 +4587,7 @@ pa_alsa_profile_set* pa_alsa_profile_set_new(const char *fname, const pa_channel - { "element-output", mapping_parse_element, NULL, NULL }, - { "direction", mapping_parse_direction, NULL, NULL }, - { "exact-channels", mapping_parse_exact_channels, NULL, NULL }, -+ { "intended-roles", mapping_parse_intended_roles, NULL, NULL }, - - /* Shared by [Mapping ...] and [Profile ...] */ - { "description", mapping_parse_description, NULL, NULL }, --- -2.16.4 - diff --git a/0027-alsa-mixer-Set-the-intended-role-of-Steelseries-Arct.patch b/0027-alsa-mixer-Set-the-intended-role-of-Steelseries-Arct.patch deleted file mode 100644 index ac38101..0000000 --- a/0027-alsa-mixer-Set-the-intended-role-of-Steelseries-Arct.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 6438e5c46dc449e4726ec9312859cc70388d2851 Mon Sep 17 00:00:00 2001 -From: Laurent Bigonville -Date: Thu, 7 Mar 2019 11:36:02 +0100 -Subject: [PATCH] alsa-mixer: Set the intended-role of Steelseries Arctis 5/7 - headset as phone - -Fixes: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/issues/640 ---- - .../alsa/mixer/profile-sets/steelseries-arctis-common-usb-audio.conf | 1 + - src/modules/alsa/mixer/profile-sets/usb-gaming-headset.conf | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/src/modules/alsa/mixer/profile-sets/steelseries-arctis-common-usb-audio.conf b/src/modules/alsa/mixer/profile-sets/steelseries-arctis-common-usb-audio.conf -index 80c33707aea4..5f11ed1e26ef 100644 ---- a/src/modules/alsa/mixer/profile-sets/steelseries-arctis-common-usb-audio.conf -+++ b/src/modules/alsa/mixer/profile-sets/steelseries-arctis-common-usb-audio.conf -@@ -7,6 +7,7 @@ device-strings = hw:%f,0,0 - channel-map = left,right - paths-input = analog-input-mic - paths-output = steelseries-arctis-output-chat-common -+intended-roles = phone - - [Mapping analog-game] - description = Game -diff --git a/src/modules/alsa/mixer/profile-sets/usb-gaming-headset.conf b/src/modules/alsa/mixer/profile-sets/usb-gaming-headset.conf -index 01ecf864bcf2..f48b44f03767 100644 ---- a/src/modules/alsa/mixer/profile-sets/usb-gaming-headset.conf -+++ b/src/modules/alsa/mixer/profile-sets/usb-gaming-headset.conf -@@ -34,6 +34,7 @@ device-strings = hw:%f,0,0 - channel-map = mono - paths-output = usb-gaming-headset-output-mono - paths-input = usb-gaming-headset-input -+intended-roles = phone - - [Mapping analog-stereo] - device-strings = hw:%f,1,0 --- -2.16.4 - diff --git a/0028-alsa-rewrite-mixer-open-close-cache-mixer-accesses-i.patch b/0028-alsa-rewrite-mixer-open-close-cache-mixer-accesses-i.patch deleted file mode 100644 index b8db228..0000000 --- a/0028-alsa-rewrite-mixer-open-close-cache-mixer-accesses-i.patch +++ /dev/null @@ -1,761 +0,0 @@ -From 3bd7c70c518d66707cbfde138ab7dcc505e463ac Mon Sep 17 00:00:00 2001 -From: Jaroslav Kysela -Date: Sat, 7 Dec 2019 20:39:21 +0100 -Subject: [PATCH] alsa: rewrite mixer open/close, cache mixer accesses in probe - -The ALSA mixer can be opened multiple times (especially for UCM -in the probe). This adds a simple mixer cache to prevent -multiple open calls. - -Signed-off-by: Jaroslav Kysela ---- - src/modules/alsa/alsa-mixer.c | 19 ++++---- - src/modules/alsa/alsa-mixer.h | 19 ++++++-- - src/modules/alsa/alsa-sink.c | 21 ++++---- - src/modules/alsa/alsa-source.c | 21 ++++---- - src/modules/alsa/alsa-ucm.c | 66 ++++++++++---------------- - src/modules/alsa/alsa-ucm.h | 1 + - src/modules/alsa/alsa-util.c | 95 +++++++++++++++++++------------------ - src/modules/alsa/alsa-util.h | 6 ++- - src/modules/alsa/module-alsa-card.c | 76 ++++++++++++++++++----------- - 9 files changed, 175 insertions(+), 149 deletions(-) - -diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c -index 7956371b604b..a3c998b654e9 100644 ---- a/src/modules/alsa/alsa-mixer.c -+++ b/src/modules/alsa/alsa-mixer.c -@@ -147,13 +147,14 @@ static int alsa_id_decode(const char *src, char *name, int *index) { - return 0; - } - --pa_alsa_jack *pa_alsa_jack_new(pa_alsa_path *path, const char *name) { -+pa_alsa_jack *pa_alsa_jack_new(pa_alsa_path *path, const char *mixer_device_name, const char *name) { - pa_alsa_jack *jack; - - pa_assert(name); - - jack = pa_xnew0(pa_alsa_jack, 1); - jack->path = path; -+ jack->mixer_device_name = pa_xstrdup(mixer_device_name); - jack->name = pa_xstrdup(name); - jack->alsa_name = pa_sprintf_malloc("%s Jack", name); - jack->state_unplugged = PA_AVAILABLE_NO; -@@ -172,6 +173,7 @@ void pa_alsa_jack_free(pa_alsa_jack *jack) { - - pa_xfree(jack->alsa_name); - pa_xfree(jack->name); -+ pa_xfree(jack->mixer_device_name); - pa_xfree(jack); - } - -@@ -1982,7 +1984,7 @@ static pa_alsa_jack* jack_get(pa_alsa_path *p, const char *section) { - if (pa_streq(j->name, section)) - goto finish; - -- j = pa_alsa_jack_new(p, section); -+ j = pa_alsa_jack_new(p, NULL, section); - PA_LLIST_INSERT_AFTER(pa_alsa_jack, p->jacks, p->last_jack, j); - - finish: -@@ -4160,7 +4162,8 @@ fail: - } - - static void mapping_paths_probe(pa_alsa_mapping *m, pa_alsa_profile *profile, -- pa_alsa_direction_t direction, pa_hashmap *used_paths) { -+ pa_alsa_direction_t direction, pa_hashmap *used_paths, -+ pa_hashmap *mixers) { - - pa_alsa_path *p; - void *state; -@@ -4185,7 +4188,7 @@ static void mapping_paths_probe(pa_alsa_mapping *m, pa_alsa_profile *profile, - - pa_assert(pcm_handle); - -- mixer_handle = pa_alsa_open_mixer_for_pcm(pcm_handle, NULL); -+ mixer_handle = pa_alsa_open_mixer_for_pcm(mixers, pcm_handle, true); - if (!mixer_handle) { - /* Cannot open mixer, remove all entries */ - pa_hashmap_remove_all(ps->paths); -@@ -4203,9 +4206,6 @@ static void mapping_paths_probe(pa_alsa_mapping *m, pa_alsa_profile *profile, - path_set_condense(ps, mixer_handle); - path_set_make_path_descriptions_unique(ps); - -- if (mixer_handle) -- snd_mixer_close(mixer_handle); -- - PA_HASHMAP_FOREACH(p, ps->paths, state) - pa_hashmap_put(used_paths, p, p); - -@@ -4785,6 +4785,7 @@ static void mapping_query_hw_device(pa_alsa_mapping *mapping, snd_pcm_t *pcm) { - - void pa_alsa_profile_set_probe( - pa_alsa_profile_set *ps, -+ pa_hashmap *mixers, - const char *dev_id, - const pa_sample_spec *ss, - unsigned default_n_fragments, -@@ -4914,14 +4915,14 @@ void pa_alsa_profile_set_probe( - PA_IDXSET_FOREACH(m, p->output_mappings, idx) - if (m->output_pcm) { - found_output |= !p->fallback_output; -- mapping_paths_probe(m, p, PA_ALSA_DIRECTION_OUTPUT, used_paths); -+ mapping_paths_probe(m, p, PA_ALSA_DIRECTION_OUTPUT, used_paths, mixers); - } - - if (p->input_mappings) - PA_IDXSET_FOREACH(m, p->input_mappings, idx) - if (m->input_pcm) { - found_input |= !p->fallback_input; -- mapping_paths_probe(m, p, PA_ALSA_DIRECTION_INPUT, used_paths); -+ mapping_paths_probe(m, p, PA_ALSA_DIRECTION_INPUT, used_paths, mixers); - } - } - -diff --git a/src/modules/alsa/alsa-mixer.h b/src/modules/alsa/alsa-mixer.h -index 7864a2c1252f..325b0c998b02 100644 ---- a/src/modules/alsa/alsa-mixer.h -+++ b/src/modules/alsa/alsa-mixer.h -@@ -32,6 +32,7 @@ - #include - - typedef struct pa_alsa_fdlist pa_alsa_fdlist; -+typedef struct pa_alsa_mixer pa_alsa_mixer; - typedef struct pa_alsa_mixer_pdata pa_alsa_mixer_pdata; - typedef struct pa_alsa_setting pa_alsa_setting; - typedef struct pa_alsa_mixer_id pa_alsa_mixer_id; -@@ -98,6 +99,13 @@ struct pa_alsa_setting { - unsigned priority; - }; - -+/* An entry for one ALSA mixer */ -+struct pa_alsa_mixer { -+ snd_mixer_t *mixer_handle; -+ pa_alsa_fdlist *fdl; -+ bool used_for_probe_only:1; -+}; -+ - /* ALSA mixer element identifier */ - struct pa_alsa_mixer_id { - char *name; -@@ -165,6 +173,9 @@ struct pa_alsa_jack { - pa_alsa_path *path; - PA_LLIST_FIELDS(pa_alsa_jack); - -+ snd_mixer_t *mixer_handle; -+ char *mixer_device_name; -+ - char *name; /* E g "Headphone" */ - char *alsa_name; /* E g "Headphone Jack" */ - bool has_control; /* is the jack itself present? */ -@@ -182,7 +193,7 @@ struct pa_alsa_jack { - bool append_pcm_to_name; - }; - --pa_alsa_jack *pa_alsa_jack_new(pa_alsa_path *path, const char *name); -+pa_alsa_jack *pa_alsa_jack_new(pa_alsa_path *path, const char *mixer_device_name, const char *name); - void pa_alsa_jack_free(pa_alsa_jack *jack); - void pa_alsa_jack_set_has_control(pa_alsa_jack *jack, bool has_control); - void pa_alsa_jack_set_plugged_in(pa_alsa_jack *jack, bool plugged_in); -@@ -201,6 +212,7 @@ struct pa_alsa_path { - char *description; - unsigned priority; - bool autodetect_eld_device; -+ pa_alsa_mixer *eld_mixer_handle; - int eld_device; - pa_proplist *proplist; - -@@ -359,14 +371,11 @@ void pa_alsa_decibel_fix_dump(pa_alsa_decibel_fix *db_fix); - pa_alsa_mapping *pa_alsa_mapping_get(pa_alsa_profile_set *ps, const char *name); - - pa_alsa_profile_set* pa_alsa_profile_set_new(const char *fname, const pa_channel_map *bonus); --void pa_alsa_profile_set_probe(pa_alsa_profile_set *ps, const char *dev_id, const pa_sample_spec *ss, unsigned default_n_fragments, unsigned default_fragment_size_msec); -+void pa_alsa_profile_set_probe(pa_alsa_profile_set *ps, pa_hashmap *mixers, const char *dev_id, const pa_sample_spec *ss, unsigned default_n_fragments, unsigned default_fragment_size_msec); - void pa_alsa_profile_set_free(pa_alsa_profile_set *s); - void pa_alsa_profile_set_dump(pa_alsa_profile_set *s); - void pa_alsa_profile_set_drop_unsupported(pa_alsa_profile_set *s); - --snd_mixer_t *pa_alsa_open_mixer_by_name(const char *dev); --snd_mixer_t *pa_alsa_open_mixer_for_pcm(snd_pcm_t *pcm, char **ctl_device); -- - pa_alsa_fdlist *pa_alsa_fdlist_new(void); - void pa_alsa_fdlist_free(pa_alsa_fdlist *fdl); - int pa_alsa_fdlist_set_handle(pa_alsa_fdlist *fdl, snd_mixer_t *mixer_handle, snd_hctl_t *hctl_handle, pa_mainloop_api* m); -diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c -index 5ea4b2597449..363b4be2fa25 100644 ---- a/src/modules/alsa/alsa-sink.c -+++ b/src/modules/alsa/alsa-sink.c -@@ -105,6 +105,7 @@ struct userdata { - char *paths_dir; - pa_alsa_fdlist *mixer_fdl; - pa_alsa_mixer_pdata *mixer_pd; -+ pa_hashmap *mixers; - snd_mixer_t *mixer_handle; - pa_alsa_path_set *mixer_path_set; - pa_alsa_path *mixer_path; -@@ -2088,13 +2089,16 @@ static void find_mixer(struct userdata *u, pa_alsa_mapping *mapping, const char - if (!mapping && !element) - return; - -+ u->mixers = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, -+ NULL, (pa_free_cb_t) pa_alsa_mixer_free); -+ - mdev = pa_proplist_gets(mapping->proplist, "alsa.mixer_device"); - if (mdev) { -- u->mixer_handle = pa_alsa_open_mixer_by_name(mdev); -+ u->mixer_handle = pa_alsa_open_mixer_by_name(u->mixers, mdev, true); - } else { -- u->mixer_handle = pa_alsa_open_mixer_for_pcm(u->pcm_handle, &u->control_device); -+ u->mixer_handle = pa_alsa_open_mixer_for_pcm(u->mixers, u->pcm_handle, true); - } -- if (!mdev) { -+ if (!u->mixer_handle) { - pa_log_info("Failed to find a working mixer device."); - return; - } -@@ -2121,10 +2125,9 @@ fail: - u->mixer_path = NULL; - } - -- if (u->mixer_handle) { -- snd_mixer_close(u->mixer_handle); -- u->mixer_handle = NULL; -- } -+ u->mixer_handle = NULL; -+ pa_hashmap_free(u->mixers); -+ u->mixers = NULL; - } - - static int setup_mixer(struct userdata *u, bool ignore_dB) { -@@ -2759,8 +2762,8 @@ static void userdata_free(struct userdata *u) { - if (u->mixer_path && !u->mixer_path_set && !u->ucm_context) - pa_alsa_path_free(u->mixer_path); - -- if (u->mixer_handle) -- snd_mixer_close(u->mixer_handle); -+ if (u->mixers) -+ pa_hashmap_free(u->mixers); - - if (u->smoother) - pa_smoother_free(u->smoother); -diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c -index bd78d45e2a5b..b46e845cc5a7 100644 ---- a/src/modules/alsa/alsa-source.c -+++ b/src/modules/alsa/alsa-source.c -@@ -93,6 +93,7 @@ struct userdata { - char *paths_dir; - pa_alsa_fdlist *mixer_fdl; - pa_alsa_mixer_pdata *mixer_pd; -+ pa_hashmap *mixers; - snd_mixer_t *mixer_handle; - pa_alsa_path_set *mixer_path_set; - pa_alsa_path *mixer_path; -@@ -1794,13 +1795,16 @@ static void find_mixer(struct userdata *u, pa_alsa_mapping *mapping, const char - if (!mapping && !element) - return; - -+ u->mixers = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, -+ NULL, (pa_free_cb_t) pa_alsa_mixer_free); -+ - mdev = pa_proplist_gets(mapping->proplist, "alsa.mixer_device"); - if (mdev) { -- u->mixer_handle = pa_alsa_open_mixer_by_name(mdev); -+ u->mixer_handle = pa_alsa_open_mixer_by_name(u->mixers, mdev, false); - } else { -- u->mixer_handle = pa_alsa_open_mixer_for_pcm(u->pcm_handle, &u->control_device); -+ u->mixer_handle = pa_alsa_open_mixer_for_pcm(u->mixers, u->pcm_handle, false); - } -- if (!mdev) { -+ if (!u->mixer_handle) { - pa_log_info("Failed to find a working mixer device."); - return; - } -@@ -1827,10 +1831,9 @@ fail: - u->mixer_path = NULL; - } - -- if (u->mixer_handle) { -- snd_mixer_close(u->mixer_handle); -- u->mixer_handle = NULL; -- } -+ u->mixer_handle = NULL; -+ pa_hashmap_free(u->mixers); -+ u->mixers = NULL; - } - - static int setup_mixer(struct userdata *u, bool ignore_dB) { -@@ -2403,8 +2406,8 @@ static void userdata_free(struct userdata *u) { - if (u->mixer_path && !u->mixer_path_set && !u->ucm_context) - pa_alsa_path_free(u->mixer_path); - -- if (u->mixer_handle) -- snd_mixer_close(u->mixer_handle); -+ if (u->mixers) -+ pa_hashmap_free(u->mixers); - - if (u->smoother) - pa_smoother_free(u->smoother); -diff --git a/src/modules/alsa/alsa-ucm.c b/src/modules/alsa/alsa-ucm.c -index a64505a0c781..b9a4b8c4b436 100644 ---- a/src/modules/alsa/alsa-ucm.c -+++ b/src/modules/alsa/alsa-ucm.c -@@ -820,13 +820,13 @@ static int pa_alsa_ucm_device_cmp(const void *a, const void *b) { - return strcmp(pa_proplist_gets(d1->proplist, PA_ALSA_PROP_UCM_NAME), pa_proplist_gets(d2->proplist, PA_ALSA_PROP_UCM_NAME)); - } - --static void probe_volumes(pa_hashmap *hash, bool is_sink, snd_pcm_t *pcm_handle, bool ignore_dB) { -+static void probe_volumes(pa_hashmap *hash, bool is_sink, snd_pcm_t *pcm_handle, pa_hashmap *mixers, bool ignore_dB) { - pa_device_port *port; - pa_alsa_path *path; - pa_alsa_ucm_port_data *data; - pa_alsa_ucm_device *dev; -- snd_mixer_t *mixer_handle = NULL; -- const char *profile, *mdev_opened = NULL, *mdev, *mdev2; -+ snd_mixer_t *mixer_handle; -+ const char *profile, *mdev, *mdev2; - void *state, *state2; - int idx; - -@@ -843,16 +843,9 @@ static void probe_volumes(pa_hashmap *hash, bool is_sink, snd_pcm_t *pcm_handle, - mdev = mdev2; - } - -- if (!mdev_opened || !pa_streq(mdev_opened, mdev)) { -- if (mixer_handle) { -- snd_mixer_close(mixer_handle); -- mdev_opened = NULL; -- } -- if (!(mixer_handle = pa_alsa_open_mixer_by_name(mdev))) { -- pa_log_error("Failed to find a working mixer device (%s).", mdev); -- goto fail; -- } -- mdev_opened = mdev; -+ if (!(mixer_handle = pa_alsa_open_mixer_by_name(mixers, mdev, true))) { -+ pa_log_error("Failed to find a working mixer device (%s).", mdev); -+ goto fail; - } - - PA_HASHMAP_FOREACH_KV(profile, path, data->paths, state2) { -@@ -867,9 +860,6 @@ static void probe_volumes(pa_hashmap *hash, bool is_sink, snd_pcm_t *pcm_handle, - } - } - -- if (mixer_handle) -- snd_mixer_close(mixer_handle); -- - return; - - fail: -@@ -1194,7 +1184,7 @@ void pa_alsa_ucm_add_ports( - pa_alsa_ucm_add_ports_combination(*p, context, is_sink, card->ports, NULL, card->core); - - /* now set up volume paths if any */ -- probe_volumes(*p, is_sink, pcm_handle, ignore_dB); -+ probe_volumes(*p, is_sink, pcm_handle, context->ucm->mixers, ignore_dB); - - /* then set property PA_PROP_DEVICE_INTENDED_ROLES */ - merged_roles = pa_xstrdup(pa_proplist_gets(proplist, PA_PROP_DEVICE_INTENDED_ROLES)); -@@ -1543,6 +1533,7 @@ static pa_alsa_jack* ucm_get_jack(pa_alsa_ucm_config *ucm, pa_alsa_ucm_device *d - pa_alsa_jack *j; - const char *device_name; - const char *jack_control; -+ const char *mixer_device_name; - char *name; - - pa_assert(ucm); -@@ -1585,7 +1576,14 @@ static pa_alsa_jack* ucm_get_jack(pa_alsa_ucm_config *ucm, pa_alsa_ucm_device *d - if (pa_streq(j->name, name)) - goto finish; - -- j = pa_alsa_jack_new(NULL, name); -+ mixer_device_name = get_jack_mixer_device(device, true); -+ if (!mixer_device_name) -+ mixer_device_name = get_jack_mixer_device(device, false); -+ if (!mixer_device_name) { -+ pa_log("[%s] No mixer device name for JackControl \"%s\"", device_name, jack_control); -+ return NULL; -+ } -+ j = pa_alsa_jack_new(NULL, mixer_device_name, name); - PA_LLIST_PREPEND(pa_alsa_jack, ucm->jacks, j); - - finish: -@@ -1765,44 +1763,28 @@ static void profile_finalize_probing(pa_alsa_profile *p) { - } - } - --static void ucm_mapping_jack_probe(pa_alsa_mapping *m) { -- snd_mixer_t *mixer_handle = NULL; -+static void ucm_mapping_jack_probe(pa_alsa_mapping *m, pa_hashmap *mixers) { -+ snd_mixer_t *mixer_handle; - pa_alsa_ucm_mapping_context *context = &m->ucm_context; - pa_alsa_ucm_device *dev; -- bool is_sink = m->direction == PA_ALSA_DIRECTION_OUTPUT; -- const char *mdev_opened = NULL, *mdev; - uint32_t idx; - - PA_IDXSET_FOREACH(dev, context->ucm_devices, idx) { - bool has_control; - -- if (!dev->jack) -+ if (!dev->jack || !dev->jack->mixer_device_name) - continue; - -- mdev = get_jack_mixer_device(dev, is_sink); -- if (mdev == NULL) { -- pa_log_error("Unable to determine mixer device for jack %s", dev->jack->name); -+ mixer_handle = pa_alsa_open_mixer_by_name(mixers, dev->jack->mixer_device_name, true); -+ if (!mixer_handle) { -+ pa_log_error("Unable to determine open mixer device '%s' for jack %s", dev->jack->mixer_device_name, dev->jack->name); - continue; - } - -- if (!mdev_opened || !pa_streq(mdev_opened, mdev)) { -- if (mixer_handle) { -- snd_mixer_close(mixer_handle); -- mdev_opened = NULL; -- } -- mixer_handle = pa_alsa_open_mixer_by_name(mdev); -- if (!mixer_handle) -- continue; -- mdev_opened = mdev; -- } -- - has_control = pa_alsa_mixer_find_card(mixer_handle, dev->jack->alsa_name, 0) != NULL; - pa_alsa_jack_set_has_control(dev->jack, has_control); - pa_log_info("UCM jack %s has_control=%d", dev->jack->name, dev->jack->has_control); - } -- -- if (mixer_handle) -- snd_mixer_close(mixer_handle); - } - - static void ucm_probe_profile_set(pa_alsa_ucm_config *ucm, pa_alsa_profile_set *ps) { -@@ -1860,11 +1842,11 @@ static void ucm_probe_profile_set(pa_alsa_ucm_config *ucm, pa_alsa_profile_set * - - PA_IDXSET_FOREACH(m, p->output_mappings, idx) - if (!PA_UCM_IS_MODIFIER_MAPPING(m)) -- ucm_mapping_jack_probe(m); -+ ucm_mapping_jack_probe(m, ucm->mixers); - - PA_IDXSET_FOREACH(m, p->input_mappings, idx) - if (!PA_UCM_IS_MODIFIER_MAPPING(m)) -- ucm_mapping_jack_probe(m); -+ ucm_mapping_jack_probe(m, ucm->mixers); - - profile_finalize_probing(p); - } -diff --git a/src/modules/alsa/alsa-ucm.h b/src/modules/alsa/alsa-ucm.h -index 014bc334ad67..49362992865b 100644 ---- a/src/modules/alsa/alsa-ucm.h -+++ b/src/modules/alsa/alsa-ucm.h -@@ -248,6 +248,7 @@ struct pa_alsa_ucm_config { - snd_use_case_mgr_t *ucm_mgr; - pa_alsa_ucm_verb *active_verb; - -+ pa_hashmap *mixers; - PA_LLIST_HEAD(pa_alsa_ucm_verb, verbs); - PA_LLIST_HEAD(pa_alsa_jack, jacks); - }; -diff --git a/src/modules/alsa/alsa-util.c b/src/modules/alsa/alsa-util.c -index 08a144782394..34930c9fa155 100644 ---- a/src/modules/alsa/alsa-util.c -+++ b/src/modules/alsa/alsa-util.c -@@ -1726,83 +1726,86 @@ static int prepare_mixer(snd_mixer_t *mixer, const char *dev) { - return 0; - } - --snd_mixer_t *pa_alsa_open_mixer(int alsa_card_index, char **ctl_device) { -- int err; -- snd_mixer_t *m; -- char *md; -- snd_pcm_info_t* info; -- snd_pcm_info_alloca(&info); -- -- if ((err = snd_mixer_open(&m, 0)) < 0) { -- pa_log("Error opening mixer: %s", pa_alsa_strerror(err)); -- return NULL; -- } -- -- /* Then, try by card index */ -- md = pa_sprintf_malloc("hw:%i", alsa_card_index); -- if (prepare_mixer(m, md) >= 0) { -- -- if (ctl_device) -- *ctl_device = md; -- else -- pa_xfree(md); -- -- return m; -- } -- -+snd_mixer_t *pa_alsa_open_mixer(pa_hashmap *mixers, int alsa_card_index, bool probe) { -+ char *md = pa_sprintf_malloc("hw:%i", alsa_card_index); -+ snd_mixer_t *m = pa_alsa_open_mixer_by_name(mixers, md, probe); - pa_xfree(md); -- -- snd_mixer_close(m); -- return NULL; -+ return m; - } - --snd_mixer_t *pa_alsa_open_mixer_by_name(const char *dev) { -+snd_mixer_t *pa_alsa_open_mixer_by_name(pa_hashmap *mixers, const char *dev, bool probe) { - int err; - snd_mixer_t *m; -+ pa_alsa_mixer *pm; - -+ pa_assert(mixers); - pa_assert(dev); - -+ pm = pa_hashmap_get(mixers, dev); -+ if (pm) { -+ if (!probe) -+ pm->used_for_probe_only = false; -+ return pm->mixer_handle; -+ } -+ - if ((err = snd_mixer_open(&m, 0)) < 0) { - pa_log("Error opening mixer: %s", pa_alsa_strerror(err)); - return NULL; - } - -- if (prepare_mixer(m, dev) >= 0) -- return m; -+ if (prepare_mixer(m, dev) >= 0) { -+ pm = pa_xnew0(pa_alsa_mixer, 1); -+ if (pm) { -+ pm->used_for_probe_only = probe; -+ pm->mixer_handle = m; -+ pa_hashmap_put(mixers, pa_xstrdup(dev), pm); -+ return m; -+ } -+ } - - snd_mixer_close(m); - return NULL; - } - --snd_mixer_t *pa_alsa_open_mixer_for_pcm(snd_pcm_t *pcm, char **ctl_device) { -- snd_mixer_t *m; -+snd_mixer_t *pa_alsa_open_mixer_for_pcm(pa_hashmap *mixers, snd_pcm_t *pcm, bool probe) { - snd_pcm_info_t* info; - snd_pcm_info_alloca(&info); - - pa_assert(pcm); - - if (snd_pcm_info(pcm, info) >= 0) { -- char *md; - int card_idx; - -- if ((card_idx = snd_pcm_info_get_card(info)) >= 0) { -+ if ((card_idx = snd_pcm_info_get_card(info)) >= 0) -+ return pa_alsa_open_mixer(mixers, card_idx, probe); -+ } - -- md = pa_sprintf_malloc("hw:%i", card_idx); -- m = pa_alsa_open_mixer_by_name(md); -- if (m) { -- if (ctl_device) -- *ctl_device = md; -- else -- pa_xfree(md); -+ return NULL; -+} - -- return m; -- } -+void pa_alsa_mixer_set_fdlist(pa_hashmap *mixers, snd_mixer_t *mixer_handle, pa_mainloop_api *ml) -+{ -+ pa_alsa_mixer *pm; -+ void *state; - -- pa_xfree(md); -+ PA_HASHMAP_FOREACH(pm, mixers, state) -+ if (pm->mixer_handle == mixer_handle) { -+ pm->used_for_probe_only = false; -+ if (!pm->fdl) { -+ pm->fdl = pa_alsa_fdlist_new(); -+ if (pm->fdl) -+ pa_alsa_fdlist_set_handle(pm->fdl, pm->mixer_handle, NULL, ml); -+ } - } -- } -+} - -- return NULL; -+void pa_alsa_mixer_free(pa_alsa_mixer *mixer) -+{ -+ if (mixer->fdl) -+ pa_alsa_fdlist_free(mixer->fdl); -+ if (mixer->mixer_handle) -+ snd_mixer_close(mixer->mixer_handle); -+ pa_xfree(mixer); - } - - int pa_alsa_get_hdmi_eld(snd_hctl_elem_t *elem, pa_hdmi_eld *eld) { -diff --git a/src/modules/alsa/alsa-util.h b/src/modules/alsa/alsa-util.h -index ceca48809400..0d3d5af13370 100644 ---- a/src/modules/alsa/alsa-util.h -+++ b/src/modules/alsa/alsa-util.h -@@ -144,7 +144,11 @@ bool pa_alsa_may_tsched(bool want); - snd_mixer_elem_t *pa_alsa_mixer_find_card(snd_mixer_t *mixer, const char *name, unsigned int device); - snd_mixer_elem_t *pa_alsa_mixer_find_pcm(snd_mixer_t *mixer, const char *name, unsigned int device); - --snd_mixer_t *pa_alsa_open_mixer(int alsa_card_index, char **ctl_device); -+snd_mixer_t *pa_alsa_open_mixer(pa_hashmap *mixers, int alsa_card_index, bool probe); -+snd_mixer_t *pa_alsa_open_mixer_by_name(pa_hashmap *mixers, const char *dev, bool probe); -+snd_mixer_t *pa_alsa_open_mixer_for_pcm(pa_hashmap *mixers, snd_pcm_t *pcm, bool probe); -+void pa_alsa_mixer_set_fdlist(pa_hashmap *mixers, snd_mixer_t *mixer, pa_mainloop_api *ml); -+void pa_alsa_mixer_free(pa_alsa_mixer *mixer); - - typedef struct pa_hdmi_eld pa_hdmi_eld; - struct pa_hdmi_eld { -diff --git a/src/modules/alsa/module-alsa-card.c b/src/modules/alsa/module-alsa-card.c -index ba7a19a38983..3b2f99fc4e54 100644 ---- a/src/modules/alsa/module-alsa-card.c -+++ b/src/modules/alsa/module-alsa-card.c -@@ -111,9 +111,8 @@ struct userdata { - char *device_id; - int alsa_card_index; - -- snd_mixer_t *mixer_handle; -+ pa_hashmap *mixers; - pa_hashmap *jacks; -- pa_alsa_fdlist *mixer_fdl; - - pa_card *card; - -@@ -569,9 +568,6 @@ static void init_eld_ctls(struct userdata *u) { - void *state; - pa_device_port *port; - -- if (!u->mixer_handle) -- return; -- - /* The code in this function expects ports to have a pa_alsa_port_data - * struct as their data, but in UCM mode ports don't have any data. Hence, - * the ELD controls can't currently be used in UCM mode. */ -@@ -580,6 +576,7 @@ static void init_eld_ctls(struct userdata *u) { - - PA_HASHMAP_FOREACH(port, u->card->ports, state) { - pa_alsa_port_data *data = PA_DEVICE_PORT_DATA(port); -+ snd_mixer_t *mixer_handle; - snd_mixer_elem_t* melem; - int device; - -@@ -588,8 +585,13 @@ static void init_eld_ctls(struct userdata *u) { - if (device < 0) - continue; - -- melem = pa_alsa_mixer_find_pcm(u->mixer_handle, "ELD", device); -+ mixer_handle = pa_alsa_open_mixer(u->mixers, u->alsa_card_index, true); -+ if (!mixer_handle) -+ continue; -+ -+ melem = pa_alsa_mixer_find_pcm(mixer_handle, "ELD", device); - if (melem) { -+ pa_alsa_mixer_set_fdlist(u->mixers, mixer_handle, u->core->mainloop); - snd_mixer_elem_set_callback(melem, hdmi_eld_changed); - snd_mixer_elem_set_callback_private(melem, u); - hdmi_eld_changed(melem, 0); -@@ -630,25 +632,31 @@ static void init_jacks(struct userdata *u) { - if (pa_hashmap_size(u->jacks) == 0) - return; - -- u->mixer_fdl = pa_alsa_fdlist_new(); -- -- u->mixer_handle = pa_alsa_open_mixer(u->alsa_card_index, NULL); -- if (u->mixer_handle && pa_alsa_fdlist_set_handle(u->mixer_fdl, u->mixer_handle, NULL, u->core->mainloop) >= 0) { -- PA_HASHMAP_FOREACH(jack, u->jacks, state) { -- jack->melem = pa_alsa_mixer_find_card(u->mixer_handle, jack->alsa_name, 0); -- if (!jack->melem) { -- pa_log_warn("Jack '%s' seems to have disappeared.", jack->alsa_name); -- pa_alsa_jack_set_has_control(jack, false); -- continue; -+ PA_HASHMAP_FOREACH(jack, u->jacks, state) { -+ if (!jack->mixer_device_name) { -+ jack->mixer_handle = pa_alsa_open_mixer(u->mixers, u->alsa_card_index, false); -+ if (!jack->mixer_handle) { -+ pa_log("Failed to open mixer for card %d for jack detection", u->alsa_card_index); -+ continue; -+ } -+ } else { -+ jack->mixer_handle = pa_alsa_open_mixer_by_name(u->mixers, jack->mixer_device_name, false); -+ if (!jack->mixer_handle) { -+ pa_log("Failed to open mixer '%s' for jack detection", jack->mixer_device_name); -+ continue; - } -- snd_mixer_elem_set_callback(jack->melem, report_jack_state); -- snd_mixer_elem_set_callback_private(jack->melem, u); -- report_jack_state(jack->melem, 0); - } -- -- } else -- pa_log("Failed to open mixer for jack detection"); -- -+ pa_alsa_mixer_set_fdlist(u->mixers, jack->mixer_handle, u->core->mainloop); -+ jack->melem = pa_alsa_mixer_find_card(jack->mixer_handle, jack->alsa_name, 0); -+ if (!jack->melem) { -+ pa_log_warn("Jack '%s' seems to have disappeared.", jack->alsa_name); -+ pa_alsa_jack_set_has_control(jack, false); -+ continue; -+ } -+ snd_mixer_elem_set_callback(jack->melem, report_jack_state); -+ snd_mixer_elem_set_callback_private(jack->melem, u); -+ report_jack_state(jack->melem, 0); -+ } - } - - static void set_card_name(pa_card_new_data *data, pa_modargs *ma, const char *device_id) { -@@ -772,6 +780,10 @@ int pa__init(pa_module *m) { - u->use_ucm = true; - u->ucm.core = m->core; - -+ u->mixers = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, -+ pa_xfree, (pa_free_cb_t) pa_alsa_mixer_free); -+ u->ucm.mixers = u->mixers; /* alias */ -+ - if (!(u->modargs = pa_modargs_new(m->argument, valid_modargs))) { - pa_log("Failed to parse module arguments."); - goto fail; -@@ -852,7 +864,7 @@ int pa__init(pa_module *m) { - - u->profile_set->ignore_dB = ignore_dB; - -- pa_alsa_profile_set_probe(u->profile_set, u->device_id, &m->core->default_sample_spec, m->core->default_n_fragments, m->core->default_fragment_size_msec); -+ pa_alsa_profile_set_probe(u->profile_set, u->mixers, u->device_id, &m->core->default_sample_spec, m->core->default_n_fragments, m->core->default_fragment_size_msec); - pa_alsa_profile_set_dump(u->profile_set); - - pa_card_new_data_init(&data); -@@ -952,6 +964,16 @@ int pa__init(pa_module *m) { - init_profile(u); - init_eld_ctls(u); - -+ /* Remove all probe only mixers */ -+ if (u->mixers) { -+ const char *devname; -+ pa_alsa_mixer *pm; -+ void *state; -+ PA_HASHMAP_FOREACH_KV(devname, pm, u->mixers, state) -+ if (pm->used_for_probe_only) -+ pa_hashmap_remove_and_free(u->mixers, devname); -+ } -+ - if (reserve) - pa_reserve_wrapper_unref(reserve); - -@@ -1002,10 +1024,8 @@ void pa__done(pa_module*m) { - if (!(u = m->userdata)) - goto finish; - -- if (u->mixer_fdl) -- pa_alsa_fdlist_free(u->mixer_fdl); -- if (u->mixer_handle) -- snd_mixer_close(u->mixer_handle); -+ if (u->mixers) -+ pa_hashmap_free(u->mixers); - if (u->jacks) - pa_hashmap_free(u->jacks); - --- -2.16.4 - diff --git a/0029-alsa-ucm-add-support-for-HDMI-ELD.patch b/0029-alsa-ucm-add-support-for-HDMI-ELD.patch deleted file mode 100644 index ec3db18..0000000 --- a/0029-alsa-ucm-add-support-for-HDMI-ELD.patch +++ /dev/null @@ -1,264 +0,0 @@ -From 3ceff8bb3f697ec16dc5c72e658b10ac40bc19f5 Mon Sep 17 00:00:00 2001 -From: Jaroslav Kysela -Date: Sat, 7 Dec 2019 23:22:33 +0100 -Subject: [PATCH] alsa-ucm: add support for HDMI ELD - -Signed-off-by: Jaroslav Kysela ---- - src/modules/alsa/alsa-ucm.c | 72 +++++++++++++++++++++++++++++++++++-- - src/modules/alsa/alsa-ucm.h | 7 ++++ - src/modules/alsa/module-alsa-card.c | 56 ++++++++++++++++++----------- - 3 files changed, 113 insertions(+), 22 deletions(-) - -diff --git a/src/modules/alsa/alsa-ucm.c b/src/modules/alsa/alsa-ucm.c -index b9a4b8c4b436..5695840abaf1 100644 ---- a/src/modules/alsa/alsa-ucm.c -+++ b/src/modules/alsa/alsa-ucm.c -@@ -820,6 +820,36 @@ static int pa_alsa_ucm_device_cmp(const void *a, const void *b) { - return strcmp(pa_proplist_gets(d1->proplist, PA_ALSA_PROP_UCM_NAME), pa_proplist_gets(d2->proplist, PA_ALSA_PROP_UCM_NAME)); - } - -+static void set_eld_devices(pa_hashmap *hash) -+{ -+ pa_device_port *port; -+ pa_alsa_ucm_port_data *data; -+ pa_alsa_ucm_device *dev; -+ const char *eld_mixer_device_name; -+ void *state; -+ int idx, eld_device; -+ -+ PA_HASHMAP_FOREACH(port, hash, state) { -+ data = PA_DEVICE_PORT_DATA(port); -+ eld_mixer_device_name = NULL; -+ eld_device = -1; -+ PA_DYNARRAY_FOREACH(dev, data->devices, idx) { -+ if (dev->eld_device >= 0 && dev->eld_mixer_device_name) { -+ if (eld_device >= 0 && eld_device != dev->eld_device) { -+ pa_log_error("The ELD device is already set!"); -+ } else if (eld_mixer_device_name && pa_streq(dev->eld_mixer_device_name, eld_mixer_device_name)) { -+ pa_log_error("The ELD mixer device is already set (%s, %s)!", dev->eld_mixer_device_name, dev->eld_mixer_device_name); -+ } else { -+ eld_mixer_device_name = dev->eld_mixer_device_name; -+ eld_device = dev->eld_device; -+ } -+ } -+ } -+ data->eld_device = eld_device; -+ data->eld_mixer_device_name = pa_xstrdup(eld_mixer_device_name); -+ } -+} -+ - static void probe_volumes(pa_hashmap *hash, bool is_sink, snd_pcm_t *pcm_handle, pa_hashmap *mixers, bool ignore_dB) { - pa_device_port *port; - pa_alsa_path *path; -@@ -1159,6 +1189,9 @@ void pa_alsa_ucm_add_ports_combination( - ucm_add_ports_combination(p, context, is_sink, pdevices, 0, PA_IDXSET_INVALID, ports, cp, core); - pa_xfree(pdevices); - } -+ -+ /* ELD devices */ -+ set_eld_devices(ports); - } - - void pa_alsa_ucm_add_ports( -@@ -1709,6 +1742,33 @@ static int ucm_create_profile( - return 0; - } - -+static void mapping_init_eld(pa_alsa_mapping *m, snd_pcm_t *pcm) -+{ -+ pa_alsa_ucm_mapping_context *context = &m->ucm_context; -+ pa_alsa_ucm_device *dev; -+ uint32_t idx; -+ char *mdev; -+ snd_pcm_info_t *info; -+ int pcm_card, pcm_device; -+ -+ snd_pcm_info_alloca(&info); -+ if (snd_pcm_info(pcm, info) < 0) -+ return; -+ -+ if ((pcm_card = snd_pcm_info_get_card(info)) < 0) -+ return; -+ if ((pcm_device = snd_pcm_info_get_device(info)) < 0) -+ return; -+ -+ PA_IDXSET_FOREACH(dev, context->ucm_devices, idx) { -+ mdev = pa_sprintf_malloc("hw:%i", pcm_card); -+ if (mdev == NULL) -+ continue; -+ dev->eld_mixer_device_name = mdev; -+ dev->eld_device = pcm_device; -+ } -+} -+ - static snd_pcm_t* mapping_open_pcm(pa_alsa_ucm_config *ucm, pa_alsa_mapping *m, int mode) { - snd_pcm_t* pcm; - pa_sample_spec try_ss = ucm->core->default_sample_spec; -@@ -1730,8 +1790,11 @@ static snd_pcm_t* mapping_open_pcm(pa_alsa_ucm_config *ucm, pa_alsa_mapping *m, - pcm = pa_alsa_open_by_device_string(m->device_strings[0], NULL, &try_ss, - &try_map, mode, &try_period_size, &try_buffer_size, 0, NULL, NULL, exact_channels); - -- if (pcm && !exact_channels) -- m->channel_map = try_map; -+ if (pcm) { -+ if (!exact_channels) -+ m->channel_map = try_map; -+ mapping_init_eld(m, pcm); -+ } - - return pcm; - } -@@ -1912,6 +1975,8 @@ static void free_verb(pa_alsa_ucm_verb *verb) { - if (di->supported_devices) - pa_idxset_free(di->supported_devices, NULL); - -+ pa_xfree(di->eld_mixer_device_name); -+ - pa_xfree(di); - } - -@@ -2115,6 +2180,7 @@ static void ucm_port_data_init(pa_alsa_ucm_port_data *port, pa_alsa_ucm_config * - port->ucm = ucm; - port->core_port = core_port; - port->devices = pa_dynarray_new(NULL); -+ port->eld_device = -1; - - for (i = 0; i < n_devices; i++) { - pa_dynarray_append(port->devices, devices[i]); -@@ -2139,6 +2205,8 @@ static void ucm_port_data_free(pa_device_port *port) { - - if (ucm_port->paths) - pa_hashmap_free(ucm_port->paths); -+ -+ pa_xfree(ucm_port->eld_mixer_device_name); - } - - static void ucm_port_update_available(pa_alsa_ucm_port_data *port) { -diff --git a/src/modules/alsa/alsa-ucm.h b/src/modules/alsa/alsa-ucm.h -index 49362992865b..48fd9db3f79f 100644 ---- a/src/modules/alsa/alsa-ucm.h -+++ b/src/modules/alsa/alsa-ucm.h -@@ -207,6 +207,9 @@ struct pa_alsa_ucm_device { - pa_alsa_jack *jack; - pa_dynarray *hw_mute_jacks; /* pa_alsa_jack */ - pa_available_t available; -+ -+ char *eld_mixer_device_name; -+ int eld_device; - }; - - void pa_alsa_ucm_device_update_available(pa_alsa_ucm_device *device); -@@ -273,6 +276,10 @@ struct pa_alsa_ucm_port_data { - pa_hashmap *paths; - /* Current path, set when activating profile */ - pa_alsa_path *path; -+ -+ /* ELD info */ -+ char *eld_mixer_device_name; -+ int eld_device; /* PCM device number */ - }; - - struct pa_alsa_ucm_volume { -diff --git a/src/modules/alsa/module-alsa-card.c b/src/modules/alsa/module-alsa-card.c -index 3b2f99fc4e54..c5852b43d844 100644 ---- a/src/modules/alsa/module-alsa-card.c -+++ b/src/modules/alsa/module-alsa-card.c -@@ -512,15 +512,24 @@ static int report_jack_state(snd_mixer_elem_t *melem, unsigned int mask) { - return 0; - } - --static pa_device_port* find_port_with_eld_device(pa_hashmap *ports, int device) { -+static pa_device_port* find_port_with_eld_device(struct userdata *u, int device) { - void *state; - pa_device_port *p; - -- PA_HASHMAP_FOREACH(p, ports, state) { -- pa_alsa_port_data *data = PA_DEVICE_PORT_DATA(p); -- pa_assert(data->path); -- if (device == data->path->eld_device) -- return p; -+ if (u->use_ucm) { -+ PA_HASHMAP_FOREACH(p, u->card->ports, state) { -+ pa_alsa_ucm_port_data *data = PA_DEVICE_PORT_DATA(p); -+ pa_assert(data->eld_mixer_device_name); -+ if (device == data->eld_device) -+ return p; -+ } -+ } else { -+ PA_HASHMAP_FOREACH(p, u->card->ports, state) { -+ pa_alsa_port_data *data = PA_DEVICE_PORT_DATA(p); -+ pa_assert(data->path); -+ if (device == data->path->eld_device) -+ return p; -+ } - } - return NULL; - } -@@ -537,10 +546,7 @@ static int hdmi_eld_changed(snd_mixer_elem_t *melem, unsigned int mask) { - if (mask == SND_CTL_EVENT_MASK_REMOVE) - return 0; - -- if (u->use_ucm) -- return 0; -- -- p = find_port_with_eld_device(u->card->ports, device); -+ p = find_port_with_eld_device(u, device); - if (p == NULL) { - pa_log_error("Invalid device changed in ALSA: %d", device); - return 0; -@@ -571,21 +577,30 @@ static void init_eld_ctls(struct userdata *u) { - /* The code in this function expects ports to have a pa_alsa_port_data - * struct as their data, but in UCM mode ports don't have any data. Hence, - * the ELD controls can't currently be used in UCM mode. */ -- if (u->use_ucm) -- return; -- - PA_HASHMAP_FOREACH(port, u->card->ports, state) { -- pa_alsa_port_data *data = PA_DEVICE_PORT_DATA(port); - snd_mixer_t *mixer_handle; - snd_mixer_elem_t* melem; - int device; - -- pa_assert(data->path); -- device = data->path->eld_device; -- if (device < 0) -- continue; -+ if (u->use_ucm) { -+ pa_alsa_ucm_port_data *data = PA_DEVICE_PORT_DATA(port); -+ device = data->eld_device; -+ if (device < 0 || !data->eld_mixer_device_name) -+ continue; -+ -+ mixer_handle = pa_alsa_open_mixer_by_name(u->mixers, data->eld_mixer_device_name, true); -+ } else { -+ pa_alsa_port_data *data = PA_DEVICE_PORT_DATA(port); -+ -+ pa_assert(data->path); -+ -+ device = data->path->eld_device; -+ if (device < 0) -+ continue; -+ -+ mixer_handle = pa_alsa_open_mixer(u->mixers, u->alsa_card_index, true); -+ } - -- mixer_handle = pa_alsa_open_mixer(u->mixers, u->alsa_card_index, true); - if (!mixer_handle) - continue; - -@@ -595,9 +610,10 @@ static void init_eld_ctls(struct userdata *u) { - snd_mixer_elem_set_callback(melem, hdmi_eld_changed); - snd_mixer_elem_set_callback_private(melem, u); - hdmi_eld_changed(melem, 0); -+ pa_log_info("ELD device found for port %s (%d).", port->name, device); - } - else -- pa_log_debug("No ELD device found for port %s.", port->name); -+ pa_log_debug("No ELD device found for port %s (%d).", port->name, device); - } - } - --- -2.16.4 - diff --git a/0030-alsa-mixer-do-the-quick-card-number-lookup-to-save-m.patch b/0030-alsa-mixer-do-the-quick-card-number-lookup-to-save-m.patch deleted file mode 100644 index 4c263af..0000000 --- a/0030-alsa-mixer-do-the-quick-card-number-lookup-to-save-m.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 8837c90b7fe6b7c3cbbaeda0a29e2f5d311c3d14 Mon Sep 17 00:00:00 2001 -From: Jaroslav Kysela -Date: Sun, 8 Dec 2019 22:48:45 +0100 -Subject: [PATCH] alsa-mixer: do the quick card number lookup to save mixer - instances - -Signed-off-by: Jaroslav Kysela ---- - src/modules/alsa/alsa-mixer.h | 1 + - src/modules/alsa/alsa-util.c | 33 +++++++++++++++++++++++++++++++++ - 2 files changed, 34 insertions(+) - -diff --git a/src/modules/alsa/alsa-mixer.h b/src/modules/alsa/alsa-mixer.h -index 325b0c998b02..d740a78c8dce 100644 ---- a/src/modules/alsa/alsa-mixer.h -+++ b/src/modules/alsa/alsa-mixer.h -@@ -102,6 +102,7 @@ struct pa_alsa_setting { - /* An entry for one ALSA mixer */ - struct pa_alsa_mixer { - snd_mixer_t *mixer_handle; -+ int card_index; - pa_alsa_fdlist *fdl; - bool used_for_probe_only:1; - }; -diff --git a/src/modules/alsa/alsa-util.c b/src/modules/alsa/alsa-util.c -index 34930c9fa155..d86f43c10098 100644 ---- a/src/modules/alsa/alsa-util.c -+++ b/src/modules/alsa/alsa-util.c -@@ -1737,11 +1737,33 @@ snd_mixer_t *pa_alsa_open_mixer_by_name(pa_hashmap *mixers, const char *dev, boo - int err; - snd_mixer_t *m; - pa_alsa_mixer *pm; -+ char *dev2; -+ void *state; - - pa_assert(mixers); - pa_assert(dev); - - pm = pa_hashmap_get(mixers, dev); -+ -+ /* The quick card number/index lookup (hw:#) -+ * We already know the card number/index, thus use the mixer -+ * from the cache at first. -+ */ -+ if (!pm && pa_strneq(dev, "hw:", 3)) { -+ const char *s = dev + 3; -+ int card_index; -+ while (*s && *s >= 0 && *s <= '9') s++; -+ if (*s == '\0' && pa_atoi(dev + 3, &card_index) >= 0) { -+ PA_HASHMAP_FOREACH_KV(dev2, pm, mixers, state) { -+ if (pm->card_index == card_index) { -+ dev = dev2; -+ pm = pa_hashmap_get(mixers, dev); -+ break; -+ } -+ } -+ } -+ } -+ - if (pm) { - if (!probe) - pm->used_for_probe_only = false; -@@ -1756,6 +1778,17 @@ snd_mixer_t *pa_alsa_open_mixer_by_name(pa_hashmap *mixers, const char *dev, boo - if (prepare_mixer(m, dev) >= 0) { - pm = pa_xnew0(pa_alsa_mixer, 1); - if (pm) { -+ snd_hctl_t *hctl; -+ pm->card_index = -1; -+ /* determine the ALSA card number (index) and store it to card_index */ -+ err = snd_mixer_get_hctl(m, dev, &hctl); -+ if (err >= 0) { -+ snd_ctl_card_info_t *info; -+ snd_ctl_card_info_alloca(&info); -+ err = snd_ctl_card_info(snd_hctl_ctl(hctl), info); -+ if (err >= 0) -+ pm->card_index = snd_ctl_card_info_get_card(info); -+ } - pm->used_for_probe_only = probe; - pm->mixer_handle = m; - pa_hashmap_put(mixers, pa_xstrdup(dev), pm); --- -2.16.4 - diff --git a/0031-alsa-mixer-improve-check-for-the-empty-path-set-for-.patch b/0031-alsa-mixer-improve-check-for-the-empty-path-set-for-.patch deleted file mode 100644 index a11ad13..0000000 --- a/0031-alsa-mixer-improve-check-for-the-empty-path-set-for-.patch +++ /dev/null @@ -1,134 +0,0 @@ -From d7dbd0cbe3191661c02ac89d108b36c79474de3c Mon Sep 17 00:00:00 2001 -From: Jaroslav Kysela -Date: Sun, 8 Dec 2019 23:17:32 +0100 -Subject: [PATCH] alsa-mixer: improve check for the empty path set for - sink/source - -The unused mixer instances are created without this code. - -Signed-off-by: Jaroslav Kysela ---- - src/modules/alsa/alsa-mixer.c | 6 ++++++ - src/modules/alsa/alsa-mixer.h | 1 + - src/modules/alsa/alsa-sink.c | 19 +++++++++++++------ - src/modules/alsa/alsa-source.c | 9 ++++++--- - 4 files changed, 26 insertions(+), 9 deletions(-) - -diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c -index a3c998b654e9..d184aec7aee7 100644 ---- a/src/modules/alsa/alsa-mixer.c -+++ b/src/modules/alsa/alsa-mixer.c -@@ -741,6 +741,12 @@ void pa_alsa_path_set_free(pa_alsa_path_set *ps) { - pa_xfree(ps); - } - -+int pa_alsa_path_set_is_empty(pa_alsa_path_set *ps) { -+ if (ps && !pa_hashmap_isempty(ps->paths)) -+ return 0; -+ return 1; -+} -+ - static long to_alsa_dB(pa_volume_t v) { - return lround(pa_sw_volume_to_dB(v) * 100.0); - } -diff --git a/src/modules/alsa/alsa-mixer.h b/src/modules/alsa/alsa-mixer.h -index d740a78c8dce..df739cc2e0f3 100644 ---- a/src/modules/alsa/alsa-mixer.h -+++ b/src/modules/alsa/alsa-mixer.h -@@ -272,6 +272,7 @@ pa_alsa_path_set *pa_alsa_path_set_new(pa_alsa_mapping *m, pa_alsa_direction_t d - void pa_alsa_path_set_dump(pa_alsa_path_set *s); - void pa_alsa_path_set_set_callback(pa_alsa_path_set *ps, snd_mixer_t *m, snd_mixer_elem_callback_t cb, void *userdata); - void pa_alsa_path_set_free(pa_alsa_path_set *s); -+int pa_alsa_path_set_is_empty(pa_alsa_path_set *s); - - struct pa_alsa_mapping { - pa_alsa_profile_set *profile_set; -diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c -index 363b4be2fa25..042d4dfd9c89 100644 ---- a/src/modules/alsa/alsa-sink.c -+++ b/src/modules/alsa/alsa-sink.c -@@ -1651,7 +1651,6 @@ static int sink_set_port_ucm_cb(pa_sink *s, pa_device_port *p) { - - pa_assert(u); - pa_assert(p); -- pa_assert(u->mixer_handle); - pa_assert(u->ucm_context); - - data = PA_DEVICE_PORT_DATA(p); -@@ -2089,6 +2088,9 @@ static void find_mixer(struct userdata *u, pa_alsa_mapping *mapping, const char - if (!mapping && !element) - return; - -+ if (!element && mapping && pa_alsa_path_set_is_empty(mapping->output_path_set)) -+ return; -+ - u->mixers = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, - NULL, (pa_free_cb_t) pa_alsa_mixer_free); - -@@ -2113,8 +2115,9 @@ static void find_mixer(struct userdata *u, pa_alsa_mapping *mapping, const char - - pa_log_debug("Probed mixer path %s:", u->mixer_path->name); - pa_alsa_path_dump(u->mixer_path); -- } else if (!(u->mixer_path_set = mapping->output_path_set)) -- goto fail; -+ } else { -+ u->mixer_path_set = mapping->output_path_set; -+ } - - return; - -@@ -2559,10 +2562,14 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca - goto fail; - } - -- if (u->ucm_context) -+ if (u->ucm_context) { - pa_alsa_ucm_add_ports(&data.ports, data.proplist, u->ucm_context, true, card, u->pcm_handle, ignore_dB); -- else if (u->mixer_path_set) -- pa_alsa_add_ports(&data, u->mixer_path_set, card); -+ find_mixer(u, mapping, pa_modargs_get_value(ma, "control", NULL), ignore_dB); -+ } else { -+ find_mixer(u, mapping, pa_modargs_get_value(ma, "control", NULL), ignore_dB); -+ if (u->mixer_path_set) -+ pa_alsa_add_ports(&data, u->mixer_path_set, card); -+ } - - u->sink = pa_sink_new(m->core, &data, PA_SINK_HARDWARE | PA_SINK_LATENCY | (u->use_tsched ? PA_SINK_DYNAMIC_LATENCY : 0) | - (set_formats ? PA_SINK_SET_FORMATS : 0)); -diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c -index b46e845cc5a7..104de4e266dd 100644 ---- a/src/modules/alsa/alsa-source.c -+++ b/src/modules/alsa/alsa-source.c -@@ -1522,7 +1522,6 @@ static int source_set_port_ucm_cb(pa_source *s, pa_device_port *p) { - - pa_assert(u); - pa_assert(p); -- pa_assert(u->mixer_handle); - pa_assert(u->ucm_context); - - data = PA_DEVICE_PORT_DATA(p); -@@ -1795,6 +1794,9 @@ static void find_mixer(struct userdata *u, pa_alsa_mapping *mapping, const char - if (!mapping && !element) - return; - -+ if (!element && mapping && pa_alsa_path_set_is_empty(mapping->input_path_set)) -+ return; -+ - u->mixers = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, - NULL, (pa_free_cb_t) pa_alsa_mixer_free); - -@@ -1819,8 +1821,9 @@ static void find_mixer(struct userdata *u, pa_alsa_mapping *mapping, const char - - pa_log_debug("Probed mixer path %s:", u->mixer_path->name); - pa_alsa_path_dump(u->mixer_path); -- } else if (!(u->mixer_path_set = mapping->input_path_set)) -- goto fail; -+ } else { -+ u->mixer_path_set = mapping->input_path_set; -+ } - - return; - --- -2.16.4 - diff --git a/0032-alsa-ucm-allow-to-set-profile-priority-from-UCM-valu.patch b/0032-alsa-ucm-allow-to-set-profile-priority-from-UCM-valu.patch deleted file mode 100644 index d618fe6..0000000 --- a/0032-alsa-ucm-allow-to-set-profile-priority-from-UCM-valu.patch +++ /dev/null @@ -1,128 +0,0 @@ -From cd4a69374cefe7c720bd6916f06ff7151da9892a Mon Sep 17 00:00:00 2001 -From: Jaroslav Kysela -Date: Tue, 10 Dec 2019 12:34:19 +0100 -Subject: [PATCH] alsa-ucm: allow to set profile priority from UCM value - -Signed-off-by: Jaroslav Kysela ---- - src/modules/alsa/alsa-ucm.c | 59 +++++++++++++++++++++++++++++++++------------ - src/modules/alsa/alsa-ucm.h | 1 + - 2 files changed, 45 insertions(+), 15 deletions(-) - -diff --git a/src/modules/alsa/alsa-ucm.c b/src/modules/alsa/alsa-ucm.c -index 5695840abaf1..a57be6d22497 100644 ---- a/src/modules/alsa/alsa-ucm.c -+++ b/src/modules/alsa/alsa-ucm.c -@@ -146,6 +146,26 @@ static struct ucm_info dev_info[] = { - {NULL, 0} - }; - -+ -+static char *ucm_verb_value( -+ snd_use_case_mgr_t *uc_mgr, -+ const char *verb_name, -+ const char *id) { -+ -+ const char *value; -+ char *_id = pa_sprintf_malloc("=%s//%s", id, verb_name); -+ int err = snd_use_case_get(uc_mgr, _id, &value); -+ pa_xfree(_id); -+ if (err < 0) -+ return NULL; -+ pa_log_debug("Got %s for verb %s: %s", id, verb_name, value); -+ /* Use the cast here to allow free() call without casting for callers. -+ * The snd_use_case_get() returns mallocated string. -+ * See the Note: in use-case.h for snd_use_case_get(). -+ */ -+ return (char *)value; -+} -+ - static int ucm_device_exists(pa_idxset *idxset, pa_alsa_ucm_device *dev) { - pa_alsa_ucm_device *d; - uint32_t idx; -@@ -766,6 +786,8 @@ int pa_alsa_ucm_get_verb(snd_use_case_mgr_t *uc_mgr, const char *verb_name, cons - pa_alsa_ucm_device *d; - pa_alsa_ucm_modifier *mod; - pa_alsa_ucm_verb *verb; -+ char *value; -+ unsigned ui; - int err = 0; - - *p_verb = NULL; -@@ -780,6 +802,11 @@ int pa_alsa_ucm_get_verb(snd_use_case_mgr_t *uc_mgr, const char *verb_name, cons - pa_proplist_sets(verb->proplist, PA_ALSA_PROP_UCM_NAME, pa_strnull(verb_name)); - pa_proplist_sets(verb->proplist, PA_ALSA_PROP_UCM_DESCRIPTION, pa_strna(verb_desc)); - -+ value = ucm_verb_value(uc_mgr, verb_name, "Priority"); -+ if (value && !pa_atou(value, &ui)) -+ verb->priority = ui > 10000 ? 10000 : ui; -+ free(value); -+ - err = ucm_get_devices(verb, uc_mgr); - if (err < 0) - pa_log("No UCM devices for verb %s", verb_name); -@@ -1637,7 +1664,7 @@ static int ucm_create_profile( - pa_alsa_ucm_modifier *mod; - int i = 0; - const char *name, *sink, *source; -- char *verb_cmp, *c; -+ unsigned int priority; - - pa_assert(ps); - -@@ -1657,24 +1684,26 @@ static int ucm_create_profile( - p->supported = true; - pa_hashmap_put(ps->profiles, p->name, p); - -- /* TODO: get profile priority from ucm info or policy management */ -- c = verb_cmp = pa_xstrdup(verb_name); -- while (*c) { -- if (*c == '_') *c = ' '; -- c++; -- } -+ /* TODO: get profile priority from policy management */ -+ priority = verb->priority; - -- for (i = 0; verb_info[i].id; i++) { -- if (strcasecmp(verb_info[i].id, verb_cmp) == 0) { -- p->priority = verb_info[i].priority; -- break; -+ if (priority == 0) { -+ char *verb_cmp, *c; -+ c = verb_cmp = pa_xstrdup(verb_name); -+ while (*c) { -+ if (*c == '_') *c = ' '; -+ c++; -+ } -+ for (i = 0; verb_info[i].id; i++) { -+ if (strcasecmp(verb_info[i].id, verb_cmp) == 0) { -+ priority = verb_info[i].priority; -+ break; -+ } - } -+ pa_xfree(verb_cmp); - } - -- pa_xfree(verb_cmp); -- -- if (verb_info[i].id == NULL) -- p->priority = 1000; -+ p->priority = priority; - - PA_LLIST_FOREACH(dev, verb->devices) { - pa_alsa_jack *jack; -diff --git a/src/modules/alsa/alsa-ucm.h b/src/modules/alsa/alsa-ucm.h -index 48fd9db3f79f..e7a795cedeb7 100644 ---- a/src/modules/alsa/alsa-ucm.h -+++ b/src/modules/alsa/alsa-ucm.h -@@ -241,6 +241,7 @@ struct pa_alsa_ucm_verb { - PA_LLIST_FIELDS(pa_alsa_ucm_verb); - - pa_proplist *proplist; -+ unsigned priority; - - PA_LLIST_HEAD(pa_alsa_ucm_device, devices); - PA_LLIST_HEAD(pa_alsa_ucm_modifier, modifiers); --- -2.16.4 - diff --git a/0033-alsa-Document-that-mixer-elements-can-be-identified-.patch b/0033-alsa-Document-that-mixer-elements-can-be-identified-.patch deleted file mode 100644 index 06a5be4..0000000 --- a/0033-alsa-Document-that-mixer-elements-can-be-identified-.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 5d70f1226b9046d814a8efe4b00453b68805e34c Mon Sep 17 00:00:00 2001 -From: Tanu Kaskinen -Date: Fri, 14 Feb 2020 11:01:04 +0200 -Subject: [PATCH] alsa: Document that mixer elements can be identified by a - combination of name and index - ---- - src/modules/alsa/mixer/paths/analog-output.conf.common | 3 ++- - src/modules/alsa/mixer/profile-sets/default.conf | 6 ++++-- - src/modules/alsa/module-alsa-sink.c | 2 +- - src/modules/alsa/module-alsa-source.c | 2 +- - 4 files changed, 8 insertions(+), 5 deletions(-) - -diff --git a/src/modules/alsa/mixer/paths/analog-output.conf.common b/src/modules/alsa/mixer/paths/analog-output.conf.common -index e52830d990ed..7bf346346fe3 100644 ---- a/src/modules/alsa/mixer/paths/analog-output.conf.common -+++ b/src/modules/alsa/mixer/paths/analog-output.conf.common -@@ -85,7 +85,8 @@ - ; required-any = ignore | enumeration | any # In this element, either this or another option must exist (or an element) - ; required-absent = ignore | enumeration | any # In this element, this option must not exist or the path will be invalid - ; --; [Element ...] # For each element that we shall control -+; [Element ...] # For each element that we shall control. The "..." here is the element name, -+; # or name and index separated by a comma. - ; required = ignore | switch | volume | enumeration | any # If set, require this element to be of this kind and available, - ; # otherwise don't consider this path valid for the card - ; required-any = ignore | switch | volume | enumeration | any # If set, at least one of the elements or jacks with required-any in this -diff --git a/src/modules/alsa/mixer/profile-sets/default.conf b/src/modules/alsa/mixer/profile-sets/default.conf -index 34c51bc5bf0a..c73bf5cea33f 100644 ---- a/src/modules/alsa/mixer/profile-sets/default.conf -+++ b/src/modules/alsa/mixer/profile-sets/default.conf -@@ -49,7 +49,8 @@ - ; # If multiple are found to be working they will be available as device ports - ; paths-output = ... - ; element-input = ... # Instead of configuring a full mixer path simply configure a single --; # mixer element for volume/mute handling -+; # mixer element for volume/mute handling. The value can be an element -+; # name, or name and index separated by a comma. - ; element-output = ... - ; priority = ... - ; direction = any | input | output # Only useful for? -@@ -72,7 +73,8 @@ - ; [DecibelFix element] # Decibel fixes can be used to work around missing or incorrect dB - ; # information from alsa. A decibel fix is a table that maps volume steps - ; # to decibel values for one volume element. The "element" part in the --; # section title is the name of the volume element. -+; # section title is the name of the volume element (or name and index -+; # separated by a comma). - ; # - ; # NOTE: This feature is meant just as a help for figuring out the correct - ; # decibel values. PulseAudio is not the correct place to maintain the -diff --git a/src/modules/alsa/module-alsa-sink.c b/src/modules/alsa/module-alsa-sink.c -index 4d4beb3cd487..a90c5e493514 100644 ---- a/src/modules/alsa/module-alsa-sink.c -+++ b/src/modules/alsa/module-alsa-sink.c -@@ -52,7 +52,7 @@ PA_MODULE_USAGE( - "tsched_buffer_size= " - "tsched_buffer_watermark= " - "ignore_dB= " -- "control= " -+ "control= " - "rewind_safeguard= " - "deferred_volume= " - "deferred_volume_safety_margin= " -diff --git a/src/modules/alsa/module-alsa-source.c b/src/modules/alsa/module-alsa-source.c -index 747ba934212e..d15228316e09 100644 ---- a/src/modules/alsa/module-alsa-source.c -+++ b/src/modules/alsa/module-alsa-source.c -@@ -61,7 +61,7 @@ PA_MODULE_USAGE( - "tsched_buffer_size= " - "tsched_buffer_watermark= " - "ignore_dB= " -- "control=" -+ "control=" - "deferred_volume= " - "deferred_volume_safety_margin= " - "deferred_volume_extra_delay= " --- -2.16.4 - diff --git a/0034-alsa-ucm-correct-the-channel-default-logic-stereo.patch b/0034-alsa-ucm-correct-the-channel-default-logic-stereo.patch deleted file mode 100644 index 429de35..0000000 --- a/0034-alsa-ucm-correct-the-channel-default-logic-stereo.patch +++ /dev/null @@ -1,45 +0,0 @@ -From cabd387e26b5fe03661f4b894826c7c6b58d7efa Mon Sep 17 00:00:00 2001 -From: Jaroslav Kysela -Date: Tue, 11 Feb 2020 10:54:16 +0100 -Subject: [PATCH] alsa-ucm: correct the channel default logic (stereo) - -Signed-off-by: Jaroslav Kysela ---- - src/modules/alsa/alsa-ucm.c | 13 ++++++++++--- - 1 file changed, 10 insertions(+), 3 deletions(-) - -diff --git a/src/modules/alsa/alsa-ucm.c b/src/modules/alsa/alsa-ucm.c -index a57be6d22497..b7d2c5b9c51a 100644 ---- a/src/modules/alsa/alsa-ucm.c -+++ b/src/modules/alsa/alsa-ucm.c -@@ -377,6 +377,13 @@ static int ucm_get_device_property( - pa_log("UCM playback device %s fetch pcm failed", device_name); - } - -+ if (pa_proplist_gets(device->proplist, PA_ALSA_PROP_UCM_SINK) && -+ device->playback_channels == 0) { -+ pa_log("UCM file does not specify 'PlaybackChannels' " -+ "for device %s, assuming stereo duplex.", device_name); -+ device->playback_channels = 2; -+ } -+ - value = pa_proplist_gets(device->proplist, PA_ALSA_PROP_UCM_CAPTURE_CHANNELS); - if (value) { /* input */ - /* get channels */ -@@ -391,10 +398,10 @@ static int ucm_get_device_property( - pa_log("UCM capture device %s fetch pcm failed", device_name); - } - -- if (device->playback_channels == 0 && device->capture_channels == 0) { -- pa_log_warn("UCM file does not specify 'PlaybackChannels' or 'CaptureChannels'" -+ if (pa_proplist_gets(device->proplist, PA_ALSA_PROP_UCM_SOURCE) && -+ device->capture_channels == 0) { -+ pa_log("UCM file does not specify 'CaptureChannels' " - "for device %s, assuming stereo duplex.", device_name); -- device->playback_channels = 2; - device->capture_channels = 2; - } - --- -2.16.4 - diff --git a/0035-alsa-ucm-do-not-assign-JackHWMute-when-JackControl-i.patch b/0035-alsa-ucm-do-not-assign-JackHWMute-when-JackControl-i.patch deleted file mode 100644 index 0b4d9b1..0000000 --- a/0035-alsa-ucm-do-not-assign-JackHWMute-when-JackControl-i.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 4da4670fdb9a09199fb5d3bfaee252b2f4f13128 Mon Sep 17 00:00:00 2001 -From: Jaroslav Kysela -Date: Sun, 1 Mar 2020 15:55:07 +0100 -Subject: [PATCH] alsa ucm: do not assign JackHWMute when JackControl is - missing for the UCM device - -Fixes: https://github.com/alsa-project/alsa-ucm-conf/issues/14 - -Signed-off-by: Jaroslav Kysela ---- - src/modules/alsa/alsa-ucm.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/src/modules/alsa/alsa-ucm.c b/src/modules/alsa/alsa-ucm.c -index b7d2c5b9c51a..8df24e7b51d7 100644 ---- a/src/modules/alsa/alsa-ucm.c -+++ b/src/modules/alsa/alsa-ucm.c -@@ -1730,6 +1730,10 @@ static int ucm_create_profile( - /* JackHWMute contains a list of device names. Each listed device must - * be associated with the jack object that we just created. */ - jack_hw_mute = pa_proplist_gets(dev->proplist, PA_ALSA_PROP_UCM_JACK_HW_MUTE); -+ if (jack_hw_mute && !jack) { -+ pa_log("[%s] JackHWMute set, but JackControl is missing", name); -+ jack_hw_mute = NULL; -+ } - if (jack_hw_mute) { - char *hw_mute_device_name; - const char *state = NULL; --- -2.16.4 - diff --git a/0036-ucm-Don-t-log-errors-during-normal-operation.patch b/0036-ucm-Don-t-log-errors-during-normal-operation.patch deleted file mode 100644 index 49c01f5..0000000 --- a/0036-ucm-Don-t-log-errors-during-normal-operation.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 9d36210beca09cc7a3841d09e5246d4b0000c52d Mon Sep 17 00:00:00 2001 -From: Tanu Kaskinen -Date: Tue, 17 Mar 2020 09:26:57 +0200 -Subject: [PATCH] ucm: Don't log errors during normal operation - -It's completely normal to not have explicit channel configuration for -stereo devices. In fact, the ALSA developers actively avoid configuring -the channels for stereo devices. - -I also dropped the word "duplex" from the messages, because "stereo -duplex" implies bidirectionality, but most devices use one direction -only. ---- - src/modules/alsa/alsa-ucm.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/src/modules/alsa/alsa-ucm.c b/src/modules/alsa/alsa-ucm.c -index 8df24e7b51d7..37cbafae51ee 100644 ---- a/src/modules/alsa/alsa-ucm.c -+++ b/src/modules/alsa/alsa-ucm.c -@@ -379,8 +379,8 @@ static int ucm_get_device_property( - - if (pa_proplist_gets(device->proplist, PA_ALSA_PROP_UCM_SINK) && - device->playback_channels == 0) { -- pa_log("UCM file does not specify 'PlaybackChannels' " -- "for device %s, assuming stereo duplex.", device_name); -+ pa_log_info("UCM file does not specify 'PlaybackChannels' " -+ "for device %s, assuming stereo.", device_name); - device->playback_channels = 2; - } - -@@ -400,8 +400,8 @@ static int ucm_get_device_property( - - if (pa_proplist_gets(device->proplist, PA_ALSA_PROP_UCM_SOURCE) && - device->capture_channels == 0) { -- pa_log("UCM file does not specify 'CaptureChannels' " -- "for device %s, assuming stereo duplex.", device_name); -+ pa_log_info("UCM file does not specify 'CaptureChannels' " -+ "for device %s, assuming stereo.", device_name); - device->capture_channels = 2; - } - --- -2.16.4 - diff --git a/0037-alsa-handle-unavailbale-HW-volume-in-UCM.patch b/0037-alsa-handle-unavailbale-HW-volume-in-UCM.patch deleted file mode 100644 index 1b493a3..0000000 --- a/0037-alsa-handle-unavailbale-HW-volume-in-UCM.patch +++ /dev/null @@ -1,41 +0,0 @@ -From f3f16fe6df087e37f219fd829ae5f647c40fc456 Mon Sep 17 00:00:00 2001 -From: Wim Taymans -Date: Fri, 20 Mar 2020 12:03:08 +0100 -Subject: [PATCH] alsa: handle unavailbale HW volume in UCM - -It is possible that UCM doesn't specify hardware volume controls. -Fall back to software controls instead of aborting. ---- - src/modules/alsa/alsa-sink.c | 2 +- - src/modules/alsa/alsa-source.c | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c -index 042d4dfd9c89..65430caed902 100644 ---- a/src/modules/alsa/alsa-sink.c -+++ b/src/modules/alsa/alsa-sink.c -@@ -1654,7 +1654,7 @@ static int sink_set_port_ucm_cb(pa_sink *s, pa_device_port *p) { - pa_assert(u->ucm_context); - - data = PA_DEVICE_PORT_DATA(p); -- pa_assert_se(u->mixer_path = data->path); -+ u->mixer_path = data->path; - mixer_volume_init(u); - - if (s->flags & PA_SINK_DEFERRED_VOLUME) -diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c -index 104de4e266dd..c33f81e35c18 100644 ---- a/src/modules/alsa/alsa-source.c -+++ b/src/modules/alsa/alsa-source.c -@@ -1525,7 +1525,7 @@ static int source_set_port_ucm_cb(pa_source *s, pa_device_port *p) { - pa_assert(u->ucm_context); - - data = PA_DEVICE_PORT_DATA(p); -- pa_assert_se(u->mixer_path = data->path); -+ u->mixer_path = data->path; - mixer_volume_init(u); - - if (s->flags & PA_SOURCE_DEFERRED_VOLUME) --- -2.16.4 - diff --git a/0038-alsa-ucm-use-the-right-profile-name.patch b/0038-alsa-ucm-use-the-right-profile-name.patch deleted file mode 100644 index f45e982..0000000 --- a/0038-alsa-ucm-use-the-right-profile-name.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 4dc73f5167f7d4c2cf1d3e9c8bb7c796f3a35a4e Mon Sep 17 00:00:00 2001 -From: Wim Taymans -Date: Wed, 25 Mar 2020 16:30:23 +0100 -Subject: [PATCH] alsa-ucm: use the right profile name - -Use the right profile name or else we could pass NULL to -pa_hashmap_get() and crash. ---- - src/modules/alsa/alsa-ucm.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/modules/alsa/alsa-ucm.c b/src/modules/alsa/alsa-ucm.c -index 37cbafae51ee..9d6456162c55 100644 ---- a/src/modules/alsa/alsa-ucm.c -+++ b/src/modules/alsa/alsa-ucm.c -@@ -1315,7 +1315,7 @@ int pa_alsa_ucm_set_profile(pa_alsa_ucm_config *ucm, pa_card *card, const char * - /* select volume controls on ports */ - PA_HASHMAP_FOREACH(port, card->ports, state) { - data = PA_DEVICE_PORT_DATA(port); -- data->path = pa_hashmap_get(data->paths, new_profile); -+ data->path = pa_hashmap_get(data->paths, profile); - } - - return ret; --- -2.16.4 - diff --git a/0039-ucm-fix-the-port-ucm-device-activation-on-boot.patch b/0039-ucm-fix-the-port-ucm-device-activation-on-boot.patch deleted file mode 100644 index 72277a4..0000000 --- a/0039-ucm-fix-the-port-ucm-device-activation-on-boot.patch +++ /dev/null @@ -1,83 +0,0 @@ -From fc5f263e594cf5ecb7034fb54dadb286d2b4a810 Mon Sep 17 00:00:00 2001 -From: Jaroslav Kysela -Date: Tue, 31 Mar 2020 13:24:36 +0200 -Subject: [PATCH] ucm: fix the port / ucm device activation on boot - -The UCM device must be activated using the pa_alsa_ucm_set_port() -call on boot (the sink creation time). In case when the -mixer controls are not defined for the application in the -UCM configuration, the mixer_handle is NULL. - -Call the pa_alsa_ucm_set_port() before the mixer_handle check. - -Signed-off-by: Jaroslav Kysela ---- - src/modules/alsa/alsa-sink.c | 13 +++++++++---- - src/modules/alsa/alsa-source.c | 13 +++++++++---- - 2 files changed, 18 insertions(+), 8 deletions(-) - -diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c -index 65430caed902..7048371e1832 100644 ---- a/src/modules/alsa/alsa-sink.c -+++ b/src/modules/alsa/alsa-sink.c -@@ -2138,6 +2138,15 @@ static int setup_mixer(struct userdata *u, bool ignore_dB) { - - pa_assert(u); - -+ /* This code is before the u->mixer_handle check, because if the UCM -+ * configuration doesn't specify volume or mute controls, u->mixer_handle -+ * will be NULL, but the UCM device enable sequence will still need to be -+ * executed. */ -+ if (u->sink->active_port && u->ucm_context) { -+ if (pa_alsa_ucm_set_port(u->ucm_context, u->sink->active_port, true) < 0) -+ return -1; -+ } -+ - if (!u->mixer_handle) - return 0; - -@@ -2155,10 +2164,6 @@ static int setup_mixer(struct userdata *u, bool ignore_dB) { - } else { - pa_alsa_ucm_port_data *data; - -- /* First activate the port on the UCM side */ -- if (pa_alsa_ucm_set_port(u->ucm_context, u->sink->active_port, true) < 0) -- return -1; -- - data = PA_DEVICE_PORT_DATA(u->sink->active_port); - - /* Now activate volume controls, if any */ -diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c -index c33f81e35c18..bf9e093b336a 100644 ---- a/src/modules/alsa/alsa-source.c -+++ b/src/modules/alsa/alsa-source.c -@@ -1844,6 +1844,15 @@ static int setup_mixer(struct userdata *u, bool ignore_dB) { - - pa_assert(u); - -+ /* This code is before the u->mixer_handle check, because if the UCM -+ * configuration doesn't specify volume or mute controls, u->mixer_handle -+ * will be NULL, but the UCM device enable sequence will still need to be -+ * executed. */ -+ if (u->source->active_port && u->ucm_context) { -+ if (pa_alsa_ucm_set_port(u->ucm_context, u->source->active_port, false) < 0) -+ return -1; -+ } -+ - if (!u->mixer_handle) - return 0; - -@@ -1861,10 +1870,6 @@ static int setup_mixer(struct userdata *u, bool ignore_dB) { - } else { - pa_alsa_ucm_port_data *data; - -- /* First activate the port on the UCM side */ -- if (pa_alsa_ucm_set_port(u->ucm_context, u->source->active_port, false) < 0) -- return -1; -- - data = PA_DEVICE_PORT_DATA(u->source->active_port); - - /* Now activate volume controls, if any */ --- -2.16.4 - diff --git a/0040-alsa-sink-source-fix-the-mixer-initialization.patch b/0040-alsa-sink-source-fix-the-mixer-initialization.patch deleted file mode 100644 index 6d08f80..0000000 --- a/0040-alsa-sink-source-fix-the-mixer-initialization.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 5eb02e31a6de116395075f814123daaad424d5a4 Mon Sep 17 00:00:00 2001 -From: Jaroslav Kysela -Date: Tue, 31 Mar 2020 13:32:46 +0200 -Subject: [PATCH] alsa sink/source: fix the mixer initialization - -- remove duplicate mixer initialization in sink -- use the similar mixer initialization for source like for sink - -Signed-off-by: Jaroslav Kysela ---- - src/modules/alsa/alsa-sink.c | 2 -- - src/modules/alsa/alsa-source.c | 12 +++++++----- - 2 files changed, 7 insertions(+), 7 deletions(-) - -diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c -index 7048371e1832..b5fc0cd93972 100644 ---- a/src/modules/alsa/alsa-sink.c -+++ b/src/modules/alsa/alsa-sink.c -@@ -2511,8 +2511,6 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca - /* ALSA might tweak the sample spec, so recalculate the frame size */ - frame_size = pa_frame_size(&ss); - -- find_mixer(u, mapping, pa_modargs_get_value(ma, "control", NULL), ignore_dB); -- - pa_sink_new_data_init(&data); - data.driver = driver; - data.module = m; -diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c -index bf9e093b336a..829216a8a1a1 100644 ---- a/src/modules/alsa/alsa-source.c -+++ b/src/modules/alsa/alsa-source.c -@@ -2198,8 +2198,6 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p - /* ALSA might tweak the sample spec, so recalculate the frame size */ - frame_size = pa_frame_size(&ss); - -- find_mixer(u, mapping, pa_modargs_get_value(ma, "control", NULL), ignore_dB); -- - pa_source_new_data_init(&data); - data.driver = driver; - data.module = m; -@@ -2254,10 +2252,14 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p - goto fail; - } - -- if (u->ucm_context) -+ if (u->ucm_context) { - pa_alsa_ucm_add_ports(&data.ports, data.proplist, u->ucm_context, false, card, u->pcm_handle, ignore_dB); -- else if (u->mixer_path_set) -- pa_alsa_add_ports(&data, u->mixer_path_set, card); -+ find_mixer(u, mapping, pa_modargs_get_value(ma, "control", NULL), ignore_dB); -+ } else { -+ find_mixer(u, mapping, pa_modargs_get_value(ma, "control", NULL), ignore_dB); -+ if (u->mixer_path_set) -+ pa_alsa_add_ports(&data, u->mixer_path_set, card); -+ } - - u->source = pa_source_new(m->core, &data, PA_SOURCE_HARDWARE|PA_SOURCE_LATENCY|(u->use_tsched ? PA_SOURCE_DYNAMIC_LATENCY : 0)); - volume_is_set = data.volume_is_set; --- -2.16.4 - From 07d8379bd5b84f40d38c6073f5161a9b2e137d09c56ac78f27163049b40c8393 Mon Sep 17 00:00:00 2001 From: Ondrej Holecek Date: Tue, 1 Dec 2020 10:02:26 +0000 Subject: [PATCH 3/3] Accepting request 852072 from home:tiwai:branches:multimedia:libs - Build with --enable-stream-restore-clear-old-devices: This is a bit destructive option, it will clear the old PA routing once when upgraded prior to 14.0, but it's required for GNOME (see the release notes above). It should be a one-off action, and hopefully wouldn't bother too much. OBS-URL: https://build.opensuse.org/request/show/852072 OBS-URL: https://build.opensuse.org/package/show/multimedia:libs/pulseaudio?expand=0&rev=224 --- pulseaudio.changes | 5 +++++ pulseaudio.spec | 1 + 2 files changed, 6 insertions(+) diff --git a/pulseaudio.changes b/pulseaudio.changes index 87af92f..71d7318 100644 --- a/pulseaudio.changes +++ b/pulseaudio.changes @@ -4,6 +4,11 @@ Wed Nov 25 17:10:35 CET 2020 - tiwai@suse.de - Update to pulseaudio 14.0: see details in: https://www.freedesktop.org/wiki/Software/PulseAudio/Notes/14.0/ +- Build with --enable-stream-restore-clear-old-devices: + This is a bit destructive option, it will clear the old PA routing + once when upgraded prior to 14.0, but it's required for GNOME + (see the release notes above). It should be a one-off action, + and hopefully wouldn't bother too much. - Drop obsoleted patches: 0001-alsa-mixer-path-test-Hide-unused-functions-when-buil.patch 0002-alsa-mixer-recognize-the-Speaker-Jack-control.patch diff --git a/pulseaudio.spec b/pulseaudio.spec index ad4c68f..bc7a77e 100644 --- a/pulseaudio.spec +++ b/pulseaudio.spec @@ -371,6 +371,7 @@ export CFLAGS="%{optflags} -fPIE" --with-udev-rules-dir=%{_udevrulesdir} \ --with-pulsedsp-location='%{_prefix}/\\$$LIB/pulseaudio' \ --with-systemduserunitdir=%{_userunitdir} \ + --enable-stream-restore-clear-old-devices \ %{nil} %make_build %make_build doxygen