From c1c191f770fbe62c4c2572dd721862ac4e69e176 Mon Sep 17 00:00:00 2001
From: David Henningsson <david.henningsson@canonical.com>
Date: Thu, 23 Feb 2012 07:17:03 +0100
Subject: [PATCH 1/6] alsa: Add port information to HDMI profiles

For Nvidia and Intel, support probing of up to four HDMI devices.
Also add port information to all HDMI profiles.

Signed-off-by: David Henningsson <david.henningsson@canonical.com>
---
 src/Makefile.am                                    |   5 +
 src/modules/alsa/mixer/paths/hdmi-output-0.conf    |   6 +
 src/modules/alsa/mixer/paths/hdmi-output-1.conf    |   6 +
 src/modules/alsa/mixer/paths/hdmi-output-2.conf    |   6 +
 src/modules/alsa/mixer/paths/hdmi-output-3.conf    |   6 +
 .../alsa/mixer/profile-sets/90-pulseaudio.rules    |   8 +-
 src/modules/alsa/mixer/profile-sets/default.conf   |   1 +
 .../alsa/mixer/profile-sets/extra-hdmi.conf        | 158 +++++++++++++++++++++
 8 files changed, 195 insertions(+), 1 deletion(-)
 create mode 100644 src/modules/alsa/mixer/paths/hdmi-output-0.conf
 create mode 100644 src/modules/alsa/mixer/paths/hdmi-output-1.conf
 create mode 100644 src/modules/alsa/mixer/paths/hdmi-output-2.conf
 create mode 100644 src/modules/alsa/mixer/paths/hdmi-output-3.conf
 create mode 100644 src/modules/alsa/mixer/profile-sets/extra-hdmi.conf

diff --git a/src/Makefile.am b/src/Makefile.am
index ffe7558..5a8082a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -83,83 +83,88 @@ AM_CFLAGS = \
 	-DPA_SYSTEM_STATE_PATH=\"$(PA_SYSTEM_STATE_PATH)\" \
 	-DAO_REQUIRE_CAS \
 	-DPULSE_LOCALEDIR=\"$(pulselocaledir)\" \
 	-DPA_MACHINE_ID=\"$(localstatedir)/lib/dbus/machine-id\" \
         -DPA_ALSA_PATHS_DIR=\"$(alsapathsdir)\" \
         -DPA_ALSA_PROFILE_SETS_DIR=\"$(alsaprofilesetsdir)\"
 
 AM_LIBADD = $(PTHREAD_LIBS) $(INTLLIBS)
 AM_LDADD = $(PTHREAD_LIBS) $(INTLLIBS)
 AM_LDFLAGS = $(NODELETE_LDFLAGS)
 
 if STATIC_BINS
 BINLDFLAGS = -static
 endif
 
 if OS_IS_WIN32
 AM_LDFLAGS+=-Wl,--export-all-symbols
 WINSOCK_LIBS=-lwsock32 -lws2_32 -lwininet
 endif
 
 FOREIGN_CFLAGS = -w
 MODULE_LDFLAGS = -module -disable-static -avoid-version $(LDFLAGS_NOUNDEFINED)
 
 ###################################
 #          Extra files            #
 ###################################
 
 ALSA_PROFILES = \
 		modules/alsa/mixer/profile-sets/default.conf \
 		modules/alsa/mixer/profile-sets/maudio-fasttrack-pro.conf \
+		modules/alsa/mixer/profile-sets/extra-hdmi.conf \
 		modules/alsa/mixer/profile-sets/native-instruments-audio4dj.conf \
 		modules/alsa/mixer/profile-sets/native-instruments-audio8dj.conf
 
 ALSA_PATHS = \
 		modules/alsa/mixer/paths/analog-input-aux.conf \
 		modules/alsa/mixer/paths/analog-input.conf \
 		modules/alsa/mixer/paths/analog-input.conf.common \
 		modules/alsa/mixer/paths/analog-input-fm.conf \
 		modules/alsa/mixer/paths/analog-input-internal-mic.conf \
 		modules/alsa/mixer/paths/analog-input-linein.conf \
 		modules/alsa/mixer/paths/analog-input-mic.conf \
 		modules/alsa/mixer/paths/analog-input-mic.conf.common \
 		modules/alsa/mixer/paths/analog-input-mic-line.conf \
 		modules/alsa/mixer/paths/analog-input-tvtuner.conf \
 		modules/alsa/mixer/paths/analog-input-video.conf \
 		modules/alsa/mixer/paths/analog-output.conf \
 		modules/alsa/mixer/paths/analog-output-speaker.conf \
 		modules/alsa/mixer/paths/analog-output.conf.common \
 		modules/alsa/mixer/paths/analog-output-desktop-speaker.conf \
 		modules/alsa/mixer/paths/analog-output-headphones.conf \
 		modules/alsa/mixer/paths/analog-output-headphones-2.conf \
 		modules/alsa/mixer/paths/analog-output-lfe-on-mono.conf \
 		modules/alsa/mixer/paths/analog-output-mono.conf
+		modules/alsa/mixer/paths/hdmi-output-0.conf \
+		modules/alsa/mixer/paths/hdmi-output-1.conf \
+		modules/alsa/mixer/paths/hdmi-output-2.conf \
+		modules/alsa/mixer/paths/hdmi-output-3.conf
 
 EXTRA_DIST = \
 		pulse/client.conf.in \
 		pulse/version.h.in \
 		daemon/daemon.conf.in \
 		daemon/default.pa.in \
 		daemon/system.pa.in \
 		daemon/default.pa.win32 \
 		depmod.py \
 		daemon/esdcompat.in \
 		daemon/start-pulseaudio-x11.in \
 		daemon/start-pulseaudio-kde.in \
 		utils/padsp \
 		modules/module-defs.h.m4 \
 		daemon/pulseaudio.desktop.in \
 		daemon/pulseaudio-kde.desktop.in \
 		map-file \
 		daemon/pulseaudio-system.conf \
 		modules/alsa/mixer/profile-sets/90-pulseaudio.rules \
 		${ALSA_PROFILES} \
 		${ALSA_PATHS}
 
 pulseconf_DATA = \
 		default.pa \
 		system.pa \
 		daemon.conf \
 		client.conf
 
 dbuspolicy_DATA = \
 		daemon/pulseaudio-system.conf
