aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2014-05-05 09:36:43 -0700
committerBen Hutchings <ben@decadent.org.uk>2014-06-09 13:29:08 +0100
commite058d7cd3fb7328c3d768686e416e873a1bf2e3f (patch)
treecd5ea41a7a13680a94a4292401c4ec550c31dbdb
parent41023bc32be31ec611c014dc26c8412850a6a6da (diff)
downloadkernel_samsung_smdk4412-e058d7cd3fb7328c3d768686e416e873a1bf2e3f.zip
kernel_samsung_smdk4412-e058d7cd3fb7328c3d768686e416e873a1bf2e3f.tar.gz
kernel_samsung_smdk4412-e058d7cd3fb7328c3d768686e416e873a1bf2e3f.tar.bz2
Input: elantech - fix touchpad initialization on Gigabyte U2442
commit 36189cc3cd57ab0f1cd75241f93fe01de928ac06 upstream. The hw_version 3 Elantech touchpad on the Gigabyte U2442 does not accept 0x0b as initialization value for r10, this stand-alone version of the driver: http://planet76.com/drivers/elantech/psmouse-elantech-v6.tar.bz2 Uses 0x03 which does work, so this means not setting bit 3 of r10 which sets: "Enable Real H/W Resolution In Absolute mode" Which will result in half the x and y resolution we get with that bit set, so simply not setting it everywhere is not a solution. We've been unable to find a way to identify touchpads where setting the bit will fail, so this patch uses a dmi based blacklist for this. https://bugzilla.kernel.org/show_bug.cgi?id=61151 Reported-by: Philipp Wolfer <ph.wolfer@gmail.com> Tested-by: Philipp Wolfer <ph.wolfer@gmail.com> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> [bwh: Backported to 3.2: adjust context] Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
-rw-r--r--Documentation/input/elantech.txt5
-rw-r--r--drivers/input/mouse/elantech.c26
-rw-r--r--drivers/input/mouse/elantech.h1
3 files changed, 30 insertions, 2 deletions
diff --git a/Documentation/input/elantech.txt b/Documentation/input/elantech.txt
index 5602eb7..e1ae127 100644
--- a/Documentation/input/elantech.txt
+++ b/Documentation/input/elantech.txt
@@ -504,9 +504,12 @@ byte 5:
* reg_10
bit 7 6 5 4 3 2 1 0
- 0 0 0 0 0 0 0 A
+ 0 0 0 0 R F T A
A: 1 = enable absolute tracking
+ T: 1 = enable two finger mode auto correct
+ F: 1 = disable ABS Position Filter
+ R: 1 = enable real hardware resolution
6.2 Native absolute mode 6 byte packet format
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
index e2a9867..342a059 100644
--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -11,6 +11,7 @@
*/
#include <linux/delay.h>
+#include <linux/dmi.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/input.h>
@@ -783,7 +784,11 @@ static int elantech_set_absolute_mode(struct psmouse *psmouse)
break;
case 3:
- etd->reg_10 = 0x0b;
+ if (etd->set_hw_resolution)
+ etd->reg_10 = 0x0b;
+ else
+ etd->reg_10 = 0x03;
+
if (elantech_write_reg(psmouse, 0x10, etd->reg_10))
rc = -1;
@@ -1206,6 +1211,22 @@ static int elantech_reconnect(struct psmouse *psmouse)
}
/*
+ * Some hw_version 3 models go into error state when we try to set bit 3 of r10
+ */
+static const struct dmi_system_id no_hw_res_dmi_table[] = {
+#if defined(CONFIG_DMI) && defined(CONFIG_X86)
+ {
+ /* Gigabyte U2442 */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "U2442"),
+ },
+ },
+#endif
+ { }
+};
+
+/*
* determine hardware version and set some properties according to it.
*/
static int elantech_set_properties(struct elantech_data *etd)
@@ -1254,6 +1275,9 @@ static int elantech_set_properties(struct elantech_data *etd)
etd->reports_pressure = true;
}
+ /* Enable real hardware resolution on hw_version 3 ? */
+ etd->set_hw_resolution = !dmi_check_system(no_hw_res_dmi_table);
+
return 0;
}
diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h
index 9e5f1aa..3569bed 100644
--- a/drivers/input/mouse/elantech.h
+++ b/drivers/input/mouse/elantech.h
@@ -128,6 +128,7 @@ struct elantech_data {
bool paritycheck;
bool jumpy_cursor;
bool reports_pressure;
+ bool set_hw_resolution;
unsigned char hw_version;
unsigned int fw_version;
unsigned int single_finger_reports;