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 +- .../alsa/mixer/paths/analog-output.conf.common | 4 ++ src/modules/alsa/mixer/paths/hdmi-output-0.conf | 3 +- src/modules/alsa/mixer/paths/hdmi-output-1.conf | 3 +- src/modules/alsa/mixer/paths/hdmi-output-2.conf | 3 +- src/modules/alsa/mixer/paths/hdmi-output-3.conf | 3 +- src/modules/alsa/mixer/paths/hdmi-output-4.conf | 3 +- src/modules/alsa/mixer/paths/hdmi-output-5.conf | 3 +- src/modules/alsa/mixer/paths/hdmi-output-6.conf | 3 +- src/modules/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 cb482906b..7ae40511c 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 827a65081..99ca5061b 100644 --- a/src/modules/alsa/alsa-sink.c +++ b/src/modules/alsa/alsa-sink.c @@ -1912,7 +1912,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 6bec188ea..84abbf1d9 100644 --- a/src/modules/alsa/alsa-source.c +++ b/src/modules/alsa/alsa-source.c @@ -1615,7 +1615,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.14.2