diff --git a/src/modules/alsa/mixer/paths/hdmi-output-0.conf b/src/modules/alsa/mixer/paths/hdmi-output-0.conf
new file mode 100644
index 0000000..46ee4fd
--- /dev/null
+++ b/src/modules/alsa/mixer/paths/hdmi-output-0.conf
@@ -0,0 +1,6 @@
+[General]
+description = HDMI / DisplayPort
+priority = 59
+
+[Jack HDMI/DP,pcm=3]
+required-any = any
diff --git a/src/modules/alsa/mixer/paths/hdmi-output-1.conf b/src/modules/alsa/mixer/paths/hdmi-output-1.conf
new file mode 100644
index 0000000..da8fcb4
--- /dev/null
+++ b/src/modules/alsa/mixer/paths/hdmi-output-1.conf
@@ -0,0 +1,6 @@
+[General]
+description = HDMI / DisplayPort 2
+priority = 58
+
+[Jack HDMI/DP,pcm=7]
+required-any = any
diff --git a/src/modules/alsa/mixer/paths/hdmi-output-2.conf b/src/modules/alsa/mixer/paths/hdmi-output-2.conf
new file mode 100644
index 0000000..5fcddc6
--- /dev/null
+++ b/src/modules/alsa/mixer/paths/hdmi-output-2.conf
@@ -0,0 +1,6 @@
+[General]
+description = HDMI / DisplayPort 3
+priority = 57
+
+[Jack HDMI/DP,pcm=8]
+required-any = any
diff --git a/src/modules/alsa/mixer/paths/hdmi-output-3.conf b/src/modules/alsa/mixer/paths/hdmi-output-3.conf
new file mode 100644
index 0000000..8200787
--- /dev/null
+++ b/src/modules/alsa/mixer/paths/hdmi-output-3.conf
@@ -0,0 +1,6 @@
+[General]
+description = HDMI / DisplayPort 4
+priority = 56
+
+[Jack HDMI/DP,pcm=9]
+required-any = any
diff --git a/src/modules/alsa/mixer/profile-sets/90-pulseaudio.rules b/src/modules/alsa/mixer/profile-sets/90-pulseaudio.rules
index b8e88d0..8252910 100644
--- a/src/modules/alsa/mixer/profile-sets/90-pulseaudio.rules
+++ b/src/modules/alsa/mixer/profile-sets/90-pulseaudio.rules
@@ -1,27 +1,33 @@
 # do not edit this file, it will be overwritten on update
 
 # This file is part of PulseAudio.
 #
 # PulseAudio is free software; you can redistribute it and/or modify
 # it under the terms of the GNU Lesser General Public License as
 # published by the Free Software Foundation; either version 2.1 of the
 # License, or (at your option) any later version.
 #
 # PulseAudio is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
+# Lesser General Public License for more details.
 #
 # You should have received a copy of the GNU Lesser General Public License
 # along with PulseAudio; if not, write to the Free Software Foundation,
 # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 
 SUBSYSTEM!="sound", GOTO="pulseaudio_end"
 ACTION!="change", GOTO="pulseaudio_end"
 KERNEL!="card*", GOTO="pulseaudio_end"
+SUBSYSTEMS=="usb", GOTO="pulseaudio_check_usb"
 
 SUBSYSTEMS=="usb", ATTRS{idVendor}=="17cc", ATTRS{idProduct}=="1978", ENV{PULSE_PROFILE_SET}="native-instruments-audio8dj.conf"
 SUBSYSTEMS=="usb", ATTRS{idVendor}=="17cc", ATTRS{idProduct}=="0839", ENV{PULSE_PROFILE_SET}="native-instruments-audio4dj.conf"
 SUBSYSTEMS=="usb", ATTRS{idVendor}=="0763", ATTRS{idProduct}=="2012", ENV{PULSE_PROFILE_SET}="maudio-fasttrack-pro.conf"
 
+# NVidia and Intel HDAs often have more than one HDMI codec/port on the same card
+ATTRS{vendor}=="0x10de", ENV{PULSE_PROFILE_SET}="extra-hdmi.conf"
+ATTRS{vendor}=="0x8086", ENV{PULSE_PROFILE_SET}="extra-hdmi.conf"
+GOTO="pulseaudio_end"
+
 LABEL="pulseaudio_end"
diff --git a/src/modules/alsa/mixer/profile-sets/default.conf b/src/modules/alsa/mixer/profile-sets/default.conf
index 5d352f1..71dd63f 100644
--- a/src/modules/alsa/mixer/profile-sets/default.conf
+++ b/src/modules/alsa/mixer/profile-sets/default.conf
@@ -109,36 +109,37 @@ paths-output = analog-output analog-output-speaker analog-output-desktop-speaker
 priority = 7
 direction = output
 
 [Mapping iec958-stereo]
 device-strings = iec958:%f
 channel-map = left,right
 priority = 5
 
 [Mapping iec958-surround-40]
 device-strings = iec958:%f
 channel-map = front-left,front-right,rear-left,rear-right
 priority = 1
 
 [Mapping iec958-ac3-surround-40]
 device-strings = a52:%f
 channel-map = front-left,front-right,rear-left,rear-right
 priority = 2
 direction = output
 
 [Mapping iec958-ac3-surround-51]
 device-strings = a52:%f
 channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
 priority = 3
 direction = output
 
 [Mapping hdmi-stereo]
 device-strings = hdmi:%f
 channel-map = left,right
 priority = 4
 direction = output
