diff options
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 | ||
