[RFC Patch 2/3] Support UCM in Pulseaudio

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

 



add port for ucm

diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c
index b6cf085..2cd37a9 100644
--- a/src/modules/alsa/alsa-mixer.c
+++ b/src/modules/alsa/alsa-mixer.c
@@ -3168,6 +3168,8 @@ static void mapping_free(pa_alsa_mapping *m) {
     pa_xstrfreev(m->input_element);
     pa_xstrfreev(m->output_element);

+    pa_xfree(m->ucm_devices);
+
     pa_assert(!m->input_pcm);
     pa_assert(!m->output_pcm);

@@ -3225,7 +3227,7 @@ void pa_alsa_profile_set_free(pa_alsa_profile_set *ps) {
     pa_xfree(ps);
 }

-static pa_alsa_mapping *mapping_get(pa_alsa_profile_set *ps, const
char *name) {
+pa_alsa_mapping *mapping_get(pa_alsa_profile_set *ps, const char *name) {
     pa_alsa_mapping *m;

     if (!pa_startswith(name, "Mapping "))
diff --git a/src/modules/alsa/alsa-mixer.h b/src/modules/alsa/alsa-mixer.h
index c9d968a..fc206f5 100644
--- a/src/modules/alsa/alsa-mixer.h
+++ b/src/modules/alsa/alsa-mixer.h
@@ -47,6 +47,7 @@ typedef struct pa_alsa_profile_set pa_alsa_profile_set;
 typedef struct pa_alsa_port_data pa_alsa_port_data;

 #include "alsa-util.h"
+#include "alsa-ucm.h"

 typedef enum pa_alsa_switch_use {
     PA_ALSA_SWITCH_IGNORE,
@@ -226,6 +227,8 @@ void pa_alsa_path_set_dump(pa_alsa_path_set *s);
 void pa_alsa_path_set_set_callback(pa_alsa_path_set *ps, snd_mixer_t
*m, snd_mixer_elem_callback_t cb, void *userdata);
 void pa_alsa_path_set_free(pa_alsa_path_set *s);

+pa_alsa_mapping *mapping_get(pa_alsa_profile_set *ps, const char *name);
+
 struct pa_alsa_mapping {
     pa_alsa_profile_set *profile_set;

@@ -251,6 +254,11 @@ struct pa_alsa_mapping {

     pa_sink *sink;
     pa_source *source;
+
+    /* ucm device */
+    pa_alsa_ucm_config *ucm;
+    int ucm_devices_num;
+    pa_alsa_ucm_device **ucm_devices;
 };

 struct pa_alsa_profile {
diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c
index 066f2dd..6cc43ee 100644
--- a/src/modules/alsa/alsa-sink.c
+++ b/src/modules/alsa/alsa-sink.c
@@ -1450,6 +1450,16 @@ static void mixer_volume_init(struct userdata *u) {
     }
 }

+static int sink_set_port_ucm_cb(pa_sink *s, pa_device_port *p) {
+    pa_alsa_port_data_ucm *data;
+
+    pa_assert(p);
+
+    data = PA_DEVICE_PORT_DATA(p);
+
+    return ucm_set_port(data);
+}
+
 static int sink_set_port_cb(pa_sink *s, pa_device_port *p) {
     struct userdata *u = s->userdata;
     pa_alsa_port_data *data;
@@ -1846,6 +1856,18 @@ fail:
     }
 }

+/* FIXME: hardware volume/mute ??? */
+static int ucm_setup_mixer(struct userdata *u, pa_bool_t ignore_dB) {
+    pa_assert(u && u->sink);
+
+    if (u->sink->active_port) {
+        pa_alsa_port_data_ucm *data;
+        data = PA_DEVICE_PORT_DATA(u->sink->active_port);
+        return ucm_set_port(data);
+    }
+
+    return 0;
+}

 static int setup_mixer(struct userdata *u, pa_bool_t ignore_dB) {
     pa_bool_t need_mixer_callback = FALSE;
@@ -2113,7 +2135,8 @@ pa_sink *pa_alsa_sink_new(pa_module *m,
pa_modargs *ma, const char*driver, pa_ca
     /* ALSA might tweak the sample spec, so recalculate the frame size */
     frame_size = pa_frame_size(&ss);

-    find_mixer(u, mapping, pa_modargs_get_value(ma, "control", NULL),
ignore_dB);
+    if (!mapping->ucm)
+        find_mixer(u, mapping, pa_modargs_get_value(ma, "control",
NULL), ignore_dB);

     pa_sink_new_data_init(&data);
     data.driver = driver;
@@ -2158,7 +2181,9 @@ pa_sink *pa_alsa_sink_new(pa_module *m,
pa_modargs *ma, const char*driver, pa_ca
         goto fail;
     }

-    if (u->mixer_path_set)
+    if (mapping->ucm)
+        ucm_add_ports(&data.ports, data.proplist, mapping);
+    else if (u->mixer_path_set)
         pa_alsa_add_ports(&data.ports, u->mixer_path_set);

     u->sink = pa_sink_new(m->core, &data, PA_SINK_HARDWARE |
PA_SINK_LATENCY | (u->use_tsched ? PA_SINK_DYNAMIC_LATENCY : 0) |
@@ -2186,7 +2211,10 @@ pa_sink *pa_alsa_sink_new(pa_module *m,
pa_modargs *ma, const char*driver, pa_ca
     if (u->use_tsched)
         u->sink->update_requested_latency = sink_update_requested_latency_cb;
     u->sink->set_state = sink_set_state_cb;
-    u->sink->set_port = sink_set_port_cb;
+    if (mapping->ucm)
+        u->sink->set_port = sink_set_port_ucm_cb;
+    else
+        u->sink->set_port = sink_set_port_cb;
     u->sink->userdata = u;

     pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq);
@@ -2238,7 +2266,11 @@ pa_sink *pa_alsa_sink_new(pa_module *m,
pa_modargs *ma, const char*driver, pa_ca
     if (update_sw_params(u) < 0)
         goto fail;

-    if (setup_mixer(u, ignore_dB) < 0)
+    if (mapping->ucm) {
+        if (ucm_setup_mixer(u, ignore_dB) < 0)
+            goto fail;
+    }
+    else if (setup_mixer(u, ignore_dB) < 0)
         goto fail;

     pa_alsa_dump(PA_LOG_DEBUG, u->pcm_handle);
diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c
index f03b76e..1a3812b 100644
--- a/src/modules/alsa/alsa-source.c
+++ b/src/modules/alsa/alsa-source.c
@@ -1301,6 +1301,16 @@ static void mixer_volume_init(struct userdata *u) {
     }
 }

+static int source_set_port_ucm_cb(pa_source *s, pa_device_port *p) {
+    pa_alsa_port_data_ucm *data;
+
+    pa_assert(p);
+
+    data = PA_DEVICE_PORT_DATA(p);
+
+    return ucm_set_port(data);
+}
+
 static int source_set_port_cb(pa_source *s, pa_device_port *p) {
     struct userdata *u = s->userdata;
     pa_alsa_port_data *data;
@@ -1546,6 +1556,19 @@ fail:
     }
 }

+/* FIXME: hardware volume/mute ??? */
+static int ucm_setup_mixer(struct userdata *u, pa_bool_t ignore_dB) {
+    pa_assert(u && u->source);
+
+    if (u->source->active_port) {
+        pa_alsa_port_data_ucm *data;
+        data = PA_DEVICE_PORT_DATA(u->source->active_port);
+        return ucm_set_port(data);
+    }
+
+    return 0;
+}
+
 static int setup_mixer(struct userdata *u, pa_bool_t ignore_dB) {
     pa_bool_t need_mixer_callback = FALSE;

@@ -1802,7 +1825,8 @@ pa_source *pa_alsa_source_new(pa_module *m,
pa_modargs *ma, const char*driver, p
     /* ALSA might tweak the sample spec, so recalculate the frame size */
     frame_size = pa_frame_size(&ss);

-    find_mixer(u, mapping, pa_modargs_get_value(ma, "control", NULL),
ignore_dB);
+    if (mapping->ucm)
+        find_mixer(u, mapping, pa_modargs_get_value(ma, "control",
NULL), ignore_dB);

     pa_source_new_data_init(&data);
     data.driver = driver;
@@ -1847,7 +1871,9 @@ pa_source *pa_alsa_source_new(pa_module *m,
pa_modargs *ma, const char*driver, p
         goto fail;
     }

-    if (u->mixer_path_set)
+    if (mapping->ucm)
+        ucm_add_ports(&data.ports, data.proplist, mapping);
+    else if (u->mixer_path_set)
         pa_alsa_add_ports(&data.ports, u->mixer_path_set);

     u->source = pa_source_new(m->core, &data,
PA_SOURCE_HARDWARE|PA_SOURCE_LATENCY|(u->use_tsched ?
PA_SOURCE_DYNAMIC_LATENCY : 0));
@@ -1874,7 +1900,10 @@ pa_source *pa_alsa_source_new(pa_module *m,
pa_modargs *ma, const char*driver, p
     if (u->use_tsched)
         u->source->update_requested_latency =
source_update_requested_latency_cb;
     u->source->set_state = source_set_state_cb;
-    u->source->set_port = source_set_port_cb;
+    if (mapping->ucm)
+        u->source->set_port = source_set_port_ucm_cb;
+    else
+        u->source->set_port = source_set_port_cb;
     u->source->userdata = u;

     pa_source_set_asyncmsgq(u->source, u->thread_mq.inq);
@@ -1918,7 +1947,11 @@ pa_source *pa_alsa_source_new(pa_module *m,
pa_modargs *ma, const char*driver, p
     if (update_sw_params(u) < 0)
         goto fail;

-    if (setup_mixer(u, ignore_dB) < 0)
+    if (mapping->ucm) {
+        if (ucm_setup_mixer(u, ignore_dB) < 0)
+            goto fail;
+    }
+    else if (setup_mixer(u, ignore_dB) < 0)
         goto fail;

     pa_alsa_dump(PA_LOG_DEBUG, u->pcm_handle);

-- 
Wei.Feng (irc wei_feng)
Linaro Multimedia Team
Linaro.org???Open source software for ARM SoCs
Follow?Linaro:?Facebook?|?Twitter?|?Blog


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

  Powered by Linux