+paths-output = hdmi-output-0
 
 ; An example for defining multiple-sink profiles
 #[Profile output:analog-stereo+output:iec958-stereo+input:analog-stereo]
 #description = Foobar
 #output-mappings = analog-stereo iec958-stereo
 #input-mappings = analog-stereo
diff --git a/src/modules/alsa/mixer/profile-sets/extra-hdmi.conf b/src/modules/alsa/mixer/profile-sets/extra-hdmi.conf
new file mode 100644
index 0000000..d0bff6a
--- /dev/null
+++ b/src/modules/alsa/mixer/profile-sets/extra-hdmi.conf
@@ -0,0 +1,158 @@
+# This file is part of PulseAudio.
+#
+# PulseAudio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# PulseAudio is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with PulseAudio; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+; This is a profile for Nvidia and Intel cards - some cards have four HDMI codecs,
+; and which ones are working seems to vary a lot between GPU boards. In addition,
+; Nvidia and Intel make southbridges as well, so we need to keep the existing
+; analog profiles.
+; (And by not adding all these extra profiles to default.conf, we make sure
+; there is no performance hit for non-Nvidia/Intel cards.)
+
+[General]
+auto-profiles = yes
+
+[Mapping analog-mono]
+device-strings = hw:%f
+channel-map = mono
+paths-output = analog-output analog-output-speaker analog-output-desktop-speaker analog-output-headphones analog-output-headphones-2 analog-output-mono analog-output-lfe-on-mono
+paths-input = analog-input-front-mic analog-input-rear-mic analog-input-internal-mic analog-input-dock-mic analog-input analog-input-mic analog-input-linein analog-input-aux analog-input-video analog-input-tvtuner analog-input-fm analog-input-mic-line
+priority = 1
+
+[Mapping analog-stereo]
+device-strings = front:%f hw:%f
+channel-map = left,right
+paths-output = analog-output analog-output-speaker analog-output-desktop-speaker analog-output-headphones analog-output-headphones-2 analog-output-mono analog-output-lfe-on-mono
+paths-input = analog-input-front-mic analog-input-rear-mic analog-input-internal-mic analog-input-dock-mic analog-input analog-input-mic analog-input-linein analog-input-aux analog-input-video analog-input-tvtuner analog-input-fm analog-input-mic-line
+priority = 10
+
+[Mapping analog-surround-40]
+device-strings = surround40:%f
+channel-map = front-left,front-right,rear-left,rear-right
+paths-output = analog-output analog-output-speaker analog-output-desktop-speaker analog-output-lfe-on-mono
+priority = 7
+direction = output
+
+[Mapping analog-surround-41]
+device-strings = surround41:%f
+channel-map = front-left,front-right,rear-left,rear-right,lfe
+paths-output = analog-output analog-output-speaker analog-output-desktop-speaker analog-output-lfe-on-mono
+priority = 8
+direction = output
+
+[Mapping analog-surround-50]
+device-strings = surround50:%f
+channel-map = front-left,front-right,rear-left,rear-right,front-center
+paths-output = analog-output analog-output-speaker analog-output-desktop-speaker analog-output-lfe-on-mono
+priority = 7
+direction = output
+
+[Mapping analog-surround-51]
+device-strings = surround51:%f
+channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
+paths-output = analog-output analog-output-speaker analog-output-desktop-speaker analog-output-lfe-on-mono
+priority = 8
+direction = output
+
+[Mapping analog-surround-71]
+device-strings = surround71:%f
+channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe,side-left,side-right
+description = Analog Surround 7.1
+paths-output = analog-output analog-output-speaker analog-output-desktop-speaker analog-output-lfe-on-mono
+priority = 7
+direction = output
+
+[Mapping iec958-stereo]
+device-strings = iec958:%f
+channel-map = left,right
+paths-input = iec958-stereo-input
+paths-output = iec958-stereo-output
+priority = 5
+
+[Mapping iec958-ac3-surround-40]
+device-strings = a52:%f
+channel-map = front-left,front-right,rear-left,rear-right
+priority = 2
+direction = output
+
+[Mapping iec958-ac3-surround-51]
+device-strings = a52:%f
+channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
+priority = 3
+direction = output
+
+[Mapping hdmi-stereo]
+device-strings = hdmi:%f
+description = Digital Stereo (HDMI)
+paths-output = hdmi-output-0
+channel-map = left,right
+priority = 4
+direction = output
+
+[Mapping hdmi-surround]
+description = Digital Surround 5.1 (HDMI)
+device-strings = hdmi:%f
+paths-output = hdmi-output-0
+channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
+priority = 3
+direction = output
+
+[Mapping hdmi-stereo-extra1]
+description = Digital Stereo (HDMI)
+device-strings = hdmi:%f,1
+paths-output = hdmi-output-1
+channel-map = left,right
+priority = 2
+direction = output
+
+[Mapping hdmi-surround-extra1]
+description = Digital Surround 5.1 (HDMI)
+device-strings = hdmi:%f,1
+paths-output = hdmi-output-1
+channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
+priority = 1
+direction = output
+
+[Mapping hdmi-stereo-extra2]
+description = Digital Stereo (HDMI)
+device-strings = hdmi:%f,2
+paths-output = hdmi-output-2
+channel-map = left,right
+priority = 2
+direction = output
+
+[Mapping hdmi-surround-extra2]
+description = Digital Surround 5.1 (HDMI)
+device-strings = hdmi:%f,2
+paths-output = hdmi-output-2
+channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
+priority = 1
+direction = output
+
+[Mapping hdmi-stereo-extra3]
+description = Digital Stereo (HDMI)
+device-strings = hdmi:%f,3
+paths-output = hdmi-output-3
+channel-map = left,right
+priority = 2
+direction = output
+
+[Mapping hdmi-surround-extra3]
+description = Digital Surround 5.1 (HDMI)
+device-strings = hdmi:%f,3
+paths-output = hdmi-output-3
+channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
+priority = 1
+direction = output
-- 
1.9.3


