diff options
author | Daniel Ritz <daniel.ritz-ml@swissonline.ch> | 2006-12-11 12:17:45 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-01-22 14:46:55 -0500 |
commit | c9d8c2b324d24ffb4fdcd93b3f752530a5a0a591 (patch) | |
tree | 2f18bdb4952866fe5e7475e0cafdd774a1c9db69 /drivers/usb/input/usbtouchscreen.c | |
parent | 365bbe0d0caaf2ba74d56556827babf0bc66965d (diff) |
usbtouchscreen: make ITM screens report BTN_TOUCH as zero when not touched
ITM screens send invalid x/y data when not touched. this was fixes a while ago
but the problem is if the screen is not touched anymore the driver never does
not report BTN_TOUCH as zero. fix it by sending the report with the last valid
coordinates when pressure is released.
Signed-off-by: Daniel Ritz <daniel.ritz@gmx.ch>
Cc: J.P. Delport <jpdelport@csir.co.za>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/input/usbtouchscreen.c')
-rw-r--r-- | drivers/usb/input/usbtouchscreen.c | 98 |
1 files changed, 59 insertions, 39 deletions
diff --git a/drivers/usb/input/usbtouchscreen.c b/drivers/usb/input/usbtouchscreen.c index 7f3c57da9bc0..86e37a20f8e5 100644 --- a/drivers/usb/input/usbtouchscreen.c +++ b/drivers/usb/input/usbtouchscreen.c | |||
@@ -66,7 +66,7 @@ struct usbtouch_device_info { | |||
66 | 66 | ||
67 | void (*process_pkt) (struct usbtouch_usb *usbtouch, unsigned char *pkt, int len); | 67 | void (*process_pkt) (struct usbtouch_usb *usbtouch, unsigned char *pkt, int len); |
68 | int (*get_pkt_len) (unsigned char *pkt, int len); | 68 | int (*get_pkt_len) (unsigned char *pkt, int len); |
69 | int (*read_data) (unsigned char *pkt, int *x, int *y, int *touch, int *press); | 69 | int (*read_data) (struct usbtouch_usb *usbtouch, unsigned char *pkt); |
70 | int (*init) (struct usbtouch_usb *usbtouch); | 70 | int (*init) (struct usbtouch_usb *usbtouch); |
71 | }; | 71 | }; |
72 | 72 | ||
@@ -85,6 +85,9 @@ struct usbtouch_usb { | |||
85 | struct usbtouch_device_info *type; | 85 | struct usbtouch_device_info *type; |
86 | char name[128]; | 86 | char name[128]; |
87 | char phys[64]; | 87 | char phys[64]; |
88 | |||
89 | int x, y; | ||
90 | int touch, press; | ||
88 | }; | 91 | }; |
89 | 92 | ||
90 | 93 | ||
@@ -161,14 +164,14 @@ static struct usb_device_id usbtouch_devices[] = { | |||
161 | #define EGALAX_PKT_TYPE_REPT 0x80 | 164 | #define EGALAX_PKT_TYPE_REPT 0x80 |
162 | #define EGALAX_PKT_TYPE_DIAG 0x0A | 165 | #define EGALAX_PKT_TYPE_DIAG 0x0A |
163 | 166 | ||
164 | static int egalax_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press) | 167 | static int egalax_read_data(struct usbtouch_usb *dev, unsigned char *pkt) |
165 | { | 168 | { |
166 | if ((pkt[0] & EGALAX_PKT_TYPE_MASK) != EGALAX_PKT_TYPE_REPT) | 169 | if ((pkt[0] & EGALAX_PKT_TYPE_MASK) != EGALAX_PKT_TYPE_REPT) |
167 | return 0; | 170 | return 0; |
168 | 171 | ||
169 | *x = ((pkt[3] & 0x0F) << 7) | (pkt[4] & 0x7F); | 172 | dev->x = ((pkt[3] & 0x0F) << 7) | (pkt[4] & 0x7F); |
170 | *y = ((pkt[1] & 0x0F) << 7) | (pkt[2] & 0x7F); | 173 | dev->y = ((pkt[1] & 0x0F) << 7) | (pkt[2] & 0x7F); |
171 | *touch = pkt[0] & 0x01; | 174 | dev->touch = pkt[0] & 0x01; |
172 | 175 | ||
173 | return 1; | 176 | return 1; |
174 | } | 177 | } |
@@ -195,11 +198,11 @@ static int egalax_get_pkt_len(unsigned char *buf, int len) | |||
195 | * PanJit Part | 198 | * PanJit Part |
196 | */ | 199 | */ |
197 | #ifdef CONFIG_USB_TOUCHSCREEN_PANJIT | 200 | #ifdef CONFIG_USB_TOUCHSCREEN_PANJIT |
198 | static int panjit_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press) | 201 | static int panjit_read_data(struct usbtouch_usb *dev, unsigned char *pkt) |
199 | { | 202 | { |
200 | *x = ((pkt[2] & 0x0F) << 8) | pkt[1]; | 203 | dev->x = ((pkt[2] & 0x0F) << 8) | pkt[1]; |
201 | *y = ((pkt[4] & 0x0F) << 8) | pkt[3]; | 204 | dev->y = ((pkt[4] & 0x0F) << 8) | pkt[3]; |
202 | *touch = pkt[0] & 0x01; | 205 | dev->touch = pkt[0] & 0x01; |
203 | 206 | ||
204 | return 1; | 207 | return 1; |
205 | } | 208 | } |
@@ -215,11 +218,11 @@ static int panjit_read_data(unsigned char *pkt, int *x, int *y, int *touch, int | |||
215 | #define MTOUCHUSB_RESET 7 | 218 | #define MTOUCHUSB_RESET 7 |
216 | #define MTOUCHUSB_REQ_CTRLLR_ID 10 | 219 | #define MTOUCHUSB_REQ_CTRLLR_ID 10 |
217 | 220 | ||
218 | static int mtouch_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press) | 221 | static int mtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt) |
219 | { | 222 | { |
220 | *x = (pkt[8] << 8) | pkt[7]; | 223 | dev->x = (pkt[8] << 8) | pkt[7]; |
221 | *y = (pkt[10] << 8) | pkt[9]; | 224 | dev->y = (pkt[10] << 8) | pkt[9]; |
222 | *touch = (pkt[2] & 0x40) ? 1 : 0; | 225 | dev->touch = (pkt[2] & 0x40) ? 1 : 0; |
223 | 226 | ||
224 | return 1; | 227 | return 1; |
225 | } | 228 | } |
@@ -260,14 +263,32 @@ static int mtouch_init(struct usbtouch_usb *usbtouch) | |||
260 | * ITM Part | 263 | * ITM Part |
261 | */ | 264 | */ |
262 | #ifdef CONFIG_USB_TOUCHSCREEN_ITM | 265 | #ifdef CONFIG_USB_TOUCHSCREEN_ITM |
263 | static int itm_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press) | 266 | static int itm_read_data(struct usbtouch_usb *dev, unsigned char *pkt) |
264 | { | 267 | { |
265 | *x = ((pkt[0] & 0x1F) << 7) | (pkt[3] & 0x7F); | 268 | int touch; |
266 | *y = ((pkt[1] & 0x1F) << 7) | (pkt[4] & 0x7F); | 269 | /* |
267 | *press = ((pkt[2] & 0x01) << 7) | (pkt[5] & 0x7F); | 270 | * ITM devices report invalid x/y data if not touched. |
268 | *touch = ~pkt[7] & 0x20; | 271 | * if the screen was touched before but is not touched any more |
272 | * report touch as 0 with the last valid x/y data once. then stop | ||
273 | * reporting data until touched again. | ||
274 | */ | ||
275 | dev->press = ((pkt[2] & 0x01) << 7) | (pkt[5] & 0x7F); | ||
276 | |||
277 | touch = ~pkt[7] & 0x20; | ||
278 | if (!touch) { | ||
279 | if (dev->touch) { | ||
280 | dev->touch = 0; | ||
281 | return 1; | ||
282 | } | ||
269 | 283 | ||
270 | return *touch; | 284 | return 0; |
285 | } | ||
286 | |||
287 | dev->x = ((pkt[0] & 0x1F) << 7) | (pkt[3] & 0x7F); | ||
288 | dev->y = ((pkt[1] & 0x1F) << 7) | (pkt[4] & 0x7F); | ||
289 | dev->touch = touch; | ||
290 | |||
291 | return 1; | ||
271 | } | 292 | } |
272 | #endif | 293 | #endif |
273 | 294 | ||
@@ -276,7 +297,7 @@ static int itm_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *pr | |||
276 | * eTurboTouch part | 297 | * eTurboTouch part |
277 | */ | 298 | */ |
278 | #ifdef CONFIG_USB_TOUCHSCREEN_ETURBO | 299 | #ifdef CONFIG_USB_TOUCHSCREEN_ETURBO |
279 | static int eturbo_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press) | 300 | static int eturbo_read_data(struct usbtouch_usb *dev, unsigned char *pkt) |
280 | { | 301 | { |
281 | unsigned int shift; | 302 | unsigned int shift; |
282 | 303 | ||
@@ -285,9 +306,9 @@ static int eturbo_read_data(unsigned char *pkt, int *x, int *y, int *touch, int | |||
285 | return 0; | 306 | return 0; |
286 | 307 | ||
287 | shift = (6 - (pkt[0] & 0x03)); | 308 | shift = (6 - (pkt[0] & 0x03)); |
288 | *x = ((pkt[3] << 7) | pkt[4]) >> shift; | 309 | dev->x = ((pkt[3] << 7) | pkt[4]) >> shift; |
289 | *y = ((pkt[1] << 7) | pkt[2]) >> shift; | 310 | dev->y = ((pkt[1] << 7) | pkt[2]) >> shift; |
290 | *touch = (pkt[0] & 0x10) ? 1 : 0; | 311 | dev->touch = (pkt[0] & 0x10) ? 1 : 0; |
291 | 312 | ||
292 | return 1; | 313 | return 1; |
293 | } | 314 | } |
@@ -307,14 +328,14 @@ static int eturbo_get_pkt_len(unsigned char *buf, int len) | |||
307 | * Gunze part | 328 | * Gunze part |
308 | */ | 329 | */ |
309 | #ifdef CONFIG_USB_TOUCHSCREEN_GUNZE | 330 | #ifdef CONFIG_USB_TOUCHSCREEN_GUNZE |
310 | static int gunze_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press) | 331 | static int gunze_read_data(struct usbtouch_usb *dev, unsigned char *pkt) |
311 | { | 332 | { |
312 | if (!(pkt[0] & 0x80) || ((pkt[1] | pkt[2] | pkt[3]) & 0x80)) | 333 | if (!(pkt[0] & 0x80) || ((pkt[1] | pkt[2] | pkt[3]) & 0x80)) |
313 | return 0; | 334 | return 0; |
314 | 335 | ||
315 | *x = ((pkt[0] & 0x1F) << 7) | (pkt[2] & 0x7F); | 336 | dev->x = ((pkt[0] & 0x1F) << 7) | (pkt[2] & 0x7F); |
316 | *y = ((pkt[1] & 0x1F) << 7) | (pkt[3] & 0x7F); | 337 | dev->y = ((pkt[1] & 0x1F) << 7) | (pkt[3] & 0x7F); |
317 | *touch = pkt[0] & 0x20; | 338 | dev->touch = pkt[0] & 0x20; |
318 | 339 | ||
319 | return 1; | 340 | return 1; |
320 | } | 341 | } |
@@ -383,11 +404,11 @@ static int dmc_tsc10_init(struct usbtouch_usb *usbtouch) | |||
383 | } | 404 | } |
384 | 405 | ||
385 | 406 | ||
386 | static int dmc_tsc10_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press) | 407 | static int dmc_tsc10_read_data(struct usbtouch_usb *dev, unsigned char *pkt) |
387 | { | 408 | { |
388 | *x = ((pkt[2] & 0x03) << 8) | pkt[1]; | 409 | dev->x = ((pkt[2] & 0x03) << 8) | pkt[1]; |
389 | *y = ((pkt[4] & 0x03) << 8) | pkt[3]; | 410 | dev->y = ((pkt[4] & 0x03) << 8) | pkt[3]; |
390 | *touch = pkt[0] & 0x01; | 411 | dev->touch = pkt[0] & 0x01; |
391 | 412 | ||
392 | return 1; | 413 | return 1; |
393 | } | 414 | } |
@@ -492,23 +513,22 @@ static struct usbtouch_device_info usbtouch_dev_info[] = { | |||
492 | static void usbtouch_process_pkt(struct usbtouch_usb *usbtouch, | 513 | static void usbtouch_process_pkt(struct usbtouch_usb *usbtouch, |
493 | unsigned char *pkt, int len) | 514 | unsigned char *pkt, int len) |
494 | { | 515 | { |
495 | int x, y, touch, press; | ||
496 | struct usbtouch_device_info *type = usbtouch->type; | 516 | struct usbtouch_device_info *type = usbtouch->type; |
497 | 517 | ||
498 | if (!type->read_data(pkt, &x, &y, &touch, &press)) | 518 | if (!type->read_data(usbtouch, pkt)) |
499 | return; | 519 | return; |
500 | 520 | ||
501 | input_report_key(usbtouch->input, BTN_TOUCH, touch); | 521 | input_report_key(usbtouch->input, BTN_TOUCH, usbtouch->touch); |
502 | 522 | ||
503 | if (swap_xy) { | 523 | if (swap_xy) { |
504 | input_report_abs(usbtouch->input, ABS_X, y); | 524 | input_report_abs(usbtouch->input, ABS_X, usbtouch->y); |
505 | input_report_abs(usbtouch->input, ABS_Y, x); | 525 | input_report_abs(usbtouch->input, ABS_Y, usbtouch->x); |
506 | } else { | 526 | } else { |
507 | input_report_abs(usbtouch->input, ABS_X, x); | 527 | input_report_abs(usbtouch->input, ABS_X, usbtouch->x); |
508 | input_report_abs(usbtouch->input, ABS_Y, y); | 528 | input_report_abs(usbtouch->input, ABS_Y, usbtouch->y); |
509 | } | 529 | } |
510 | if (type->max_press) | 530 | if (type->max_press) |
511 | input_report_abs(usbtouch->input, ABS_PRESSURE, press); | 531 | input_report_abs(usbtouch->input, ABS_PRESSURE, usbtouch->press); |
512 | input_sync(usbtouch->input); | 532 | input_sync(usbtouch->input); |
513 | } | 533 | } |
514 | 534 | ||