From 67f11ff30177d40e408523bdce0eeff27b8e6f9b Mon Sep 17 00:00:00 2001 From: Tanu Kaskinen Date: Sun, 8 Oct 2017 19:48:25 +0300 Subject: [PATCH] alsa-mixer: autodetect the HDMI jack PCM device This removes the need to hardcode the PCM device index in the HDMI jack names. The hardcoded values don't work with the Intel HDMI LPE driver. BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=100488 --- src/modules/alsa/alsa-mixer.c | 53 +++++++++++++++++-- src/modules/alsa/alsa-mixer.h | 4 +- src/modules/alsa/alsa-sink.c | 2 +- src/modules/alsa/alsa-source.c | 2 +- .../mixer/paths/analog-output.conf.common | 4 ++ .../alsa/mixer/paths/hdmi-output-0.conf | 3 +- .../alsa/mixer/paths/hdmi-output-1.conf | 3 +- .../alsa/mixer/paths/hdmi-output-2.conf | 3 +- .../alsa/mixer/paths/hdmi-output-3.conf | 3 +- .../alsa/mixer/paths/hdmi-output-4.conf | 3 +- .../alsa/mixer/paths/hdmi-output-5.conf | 3 +- .../alsa/mixer/paths/hdmi-output-6.conf | 3 +- .../alsa/mixer/paths/hdmi-output-7.conf | 3 +- 13 files changed, 73 insertions(+), 16 deletions(-) diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c index 02ab4a611..eaee7ea0a 100644 --- a/src/modules/alsa/alsa-mixer.c +++ b/src/modules/alsa/alsa-mixer.c @@ -1812,12 +1812,31 @@ static int element_probe(pa_alsa_element *e, snd_mixer_t *m) { return 0; } -static int jack_probe(pa_alsa_jack *j, snd_mixer_t *m) { +static int jack_probe(pa_alsa_jack *j, pa_alsa_mapping *mapping, snd_mixer_t *m) { bool has_control; pa_assert(j); pa_assert(j->path); + if (j->append_pcm_to_name) { + char *new_name; + + if (!mapping) { + /* This could also be an assertion, because this should never + * happen. At the time of writing, mapping can only be NULL when + * module-alsa-sink/source synthesizes a path, and those + * synthesized paths never have any jacks, so jack_probe() should + * never be called with a NULL mapping. */ + pa_log("Jack %s: append_pcm_to_name is set, but mapping is NULL. Can't use this jack.", j->name); + return -1; + } + + new_name = pa_sprintf_malloc("%s,pcm=%i Jack", j->name, mapping->hw_device_index); + pa_xfree(j->alsa_name); + j->alsa_name = new_name; + j->append_pcm_to_name = false; + } + has_control = pa_alsa_mixer_find(m, j->alsa_name, 0) != NULL; pa_alsa_jack_set_has_control(j, has_control); @@ -2326,6 +2345,30 @@ static int jack_parse_state(pa_config_parser_state *state) { return 0; } +static int jack_parse_append_pcm_to_name(pa_config_parser_state *state) { + pa_alsa_path *path; + pa_alsa_jack *jack; + int b; + + pa_assert(state); + + path = state->userdata; + if (!(jack = jack_get(path, state->section))) { + pa_log("[%s:%u] Option 'append_pcm_to_name' not expected in section '%s'", + state->filename, state->lineno, state->section); + return -1; + } + + b = pa_parse_boolean(state->rvalue); + if (b < 0) { + pa_log("[%s:%u] Invalid value for 'append_pcm_to_name': %s", state->filename, state->lineno, state->rvalue); + return -1; + } + + jack->append_pcm_to_name = b; + return 0; +} + 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; @@ -2534,6 +2577,7 @@ pa_alsa_path* pa_alsa_path_new(const char *paths_dir, const char *fname, pa_alsa /* [Jack ...] */ { "state.plugged", jack_parse_state, NULL, NULL }, { "state.unplugged", jack_parse_state, NULL, NULL }, + { "append-pcm-to-name", jack_parse_append_pcm_to_name, NULL, NULL }, /* [Element ...] */ { "switch", element_parse_switch, NULL, NULL }, @@ -2746,7 +2790,7 @@ static void path_create_settings(pa_alsa_path *p) { element_create_settings(p->elements, NULL); } -int pa_alsa_path_probe(pa_alsa_path *p, snd_mixer_t *m, bool ignore_dB) { +int pa_alsa_path_probe(pa_alsa_path *p, pa_alsa_mapping *mapping, snd_mixer_t *m, bool ignore_dB) { pa_alsa_element *e; pa_alsa_jack *j; double min_dB[PA_CHANNEL_POSITION_MAX], max_dB[PA_CHANNEL_POSITION_MAX]; @@ -2766,7 +2810,7 @@ int pa_alsa_path_probe(pa_alsa_path *p, snd_mixer_t *m, bool ignore_dB) { pa_log_debug("Probing path '%s'", p->name); PA_LLIST_FOREACH(j, p->jacks) { - if (jack_probe(j, m) < 0) { + if (jack_probe(j, mapping, m) < 0) { p->supported = false; pa_log_debug("Probe of jack '%s' failed.", j->alsa_name); return -1; @@ -3968,9 +4012,8 @@ static void mapping_paths_probe(pa_alsa_mapping *m, pa_alsa_profile *profile, } PA_HASHMAP_FOREACH(p, ps->paths, state) { - if (pa_alsa_path_probe(p, mixer_handle, m->profile_set->ignore_dB) < 0) { + if (pa_alsa_path_probe(p, m, mixer_handle, m->profile_set->ignore_dB) < 0) pa_hashmap_remove(ps->paths, p); - } } path_set_condense(ps, mixer_handle); diff --git a/src/modules/alsa/alsa-mixer.h b/src/modules/alsa/alsa-mixer.h index 0f1c5b91f..c64f42b70 100644 --- a/src/modules/alsa/alsa-mixer.h +++ b/src/modules/alsa/alsa-mixer.h @@ -171,6 +171,8 @@ struct pa_alsa_jack { pa_dynarray *ucm_devices; /* pa_alsa_ucm_device */ pa_dynarray *ucm_hw_mute_devices; /* pa_alsa_ucm_device */ + + bool append_pcm_to_name; }; pa_alsa_jack *pa_alsa_jack_new(pa_alsa_path *path, const char *name); @@ -234,7 +236,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); -int pa_alsa_path_probe(pa_alsa_path *p, snd_mixer_t *m, bool ignore_dB); +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); int pa_alsa_path_get_mute(pa_alsa_path *path, snd_mixer_t *m, bool *muted); diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c index a80caab2e..8786c98b7 100644 --- a/src/modules/alsa/alsa-sink.c +++ b/src/modules/alsa/alsa-sink.c @@ -1922,7 +1922,7 @@ static void find_mixer(struct userdata *u, pa_alsa_mapping *mapping, const char if (!(u->mixer_path = pa_alsa_path_synthesize(element, PA_ALSA_DIRECTION_OUTPUT))) goto fail; - if (pa_alsa_path_probe(u->mixer_path, u->mixer_handle, ignore_dB) < 0) + if (pa_alsa_path_probe(u->mixer_path, NULL, u->mixer_handle, ignore_dB) < 0) goto fail; pa_log_debug("Probed mixer path %s:", u->mixer_path->name); diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c index 3f87a4792..ba369284c 100644 --- a/src/modules/alsa/alsa-source.c +++ b/src/modules/alsa/alsa-source.c @@ -1617,7 +1617,7 @@ static void find_mixer(struct userdata *u, pa_alsa_mapping *mapping, const char if (!(u->mixer_path = pa_alsa_path_synthesize(element, PA_ALSA_DIRECTION_INPUT))) goto fail; - if (pa_alsa_path_probe(u->mixer_path, u->mixer_handle, ignore_dB) < 0) + if (pa_alsa_path_probe(u->mixer_path, NULL, u->mixer_handle, ignore_dB) < 0) goto fail; pa_log_debug("Probed mixer path %s:", u->mixer_path->name); diff --git a/src/modules/alsa/mixer/paths/analog-output.conf.common b/src/modules/alsa/mixer/paths/analog-output.conf.common index 17b45278a..baf37660e 100644 --- a/src/modules/alsa/mixer/paths/analog-output.conf.common +++ b/src/modules/alsa/mixer/paths/analog-output.conf.common @@ -122,6 +122,10 @@ ; # the required-any are present. ; state.plugged = yes | no | unknown # Normally a plugged jack would mean the port becomes available, and an unplugged means it's ; state.unplugged = yes | no | unknown # unavailable, but the port status can be overridden by specifying state.plugged and/or state.unplugged. +; append-pcm-to-name = no | yes # Add ",pcm=N" to the jack name? N is the hw PCM device index. HDMI jacks have +; # the PCM device index in their name, but different drivers use different +; # numbering schemes, so we can't hardcode the full jack name in our configuration +; # files. [Element PCM] switch = mute diff --git a/src/modules/alsa/mixer/paths/hdmi-output-0.conf b/src/modules/alsa/mixer/paths/hdmi-output-0.conf index 331014709..a87205cea 100644 --- a/src/modules/alsa/mixer/paths/hdmi-output-0.conf +++ b/src/modules/alsa/mixer/paths/hdmi-output-0.conf @@ -6,5 +6,6 @@ eld-device = 3 [Properties] device.icon_name = video-display -[Jack HDMI/DP,pcm=3] +[Jack HDMI/DP] +append-pcm-to-name = yes required = ignore diff --git a/src/modules/alsa/mixer/paths/hdmi-output-1.conf b/src/modules/alsa/mixer/paths/hdmi-output-1.conf index d81ee789c..b513ffd70 100644 --- a/src/modules/alsa/mixer/paths/hdmi-output-1.conf +++ b/src/modules/alsa/mixer/paths/hdmi-output-1.conf @@ -6,5 +6,6 @@ eld-device = 7 [Properties] device.icon_name = video-display -[Jack HDMI/DP,pcm=7] +[Jack HDMI/DP] +append-pcm-to-name = yes required = ignore diff --git a/src/modules/alsa/mixer/paths/hdmi-output-2.conf b/src/modules/alsa/mixer/paths/hdmi-output-2.conf index 349812fc2..a2386650e 100644 --- a/src/modules/alsa/mixer/paths/hdmi-output-2.conf +++ b/src/modules/alsa/mixer/paths/hdmi-output-2.conf @@ -6,5 +6,6 @@ eld-device = 8 [Properties] device.icon_name = video-display -[Jack HDMI/DP,pcm=8] +[Jack HDMI/DP] +append-pcm-to-name = yes required = ignore diff --git a/src/modules/alsa/mixer/paths/hdmi-output-3.conf b/src/modules/alsa/mixer/paths/hdmi-output-3.conf index 81463c946..edceb36e1 100644 --- a/src/modules/alsa/mixer/paths/hdmi-output-3.conf +++ b/src/modules/alsa/mixer/paths/hdmi-output-3.conf @@ -6,5 +6,6 @@ eld-device = 9 [Properties] device.icon_name = video-display -[Jack HDMI/DP,pcm=9] +[Jack HDMI/DP] +append-pcm-to-name = yes required = ignore diff --git a/src/modules/alsa/mixer/paths/hdmi-output-4.conf b/src/modules/alsa/mixer/paths/hdmi-output-4.conf index d61ec7547..0d1401eef 100644 --- a/src/modules/alsa/mixer/paths/hdmi-output-4.conf +++ b/src/modules/alsa/mixer/paths/hdmi-output-4.conf @@ -6,5 +6,6 @@ eld-device = 10 [Properties] device.icon_name = video-display -[Jack HDMI/DP,pcm=10] +[Jack HDMI/DP] +append-pcm-to-name = yes required = ignore diff --git a/src/modules/alsa/mixer/paths/hdmi-output-5.conf b/src/modules/alsa/mixer/paths/hdmi-output-5.conf index 02c15e893..883cccc20 100644 --- a/src/modules/alsa/mixer/paths/hdmi-output-5.conf +++ b/src/modules/alsa/mixer/paths/hdmi-output-5.conf @@ -6,5 +6,6 @@ eld-device = 11 [Properties] device.icon_name = video-display -[Jack HDMI/DP,pcm=11] +[Jack HDMI/DP] +append-pcm-to-name = yes required = ignore diff --git a/src/modules/alsa/mixer/paths/hdmi-output-6.conf b/src/modules/alsa/mixer/paths/hdmi-output-6.conf index 188a1adb3..d8ac2f55c 100644 --- a/src/modules/alsa/mixer/paths/hdmi-output-6.conf +++ b/src/modules/alsa/mixer/paths/hdmi-output-6.conf @@ -6,5 +6,6 @@ eld-device = 12 [Properties] device.icon_name = video-display -[Jack HDMI/DP,pcm=12] +[Jack HDMI/DP] +append-pcm-to-name = yes required = ignore diff --git a/src/modules/alsa/mixer/paths/hdmi-output-7.conf b/src/modules/alsa/mixer/paths/hdmi-output-7.conf index 80f4e3722..dd090855f 100644 --- a/src/modules/alsa/mixer/paths/hdmi-output-7.conf +++ b/src/modules/alsa/mixer/paths/hdmi-output-7.conf @@ -6,5 +6,6 @@ eld-device = 13 [Properties] device.icon_name = video-display -[Jack HDMI/DP,pcm=13] +[Jack HDMI/DP] +append-pcm-to-name = yes required = ignore -- 2.34.1