From 0a72e1cc6aeede3e1d5ee2eb4b5e6486a14a9da3 Mon Sep 17 00:00:00 2001
From: "Alexander E. Patrakov" <patrakov@gmail.com>
Date: Thu, 10 Apr 2014 21:13:43 +0600
Subject: [PATCH 2/6] Name HDMI outputs uniquely

On Haswell hardware, there are multiple HDMI outputs capable of
digital sound output. As they were identically named, KDE's control
center was unable to distinguish them, restored the wrong profile and
thus routed sound to the wrong HDMI monitor.

Also, having identically-named menu items in other mixer applications
looks like a bug.
---
 src/modules/alsa/mixer/profile-sets/extra-hdmi.conf | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/modules/alsa/mixer/profile-sets/extra-hdmi.conf b/src/modules/alsa/mixer/profile-sets/extra-hdmi.conf
index d0bff6a..c721d48 100644
--- a/src/modules/alsa/mixer/profile-sets/extra-hdmi.conf
+++ b/src/modules/alsa/mixer/profile-sets/extra-hdmi.conf
@@ -83,76 +83,76 @@ priority = 5
 
 [Mapping iec958-ac3-surround-40]
 device-strings = a52:%f
 channel-map = front-left,front-right,rear-left,rear-right
 priority = 2
 direction = output
 
 [Mapping iec958-ac3-surround-51]
 device-strings = a52:%f
 channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
 priority = 3
 direction = output
 
 [Mapping hdmi-stereo]
 device-strings = hdmi:%f
 description = Digital Stereo (HDMI)
 paths-output = hdmi-output-0
 channel-map = left,right
 priority = 4
 direction = output
 
 [Mapping hdmi-surround]
 description = Digital Surround 5.1 (HDMI)
 device-strings = hdmi:%f
 paths-output = hdmi-output-0
 channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
 priority = 3
 direction = output
 
 [Mapping hdmi-stereo-extra1]
-description = Digital Stereo (HDMI)
+description = Digital Stereo (HDMI 2)
 device-strings = hdmi:%f,1
 paths-output = hdmi-output-1
 channel-map = left,right
 priority = 2
 direction = output
 
 [Mapping hdmi-surround-extra1]
-description = Digital Surround 5.1 (HDMI)
+description = Digital Surround 5.1 (HDMI 2)
 device-strings = hdmi:%f,1
 paths-output = hdmi-output-1
 channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
 priority = 1
 direction = output
 
 [Mapping hdmi-stereo-extra2]
-description = Digital Stereo (HDMI)
+description = Digital Stereo (HDMI 3)
 device-strings = hdmi:%f,2
 paths-output = hdmi-output-2
 channel-map = left,right
 priority = 2
 direction = output
 
 [Mapping hdmi-surround-extra2]
-description = Digital Surround 5.1 (HDMI)
+description = Digital Surround 5.1 (HDMI 3)
 device-strings = hdmi:%f,2
 paths-output = hdmi-output-2
 channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
 priority = 1
 direction = output
 
 [Mapping hdmi-stereo-extra3]
-description = Digital Stereo (HDMI)
+description = Digital Stereo (HDMI 4)
 device-strings = hdmi:%f,3
 paths-output = hdmi-output-3
 channel-map = left,right
 priority = 2
 direction = output
 
 [Mapping hdmi-surround-extra3]
-description = Digital Surround 5.1 (HDMI)
+description = Digital Surround 5.1 (HDMI 4)
 device-strings = hdmi:%f,3
 paths-output = hdmi-output-3
 channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
 priority = 1
 direction = output
-- 
1.9.3


From 675f43beddf961c0cd99b88301ca5316cdb6e61a Mon Sep 17 00:00:00 2001
From: David Henningsson <david.henningsson@canonical.com>
Date: Thu, 23 Feb 2012 07:17:04 +0100
Subject: [PATCH 3/6] Add a new module switch-on-port-available that acts on
 port changes

This module tries to switch to a port when availability changes to
"YES", and tries to switch away when availability changes to "NO".

Once there is a priority list infrastructure in place and ready,
this functionality might be redundant, but this will do as an
interim solution.
---
 src/Makefile.am                               |   6 +
 src/modules/module-switch-on-port-available.c | 233 ++++++++++++++++++++++++++
 2 files changed, 239 insertions(+)
 create mode 100644 src/modules/module-switch-on-port-available.c

diff --git a/src/Makefile.am b/src/Makefile.am
index 5a8082a..4199f21 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1007,60 +1007,61 @@ modlibexec_LTLIBRARIES += \
 		module-cli.la \
 		module-cli-protocol-tcp.la \
 		module-simple-protocol-tcp.la \
 		module-null-sink.la \
 		module-sine-source.la \
 		module-detect.la \
 		module-volume-restore.la \
 		module-device-manager.la \
 		module-device-restore.la \
 		module-stream-restore.la \
 		module-card-restore.la \
 		module-default-device-restore.la \
 		module-always-sink.la \
 		module-rescue-streams.la \
 		module-intended-roles.la \
 		module-suspend-on-idle.la \
 		module-http-protocol-tcp.la \
 		module-sine.la \
 		module-native-protocol-tcp.la \
 		module-native-protocol-fd.la \
 		module-esound-protocol-tcp.la \
 		module-combine.la \
 		module-remap-sink.la \
 		module-ladspa-sink.la \
 		module-esound-sink.la \
 		module-tunnel-sink.la \
 		module-tunnel-source.la \
 		module-position-event-sounds.la \
 		module-augment-properties.la \
 		module-cork-music-on-phone.la \
