summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTanu Kaskinen <tanuk@iki.fi>2015-10-23 13:37:11 +0300
committerTanu Kaskinen <tanuk@iki.fi>2016-06-28 16:55:42 +0300
commita222a07920731f3c4967faccab7469af50b428a4 (patch)
tree75214ad6c2098cc538096a4e22aaaeeda272777a
parent0045f552aa866dfef8761ad516da098788471acd (diff)
alsa: set availability for (some) unavailable profiles
The alsa card hasn't so far set any availability for profiles. That caused an issue with some HDMI hardware: the sound card has two HDMI outputs, but only the second of them is actually usable. The unavailable port is marked as unavailable and the available port is marked as available, but this information isn't propagated to the profile availability. Without profile availability information, the initial profile policy picks the unavailable one, since it has a higher priority value. This patch adds simple logic for marking some profiles unavailable: if the profile only contains unavailable ports, the profile is unavailable too. This can be improved in the future so that if a profile contains sinks or sources that only contain unavailable ports, the profile should be marked as unavailable. Implementing that requires adding more information about the sinks and sources to pa_card_profile, however. BugLink: https://bugzilla.yoctoproject.org/show_bug.cgi?id=8448
-rw-r--r--src/modules/alsa/module-alsa-card.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/src/modules/alsa/module-alsa-card.c b/src/modules/alsa/module-alsa-card.c
index 7aeee15b1..d807a82ea 100644
--- a/src/modules/alsa/module-alsa-card.c
+++ b/src/modules/alsa/module-alsa-card.c
@@ -366,6 +366,7 @@ static int report_jack_state(snd_mixer_elem_t *melem, unsigned int mask) {
void *state;
pa_alsa_jack *jack;
struct temp_port_avail *tp, *tports;
+ pa_card_profile *profile;
pa_assert(u);
@@ -426,6 +427,32 @@ static int report_jack_state(snd_mixer_elem_t *melem, unsigned int mask) {
if (tp->avail == PA_AVAILABLE_NO)
pa_device_port_set_available(tp->port, tp->avail);
+ /* Update profile availabilities. The logic could be improved; for now we
+ * only set obviously unavailable profiles (those that contain only
+ * unavailable ports) to PA_AVAILABLE_NO and all others to
+ * PA_AVAILABLE_UNKNOWN. */
+ PA_HASHMAP_FOREACH(profile, u->card->profiles, state) {
+ pa_device_port *port;
+ void *state2;
+ pa_available_t available = PA_AVAILABLE_NO;
+
+ /* Don't touch the "off" profile. */
+ if (profile->n_sources == 0 && profile->n_sinks == 0)
+ continue;
+
+ PA_HASHMAP_FOREACH(port, u->card->ports, state2) {
+ if (!pa_hashmap_get(port->profiles, profile->name))
+ continue;
+
+ if (port->available != PA_AVAILABLE_NO) {
+ available = PA_AVAILABLE_UNKNOWN;
+ break;
+ }
+ }
+
+ pa_card_profile_set_available(profile, available);
+ }
+
pa_xfree(tports);
return 0;
}