Commit 95eb9296 authored by Srihari Vijayaraghavan's avatar Srihari Vijayaraghavan Committed by Luis Henriques

Input: i8042 - reset keyboard to fix Elantech touchpad detection

commit 148e9a71 upstream.

On some laptops, keyboard needs to be reset in order to successfully detect
touchpad (e.g., some Gigabyte laptop models with Elantech touchpads).
Without resettin keyboard touchpad pretends to be completely dead.

Based on the original patch by Mateusz Jończyk this version has been
expanded to include DMI based detection & application of the fix
automatically on the affected models of laptops. This has been confirmed to
fix problem by three users already on three different models of laptops.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=81331Signed-off-by: default avatarSrihari Vijayaraghavan <linux.bug.reporting@gmail.com>
Acked-by: default avatarMateusz Jończyk <mat.jonczyk@o2.pl>
Tested-by: default avatarSrihari Vijayaraghavan <linux.bug.reporting@gmail.com>
Tested by: Zakariya Dehlawi <zdehlawi@gmail.com>
Tested-by: default avatarGuillaum Bouchard <guillaum.bouchard@gmail.com>
Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: default avatarLuis Henriques <luis.henriques@canonical.com>
parent 66497921
...@@ -1226,6 +1226,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted. ...@@ -1226,6 +1226,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
i8042.notimeout [HW] Ignore timeout condition signalled by controller i8042.notimeout [HW] Ignore timeout condition signalled by controller
i8042.reset [HW] Reset the controller during init and cleanup i8042.reset [HW] Reset the controller during init and cleanup
i8042.unlock [HW] Unlock (ignore) the keylock i8042.unlock [HW] Unlock (ignore) the keylock
i8042.kbdreset [HW] Reset device connected to KBD port
i810= [HW,DRM] i810= [HW,DRM]
......
...@@ -728,6 +728,35 @@ static const struct dmi_system_id __initconst i8042_dmi_dritek_table[] = { ...@@ -728,6 +728,35 @@ static const struct dmi_system_id __initconst i8042_dmi_dritek_table[] = {
{ } { }
}; };
/*
* Some laptops need keyboard reset before probing for the trackpad to get
* it detected, initialised & finally work.
*/
static const struct dmi_system_id __initconst i8042_dmi_kbdreset_table[] = {
{
/* Gigabyte P35 v2 - Elantech touchpad */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
DMI_MATCH(DMI_PRODUCT_NAME, "P35V2"),
},
},
{
/* Aorus branded Gigabyte X3 Plus - Elantech touchpad */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
DMI_MATCH(DMI_PRODUCT_NAME, "X3"),
},
},
{
/* Gigabyte P34 - Elantech touchpad */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
DMI_MATCH(DMI_PRODUCT_NAME, "P34"),
},
},
{ }
};
#endif /* CONFIG_X86 */ #endif /* CONFIG_X86 */
#ifdef CONFIG_PNP #ifdef CONFIG_PNP
...@@ -1023,6 +1052,9 @@ static int __init i8042_platform_init(void) ...@@ -1023,6 +1052,9 @@ static int __init i8042_platform_init(void)
if (dmi_check_system(i8042_dmi_dritek_table)) if (dmi_check_system(i8042_dmi_dritek_table))
i8042_dritek = true; i8042_dritek = true;
if (dmi_check_system(i8042_dmi_kbdreset_table))
i8042_kbdreset = true;
/* /*
* A20 was already enabled during early kernel init. But some buggy * A20 was already enabled during early kernel init. But some buggy
* BIOSes (in MSI Laptops) require A20 to be enabled using 8042 to * BIOSes (in MSI Laptops) require A20 to be enabled using 8042 to
......
...@@ -67,6 +67,10 @@ static bool i8042_notimeout; ...@@ -67,6 +67,10 @@ static bool i8042_notimeout;
module_param_named(notimeout, i8042_notimeout, bool, 0); module_param_named(notimeout, i8042_notimeout, bool, 0);
MODULE_PARM_DESC(notimeout, "Ignore timeouts signalled by i8042"); MODULE_PARM_DESC(notimeout, "Ignore timeouts signalled by i8042");
static bool i8042_kbdreset;
module_param_named(kbdreset, i8042_kbdreset, bool, 0);
MODULE_PARM_DESC(kbdreset, "Reset device connected to KBD port");
#ifdef CONFIG_X86 #ifdef CONFIG_X86
static bool i8042_dritek; static bool i8042_dritek;
module_param_named(dritek, i8042_dritek, bool, 0); module_param_named(dritek, i8042_dritek, bool, 0);
...@@ -789,6 +793,16 @@ static int __init i8042_check_aux(void) ...@@ -789,6 +793,16 @@ static int __init i8042_check_aux(void)
if (i8042_toggle_aux(true)) if (i8042_toggle_aux(true))
return -1; return -1;
/*
* Reset keyboard (needed on some laptops to successfully detect
* touchpad, e.g., some Gigabyte laptop models with Elantech
* touchpads).
*/
if (i8042_kbdreset) {
pr_warn("Attempting to reset device connected to KBD port\n");
i8042_kbd_write(NULL, (unsigned char) 0xff);
}
/* /*
* Test AUX IRQ delivery to make sure BIOS did not grab the IRQ and * Test AUX IRQ delivery to make sure BIOS did not grab the IRQ and
* used it for a PCI card or somethig else. * used it for a PCI card or somethig else.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment