diff options
author | Hans de Goede <hdegoede@redhat.com> | 2023-11-20 16:42:35 +0100 |
---|---|---|
committer | Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> | 2023-11-23 13:24:19 +0100 |
commit | fb103b90e944ecd664577c0fd37a069282dcd294 (patch) | |
tree | dbaa84ad6d4a0f953aa4d37513341d05cf0fd2f2 /drivers/platform/x86/asus-nb-wmi.c | |
parent | platform/x86: asus-wmi: Change q500a_i8042_filter() into a generic i8042-filter (diff) | |
download | linux-fb103b90e944ecd664577c0fd37a069282dcd294.tar.xz linux-fb103b90e944ecd664577c0fd37a069282dcd294.zip |
platform/x86: asus-wmi: Filter Volume key presses if also reported via atkbd
Use the i8042-filter to check if Volume key presses are also reported
via atkbd and if yes then filter out the WMI events to avoid reporting
each key-press twice.
Note depending on in which order the PS/2 data vs the WMI event are
handled the first volume key press may still be reported twice. This is
a compromise versus DMI quirks (unmaintainable) or other more complex
solutions.
Closes: https://bbs.archlinux.org/viewtopic.php?pid=2128536#p2128536
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20231120154235.610808-4-hdegoede@redhat.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Diffstat (limited to 'drivers/platform/x86/asus-nb-wmi.c')
-rw-r--r-- | drivers/platform/x86/asus-nb-wmi.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c index 16241556f6fb..fceffe2082ec 100644 --- a/drivers/platform/x86/asus-nb-wmi.c +++ b/drivers/platform/x86/asus-nb-wmi.c @@ -48,9 +48,11 @@ module_param(tablet_mode_sw, uint, 0444); MODULE_PARM_DESC(tablet_mode_sw, "Tablet mode detect: -1:auto 0:disable 1:kbd-dock 2:lid-flip 3:lid-flip-rog"); static struct quirk_entry *quirks; +static bool atkbd_reports_vol_keys; static bool asus_i8042_filter(unsigned char data, unsigned char str, struct serio *port) { + static bool extended_e0; static bool extended_e1; if (str & I8042_STR_AUXDATA) @@ -68,6 +70,20 @@ static bool asus_i8042_filter(unsigned char data, unsigned char str, struct seri } } + if (data == 0xe0) { + extended_e0 = true; + } else if (extended_e0) { + extended_e0 = false; + + switch (data & 0x7f) { + case 0x20: /* e0 20 / e0 a0, Volume Mute press / release */ + case 0x2e: /* e0 2e / e0 ae, Volume Down press / release */ + case 0x30: /* e0 30 / e0 b0, Volume Up press / release */ + atkbd_reports_vol_keys = true; + break; + } + } + return false; } @@ -609,6 +625,13 @@ static void asus_nb_wmi_key_filter(struct asus_wmi_driver *asus_wmi, int *code, *code = ASUS_WMI_KEY_IGNORE; break; + case 0x30: /* Volume Up */ + case 0x31: /* Volume Down */ + case 0x32: /* Volume Mute */ + if (atkbd_reports_vol_keys) + *code = ASUS_WMI_KEY_IGNORE; + + break; } } |