card: Update card with new common.
This commit is contained in:
parent
2d1a50d450
commit
e0d66cf4ad
1 changed files with 80 additions and 52 deletions
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2013-2018 Jolla Ltd.
|
* Copyright (C) 2013-2022 Jolla Ltd.
|
||||||
*
|
*
|
||||||
* Contact: Juho Hämäläinen <juho.hamalainen@jolla.com>
|
* Contact: Juho Hämäläinen <juho.hamalainen@jolla.com>
|
||||||
*
|
*
|
||||||
|
|
@ -61,6 +61,7 @@
|
||||||
|
|
||||||
#include <droid/droid-util.h>
|
#include <droid/droid-util.h>
|
||||||
#include <droid/sllist.h>
|
#include <droid/sllist.h>
|
||||||
|
#include <droid/utils.h>
|
||||||
#include "droid-sink.h"
|
#include "droid-sink.h"
|
||||||
#include "droid-source.h"
|
#include "droid-source.h"
|
||||||
|
|
||||||
|
|
@ -73,16 +74,13 @@ PA_MODULE_USAGE(
|
||||||
"source_name=<name for the source> "
|
"source_name=<name for the source> "
|
||||||
"namereg_fail=<when false attempt to synthesise new names if they are already taken> "
|
"namereg_fail=<when false attempt to synthesise new names if they are already taken> "
|
||||||
"rate=<sample rate> "
|
"rate=<sample rate> "
|
||||||
"output_flags=<flags for sink> "
|
|
||||||
"module_id=<which droid hw module to load, default primary> "
|
"module_id=<which droid hw module to load, default primary> "
|
||||||
"voice_source_routing=<always true, parameter left for compatibility> "
|
"voice_source_routing=<always true, parameter left for compatibility> "
|
||||||
"deferred_volume=<synchronize software and hardware volume changes to avoid momentary jumps?> "
|
"deferred_volume=<synchronize software and hardware volume changes to avoid momentary jumps?> "
|
||||||
"config=<location for droid audio configuration> "
|
"config=<location for droid audio configuration> "
|
||||||
"voice_property_key=<proplist key searched for sink-input that should control voice call volume> "
|
"voice_property_key=<proplist key searched for sink-input that should control voice call volume> "
|
||||||
"voice_property_value=<proplist value for the key for voice control sink-input> "
|
"voice_property_value=<proplist value for the key for voice control sink-input> "
|
||||||
"default_profile=<boolean. create default profile for primary module or not. defaults to true> "
|
"options=<comma separated list of options to enable/disable>"
|
||||||
"merge_inputs=<unused, always true> "
|
|
||||||
"quirks=<comma separated list of quirks to enable/disable>"
|
|
||||||
);
|
);
|
||||||
|
|
||||||
static const char* const valid_modargs[] = {
|
static const char* const valid_modargs[] = {
|
||||||
|
|
@ -97,26 +95,18 @@ static const char* const valid_modargs[] = {
|
||||||
"sink_rate",
|
"sink_rate",
|
||||||
"sink_format",
|
"sink_format",
|
||||||
"sink_channel_map",
|
"sink_channel_map",
|
||||||
"sink_mix_route",
|
|
||||||
"source_rate",
|
"source_rate",
|
||||||
"source_format",
|
"source_format",
|
||||||
"source_channel_map",
|
"source_channel_map",
|
||||||
"output_flags",
|
|
||||||
"module_id",
|
"module_id",
|
||||||
"voice_source_routing",
|
"voice_source_routing",
|
||||||
"sink_buffer",
|
"sink_buffer",
|
||||||
"source_buffer",
|
"source_buffer",
|
||||||
"deferred_volume",
|
"deferred_volume",
|
||||||
"mute_routing_before",
|
|
||||||
"mute_routing_after",
|
|
||||||
"prewrite_on_resume",
|
|
||||||
"config",
|
"config",
|
||||||
"voice_property_key",
|
"voice_property_key",
|
||||||
"voice_property_value",
|
"voice_property_value",
|
||||||
"default_profile",
|
/* DM_OPTIONS */
|
||||||
"combine",
|
|
||||||
"merge_inputs",
|
|
||||||
"quirks",
|
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -289,16 +279,57 @@ static void set_card_name(pa_modargs *ma, pa_card_new_data *data, const char *mo
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool output_enabled(struct userdata *u, pa_droid_mapping *am) {
|
static bool output_enabled(struct userdata *u, pa_droid_mapping *am) {
|
||||||
|
bool enabled = false;
|
||||||
|
|
||||||
pa_assert(u);
|
pa_assert(u);
|
||||||
pa_assert(am);
|
pa_assert(am);
|
||||||
|
|
||||||
if (!pa_droid_quirk(u->hw_module, QUIRK_OUTPUT_FAST) && am->output->flags & AUDIO_OUTPUT_FLAG_FAST)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!pa_droid_quirk(u->hw_module, QUIRK_OUTPUT_DEEP_BUFFER) && am->output->flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER)
|
if (am->mix_port->flags & AUDIO_OUTPUT_FLAG_PRIMARY)
|
||||||
return false;
|
enabled = true;
|
||||||
|
|
||||||
return true;
|
else if (am->mix_port->flags & AUDIO_OUTPUT_FLAG_RAW)
|
||||||
|
enabled = false;
|
||||||
|
|
||||||
|
else if (pa_droid_option(u->hw_module, DM_OPTION_OUTPUT_FAST) && am->mix_port->flags & AUDIO_OUTPUT_FLAG_FAST)
|
||||||
|
enabled = true;
|
||||||
|
|
||||||
|
else if (pa_droid_option(u->hw_module, DM_OPTION_OUTPUT_DEEP_BUFFER) && am->mix_port->flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER)
|
||||||
|
enabled = true;
|
||||||
|
|
||||||
|
pa_log_debug("Output mix port \"%s\" %s", am->name, enabled ? "enabled" : "disabled");
|
||||||
|
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool input_enabled(struct userdata *u, pa_droid_mapping *am) {
|
||||||
|
bool enabled = false;
|
||||||
|
|
||||||
|
pa_assert(u);
|
||||||
|
pa_assert(am);
|
||||||
|
|
||||||
|
/* Look for primary mix port as the one used for creating droid-source. */
|
||||||
|
if (dm_strcasestr(am->name, "primary"))
|
||||||
|
enabled = true;
|
||||||
|
|
||||||
|
pa_log_debug("Input mix port \"%s\" %s", am->name, enabled ? "enabled" : "disabled");
|
||||||
|
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t max_channels_for_mix_port(dm_config_port *mix_port, uint32_t previous_max_channels) {
|
||||||
|
uint32_t max_channels = 0;
|
||||||
|
dm_config_profile *profile;
|
||||||
|
void *state;
|
||||||
|
|
||||||
|
DM_LIST_FOREACH_DATA(profile, mix_port->profiles, state) {
|
||||||
|
for (int i = 0; profile->channel_masks[i]; i++) {
|
||||||
|
max_channels = audio_channel_count_from_out_mask(profile->channel_masks[i]) > max_channels
|
||||||
|
? audio_channel_count_from_out_mask(profile->channel_masks[i]) : max_channels;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return max_channels > previous_max_channels ? max_channels : previous_max_channels;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_profile(struct userdata *u, pa_hashmap *h, pa_hashmap *ports, pa_droid_profile *ap) {
|
static void add_profile(struct userdata *u, pa_hashmap *h, pa_hashmap *ports, pa_droid_profile *ap) {
|
||||||
|
|
@ -319,26 +350,23 @@ static void add_profile(struct userdata *u, pa_hashmap *h, pa_hashmap *ports, pa
|
||||||
cp->available = PA_AVAILABLE_YES;
|
cp->available = PA_AVAILABLE_YES;
|
||||||
cp->priority = ap->priority;
|
cp->priority = ap->priority;
|
||||||
|
|
||||||
|
/* Output mappings */
|
||||||
|
|
||||||
max_channels = 0;
|
max_channels = 0;
|
||||||
PA_IDXSET_FOREACH(am, ap->output_mappings, idx) {
|
PA_IDXSET_FOREACH(am, ap->output_mappings, idx) {
|
||||||
if (!output_enabled(u, am))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
cp->n_sinks++;
|
cp->n_sinks++;
|
||||||
pa_droid_add_card_ports(cp, ports, am, u->core);
|
pa_droid_add_card_ports(cp, ports, am, u->core);
|
||||||
max_channels = popcount(am->output->channel_masks) > max_channels
|
max_channels = max_channels_for_mix_port(am->mix_port, max_channels);
|
||||||
? popcount(am->output->channel_masks) : max_channels;
|
|
||||||
}
|
}
|
||||||
cp->max_sink_channels = max_channels;
|
cp->max_sink_channels = max_channels;
|
||||||
|
|
||||||
|
/* Input mappings */
|
||||||
|
|
||||||
max_channels = 0;
|
max_channels = 0;
|
||||||
if ((am = ap->input_mapping)) {
|
PA_IDXSET_FOREACH(am, ap->input_mappings, idx) {
|
||||||
const pa_droid_config_device *input;
|
|
||||||
cp->n_sources++;
|
cp->n_sources++;
|
||||||
pa_droid_add_card_ports(cp, ports, am, u->core);
|
pa_droid_add_card_ports(cp, ports, am, u->core);
|
||||||
SLLIST_FOREACH(input, am->inputs)
|
max_channels = max_channels_for_mix_port(am->mix_port, max_channels);
|
||||||
max_channels = popcount(input->channel_masks) > max_channels
|
|
||||||
? popcount(input->channel_masks) : max_channels;
|
|
||||||
}
|
}
|
||||||
cp->max_source_channels = max_channels;
|
cp->max_source_channels = max_channels;
|
||||||
|
|
||||||
|
|
@ -384,8 +412,13 @@ static void init_profile(struct userdata *u) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d->droid_profile && (am = d->droid_profile->input_mapping)) {
|
if (d->droid_profile && pa_idxset_size(d->droid_profile->input_mappings) > 0) {
|
||||||
am->source = pa_droid_source_new(u->module, u->modargs, __FILE__, (audio_devices_t) 0, &u->card_data, am, u->card);
|
PA_IDXSET_FOREACH(am, d->droid_profile->input_mappings, idx) {
|
||||||
|
if (!input_enabled(u, am))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
am->source = pa_droid_source_new(u->module, u->modargs, __FILE__, &u->card_data, am, u->card);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -437,12 +470,12 @@ static bool voicecall_profile_event_cb(struct userdata *u, pa_droid_profile *p,
|
||||||
if (enabling) {
|
if (enabling) {
|
||||||
pa_droid_sink_set_voice_control(am_output->sink, true);
|
pa_droid_sink_set_voice_control(am_output->sink, true);
|
||||||
|
|
||||||
if (pa_droid_quirk(u->hw_module, QUIRK_REALCALL))
|
if (pa_droid_option(u->hw_module, DM_OPTION_REALCALL))
|
||||||
pa_droid_set_parameters(u->hw_module, VENDOR_EXT_REALCALL_ON);
|
pa_droid_set_parameters(u->hw_module, VENDOR_EXT_REALCALL_ON);
|
||||||
} else {
|
} else {
|
||||||
pa_droid_sink_set_voice_control(am_output->sink, false);
|
pa_droid_sink_set_voice_control(am_output->sink, false);
|
||||||
|
|
||||||
if (pa_droid_quirk(u->hw_module, QUIRK_REALCALL))
|
if (pa_droid_option(u->hw_module, DM_OPTION_REALCALL))
|
||||||
pa_droid_set_parameters(u->hw_module, VENDOR_EXT_REALCALL_OFF);
|
pa_droid_set_parameters(u->hw_module, VENDOR_EXT_REALCALL_OFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -681,15 +714,20 @@ static int card_set_profile(pa_card *c, pa_card_profile *new_profile) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (next->droid_profile && (am = next->droid_profile->input_mapping)) {
|
if (next->droid_profile && pa_idxset_size(next->droid_profile->input_mappings) > 0) {
|
||||||
|
PA_IDXSET_FOREACH(am, next->droid_profile->input_mappings, idx) {
|
||||||
|
if (!input_enabled(u, am))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (!am->source)
|
if (!am->source)
|
||||||
am->source = pa_droid_source_new(u->module, u->modargs, __FILE__, (audio_devices_t) 0, &u->card_data, am, u->card);
|
am->source = pa_droid_source_new(u->module, u->modargs, __FILE__, &u->card_data, am, u->card);
|
||||||
|
|
||||||
if (source_outputs && am->source) {
|
if (source_outputs && am->source) {
|
||||||
pa_source_move_all_finish(am->source, source_outputs, false);
|
pa_source_move_all_finish(am->source, source_outputs, false);
|
||||||
source_outputs = NULL;
|
source_outputs = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* if only primary sink is left after profile change and we have detached sink-inputs attach
|
/* if only primary sink is left after profile change and we have detached sink-inputs attach
|
||||||
* them to primary sink. */
|
* them to primary sink. */
|
||||||
|
|
@ -714,23 +752,17 @@ int pa__init(pa_module *m) {
|
||||||
pa_card_new_data data;
|
pa_card_new_data data;
|
||||||
const char *module_id;
|
const char *module_id;
|
||||||
bool namereg_fail = false;
|
bool namereg_fail = false;
|
||||||
bool default_profile = true;
|
|
||||||
pa_card_profile *voicecall = NULL;
|
pa_card_profile *voicecall = NULL;
|
||||||
|
|
||||||
pa_assert(m);
|
pa_assert(m);
|
||||||
|
|
||||||
pa_log_info("Create new droid-card");
|
pa_log_info("Create new droid-card");
|
||||||
|
|
||||||
if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
|
if (!(ma = pa_droid_modargs_new(m->argument, valid_modargs))) {
|
||||||
pa_log("Failed to parse module arguments.");
|
pa_log("Failed to parse module arguments.");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pa_modargs_get_value_boolean(ma, "default_profile", &default_profile) < 0) {
|
|
||||||
pa_log("Failed to parse default_profile argument. Expects boolean value");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
u = pa_xnew0(struct userdata, 1);
|
u = pa_xnew0(struct userdata, 1);
|
||||||
u->core = m->core;
|
u->core = m->core;
|
||||||
m->userdata = u;
|
m->userdata = u;
|
||||||
|
|
@ -740,15 +772,12 @@ int pa__init(pa_module *m) {
|
||||||
if (!(u->hw_module = pa_droid_hw_module_get2(u->core, ma, module_id)))
|
if (!(u->hw_module = pa_droid_hw_module_get2(u->core, ma, module_id)))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
pa_droid_quirk_log(u->hw_module);
|
pa_droid_options_log(u->hw_module);
|
||||||
|
|
||||||
u->card_data.module_id = pa_xstrdup(module_id);
|
u->card_data.module_id = pa_xstrdup(module_id);
|
||||||
u->card_data.userdata = u;
|
u->card_data.userdata = u;
|
||||||
|
|
||||||
if (default_profile)
|
|
||||||
u->profile_set = pa_droid_profile_set_default_new(u->hw_module->enabled_module);
|
u->profile_set = pa_droid_profile_set_default_new(u->hw_module->enabled_module);
|
||||||
else
|
|
||||||
u->profile_set = pa_droid_profile_set_new(u->hw_module->enabled_module);
|
|
||||||
|
|
||||||
pa_card_new_data_init(&data);
|
pa_card_new_data_init(&data);
|
||||||
data.driver = __FILE__;
|
data.driver = __FILE__;
|
||||||
|
|
@ -859,7 +888,6 @@ void pa__done(pa_module *m) {
|
||||||
if (u->card && u->card->sources)
|
if (u->card && u->card->sources)
|
||||||
pa_idxset_remove_all(u->card->sources, (pa_free_cb_t) pa_droid_source_free);
|
pa_idxset_remove_all(u->card->sources, (pa_free_cb_t) pa_droid_source_free);
|
||||||
|
|
||||||
|
|
||||||
if (u->card)
|
if (u->card)
|
||||||
pa_card_free(u->card);
|
pa_card_free(u->card);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue