From 12e97ebba36ac725e31d5dab1374a6206342ac0d Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Tue, 11 Apr 2023 10:55:10 +0200 Subject: linux: Detect headset devices with kernel batteries The code that handles battery information coming from the kernel didn't have any code to set audio type of devices. As we add support for USB wireless headsets in the kernel, add code to detect those and set the UPDevice kind to the right value. Closes: #229 --- src/linux/up-device-supply.c | 34 +++++++++++++++++++++++++++++++++- src/linux/up-enumerator-udev.c | 7 ++++--- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/linux/up-device-supply.c b/src/linux/up-device-supply.c index 795018b..dd5bfdc 100644 --- a/src/linux/up-device-supply.c +++ b/src/linux/up-device-supply.c @@ -334,6 +334,7 @@ up_device_supply_sibling_discovered (UpDevice *device, UpDeviceKind type; } types[] = { /* In order of type priority (*within* one input node). */ + { "SOUND_INITIALIZED", UP_DEVICE_KIND_OTHER_AUDIO }, { "ID_INPUT_TABLET", UP_DEVICE_KIND_TABLET }, { "ID_INPUT_TOUCHPAD", UP_DEVICE_KIND_TOUCHPAD }, { "ID_INPUT_MOUSE", UP_DEVICE_KIND_MOUSE }, @@ -343,12 +344,26 @@ up_device_supply_sibling_discovered (UpDevice *device, /* The type priority if we have multiple siblings, * i.e. we select the first of the current type of the found type. */ UpDeviceKind priority[] = { + UP_DEVICE_KIND_OTHER_AUDIO, UP_DEVICE_KIND_KEYBOARD, UP_DEVICE_KIND_TABLET, UP_DEVICE_KIND_TOUCHPAD, UP_DEVICE_KIND_MOUSE, UP_DEVICE_KIND_GAMING_INPUT, }; + /* Form-factors set in rules.d/78-sound-card.rules in systemd */ + struct { + const char *form_factor; + UpDeviceKind kind; + } sound_types[] = { + { "webcam", UP_DEVICE_KIND_VIDEO }, + { "speaker", UP_DEVICE_KIND_SPEAKERS }, + { "headphone", UP_DEVICE_KIND_HEADPHONES }, + { "headset", UP_DEVICE_KIND_HEADSET }, + /* unhandled: + * - handset + * - microphone */ + }; if (!G_UDEV_IS_DEVICE (sibling)) return; @@ -360,7 +375,13 @@ up_device_supply_sibling_discovered (UpDevice *device, if (cur_type == UP_DEVICE_KIND_LINE_POWER) return; - if (g_strcmp0 (g_udev_device_get_subsystem (input), "input") != 0) + if (g_strcmp0 (g_udev_device_get_subsystem (input), "input") != 0 && + g_strcmp0 (g_udev_device_get_subsystem (input), "sound") != 0) + return; + + /* Only process "card" devices, as those are tagged with form-factor */ + if (g_str_equal (g_udev_device_get_subsystem (input), "sound") && + !g_str_has_prefix (g_udev_device_get_name (input), "card")) return; g_object_get (device, @@ -403,6 +424,17 @@ up_device_supply_sibling_discovered (UpDevice *device, } } + /* Match audio sub-type */ + if (new_type == UP_DEVICE_KIND_OTHER_AUDIO) { + const char *form_factor = g_udev_device_get_property (input, "SOUND_FORM_FACTOR"); + for (i = 0; i < G_N_ELEMENTS (sound_types); i++) { + if (g_strcmp0 (form_factor, sound_types[i].form_factor) == 0) { + new_type = sound_types[i].kind; + break; + } + } + } + /* TODO: Add a heuristic here (and during initial discovery) that uses * the model name. */ diff --git a/src/linux/up-enumerator-udev.c b/src/linux/up-enumerator-udev.c index 3077d11..97abaef 100644 --- a/src/linux/up-enumerator-udev.c +++ b/src/linux/up-enumerator-udev.c @@ -150,7 +150,8 @@ device_new (UpEnumeratorUdev *self, GUdevDevice *native) "native", native, NULL); - } else if (g_strcmp0 (subsys, "input") == 0) { + } else if (g_strcmp0 (subsys, "input") == 0 || + g_strcmp0 (subsys, "sound") == 0) { /* Ignore, we only resolve them to see siblings. */ return NULL; } else { @@ -302,8 +303,8 @@ up_enumerator_udev_initable_init (UpEnumerator *enumerator) guint i; const gchar **subsystems; /* List "input" first just to avoid some sibling hotplugging later */ - const gchar *subsystems_no_wup[] = {"input", "power_supply", "usb", "usbmisc", NULL}; - const gchar *subsystems_wup[] = {"input", "power_supply", "usb", "usbmisc", "tty", NULL}; + const gchar *subsystems_no_wup[] = {"input", "power_supply", "usb", "usbmisc", "sound", NULL}; + const gchar *subsystems_wup[] = {"input", "power_supply", "usb", "usbmisc", "sound", "tty", NULL}; config = up_config_new (); if (up_config_get_boolean (config, "EnableWattsUpPro")) -- cgit v1.2.1