+		module-switch-on-port-available.la \
 		module-loopback.la
 
 # See comment at librtp.la above
 if !OS_IS_WIN32
 modlibexec_LTLIBRARIES += \
 		module-rtp-send.la \
 		module-rtp-recv.la
 endif
 
 if HAVE_AF_UNIX
 modlibexec_LTLIBRARIES += \
 		module-cli-protocol-unix.la \
 		module-simple-protocol-unix.la \
 		module-http-protocol-unix.la \
 		module-native-protocol-unix.la \
 		module-esound-protocol-unix.la
 endif
 
 if HAVE_MKFIFO
 modlibexec_LTLIBRARIES += \
 		module-pipe-sink.la \
 		module-pipe-source.la
 endif
 
 if !OS_IS_WIN32
 modlibexec_LTLIBRARIES += \
 		module-esound-compat-spawnfd.la \
 		module-esound-compat-spawnpid.la
 endif
 
@@ -1229,60 +1230,61 @@ SYMDEF_FILES = \
 		modules/alsa/module-alsa-card-symdef.h \
 		modules/module-solaris-symdef.h \
 		modules/module-waveout-symdef.h \
 		modules/module-detect-symdef.h \
 		modules/rtp/module-rtp-send-symdef.h \
 		modules/rtp/module-rtp-recv-symdef.h \
 		modules/jack/module-jack-sink-symdef.h \
 		modules/jack/module-jack-source-symdef.h \
 		modules/module-volume-restore-symdef.h \
 		modules/module-device-manager-symdef.h \
 		modules/module-device-restore-symdef.h \
 		modules/module-stream-restore-symdef.h \
 		modules/module-card-restore-symdef.h \
 		modules/module-default-device-restore-symdef.h \
 		modules/module-always-sink-symdef.h \
 		modules/module-rescue-streams-symdef.h \
 		modules/module-intended-roles-symdef.h \
 		modules/module-suspend-on-idle-symdef.h \
 		modules/module-hal-detect-symdef.h \
 		modules/module-udev-detect-symdef.h \
 		modules/bluetooth/module-bluetooth-proximity-symdef.h \
 		modules/bluetooth/module-bluetooth-discover-symdef.h \
 		modules/bluetooth/module-bluetooth-device-symdef.h \
 		modules/raop/module-raop-sink-symdef.h \
 		modules/raop/module-raop-discover-symdef.h \
 		modules/gconf/module-gconf-symdef.h \
 		modules/module-position-event-sounds-symdef.h \
 		modules/module-augment-properties-symdef.h \
 		modules/module-cork-music-on-phone-symdef.h \
 		modules/module-console-kit-symdef.h \
+		modules/module-switch-on-port-available-symdef.h \
 		modules/module-loopback-symdef.h
 
 EXTRA_DIST += $(SYMDEF_FILES)
 BUILT_SOURCES += $(SYMDEF_FILES)
 
 $(SYMDEF_FILES): modules/module-defs.h.m4
 	$(MKDIR_P) $(dir $@)
 	$(M4) -Dfname="$@" $< > $@
 
 # Simple protocol
 
 module_simple_protocol_tcp_la_SOURCES = modules/module-protocol-stub.c
 module_simple_protocol_tcp_la_CFLAGS = -DUSE_TCP_SOCKETS -DUSE_PROTOCOL_SIMPLE $(AM_CFLAGS)
 module_simple_protocol_tcp_la_LDFLAGS = $(MODULE_LDFLAGS)
 module_simple_protocol_tcp_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libprotocol-simple.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
 
 module_simple_protocol_unix_la_SOURCES = modules/module-protocol-stub.c
 module_simple_protocol_unix_la_CFLAGS = -DUSE_UNIX_SOCKETS -DUSE_PROTOCOL_SIMPLE $(AM_CFLAGS)
 module_simple_protocol_unix_la_LDFLAGS = $(MODULE_LDFLAGS)
 module_simple_protocol_unix_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libprotocol-simple.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
 
 # CLI protocol
 
 module_cli_la_SOURCES = modules/module-cli.c
 module_cli_la_LDFLAGS = $(MODULE_LDFLAGS)
 module_cli_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libcli.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
 
 module_cli_protocol_tcp_la_SOURCES = modules/module-protocol-stub.c
 module_cli_protocol_tcp_la_CFLAGS = -DUSE_TCP_SOCKETS -DUSE_PROTOCOL_CLI $(AM_CFLAGS)
 module_cli_protocol_tcp_la_LDFLAGS = $(MODULE_LDFLAGS)
@@ -1349,60 +1351,64 @@ module_esound_sink_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la
 # Pipes
 
 module_pipe_sink_la_SOURCES = modules/module-pipe-sink.c
 module_pipe_sink_la_LDFLAGS = $(MODULE_LDFLAGS)
 module_pipe_sink_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
 
 module_pipe_source_la_SOURCES = modules/module-pipe-source.c
 module_pipe_source_la_LDFLAGS = $(MODULE_LDFLAGS)
 module_pipe_source_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
 
 # Fake sources/sinks
 
 module_sine_la_SOURCES = modules/module-sine.c
 module_sine_la_LDFLAGS = $(MODULE_LDFLAGS)
 module_sine_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
 
 module_null_sink_la_SOURCES = modules/module-null-sink.c
 module_null_sink_la_LDFLAGS = $(MODULE_LDFLAGS)
 module_null_sink_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
 
 module_sine_source_la_SOURCES = modules/module-sine-source.c
 module_sine_source_la_LDFLAGS = -module -avoid-version
 module_sine_source_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
 
 # Couplings
 
 module_combine_la_SOURCES = modules/module-combine.c
 module_combine_la_LDFLAGS = $(MODULE_LDFLAGS)
 module_combine_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
 
