]>
Commit | Line | Data |
---|---|---|
53c49429 GKH |
1 | From f51661105c3c8a0afcd69f995a4f4a10e53da153 Mon Sep 17 00:00:00 2001 |
2 | From: Philipp Merkel <mail@philmerk.de> | |
3 | Date: Fri, 1 Oct 2010 15:38:59 +0200 | |
4 | Subject: HID: Fix for problems with eGalax/DWAV multi-touch-screen | |
5 | MIME-Version: 1.0 | |
6 | Content-Type: text/plain; charset=UTF-8 | |
7 | Content-Transfer-Encoding: 8bit | |
8 | ||
9 | From: Philipp Merkel <mail@philmerk.de> | |
10 | ||
11 | commit f51661105c3c8a0afcd69f995a4f4a10e53da153 upstream. | |
12 | ||
13 | This patch fixes three problems with the eGalax/DWAV multi-touch | |
14 | screen found in the Eee PC T101MT: | |
15 | ||
16 | 1) While there is a dedicated multitouch driver for the screen | |
17 | (hid-egalax.c), the MULTI_INPUT quirk is also applied, preventing | |
18 | the hid-egalax driver from working. This patch removes the quirk | |
19 | so the hid-egalax driver can handle the device correctly. | |
20 | 2) The x and y coordinates sent by the screen in multi-touch mode are | |
21 | shifted by three bits from the events sent in single-touch mode, thus | |
22 | the coordinates are out of range, leading to the pointer being stuck | |
23 | in the bottom-right corner if no additional calibration is applied | |
24 | (e.g. in the X evdev driver). This patch shifts the coordinates back. | |
25 | This does not decrease accuracy as the last three bits of the "wrong" | |
26 | coordinates are always 0. | |
27 | 3) Only multi-touch pressure events are sent, single touch emulation is | |
28 | missing pressure information. This patch adds single-touch | |
29 | ABS_PRESSURE events. | |
30 | ||
31 | Signed-off-by: Philipp Merkel <mail@philmerk.de> | |
32 | Acked-by: Stéphane Chatty <chatty@enac.fr> | |
33 | Signed-off-by: Jiri Kosina <jkosina@suse.cz> | |
34 | Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> | |
35 | ||
36 | --- | |
37 | drivers/hid/hid-egalax.c | 16 +++++++++++----- | |
38 | drivers/hid/usbhid/hid-quirks.c | 1 - | |
39 | 2 files changed, 11 insertions(+), 6 deletions(-) | |
40 | ||
41 | --- a/drivers/hid/hid-egalax.c | |
42 | +++ b/drivers/hid/hid-egalax.c | |
43 | @@ -31,7 +31,7 @@ struct egalax_data { | |
44 | bool first; /* is this the first finger in the frame? */ | |
45 | bool valid; /* valid finger data, or just placeholder? */ | |
46 | bool activity; /* at least one active finger previously? */ | |
47 | - __u16 lastx, lasty; /* latest valid (x, y) in the frame */ | |
48 | + __u16 lastx, lasty, lastz; /* latest valid (x, y, z) in the frame */ | |
49 | }; | |
50 | ||
51 | static int egalax_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |
52 | @@ -79,6 +79,10 @@ static int egalax_input_mapping(struct h | |
53 | case HID_DG_TIPPRESSURE: | |
54 | hid_map_usage(hi, usage, bit, max, | |
55 | EV_ABS, ABS_MT_PRESSURE); | |
56 | + /* touchscreen emulation */ | |
57 | + input_set_abs_params(hi->input, ABS_PRESSURE, | |
58 | + field->logical_minimum, | |
59 | + field->logical_maximum, 0, 0); | |
60 | return 1; | |
61 | } | |
62 | return 0; | |
63 | @@ -109,8 +113,8 @@ static void egalax_filter_event(struct e | |
64 | if (td->valid) { | |
65 | /* emit multitouch events */ | |
66 | input_event(input, EV_ABS, ABS_MT_TRACKING_ID, td->id); | |
67 | - input_event(input, EV_ABS, ABS_MT_POSITION_X, td->x); | |
68 | - input_event(input, EV_ABS, ABS_MT_POSITION_Y, td->y); | |
69 | + input_event(input, EV_ABS, ABS_MT_POSITION_X, td->x >> 3); | |
70 | + input_event(input, EV_ABS, ABS_MT_POSITION_Y, td->y >> 3); | |
71 | input_event(input, EV_ABS, ABS_MT_PRESSURE, td->z); | |
72 | ||
73 | input_mt_sync(input); | |
74 | @@ -121,6 +125,7 @@ static void egalax_filter_event(struct e | |
75 | */ | |
76 | td->lastx = td->x; | |
77 | td->lasty = td->y; | |
78 | + td->lastz = td->z; | |
79 | } | |
80 | ||
81 | /* | |
82 | @@ -129,8 +134,9 @@ static void egalax_filter_event(struct e | |
83 | * the oldest on the panel, the one we want for single touch | |
84 | */ | |
85 | if (!td->first && td->activity) { | |
86 | - input_event(input, EV_ABS, ABS_X, td->lastx); | |
87 | - input_event(input, EV_ABS, ABS_Y, td->lasty); | |
88 | + input_event(input, EV_ABS, ABS_X, td->lastx >> 3); | |
89 | + input_event(input, EV_ABS, ABS_Y, td->lasty >> 3); | |
90 | + input_event(input, EV_ABS, ABS_PRESSURE, td->lastz); | |
91 | } | |
92 | ||
93 | if (!td->valid) { | |
94 | --- a/drivers/hid/usbhid/hid-quirks.c | |
95 | +++ b/drivers/hid/usbhid/hid-quirks.c | |
96 | @@ -34,7 +34,6 @@ static const struct hid_blacklist { | |
97 | { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD }, | |
98 | { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD }, | |
99 | { USB_VENDOR_ID_DWAV, USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER, HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET }, | |
100 | - { USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH, HID_QUIRK_MULTI_INPUT }, | |
101 | { USB_VENDOR_ID_MOJO, USB_DEVICE_ID_RETRO_ADAPTER, HID_QUIRK_MULTI_INPUT }, | |
102 | { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART, HID_QUIRK_MULTI_INPUT }, | |
103 | { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, |