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