summaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-egalax.c
diff options
context:
space:
mode:
authorPhilipp Merkel <mail@philmerk.de>2010-10-01 15:38:59 +0200
committerJiri Kosina <jkosina@suse.cz>2010-10-01 15:39:51 +0200
commitf51661105c3c8a0afcd69f995a4f4a10e53da153 (patch)
treee6ac6703e5b4973b2c5d23de6182e7725dff59f8 /drivers/hid/hid-egalax.c
parenta850ea30374ebed32a0724742601861853fde869 (diff)
HID: Fix for problems with eGalax/DWAV multi-touch-screen
This patch fixes three problems with the eGalax/DWAV multi-touch screen found in the Eee PC T101MT: 1) While there is a dedicated multitouch driver for the screen (hid-egalax.c), the MULTI_INPUT quirk is also applied, preventing the hid-egalax driver from working. This patch removes the quirk so the hid-egalax driver can handle the device correctly. 2) The x and y coordinates sent by the screen in multi-touch mode are shifted by three bits from the events sent in single-touch mode, thus the coordinates are out of range, leading to the pointer being stuck in the bottom-right corner if no additional calibration is applied (e.g. in the X evdev driver). This patch shifts the coordinates back. This does not decrease accuracy as the last three bits of the "wrong" coordinates are always 0. 3) Only multi-touch pressure events are sent, single touch emulation is missing pressure information. This patch adds single-touch ABS_PRESSURE events. Signed-off-by: Philipp Merkel <mail@philmerk.de> Acked-by: Stéphane Chatty <chatty@enac.fr> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid/hid-egalax.c')
-rw-r--r--drivers/hid/hid-egalax.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/drivers/hid/hid-egalax.c b/drivers/hid/hid-egalax.c
index 8ca7f65cf2f..54b017ad258 100644
--- a/drivers/hid/hid-egalax.c
+++ b/drivers/hid/hid-egalax.c
@@ -31,7 +31,7 @@ struct egalax_data {
bool first; /* is this the first finger in the frame? */
bool valid; /* valid finger data, or just placeholder? */
bool activity; /* at least one active finger previously? */
- __u16 lastx, lasty; /* latest valid (x, y) in the frame */
+ __u16 lastx, lasty, lastz; /* latest valid (x, y, z) in the frame */
};
static int egalax_input_mapping(struct hid_device *hdev, struct hid_input *hi,
@@ -79,6 +79,10 @@ static int egalax_input_mapping(struct hid_device *hdev, struct hid_input *hi,
case HID_DG_TIPPRESSURE:
hid_map_usage(hi, usage, bit, max,
EV_ABS, ABS_MT_PRESSURE);
+ /* touchscreen emulation */
+ input_set_abs_params(hi->input, ABS_PRESSURE,
+ field->logical_minimum,
+ field->logical_maximum, 0, 0);
return 1;
}
return 0;
@@ -109,8 +113,8 @@ static void egalax_filter_event(struct egalax_data *td, struct input_dev *input)
if (td->valid) {
/* emit multitouch events */
input_event(input, EV_ABS, ABS_MT_TRACKING_ID, td->id);
- input_event(input, EV_ABS, ABS_MT_POSITION_X, td->x);
- input_event(input, EV_ABS, ABS_MT_POSITION_Y, td->y);
+ input_event(input, EV_ABS, ABS_MT_POSITION_X, td->x >> 3);
+ input_event(input, EV_ABS, ABS_MT_POSITION_Y, td->y >> 3);
input_event(input, EV_ABS, ABS_MT_PRESSURE, td->z);
input_mt_sync(input);
@@ -121,6 +125,7 @@ static void egalax_filter_event(struct egalax_data *td, struct input_dev *input)
*/
td->lastx = td->x;
td->lasty = td->y;
+ td->lastz = td->z;
}
/*
@@ -129,8 +134,9 @@ static void egalax_filter_event(struct egalax_data *td, struct input_dev *input)
* the oldest on the panel, the one we want for single touch
*/
if (!td->first && td->activity) {
- input_event(input, EV_ABS, ABS_X, td->lastx);
- input_event(input, EV_ABS, ABS_Y, td->lasty);
+ input_event(input, EV_ABS, ABS_X, td->lastx >> 3);
+ input_event(input, EV_ABS, ABS_Y, td->lasty >> 3);
+ input_event(input, EV_ABS, ABS_PRESSURE, td->lastz);
}
if (!td->valid) {