This is required for things like modem PCMs on phones that are essentially fake devices that need to be kept open for the correspnding route (modem -> CODEC) to remain active. --- src/modules/alsa/alsa-mixer.h | 3 +++ src/modules/alsa/alsa-sink.c | 2 +- src/modules/alsa/alsa-source.c | 4 +++- src/modules/alsa/alsa-ucm.c | 13 +++++++++++++ src/modules/alsa/alsa-ucm.h | 3 +++ 5 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/modules/alsa/alsa-mixer.h b/src/modules/alsa/alsa-mixer.h index 995a34b..a4a2345 100644 --- a/src/modules/alsa/alsa-mixer.h +++ b/src/modules/alsa/alsa-mixer.h @@ -272,6 +272,9 @@ struct pa_alsa_mapping { pa_sink *sink; pa_source *source; + /* Inhibit auto-suspend */ + bool always_running; + /* ucm device context*/ pa_alsa_ucm_mapping_context ucm_context; }; diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c index 261536a..d98e9de 100644 --- a/src/modules/alsa/alsa-sink.c +++ b/src/modules/alsa/alsa-sink.c @@ -2298,7 +2298,7 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca 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)); + (set_formats ? PA_SINK_SET_FORMATS : 0) | (mapping->always_running ? PA_SINK_ALWAYS_RUNNING : 0)); pa_sink_new_data_done(&data); if (!u->sink) { diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c index 4660c6a..2776daa 100644 --- a/src/modules/alsa/alsa-source.c +++ b/src/modules/alsa/alsa-source.c @@ -1996,7 +1996,9 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p else 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)); + u->source = pa_source_new(m->core, &data, PA_SOURCE_HARDWARE | PA_SOURCE_LATENCY | + (u->use_tsched ? PA_SOURCE_DYNAMIC_LATENCY : 0) | + (mapping->always_running ? PA_SOURCE_ALWAYS_RUNNING : 0)); pa_source_new_data_done(&data); if (!u->source) { diff --git a/src/modules/alsa/alsa-ucm.c b/src/modules/alsa/alsa-ucm.c index 787dc9e..1025752 100644 --- a/src/modules/alsa/alsa-ucm.c +++ b/src/modules/alsa/alsa-ucm.c @@ -92,6 +92,8 @@ 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}, + /* PulseAudio-specific flag */ + {"AlwaysRunning", PA_ALSA_PROP_UCM_ALWAYS_RUNNING}, {NULL, NULL}, }; @@ -321,6 +323,12 @@ static int ucm_get_device_property( device->capture_priority = 100; } + /* Copy over AlwaysRunning value if it exists */ + if ((value = pa_proplist_gets(verb->proplist, PA_ALSA_PROP_UCM_ALWAYS_RUNNING))) { + pa_log_debug("Setting device %s to be always running", device_name); + pa_proplist_sets(device->proplist, PA_ALSA_PROP_UCM_ALWAYS_RUNNING, value); + } + id = pa_sprintf_malloc("%s/%s", "_conflictingdevs", device_name); n_confdev = snd_use_case_get_list(uc_mgr, id, &devices); pa_xfree(id); @@ -1133,6 +1141,7 @@ static int ucm_create_mapping_direction( pa_alsa_mapping *m; char *mapping_name; + const char *value; unsigned priority, rate, channels; mapping_name = pa_sprintf_malloc("Mapping %s: %s: %s", verb_name, device_str, is_sink ? "sink" : "source"); @@ -1163,6 +1172,10 @@ static int ucm_create_mapping_direction( if (rate) m->sample_spec.rate = rate; pa_channel_map_init_extend(&m->channel_map, channels, PA_CHANNEL_MAP_ALSA); + + /* Propagate always running value to mapping */ + if ((value = pa_proplist_gets(device->proplist, PA_ALSA_PROP_UCM_ALWAYS_RUNNING))) + m->always_running = true; } /* mapping priority is the highest one of ucm devices */ diff --git a/src/modules/alsa/alsa-ucm.h b/src/modules/alsa/alsa-ucm.h index 2fae6c4..a1339b3 100644 --- a/src/modules/alsa/alsa-ucm.h +++ b/src/modules/alsa/alsa-ucm.h @@ -83,6 +83,9 @@ typedef void snd_use_case_mgr_t; /** For devices: Quality of Service */ #define PA_ALSA_PROP_UCM_QOS "alsa.ucm.qos" +/** For devices: Signal that this device should not be auto-suspended */ +#define PA_ALSA_PROP_UCM_ALWAYS_RUNNING "alsa.ucm.always-running" + /** For devices: The modifier (if any) that this device corresponds to */ #define PA_ALSA_PROP_UCM_MODIFIER "alsa.ucm.modifier" -- 1.8.2.1