+module_switch_on_port_available_la_SOURCES = modules/module-switch-on-port-available.c
+module_switch_on_port_available_la_LDFLAGS = $(MODULE_LDFLAGS)
+module_switch_on_port_available_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+
 module_remap_sink_la_SOURCES = modules/module-remap-sink.c
 module_remap_sink_la_LDFLAGS = $(MODULE_LDFLAGS)
 module_remap_sink_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
 
 module_ladspa_sink_la_SOURCES = modules/module-ladspa-sink.c modules/ladspa.h
 module_ladspa_sink_la_CFLAGS = -DLADSPA_PATH=\"$(libdir)/ladspa:/usr/local/lib/ladspa:/usr/lib/ladspa:/usr/local/lib64/ladspa:/usr/lib64/ladspa\" $(AM_CFLAGS)
 module_ladspa_sink_la_LDFLAGS = $(MODULE_LDFLAGS)
 module_ladspa_sink_la_LIBADD = $(AM_LIBADD) $(LIBLTDL) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
 
 module_match_la_SOURCES = modules/module-match.c
 module_match_la_LDFLAGS = $(MODULE_LDFLAGS)
 module_match_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
 
 module_tunnel_sink_la_SOURCES = modules/module-tunnel.c
 module_tunnel_sink_la_CFLAGS = -DTUNNEL_SINK=1 $(AM_CFLAGS)
 module_tunnel_sink_la_LDFLAGS = $(MODULE_LDFLAGS)
 module_tunnel_sink_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
 
 module_tunnel_source_la_SOURCES = modules/module-tunnel.c
 module_tunnel_source_la_LDFLAGS = $(MODULE_LDFLAGS)
 module_tunnel_source_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
 
 module_loopback_la_SOURCES = modules/module-loopback.c
 module_loopback_la_LDFLAGS = $(MODULE_LDFLAGS)
 module_loopback_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
 
 # X11
 
 module_x11_bell_la_SOURCES = modules/x11/module-x11-bell.c
 module_x11_bell_la_CFLAGS = $(AM_CFLAGS) $(X11_CFLAGS)
diff --git a/src/modules/module-switch-on-port-available.c b/src/modules/module-switch-on-port-available.c
new file mode 100644
index 0000000..9149b6d
--- /dev/null
+++ b/src/modules/module-switch-on-port-available.c
@@ -0,0 +1,233 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2006 Lennart Poettering
+  Copyright 2011 Canonical Ltd
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as published
+  by the Free Software Foundation; either version 2.1 of the License,
+  or (at your option) any later version.
+
+  PulseAudio is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with PulseAudio; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <pulsecore/core.h>
+#include <pulsecore/device-port.h>
+#include <pulsecore/hashmap.h>
+
+#include "module-switch-on-port-available-symdef.h"
+
+struct userdata {
+     pa_hook_slot *callback_slot;
+};
+
+static pa_device_port* find_best_port(pa_hashmap *ports) {
+    void *state;
+    pa_device_port* port, *result = NULL;
+
+    PA_HASHMAP_FOREACH(port, ports, state) {
+        if (result == NULL ||
+            result->available == PA_PORT_AVAILABLE_NO ||
+            (port->available != PA_PORT_AVAILABLE_NO && port->priority > result->priority)) {
+            result = port;
+        }
+    }
+
+    return result;
+}
+
+static pa_bool_t try_to_switch_profile(pa_card *card, pa_device_port *port) {
+    pa_card_profile *best_profile = NULL, *profile;
+    void *state;
+
+    pa_log_debug("Finding best profile");
+
+    if (port->profiles)
+        PA_HASHMAP_FOREACH(profile, port->profiles, state) {
+            if (best_profile && best_profile->priority >= profile->priority)
+                continue;
+
+            /* We make a best effort to keep other direction unchanged */
+            if (card->active_profile && !port->is_input) {
+                if (card->active_profile->n_sources != profile->n_sources)
+                    continue;
+
+                if (card->active_profile->max_source_channels != profile->max_source_channels)
+                    continue;
+            }
+
+            if (card->active_profile && !port->is_output) {
+                if (card->active_profile->n_sinks != profile->n_sinks)
+                    continue;
+
+                if (card->active_profile->max_sink_channels != profile->max_sink_channels)
+                    continue;
+            }
+
+            best_profile = profile;
+        }
+
+    if (!best_profile) {
+        pa_log_debug("No suitable profile found");
+        return FALSE;
+    }
+
+    if (pa_card_set_profile(card, best_profile->name, FALSE) != 0) {
+        pa_log_debug("Could not set profile %s", best_profile->name);
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+static void find_sink_and_source(pa_card *card, pa_device_port *port, pa_sink **si, pa_source **so)
+{
+    pa_sink *sink = NULL;
+    pa_source *source = NULL;
+    uint32_t state;
+
+    if (port->is_output)
+        PA_IDXSET_FOREACH(sink, card->sinks, state)
+            if (sink->ports && port == pa_hashmap_get(sink->ports, port->name))
+                break;
+
+    if (port->is_input)
+        PA_IDXSET_FOREACH(source, card->sources, state)
+            if (source->ports && port == pa_hashmap_get(source->ports, port->name))
+                break;
+
+    *si = sink;
+    *so = source;
+}
+
+static pa_hook_result_t port_available_hook_callback(pa_core *c, pa_device_port *port, void* userdata) {
+    uint32_t state;
+    pa_card* card;
+    pa_sink *sink;
+    pa_source *source;
+    pa_bool_t is_active_profile, is_active_port;
+
+    pa_log_debug("finding port %s", port->name);
+
+    PA_IDXSET_FOREACH(card, c->cards, state)
+        if (card->ports && port == pa_hashmap_get(card->ports, port->name))
+            break;
+
+    if (!card) {
+        pa_log_warn("Did not find port %s in array of cards", port->name);
+        return PA_HOOK_OK;
+    }
+
+    find_sink_and_source(card, port, &sink, &source);
+
+    is_active_profile = port->profiles && card->active_profile &&
+        card->active_profile == pa_hashmap_get(port->profiles, card->active_profile->name);
+    is_active_port = (sink && sink->active_port == port) || (source && source->active_port == port);
+
+    if (port->available == PA_PORT_AVAILABLE_NO && !is_active_port)
+        return PA_HOOK_OK;
+
+    if (port->available == PA_PORT_AVAILABLE_YES) {
+        if (is_active_port)
+            return PA_HOOK_OK;
+
+        if (!is_active_profile) {
+            if (!try_to_switch_profile(card, port))
+                return PA_HOOK_OK;
+
+            pa_assert(card->active_profile == pa_hashmap_get(port->profiles, card->active_profile->name));
+
+            /* Now that profile has changed, our sink and source pointers must be updated */
+            find_sink_and_source(card, port, &sink, &source);
+        }
+
+        if (source)
+            pa_source_set_port(source, port->name, FALSE);
+        if (sink)
+            pa_sink_set_port(sink, port->name, FALSE);
+    }
+
+    if (port->available == PA_PORT_AVAILABLE_NO) {
+        if (sink) {
+            pa_device_port *p2 = find_best_port(sink->ports);
+
+            if (p2 && p2->available != PA_PORT_AVAILABLE_NO)
+                pa_sink_set_port(sink, p2->name, FALSE);
+            else {
+                /* Maybe try to switch to another profile? */
+            }
+        }
+
+        if (source) {
+            pa_device_port *p2 = find_best_port(source->ports);
+
+            if (p2 && p2->available != PA_PORT_AVAILABLE_NO)
+                pa_source_set_port(source, p2->name, FALSE);
+            else {
+                /* Maybe try to switch to another profile? */
+            }
+        }
+    }
+
+    return PA_HOOK_OK;
+}
+
+static void handle_all_unavailable(pa_core *core) {
+    pa_card *card;
+    uint32_t state;
+
+    PA_IDXSET_FOREACH(card, core->cards, state) {
+        pa_device_port *port;
+        void *state2;
+
+        if (!card->ports)
+            continue;
+
+        PA_HASHMAP_FOREACH(port, card->ports, state2) {
+            if (port->available == PA_PORT_AVAILABLE_NO)
+                port_available_hook_callback(core, port, NULL);
+        }
+    }
+}
+
+int pa__init(pa_module*m) {
+    struct userdata *u;
+
+    pa_assert(m);
+
+    m->userdata = u = pa_xnew(struct userdata, 1);
+
+    u->callback_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_PORT_AVAILABLE_CHANGED],
+                                       PA_HOOK_LATE, (pa_hook_cb_t) port_available_hook_callback, u);
+
+    handle_all_unavailable(m->core);
+
+    return 0;
+}
+
+void pa__done(pa_module*m) {
+    struct userdata *u;
+
+    pa_assert(m);
+
+    if (!(u = m->userdata))
+        return;
+
+    if (u->callback_slot)
+        pa_hook_slot_free(u->callback_slot);
+
+    pa_xfree(u);
+}
-- 
1.9.3


