[PATCH 2/2] alsa-ucm: Add mechanism to prevent auto-suspend of sources/sinks

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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



[Index of Archives]     [Linux Audio Users]     [AMD Graphics]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux