summaryrefslogtreecommitdiff
path: root/src/modules/alsa/alsa-mixer.c
diff options
context:
space:
mode:
authorJaroslav Kysela <perex@perex.cz>2020-04-17 15:34:24 +0200
committerTanu Kaskinen <tanuk@iki.fi>2020-06-17 06:06:12 +0000
commit0333c2ba8fc756b0be80c8eb74f8997d807ada92 (patch)
tree9cdaea545cc14c7befcf3d5217695d332b5e5782 /src/modules/alsa/alsa-mixer.c
parent66185274510a079563f30e80109229ede14677bd (diff)
alsa: legacy card - implement device port type parser and assignment
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to 'src/modules/alsa/alsa-mixer.c')
-rw-r--r--src/modules/alsa/alsa-mixer.c130
1 files changed, 100 insertions, 30 deletions
diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c
index 611e8067b..0ab9b8180 100644
--- a/src/modules/alsa/alsa-mixer.c
+++ b/src/modules/alsa/alsa-mixer.c
@@ -107,6 +107,12 @@ struct description_map {
const char *description;
};
+struct description2_map {
+ const char *key;
+ const char *description;
+ pa_device_port_type_t type;
+};
+
static char *alsa_id_str(char *dst, size_t dst_len, pa_alsa_mixer_id *id) {
if (id->index > 0) {
snprintf(dst, dst_len, "'%s',%d", id->name, id->index);
@@ -288,6 +294,19 @@ static const char *lookup_description(const char *key, const struct description_
return NULL;
}
+static const struct description2_map *lookup_description2(const char *key, const struct description2_map dm[], unsigned n) {
+ unsigned i;
+
+ if (!key)
+ return NULL;
+
+ for (i = 0; i < n; i++)
+ if (pa_streq(dm[i].key, key))
+ return &dm[i];
+
+ return NULL;
+}
+
struct pa_alsa_fdlist {
unsigned num_fds;
struct pollfd *fds;
@@ -2160,6 +2179,50 @@ static int element_parse_enumeration(pa_config_parser_state *state) {
return 0;
}
+static int parse_type(pa_config_parser_state *state) {
+ struct device_port_types {
+ const char *name;
+ pa_device_port_type_t type;
+ } device_port_types[] = {
+ { "unknown", PA_DEVICE_PORT_TYPE_UNKNOWN },
+ { "aux", PA_DEVICE_PORT_TYPE_AUX },
+ { "speaker", PA_DEVICE_PORT_TYPE_SPEAKER },
+ { "headphones", PA_DEVICE_PORT_TYPE_HEADPHONES },
+ { "line", PA_DEVICE_PORT_TYPE_LINE },
+ { "mic", PA_DEVICE_PORT_TYPE_MIC },
+ { "headset", PA_DEVICE_PORT_TYPE_HEADSET },
+ { "handset", PA_DEVICE_PORT_TYPE_HANDSET },
+ { "earpiece", PA_DEVICE_PORT_TYPE_EARPIECE },
+ { "spdif", PA_DEVICE_PORT_TYPE_SPDIF },
+ { "hdmi", PA_DEVICE_PORT_TYPE_HDMI },
+ { "tv", PA_DEVICE_PORT_TYPE_TV },
+ { "radio", PA_DEVICE_PORT_TYPE_RADIO },
+ { "video", PA_DEVICE_PORT_TYPE_VIDEO },
+ { "usb", PA_DEVICE_PORT_TYPE_USB },
+ { "bluetooth", PA_DEVICE_PORT_TYPE_BLUETOOTH },
+ { "portable", PA_DEVICE_PORT_TYPE_PORTABLE },
+ { "handsfree", PA_DEVICE_PORT_TYPE_HANDSFREE },
+ { "car", PA_DEVICE_PORT_TYPE_CAR },
+ { "hifi", PA_DEVICE_PORT_TYPE_HIFI },
+ { "phone", PA_DEVICE_PORT_TYPE_PHONE },
+ { "network", PA_DEVICE_PORT_TYPE_NETWORK },
+ { "analog", PA_DEVICE_PORT_TYPE_ANALOG },
+ };
+ pa_alsa_path *path;
+ unsigned int idx;
+
+ path = state->userdata;
+
+ for (idx = 0; idx < PA_ELEMENTSOF(device_port_types); idx++)
+ if (pa_streq(state->rvalue, device_port_types[idx].name)) {
+ path->device_port_type = device_port_types[idx].type;
+ return 0;
+ }
+
+ pa_log("[%s:%u] Invalid value for option 'type': %s", state->filename, state->lineno, state->rvalue);
+ return -1;
+}
+
static int parse_eld_device(pa_config_parser_state *state) {
pa_alsa_path *path;
uint32_t eld_device;
@@ -2642,35 +2705,38 @@ static int element_verify(pa_alsa_element *e) {
}
static int path_verify(pa_alsa_path *p) {
- static const struct description_map well_known_descriptions[] = {
- { "analog-input", N_("Analog Input") },
- { "analog-input-microphone", N_("Microphone") },
- { "analog-input-microphone-front", N_("Front Microphone") },
- { "analog-input-microphone-rear", N_("Rear Microphone") },
- { "analog-input-microphone-dock", N_("Dock Microphone") },
- { "analog-input-microphone-internal", N_("Internal Microphone") },
- { "analog-input-microphone-headset", N_("Headset Microphone") },
- { "analog-input-linein", N_("Line In") },
- { "analog-input-radio", N_("Radio") },
- { "analog-input-video", N_("Video") },
- { "analog-output", N_("Analog Output") },
- { "analog-output-headphones", N_("Headphones") },
- { "analog-output-headphones-mono", N_("Headphones Mono Output") },
- { "analog-output-lfe-on-mono", N_("LFE on Separate Mono Output") },
- { "analog-output-lineout", N_("Line Out") },
- { "analog-output-mono", N_("Analog Mono Output") },
- { "analog-output-speaker", N_("Speakers") },
- { "hdmi-output", N_("HDMI / DisplayPort") },
- { "iec958-stereo-output", N_("Digital Output (S/PDIF)") },
- { "iec958-stereo-input", N_("Digital Input (S/PDIF)") },
- { "iec958-passthrough-output", N_("Digital Passthrough (S/PDIF)") },
- { "multichannel-input", N_("Multichannel Input") },
- { "multichannel-output", N_("Multichannel Output") },
- { "steelseries-arctis-5-output-game", N_("Game Output") },
- { "steelseries-arctis-5-output-chat", N_("Chat Output") },
+ static const struct description2_map well_known_descriptions[] = {
+ { "analog-input", N_("Analog Input"), PA_DEVICE_PORT_TYPE_ANALOG },
+ { "analog-input-microphone", N_("Microphone"), PA_DEVICE_PORT_TYPE_MIC },
+ { "analog-input-microphone-front", N_("Front Microphone"), PA_DEVICE_PORT_TYPE_MIC },
+ { "analog-input-microphone-rear", N_("Rear Microphone"), PA_DEVICE_PORT_TYPE_MIC },
+ { "analog-input-microphone-dock", N_("Dock Microphone"), PA_DEVICE_PORT_TYPE_MIC },
+ { "analog-input-microphone-internal", N_("Internal Microphone"), PA_DEVICE_PORT_TYPE_MIC },
+ { "analog-input-microphone-headset", N_("Headset Microphone"), PA_DEVICE_PORT_TYPE_MIC },
+ { "analog-input-linein", N_("Line In"), PA_DEVICE_PORT_TYPE_LINE },
+ { "analog-input-radio", N_("Radio"), PA_DEVICE_PORT_TYPE_RADIO },
+ { "analog-input-video", N_("Video"), PA_DEVICE_PORT_TYPE_VIDEO },
+ { "analog-output", N_("Analog Output"), PA_DEVICE_PORT_TYPE_ANALOG },
+ { "analog-output-headphones", N_("Headphones"), PA_DEVICE_PORT_TYPE_HEADPHONES },
+ { "analog-output-headphones-mono", N_("Headphones Mono Output"), PA_DEVICE_PORT_TYPE_HEADPHONES },
+ { "analog-output-lineout", N_("Line Out"), PA_DEVICE_PORT_TYPE_LINE },
+ { "analog-output-mono", N_("Analog Mono Output"), PA_DEVICE_PORT_TYPE_ANALOG },
+ { "analog-output-speaker", N_("Speakers"), PA_DEVICE_PORT_TYPE_SPEAKER },
+ { "hdmi-output", N_("HDMI / DisplayPort"), PA_DEVICE_PORT_TYPE_HDMI },
+ { "iec958-stereo-output", N_("Digital Output (S/PDIF)"), PA_DEVICE_PORT_TYPE_SPDIF },
+ { "iec958-stereo-input", N_("Digital Input (S/PDIF)"), PA_DEVICE_PORT_TYPE_SPDIF },
+ { "iec958-passthrough-output", N_("Digital Passthrough (S/PDIF)"), PA_DEVICE_PORT_TYPE_SPDIF },
+ { "multichannel-input", N_("Multichannel Input"), PA_DEVICE_PORT_TYPE_LINE },
+ { "multichannel-output", N_("Multichannel Output"), PA_DEVICE_PORT_TYPE_LINE },
+ { "steelseries-arctis-5-output-game", N_("Game Output"), PA_DEVICE_PORT_TYPE_HEADSET },
+ { "steelseries-arctis-5-output-chat", N_("Chat Output"), PA_DEVICE_PORT_TYPE_HEADSET },
};
pa_alsa_element *e;
+ const char *key = p->description_key ? p->description_key : p->name;
+ const struct description2_map *map = lookup_description2(key,
+ well_known_descriptions,
+ PA_ELEMENTSOF(well_known_descriptions));
pa_assert(p);
@@ -2678,10 +2744,12 @@ static int path_verify(pa_alsa_path *p) {
if (element_verify(e) < 0)
return -1;
- if (!p->description)
- p->description = pa_xstrdup(lookup_description(p->description_key ? p->description_key : p->name,
- well_known_descriptions,
- PA_ELEMENTSOF(well_known_descriptions)));
+ if (map) {
+ if (p->device_port_type == PA_DEVICE_PORT_TYPE_UNKNOWN)
+ p->device_port_type = map->type;
+ if (!p->description)
+ p->description = pa_xstrdup(map->description);
+ }
if (!p->description) {
if (p->description_key)
@@ -2714,6 +2782,7 @@ pa_alsa_path* pa_alsa_path_new(const char *paths_dir, const char *fname, pa_alsa
{ "priority", pa_config_parse_unsigned, NULL, "General" },
{ "description-key", pa_config_parse_string, NULL, "General" },
{ "description", pa_config_parse_string, NULL, "General" },
+ { "type", parse_type, NULL, "General" },
{ "mute-during-activation", pa_config_parse_bool, NULL, "General" },
{ "eld-device", parse_eld_device, NULL, "General" },
@@ -5074,6 +5143,7 @@ static pa_device_port* device_port_alsa_init(pa_hashmap *ports, /* card ports */
pa_device_port_new_data_set_name(&port_data, name);
pa_device_port_new_data_set_description(&port_data, description);
pa_device_port_new_data_set_direction(&port_data, path->direction == PA_ALSA_DIRECTION_OUTPUT ? PA_DIRECTION_OUTPUT : PA_DIRECTION_INPUT);
+ pa_device_port_new_data_set_type(&port_data, path->device_port_type);
pa_device_port_new_data_set_available_group(&port_data, path->available_group);
p = pa_device_port_new(core, &port_data, sizeof(pa_alsa_port_data));