From 008fd6aee62dea03521de95892366605b2806338 Mon Sep 17 00:00:00 2001
From: David Henningsson <david.henningsson@canonical.com>
Date: Fri, 28 Mar 2014 11:59:09 +0100
Subject: [PATCH 4/6] module-switch-on-port-available: Don't switch profiles on
 uninitialized cards

This could cause the HDMI port to become the default on some systems
where analog output was available.

BugLink: https://bugs.launchpad.net/ubuntu/+source/pulseaudio/+bug/1256511
BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=73375
Signed-off-by: David Henningsson <david.henningsson@canonical.com>
---
 src/modules/module-switch-on-port-available.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/modules/module-switch-on-port-available.c b/src/modules/module-switch-on-port-available.c
index 9149b6d..ee9e2f1 100644
--- a/src/modules/module-switch-on-port-available.c
+++ b/src/modules/module-switch-on-port-available.c
@@ -104,60 +104,65 @@ static void find_sink_and_source(pa_card *card, pa_device_port *port, pa_sink **
             if (sink->ports && port == pa_hashmap_get(sink->ports, port->name))
                 break;
 
     if (port->is_input)
         PA_IDXSET_FOREACH(source, card->sources, state)
             if (source->ports && port == pa_hashmap_get(source->ports, port->name))
                 break;
 
     *si = sink;
     *so = source;
 }
 
 static pa_hook_result_t port_available_hook_callback(pa_core *c, pa_device_port *port, void* userdata) {
     uint32_t state;
     pa_card* card;
     pa_sink *sink;
     pa_source *source;
     pa_bool_t is_active_profile, is_active_port;
 
     pa_log_debug("finding port %s", port->name);
 
     PA_IDXSET_FOREACH(card, c->cards, state)
         if (card->ports && port == pa_hashmap_get(card->ports, port->name))
             break;
 
     if (!card) {
         pa_log_warn("Did not find port %s in array of cards", port->name);
         return PA_HOOK_OK;
     }
 
+    if (pa_idxset_size(card->sinks) == 0 && pa_idxset_size(card->sources) == 0)
+        /* This card is not initialized yet. We'll handle it in
+           sink_new / source_new callbacks later. */
+        return PA_HOOK_OK;
+
     find_sink_and_source(card, port, &sink, &source);
 
     is_active_profile = port->profiles && card->active_profile &&
         card->active_profile == pa_hashmap_get(port->profiles, card->active_profile->name);
     is_active_port = (sink && sink->active_port == port) || (source && source->active_port == port);
 
     if (port->available == PA_PORT_AVAILABLE_NO && !is_active_port)
         return PA_HOOK_OK;
 
     if (port->available == PA_PORT_AVAILABLE_YES) {
         if (is_active_port)
             return PA_HOOK_OK;
 
         if (!is_active_profile) {
             if (!try_to_switch_profile(card, port))
                 return PA_HOOK_OK;
 
             pa_assert(card->active_profile == pa_hashmap_get(port->profiles, card->active_profile->name));
 
             /* Now that profile has changed, our sink and source pointers must be updated */
             find_sink_and_source(card, port, &sink, &source);
         }
 
         if (source)
             pa_source_set_port(source, port->name, FALSE);
         if (sink)
             pa_sink_set_port(sink, port->name, FALSE);
     }
 
     if (port->available == PA_PORT_AVAILABLE_NO) {
-- 
1.9.3


From b532b360cc8661fbc3fdc35ae476d3ae90562bdc Mon Sep 17 00:00:00 2001
From: David Henningsson <david.henningsson@canonical.com>
Date: Mon, 19 Mar 2012 16:42:10 +0100
Subject: [PATCH 5/6] module-switch-on-port-available: Do not switch profile if
 current port is available

For switching profiles, we are a little more cautious, only switch
from an unavailable port to an available one. Profile switching is
mainly used for HDMI/DisplayPort, and this is to avoid switching from
analog to HDMI/DP when it becomes available.

See http://lists.freedesktop.org/archives/pulseaudio-discuss/2012-March/012991.html
and replies for more information.

Signed-off-by: David Henningsson <david.henningsson@canonical.com>
---
 src/modules/module-switch-on-port-available.c | 24 ++++++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/src/modules/module-switch-on-port-available.c b/src/modules/module-switch-on-port-available.c
index ee9e2f1..df9ccc6 100644
--- a/src/modules/module-switch-on-port-available.c
+++ b/src/modules/module-switch-on-port-available.c
@@ -33,77 +33,97 @@
 struct userdata {
      pa_hook_slot *callback_slot;
 };
 
 static pa_device_port* find_best_port(pa_hashmap *ports) {
     void *state;
     pa_device_port* port, *result = NULL;
 
     PA_HASHMAP_FOREACH(port, ports, state) {
         if (result == NULL ||
             result->available == PA_PORT_AVAILABLE_NO ||
             (port->available != PA_PORT_AVAILABLE_NO && port->priority > result->priority)) {
             result = port;
         }
     }
 
     return result;
 }
 
 static pa_bool_t try_to_switch_profile(pa_card *card, pa_device_port *port) {
     pa_card_profile *best_profile = NULL, *profile;
     void *state;
 
     pa_log_debug("Finding best profile");
 
     if (port->profiles)
         PA_HASHMAP_FOREACH(profile, port->profiles, state) {
             if (best_profile && best_profile->priority >= profile->priority)
                 continue;
 
+            if (!card->active_profile) {
+                best_profile = profile;
+                continue;
+            }
+
             /* We make a best effort to keep other direction unchanged */
-            if (card->active_profile && !port->is_input) {
+            if (!port->is_input) {
                 if (card->active_profile->n_sources != profile->n_sources)
                     continue;
 
                 if (card->active_profile->max_source_channels != profile->max_source_channels)
                     continue;
             }
 
-            if (card->active_profile && !port->is_output) {
+            if (!port->is_output) {
                 if (card->active_profile->n_sinks != profile->n_sinks)
                     continue;
 
                 if (card->active_profile->max_sink_channels != profile->max_sink_channels)
                     continue;
             }
 
+            if (port->is_output) {
+                /* Try not to switch to HDMI sinks from analog when HDMI is becoming available */
+                uint32_t state2;
+                pa_sink *sink;
+                pa_bool_t found_active_port = FALSE;
+                PA_IDXSET_FOREACH(sink, card->sinks, state2) {
+                    if (!sink->active_port)
+                        continue;
+                    if (sink->active_port->available != PA_PORT_AVAILABLE_NO)
+                        found_active_port = TRUE;
+                }
+                if (found_active_port)
+                    continue;
+            }
+
             best_profile = profile;
         }
 
     if (!best_profile) {
         pa_log_debug("No suitable profile found");
         return FALSE;
     }
 
     if (pa_card_set_profile(card, best_profile->name, FALSE) != 0) {
         pa_log_debug("Could not set profile %s", best_profile->name);
         return FALSE;
     }
 
     return TRUE;
 }
 
 static void find_sink_and_source(pa_card *card, pa_device_port *port, pa_sink **si, pa_source **so)
 {
     pa_sink *sink = NULL;
     pa_source *source = NULL;
     uint32_t state;
 
     if (port->is_output)
         PA_IDXSET_FOREACH(sink, card->sinks, state)
             if (sink->ports && port == pa_hashmap_get(sink->ports, port->name))
                 break;
 
     if (port->is_input)
         PA_IDXSET_FOREACH(source, card->sources, state)
             if (source->ports && port == pa_hashmap_get(source->ports, port->name))
-- 
1.9.3


From eec5774ef629be2b84679f9acf7f307f843e5e9a Mon Sep 17 00:00:00 2001
From: David Henningsson <david.henningsson@canonical.com>
Date: Thu, 23 Feb 2012 07:17:05 +0100
Subject: [PATCH 6/6] conf: Load switch-on-port-available module by default

Signed-off-by: David Henningsson <david.henningsson@canonical.com>
---
 src/daemon/default.pa.in | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/daemon/default.pa.in b/src/daemon/default.pa.in
index 00c000e..65afec1 100755
--- a/src/daemon/default.pa.in
+++ b/src/daemon/default.pa.in
@@ -105,33 +105,35 @@ load-module module-intended-roles
 
 ### Automatically suspend sinks/sources that become idle for too long
 load-module module-suspend-on-idle
 
 ### If autoexit on idle is enabled we want to make sure we only quit
 ### when no local session needs us anymore.
 load-module module-console-kit
 
 ### Enable positioned event sounds
 load-module module-position-event-sounds
 
 ### Cork music streams when a phone stream is active
 load-module module-cork-music-on-phone
 
 # X11 modules should not be started from default.pa so that one daemon
 # can be shared by multiple sessions.
 
 ### Load X11 bell module
 #load-module module-x11-bell sample=bell-windowing-system
 
 ### Register ourselves in the X11 session manager
 #load-module module-x11-xsmp
 
 ### Publish connection data in the X11 root window
 #.ifexists module-x11-publish@PA_SOEXT@
 #.nofail
 #load-module module-x11-publish
 #.fail
 #.endif
 
+load-module module-switch-on-port-available
+
 ### Make some devices default
 #set-default-sink output
 #set-default-source input
-- 
1.9.3

