diff options
author | Ping Cheng <pingc@wacom.com> | 2009-12-15 03:35:24 -0500 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2009-12-15 03:36:08 -0500 |
commit | ec67bbedcf290ef182a897017f65a2707106c7f8 (patch) | |
tree | 321fe650b72776e8555da3a94b049e2704bc2b2a /drivers/input | |
parent | ee54500d7b960984df125bdd0cd2105d6150e8f1 (diff) |
Input: wacom - add support for new LCD tablets
This adds support for the foolowing Wacom devices:
- 0x9F - a single touch only LCD tablet;
- 0xE2 - a two finger touch only LCD tablet;
- 0xE3 - a two finger touch, penabled LCD tablet.
Signed-off-by: Ping Cheng <pingc@wacom.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/tablet/wacom.h | 3 | ||||
-rw-r--r-- | drivers/input/tablet/wacom_sys.c | 226 | ||||
-rw-r--r-- | drivers/input/tablet/wacom_wac.c | 204 | ||||
-rw-r--r-- | drivers/input/tablet/wacom_wac.h | 10 |
4 files changed, 311 insertions, 132 deletions
diff --git a/drivers/input/tablet/wacom.h b/drivers/input/tablet/wacom.h index d71da970602c..16310f368dab 100644 --- a/drivers/input/tablet/wacom.h +++ b/drivers/input/tablet/wacom.h | |||
@@ -71,6 +71,7 @@ | |||
71 | * v1.51 (pc) - Added support for Intuos4 | 71 | * v1.51 (pc) - Added support for Intuos4 |
72 | * v1.52 (pc) - Query Wacom data upon system resume | 72 | * v1.52 (pc) - Query Wacom data upon system resume |
73 | * - add defines for features->type | 73 | * - add defines for features->type |
74 | * - add new devices (0x9F, 0xE2, and 0XE3) | ||
74 | */ | 75 | */ |
75 | 76 | ||
76 | /* | 77 | /* |
@@ -135,6 +136,8 @@ extern void input_dev_i4s(struct input_dev *input_dev, struct wacom_wac *wacom_w | |||
135 | extern void input_dev_i4(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | 136 | extern void input_dev_i4(struct input_dev *input_dev, struct wacom_wac *wacom_wac); |
136 | extern void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | 137 | extern void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac); |
137 | extern void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | 138 | extern void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac); |
139 | extern void input_dev_tpc(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | ||
140 | extern void input_dev_tpc2fg(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | ||
138 | extern void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | 141 | extern void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac); |
139 | extern void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | 142 | extern void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac); |
140 | extern __u16 wacom_le16_to_cpu(unsigned char *data); | 143 | extern __u16 wacom_le16_to_cpu(unsigned char *data); |
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index b5b69cc0aaf0..072f33b3b2b0 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c | |||
@@ -209,6 +209,7 @@ void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | |||
209 | input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_LEFT) | | 209 | input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_LEFT) | |
210 | BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE); | 210 | BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE); |
211 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) | | 211 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) | |
212 | BIT_MASK(BTN_TOOL_PEN) | BIT_MASK(BTN_STYLUS) | | ||
212 | BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_STYLUS2); | 213 | BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_STYLUS2); |
213 | input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); | 214 | input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); |
214 | } | 215 | } |
@@ -256,6 +257,7 @@ void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | |||
256 | BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE) | | 257 | BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE) | |
257 | BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA); | 258 | BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA); |
258 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) | | 259 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) | |
260 | BIT_MASK(BTN_TOOL_PEN) | BIT_MASK(BTN_STYLUS) | | ||
259 | BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_TOOL_BRUSH) | | 261 | BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_TOOL_BRUSH) | |
260 | BIT_MASK(BTN_TOOL_PENCIL) | BIT_MASK(BTN_TOOL_AIRBRUSH) | | 262 | BIT_MASK(BTN_TOOL_PENCIL) | BIT_MASK(BTN_TOOL_AIRBRUSH) | |
261 | BIT_MASK(BTN_TOOL_LENS) | BIT_MASK(BTN_STYLUS2); | 263 | BIT_MASK(BTN_TOOL_LENS) | BIT_MASK(BTN_STYLUS2); |
@@ -269,7 +271,8 @@ void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | |||
269 | 271 | ||
270 | void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | 272 | void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac) |
271 | { | 273 | { |
272 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_STYLUS2); | 274 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_PEN) | |
275 | BIT_MASK(BTN_STYLUS) | BIT_MASK(BTN_STYLUS2); | ||
273 | } | 276 | } |
274 | 277 | ||
275 | void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | 278 | void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac) |
@@ -277,12 +280,32 @@ void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | |||
277 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER); | 280 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER); |
278 | } | 281 | } |
279 | 282 | ||
283 | void input_dev_tpc(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | ||
284 | { | ||
285 | if (wacom_wac->features->device_type == BTN_TOOL_DOUBLETAP || | ||
286 | wacom_wac->features->device_type == BTN_TOOL_TRIPLETAP) { | ||
287 | input_set_abs_params(input_dev, ABS_RX, 0, wacom_wac->features->x_phy, 0, 0); | ||
288 | input_set_abs_params(input_dev, ABS_RY, 0, wacom_wac->features->y_phy, 0, 0); | ||
289 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_DOUBLETAP); | ||
290 | } | ||
291 | } | ||
292 | |||
293 | void input_dev_tpc2fg(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | ||
294 | { | ||
295 | if (wacom_wac->features->device_type == BTN_TOOL_TRIPLETAP) { | ||
296 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_TRIPLETAP); | ||
297 | input_dev->evbit[0] |= BIT_MASK(EV_MSC); | ||
298 | input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL); | ||
299 | } | ||
300 | } | ||
301 | |||
280 | static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc, | 302 | static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc, |
281 | struct wacom_wac *wacom_wac) | 303 | struct wacom_features *features) |
282 | { | 304 | { |
283 | struct usb_device *dev = interface_to_usbdev(intf); | 305 | struct usb_device *dev = interface_to_usbdev(intf); |
284 | struct wacom_features *features = wacom_wac->features; | 306 | char limit = 0; |
285 | char limit = 0, result = 0; | 307 | /* result has to be defined as int for some devices */ |
308 | int result = 0; | ||
286 | int i = 0, usage = WCM_UNDEFINED, finger = 0, pen = 0; | 309 | int i = 0, usage = WCM_UNDEFINED, finger = 0, pen = 0; |
287 | unsigned char *report; | 310 | unsigned char *report; |
288 | 311 | ||
@@ -328,13 +351,24 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi | |||
328 | case HID_USAGE_X: | 351 | case HID_USAGE_X: |
329 | if (usage == WCM_DESKTOP) { | 352 | if (usage == WCM_DESKTOP) { |
330 | if (finger) { | 353 | if (finger) { |
331 | features->touch_x_max = | 354 | features->device_type = BTN_TOOL_DOUBLETAP; |
332 | features->touch_y_max = | 355 | if (features->type == TABLETPC2FG) { |
333 | wacom_le16_to_cpu(&report[i + 3]); | 356 | /* need to reset back */ |
357 | features->pktlen = WACOM_PKGLEN_TPC2FG; | ||
358 | features->device_type = BTN_TOOL_TRIPLETAP; | ||
359 | } | ||
334 | features->x_max = | 360 | features->x_max = |
361 | wacom_le16_to_cpu(&report[i + 3]); | ||
362 | features->x_phy = | ||
335 | wacom_le16_to_cpu(&report[i + 6]); | 363 | wacom_le16_to_cpu(&report[i + 6]); |
336 | i += 7; | 364 | features->unit = report[i + 9]; |
365 | features->unitExpo = report[i + 11]; | ||
366 | i += 12; | ||
337 | } else if (pen) { | 367 | } else if (pen) { |
368 | /* penabled only accepts exact bytes of data */ | ||
369 | if (features->type == TABLETPC2FG) | ||
370 | features->pktlen = WACOM_PKGLEN_PENABLED; | ||
371 | features->device_type = BTN_TOOL_PEN; | ||
338 | features->x_max = | 372 | features->x_max = |
339 | wacom_le16_to_cpu(&report[i + 3]); | 373 | wacom_le16_to_cpu(&report[i + 3]); |
340 | i += 4; | 374 | i += 4; |
@@ -350,10 +384,35 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi | |||
350 | break; | 384 | break; |
351 | 385 | ||
352 | case HID_USAGE_Y: | 386 | case HID_USAGE_Y: |
353 | if (usage == WCM_DESKTOP) | 387 | if (usage == WCM_DESKTOP) { |
354 | features->y_max = | 388 | if (finger) { |
355 | wacom_le16_to_cpu(&report[i + 3]); | 389 | features->device_type = BTN_TOOL_DOUBLETAP; |
356 | i += 4; | 390 | if (features->type == TABLETPC2FG) { |
391 | /* need to reset back */ | ||
392 | features->pktlen = WACOM_PKGLEN_TPC2FG; | ||
393 | features->device_type = BTN_TOOL_TRIPLETAP; | ||
394 | features->y_max = | ||
395 | wacom_le16_to_cpu(&report[i + 3]); | ||
396 | features->y_phy = | ||
397 | wacom_le16_to_cpu(&report[i + 6]); | ||
398 | i += 7; | ||
399 | } else { | ||
400 | features->y_max = | ||
401 | features->x_max; | ||
402 | features->y_phy = | ||
403 | wacom_le16_to_cpu(&report[i + 3]); | ||
404 | i += 4; | ||
405 | } | ||
406 | } else if (pen) { | ||
407 | /* penabled only accepts exact bytes of data */ | ||
408 | if (features->type == TABLETPC2FG) | ||
409 | features->pktlen = WACOM_PKGLEN_PENABLED; | ||
410 | features->device_type = BTN_TOOL_PEN; | ||
411 | features->y_max = | ||
412 | wacom_le16_to_cpu(&report[i + 3]); | ||
413 | i += 4; | ||
414 | } | ||
415 | } | ||
357 | break; | 416 | break; |
358 | 417 | ||
359 | case HID_USAGE_FINGER: | 418 | case HID_USAGE_FINGER: |
@@ -376,7 +435,7 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi | |||
376 | break; | 435 | break; |
377 | 436 | ||
378 | case HID_COLLECTION: | 437 | case HID_COLLECTION: |
379 | /* reset UsagePage ans Finger */ | 438 | /* reset UsagePage and Finger */ |
380 | finger = usage = 0; | 439 | finger = usage = 0; |
381 | break; | 440 | break; |
382 | } | 441 | } |
@@ -388,43 +447,92 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi | |||
388 | return result; | 447 | return result; |
389 | } | 448 | } |
390 | 449 | ||
391 | static int wacom_query_tablet_data(struct usb_interface *intf) | 450 | static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_features *features) |
392 | { | 451 | { |
393 | unsigned char *rep_data; | 452 | unsigned char *rep_data; |
394 | int limit = 0; | 453 | int limit = 0, report_id = 2; |
395 | int error; | 454 | int error = -ENOMEM; |
396 | 455 | ||
397 | rep_data = kmalloc(2, GFP_KERNEL); | 456 | rep_data = kmalloc(2, GFP_KERNEL); |
398 | if (!rep_data) | 457 | if (!rep_data) |
399 | return -ENOMEM; | 458 | return error; |
400 | 459 | ||
401 | do { | 460 | /* ask to report tablet data if it is 2FGT or not a Tablet PC */ |
402 | rep_data[0] = 2; | 461 | if (features->device_type == BTN_TOOL_TRIPLETAP) { |
403 | rep_data[1] = 2; | 462 | do { |
404 | error = usb_set_report(intf, WAC_HID_FEATURE_REPORT, | 463 | rep_data[0] = 3; |
405 | 2, rep_data, 2); | 464 | rep_data[1] = 4; |
406 | if (error >= 0) | 465 | report_id = 3; |
407 | error = usb_get_report(intf, | 466 | error = usb_set_report(intf, WAC_HID_FEATURE_REPORT, |
408 | WAC_HID_FEATURE_REPORT, 2, | 467 | report_id, rep_data, 2); |
409 | rep_data, 2); | 468 | if (error >= 0) |
410 | } while ((error < 0 || rep_data[1] != 2) && limit++ < 5); | 469 | error = usb_get_report(intf, |
470 | WAC_HID_FEATURE_REPORT, report_id, | ||
471 | rep_data, 3); | ||
472 | } while ((error < 0 || rep_data[1] != 4) && limit++ < 5); | ||
473 | } else if (features->type != TABLETPC && features->type != TABLETPC2FG) { | ||
474 | do { | ||
475 | rep_data[0] = 2; | ||
476 | rep_data[1] = 2; | ||
477 | error = usb_set_report(intf, WAC_HID_FEATURE_REPORT, | ||
478 | report_id, rep_data, 2); | ||
479 | if (error >= 0) | ||
480 | error = usb_get_report(intf, | ||
481 | WAC_HID_FEATURE_REPORT, report_id, | ||
482 | rep_data, 2); | ||
483 | } while ((error < 0 || rep_data[1] != 2) && limit++ < 5); | ||
484 | } | ||
411 | 485 | ||
412 | kfree(rep_data); | 486 | kfree(rep_data); |
413 | 487 | ||
414 | return error < 0 ? error : 0; | 488 | return error < 0 ? error : 0; |
415 | } | 489 | } |
416 | 490 | ||
491 | static int wacom_retrieve_hid_descriptor(struct usb_interface *intf, | ||
492 | struct wacom_features *features) | ||
493 | { | ||
494 | int error = 0; | ||
495 | struct usb_host_interface *interface = intf->cur_altsetting; | ||
496 | struct hid_descriptor *hid_desc; | ||
497 | |||
498 | /* default device to penabled */ | ||
499 | features->device_type = BTN_TOOL_PEN; | ||
500 | |||
501 | /* only Tablet PCs need to retrieve the info */ | ||
502 | if ((features->type != TABLETPC) && (features->type != TABLETPC2FG)) | ||
503 | goto out; | ||
504 | |||
505 | if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) { | ||
506 | if (usb_get_extra_descriptor(&interface->endpoint[0], | ||
507 | HID_DEVICET_REPORT, &hid_desc)) { | ||
508 | printk("wacom: can not retrieve extra class descriptor\n"); | ||
509 | error = 1; | ||
510 | goto out; | ||
511 | } | ||
512 | } | ||
513 | error = wacom_parse_hid(intf, hid_desc, features); | ||
514 | if (error) | ||
515 | goto out; | ||
516 | |||
517 | /* touch device found but size is not defined. use default */ | ||
518 | if (features->device_type == BTN_TOOL_DOUBLETAP && !features->x_max) { | ||
519 | features->x_max = 1023; | ||
520 | features->y_max = 1023; | ||
521 | } | ||
522 | |||
523 | out: | ||
524 | return error; | ||
525 | } | ||
526 | |||
417 | static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) | 527 | static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) |
418 | { | 528 | { |
419 | struct usb_device *dev = interface_to_usbdev(intf); | 529 | struct usb_device *dev = interface_to_usbdev(intf); |
420 | struct usb_host_interface *interface = intf->cur_altsetting; | ||
421 | struct usb_endpoint_descriptor *endpoint; | 530 | struct usb_endpoint_descriptor *endpoint; |
422 | struct wacom *wacom; | 531 | struct wacom *wacom; |
423 | struct wacom_wac *wacom_wac; | 532 | struct wacom_wac *wacom_wac; |
424 | struct wacom_features *features; | 533 | struct wacom_features *features; |
425 | struct input_dev *input_dev; | 534 | struct input_dev *input_dev; |
426 | int error = -ENOMEM; | 535 | int error = -ENOMEM; |
427 | struct hid_descriptor *hid_desc; | ||
428 | 536 | ||
429 | wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); | 537 | wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); |
430 | wacom_wac = kzalloc(sizeof(struct wacom_wac), GFP_KERNEL); | 538 | wacom_wac = kzalloc(sizeof(struct wacom_wac), GFP_KERNEL); |
@@ -432,7 +540,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
432 | if (!wacom || !input_dev || !wacom_wac) | 540 | if (!wacom || !input_dev || !wacom_wac) |
433 | goto fail1; | 541 | goto fail1; |
434 | 542 | ||
435 | wacom_wac->data = usb_buffer_alloc(dev, 10, GFP_KERNEL, &wacom->data_dma); | 543 | wacom_wac->data = usb_buffer_alloc(dev, WACOM_PKGLEN_MAX, GFP_KERNEL, &wacom->data_dma); |
436 | if (!wacom_wac->data) | 544 | if (!wacom_wac->data) |
437 | goto fail1; | 545 | goto fail1; |
438 | 546 | ||
@@ -448,7 +556,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
448 | strlcat(wacom->phys, "/input0", sizeof(wacom->phys)); | 556 | strlcat(wacom->phys, "/input0", sizeof(wacom->phys)); |
449 | 557 | ||
450 | wacom_wac->features = features = get_wacom_feature(id); | 558 | wacom_wac->features = features = get_wacom_feature(id); |
451 | BUG_ON(features->pktlen > 10); | 559 | BUG_ON(features->pktlen > WACOM_PKGLEN_MAX); |
452 | 560 | ||
453 | input_dev->name = wacom_wac->features->name; | 561 | input_dev->name = wacom_wac->features->name; |
454 | wacom->wacom_wac = wacom_wac; | 562 | wacom->wacom_wac = wacom_wac; |
@@ -463,47 +571,24 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
463 | 571 | ||
464 | endpoint = &intf->cur_altsetting->endpoint[0].desc; | 572 | endpoint = &intf->cur_altsetting->endpoint[0].desc; |
465 | 573 | ||
466 | /* Initialize touch_x_max and touch_y_max in case it is not defined */ | 574 | /* Retrieve the physical and logical size for OEM devices */ |
467 | if (wacom_wac->features->type == TABLETPC) { | 575 | error = wacom_retrieve_hid_descriptor(intf, features); |
468 | features->touch_x_max = 1023; | 576 | if (error) |
469 | features->touch_y_max = 1023; | 577 | goto fail2; |
470 | } else { | ||
471 | features->touch_x_max = 0; | ||
472 | features->touch_y_max = 0; | ||
473 | } | ||
474 | |||
475 | /* TabletPC need to retrieve the physical and logical maximum from report descriptor */ | ||
476 | if (wacom_wac->features->type == TABLETPC) { | ||
477 | if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) { | ||
478 | if (usb_get_extra_descriptor(&interface->endpoint[0], | ||
479 | HID_DEVICET_REPORT, &hid_desc)) { | ||
480 | printk("wacom: can not retrive extra class descriptor\n"); | ||
481 | goto fail2; | ||
482 | } | ||
483 | } | ||
484 | error = wacom_parse_hid(intf, hid_desc, wacom_wac); | ||
485 | if (error) | ||
486 | goto fail2; | ||
487 | } | ||
488 | 578 | ||
489 | input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | 579 | input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); |
490 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_PEN) | | 580 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOUCH); |
491 | BIT_MASK(BTN_TOUCH) | BIT_MASK(BTN_STYLUS); | 581 | |
492 | input_set_abs_params(input_dev, ABS_X, 0, features->x_max, 4, 0); | 582 | input_set_abs_params(input_dev, ABS_X, 0, features->x_max, 4, 0); |
493 | input_set_abs_params(input_dev, ABS_Y, 0, features->y_max, 4, 0); | 583 | input_set_abs_params(input_dev, ABS_Y, 0, features->y_max, 4, 0); |
494 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, features->pressure_max, 0, 0); | 584 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, features->pressure_max, 0, 0); |
495 | if (features->type == TABLETPC) { | ||
496 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_DOUBLETAP); | ||
497 | input_set_abs_params(input_dev, ABS_RX, 0, features->touch_x_max, 4, 0); | ||
498 | input_set_abs_params(input_dev, ABS_RY, 0, features->touch_y_max, 4, 0); | ||
499 | } | ||
500 | input_dev->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC); | 585 | input_dev->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC); |
501 | 586 | ||
502 | wacom_init_input_dev(input_dev, wacom_wac); | 587 | wacom_init_input_dev(input_dev, wacom_wac); |
503 | 588 | ||
504 | usb_fill_int_urb(wacom->irq, dev, | 589 | usb_fill_int_urb(wacom->irq, dev, |
505 | usb_rcvintpipe(dev, endpoint->bEndpointAddress), | 590 | usb_rcvintpipe(dev, endpoint->bEndpointAddress), |
506 | wacom_wac->data, wacom_wac->features->pktlen, | 591 | wacom_wac->data, features->pktlen, |
507 | wacom_sys_irq, wacom, endpoint->bInterval); | 592 | wacom_sys_irq, wacom, endpoint->bInterval); |
508 | wacom->irq->transfer_dma = wacom->data_dma; | 593 | wacom->irq->transfer_dma = wacom->data_dma; |
509 | wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 594 | wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
@@ -512,18 +597,14 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
512 | if (error) | 597 | if (error) |
513 | goto fail3; | 598 | goto fail3; |
514 | 599 | ||
515 | /* | 600 | /* Note that if query fails it is not a hard failure */ |
516 | * Ask the tablet to report tablet data if it is not a Tablet PC. | 601 | wacom_query_tablet_data(intf, features); |
517 | * Note that if query fails it is not a hard failure. | ||
518 | */ | ||
519 | if (wacom_wac->features->type != TABLETPC) | ||
520 | wacom_query_tablet_data(intf); | ||
521 | 602 | ||
522 | usb_set_intfdata(intf, wacom); | 603 | usb_set_intfdata(intf, wacom); |
523 | return 0; | 604 | return 0; |
524 | 605 | ||
525 | fail3: usb_free_urb(wacom->irq); | 606 | fail3: usb_free_urb(wacom->irq); |
526 | fail2: usb_buffer_free(dev, 10, wacom_wac->data, wacom->data_dma); | 607 | fail2: usb_buffer_free(dev, WACOM_PKGLEN_MAX, wacom_wac->data, wacom->data_dma); |
527 | fail1: input_free_device(input_dev); | 608 | fail1: input_free_device(input_dev); |
528 | kfree(wacom); | 609 | kfree(wacom); |
529 | kfree(wacom_wac); | 610 | kfree(wacom_wac); |
@@ -539,7 +620,7 @@ static void wacom_disconnect(struct usb_interface *intf) | |||
539 | usb_kill_urb(wacom->irq); | 620 | usb_kill_urb(wacom->irq); |
540 | input_unregister_device(wacom->dev); | 621 | input_unregister_device(wacom->dev); |
541 | usb_free_urb(wacom->irq); | 622 | usb_free_urb(wacom->irq); |
542 | usb_buffer_free(interface_to_usbdev(intf), 10, | 623 | usb_buffer_free(interface_to_usbdev(intf), WACOM_PKGLEN_MAX, |
543 | wacom->wacom_wac->data, wacom->data_dma); | 624 | wacom->wacom_wac->data, wacom->data_dma); |
544 | kfree(wacom->wacom_wac); | 625 | kfree(wacom->wacom_wac); |
545 | kfree(wacom); | 626 | kfree(wacom); |
@@ -559,12 +640,15 @@ static int wacom_suspend(struct usb_interface *intf, pm_message_t message) | |||
559 | static int wacom_resume(struct usb_interface *intf) | 640 | static int wacom_resume(struct usb_interface *intf) |
560 | { | 641 | { |
561 | struct wacom *wacom = usb_get_intfdata(intf); | 642 | struct wacom *wacom = usb_get_intfdata(intf); |
643 | struct wacom_features *features = wacom->wacom_wac->features; | ||
562 | int rv; | 644 | int rv; |
563 | 645 | ||
564 | mutex_lock(&wacom->lock); | 646 | mutex_lock(&wacom->lock); |
565 | if (wacom->open) { | 647 | if (wacom->open) { |
566 | rv = usb_submit_urb(wacom->irq, GFP_NOIO); | 648 | rv = usb_submit_urb(wacom->irq, GFP_NOIO); |
567 | wacom_query_tablet_data(intf); | 649 | /* switch to wacom mode if needed */ |
650 | if (!wacom_retrieve_hid_descriptor(intf, features)) | ||
651 | wacom_query_tablet_data(intf, features); | ||
568 | } else | 652 | } else |
569 | rv = 0; | 653 | rv = 0; |
570 | mutex_unlock(&wacom->lock); | 654 | mutex_unlock(&wacom->lock); |
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index d5fc97d36102..46725894ea62 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
@@ -65,9 +65,8 @@ static int wacom_pl_irq(struct wacom_wac *wacom, void *wcombo) | |||
65 | 65 | ||
66 | prox = data[1] & 0x40; | 66 | prox = data[1] & 0x40; |
67 | 67 | ||
68 | wacom->id[0] = ERASER_DEVICE_ID; | ||
69 | if (prox) { | 68 | if (prox) { |
70 | 69 | wacom->id[0] = ERASER_DEVICE_ID; | |
71 | pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1)); | 70 | pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1)); |
72 | if (wacom->features->pressure_max > 255) | 71 | if (wacom->features->pressure_max > 255) |
73 | pressure = (pressure << 1) | ((data[4] >> 6) & 1); | 72 | pressure = (pressure << 1) | ((data[4] >> 6) & 1); |
@@ -608,54 +607,146 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) | |||
608 | return 1; | 607 | return 1; |
609 | } | 608 | } |
610 | 609 | ||
610 | |||
611 | static void wacom_tpc_finger_in(struct wacom_wac *wacom, void *wcombo, char *data, int idx) | ||
612 | { | ||
613 | wacom_report_abs(wcombo, ABS_X, | ||
614 | (data[2 + idx * 2] & 0xff) | ((data[3 + idx * 2] & 0x7f) << 8)); | ||
615 | wacom_report_abs(wcombo, ABS_Y, | ||
616 | (data[6 + idx * 2] & 0xff) | ((data[7 + idx * 2] & 0x7f) << 8)); | ||
617 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); | ||
618 | wacom_report_key(wcombo, wacom->tool[idx], 1); | ||
619 | if (idx) | ||
620 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); | ||
621 | else | ||
622 | wacom_report_key(wcombo, BTN_TOUCH, 1); | ||
623 | } | ||
624 | |||
625 | static void wacom_tpc_touch_out(struct wacom_wac *wacom, void *wcombo, int idx) | ||
626 | { | ||
627 | wacom_report_abs(wcombo, ABS_X, 0); | ||
628 | wacom_report_abs(wcombo, ABS_Y, 0); | ||
629 | wacom_report_abs(wcombo, ABS_MISC, 0); | ||
630 | wacom_report_key(wcombo, wacom->tool[idx], 0); | ||
631 | if (idx) | ||
632 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); | ||
633 | else | ||
634 | wacom_report_key(wcombo, BTN_TOUCH, 0); | ||
635 | return; | ||
636 | } | ||
637 | |||
638 | static void wacom_tpc_touch_in(struct wacom_wac *wacom, void *wcombo) | ||
639 | { | ||
640 | char *data = wacom->data; | ||
641 | struct urb *urb = ((struct wacom_combo *)wcombo)->urb; | ||
642 | static int firstFinger = 0; | ||
643 | static int secondFinger = 0; | ||
644 | |||
645 | wacom->tool[0] = BTN_TOOL_DOUBLETAP; | ||
646 | wacom->id[0] = TOUCH_DEVICE_ID; | ||
647 | wacom->tool[1] = BTN_TOOL_TRIPLETAP; | ||
648 | |||
649 | if (urb->actual_length != WACOM_PKGLEN_TPC1FG) { | ||
650 | switch (data[0]) { | ||
651 | case 6: | ||
652 | wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2])); | ||
653 | wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4])); | ||
654 | wacom_report_abs(wcombo, ABS_PRESSURE, wacom_le16_to_cpu(&data[6])); | ||
655 | wacom_report_key(wcombo, BTN_TOUCH, wacom_le16_to_cpu(&data[6])); | ||
656 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); | ||
657 | wacom_report_key(wcombo, wacom->tool[0], 1); | ||
658 | break; | ||
659 | case 13: | ||
660 | /* keep this byte to send proper out-prox event */ | ||
661 | wacom->id[1] = data[1] & 0x03; | ||
662 | |||
663 | if (data[1] & 0x01) { | ||
664 | wacom_tpc_finger_in(wacom, wcombo, data, 0); | ||
665 | firstFinger = 1; | ||
666 | } else if (firstFinger) { | ||
667 | wacom_tpc_touch_out(wacom, wcombo, 0); | ||
668 | } | ||
669 | |||
670 | if (data[1] & 0x02) { | ||
671 | /* sync first finger data */ | ||
672 | if (firstFinger) | ||
673 | wacom_input_sync(wcombo); | ||
674 | |||
675 | wacom_tpc_finger_in(wacom, wcombo, data, 1); | ||
676 | secondFinger = 1; | ||
677 | } else if (secondFinger) { | ||
678 | /* sync first finger data */ | ||
679 | if (firstFinger) | ||
680 | wacom_input_sync(wcombo); | ||
681 | |||
682 | wacom_tpc_touch_out(wacom, wcombo, 1); | ||
683 | secondFinger = 0; | ||
684 | } | ||
685 | if (!(data[1] & 0x01)) | ||
686 | firstFinger = 0; | ||
687 | break; | ||
688 | } | ||
689 | } else { | ||
690 | wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[1])); | ||
691 | wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[3])); | ||
692 | wacom_report_key(wcombo, BTN_TOUCH, 1); | ||
693 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); | ||
694 | wacom_report_key(wcombo, wacom->tool[0], 1); | ||
695 | } | ||
696 | return; | ||
697 | } | ||
698 | |||
611 | static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo) | 699 | static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo) |
612 | { | 700 | { |
613 | char *data = wacom->data; | 701 | char *data = wacom->data; |
614 | int prox = 0, pressure; | 702 | int prox = 0, pressure, idx = -1; |
615 | static int stylusInProx, touchInProx = 1, touchOut; | 703 | static int stylusInProx, touchInProx = 1, touchOut; |
616 | struct urb *urb = ((struct wacom_combo *)wcombo)->urb; | 704 | struct urb *urb = ((struct wacom_combo *)wcombo)->urb; |
617 | 705 | ||
618 | dbg("wacom_tpc_irq: received report #%d", data[0]); | 706 | dbg("wacom_tpc_irq: received report #%d", data[0]); |
619 | 707 | ||
620 | if (urb->actual_length == WACOM_PKGLEN_TPC1FG || data[0] == 6) { /* Touch data */ | 708 | if (urb->actual_length == WACOM_PKGLEN_TPC1FG || |
709 | data[0] == 6 || /* single touch */ | ||
710 | data[0] == 13) { /* 2FG touch */ | ||
621 | if (urb->actual_length == WACOM_PKGLEN_TPC1FG) { /* with touch */ | 711 | if (urb->actual_length == WACOM_PKGLEN_TPC1FG) { /* with touch */ |
622 | prox = data[0] & 0x03; | 712 | prox = data[0] & 0x01; |
623 | } else { /* with capacity */ | 713 | } else { /* with capacity */ |
624 | prox = data[1] & 0x03; | 714 | if (data[0] == 6) |
715 | /* single touch */ | ||
716 | prox = data[1] & 0x01; | ||
717 | else | ||
718 | /* 2FG touch data */ | ||
719 | prox = data[1] & 0x03; | ||
625 | } | 720 | } |
626 | 721 | ||
627 | if (!stylusInProx) { /* stylus not in prox */ | 722 | if (!stylusInProx) { /* stylus not in prox */ |
628 | if (prox) { | 723 | if (prox) { |
629 | if (touchInProx) { | 724 | if (touchInProx) { |
630 | wacom->tool[1] = BTN_TOOL_DOUBLETAP; | 725 | wacom_tpc_touch_in(wacom, wcombo); |
631 | wacom->id[0] = TOUCH_DEVICE_ID; | ||
632 | if (urb->actual_length != WACOM_PKGLEN_TPC1FG) { | ||
633 | wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2])); | ||
634 | wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4])); | ||
635 | wacom_report_abs(wcombo, ABS_PRESSURE, wacom_le16_to_cpu(&data[6])); | ||
636 | wacom_report_key(wcombo, BTN_TOUCH, wacom_le16_to_cpu(&data[6])); | ||
637 | } else { | ||
638 | wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[1])); | ||
639 | wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[3])); | ||
640 | wacom_report_key(wcombo, BTN_TOUCH, 1); | ||
641 | } | ||
642 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); | ||
643 | wacom_report_key(wcombo, wacom->tool[1], prox & 0x01); | ||
644 | touchOut = 1; | 726 | touchOut = 1; |
645 | return 1; | 727 | return 1; |
646 | } | 728 | } |
647 | } else { | 729 | } else { |
648 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); | 730 | /* 2FGT out-prox */ |
649 | wacom_report_key(wcombo, wacom->tool[1], prox & 0x01); | 731 | if ((data[0] & 0xff) == 13) { |
650 | wacom_report_key(wcombo, BTN_TOUCH, 0); | 732 | idx = (wacom->id[1] & 0x01) - 1; |
733 | if (idx == 0) { | ||
734 | wacom_tpc_touch_out(wacom, wcombo, idx); | ||
735 | /* sync first finger event */ | ||
736 | if (wacom->id[1] & 0x02) | ||
737 | wacom_input_sync(wcombo); | ||
738 | } | ||
739 | idx = (wacom->id[1] & 0x02) - 1; | ||
740 | if (idx == 1) | ||
741 | wacom_tpc_touch_out(wacom, wcombo, idx); | ||
742 | } else /* one finger touch */ | ||
743 | wacom_tpc_touch_out(wacom, wcombo, 0); | ||
651 | touchOut = 0; | 744 | touchOut = 0; |
652 | touchInProx = 1; | 745 | touchInProx = 1; |
653 | return 1; | 746 | return 1; |
654 | } | 747 | } |
655 | } else if (touchOut || !prox) { /* force touch out-prox */ | 748 | } else if (touchOut || !prox) { /* force touch out-prox */ |
656 | wacom_report_abs(wcombo, ABS_MISC, TOUCH_DEVICE_ID); | 749 | wacom_tpc_touch_out(wacom, wcombo, 0); |
657 | wacom_report_key(wcombo, wacom->tool[1], 0); | ||
658 | wacom_report_key(wcombo, BTN_TOUCH, 0); | ||
659 | touchOut = 0; | 750 | touchOut = 0; |
660 | touchInProx = 1; | 751 | touchInProx = 1; |
661 | return 1; | 752 | return 1; |
@@ -665,38 +756,14 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo) | |||
665 | 756 | ||
666 | touchInProx = 0; | 757 | touchInProx = 0; |
667 | 758 | ||
668 | wacom->id[0] = ERASER_DEVICE_ID; | ||
669 | |||
670 | /* | ||
671 | * if going from out of proximity into proximity select between the eraser | ||
672 | * and the pen based on the state of the stylus2 button, choose eraser if | ||
673 | * pressed else choose pen. if not a proximity change from out to in, send | ||
674 | * an out of proximity for previous tool then a in for new tool. | ||
675 | */ | ||
676 | if (prox) { /* in prox */ | 759 | if (prox) { /* in prox */ |
677 | if (!wacom->tool[0]) { | 760 | if (!wacom->id[0]) { |
678 | /* Going into proximity select tool */ | 761 | /* Going into proximity select tool */ |
679 | wacom->tool[1] = (data[1] & 0x08) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; | 762 | wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; |
680 | if (wacom->tool[1] == BTN_TOOL_PEN) | 763 | if (wacom->tool[0] == BTN_TOOL_PEN) |
681 | wacom->id[0] = STYLUS_DEVICE_ID; | 764 | wacom->id[0] = STYLUS_DEVICE_ID; |
682 | } else if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[1] & 0x08)) { | 765 | else |
683 | /* | 766 | wacom->id[0] = ERASER_DEVICE_ID; |
684 | * was entered with stylus2 pressed | ||
685 | * report out proximity for previous tool | ||
686 | */ | ||
687 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); | ||
688 | wacom_report_key(wcombo, wacom->tool[1], 0); | ||
689 | wacom_input_sync(wcombo); | ||
690 | |||
691 | /* set new tool */ | ||
692 | wacom->tool[1] = BTN_TOOL_PEN; | ||
693 | wacom->id[0] = STYLUS_DEVICE_ID; | ||
694 | return 0; | ||
695 | } | ||
696 | if (wacom->tool[1] != BTN_TOOL_RUBBER) { | ||
697 | /* Unknown tool selected default to pen tool */ | ||
698 | wacom->tool[1] = BTN_TOOL_PEN; | ||
699 | wacom->id[0] = STYLUS_DEVICE_ID; | ||
700 | } | 767 | } |
701 | wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); | 768 | wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); |
702 | wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10); | 769 | wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10); |
@@ -706,17 +773,21 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo) | |||
706 | if (pressure < 0) | 773 | if (pressure < 0) |
707 | pressure = wacom->features->pressure_max + pressure + 1; | 774 | pressure = wacom->features->pressure_max + pressure + 1; |
708 | wacom_report_abs(wcombo, ABS_PRESSURE, pressure); | 775 | wacom_report_abs(wcombo, ABS_PRESSURE, pressure); |
709 | wacom_report_key(wcombo, BTN_TOUCH, pressure); | 776 | wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x05); |
710 | } else { | 777 | } else { |
778 | wacom_report_abs(wcombo, ABS_X, 0); | ||
779 | wacom_report_abs(wcombo, ABS_Y, 0); | ||
711 | wacom_report_abs(wcombo, ABS_PRESSURE, 0); | 780 | wacom_report_abs(wcombo, ABS_PRESSURE, 0); |
712 | wacom_report_key(wcombo, BTN_STYLUS, 0); | 781 | wacom_report_key(wcombo, BTN_STYLUS, 0); |
713 | wacom_report_key(wcombo, BTN_STYLUS2, 0); | 782 | wacom_report_key(wcombo, BTN_STYLUS2, 0); |
714 | wacom_report_key(wcombo, BTN_TOUCH, 0); | 783 | wacom_report_key(wcombo, BTN_TOUCH, 0); |
784 | wacom->id[0] = 0; | ||
785 | /* pen is out so touch can be enabled now */ | ||
786 | touchInProx = 1; | ||
715 | } | 787 | } |
716 | wacom_report_key(wcombo, wacom->tool[1], prox); | 788 | wacom_report_key(wcombo, wacom->tool[0], prox); |
717 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); | 789 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); |
718 | stylusInProx = prox; | 790 | stylusInProx = prox; |
719 | wacom->tool[0] = prox; | ||
720 | return 1; | 791 | return 1; |
721 | } | 792 | } |
722 | return 0; | 793 | return 0; |
@@ -751,6 +822,7 @@ int wacom_wac_irq(struct wacom_wac *wacom_wac, void *wcombo) | |||
751 | return wacom_intuos_irq(wacom_wac, wcombo); | 822 | return wacom_intuos_irq(wacom_wac, wcombo); |
752 | 823 | ||
753 | case TABLETPC: | 824 | case TABLETPC: |
825 | case TABLETPC2FG: | ||
754 | return wacom_tpc_irq(wacom_wac, wcombo); | 826 | return wacom_tpc_irq(wacom_wac, wcombo); |
755 | 827 | ||
756 | default: | 828 | default: |
@@ -791,9 +863,17 @@ void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_w | |||
791 | input_dev_i4s(input_dev, wacom_wac); | 863 | input_dev_i4s(input_dev, wacom_wac); |
792 | input_dev_i(input_dev, wacom_wac); | 864 | input_dev_i(input_dev, wacom_wac); |
793 | break; | 865 | break; |
866 | case TABLETPC2FG: | ||
867 | input_dev_tpc2fg(input_dev, wacom_wac); | ||
868 | /* fall through */ | ||
869 | case TABLETPC: | ||
870 | input_dev_tpc(input_dev, wacom_wac); | ||
871 | if (wacom_wac->features->device_type != BTN_TOOL_PEN) | ||
872 | break; /* no need to process stylus stuff */ | ||
873 | |||
874 | /* fall through */ | ||
794 | case PL: | 875 | case PL: |
795 | case PTU: | 876 | case PTU: |
796 | case TABLETPC: | ||
797 | input_dev_pl(input_dev, wacom_wac); | 877 | input_dev_pl(input_dev, wacom_wac); |
798 | /* fall through */ | 878 | /* fall through */ |
799 | case PENPARTNER: | 879 | case PENPARTNER: |
@@ -863,6 +943,9 @@ static struct wacom_features wacom_features[] = { | |||
863 | { "Wacom ISDv4 90", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }, | 943 | { "Wacom ISDv4 90", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }, |
864 | { "Wacom ISDv4 93", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }, | 944 | { "Wacom ISDv4 93", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }, |
865 | { "Wacom ISDv4 9A", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }, | 945 | { "Wacom ISDv4 9A", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }, |
946 | { "Wacom ISDv4 9F", WACOM_PKGLEN_PENABLED, 26202, 16325, 255, 0, TABLETPC }, | ||
947 | { "Wacom ISDv4 E2", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, 0, TABLETPC2FG }, | ||
948 | { "Wacom ISDv4 E3", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, 0, TABLETPC2FG }, | ||
866 | { "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS }, | 949 | { "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS }, |
867 | { } | 950 | { } |
868 | }; | 951 | }; |
@@ -927,6 +1010,9 @@ static struct usb_device_id wacom_ids[] = { | |||
927 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x90) }, | 1010 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x90) }, |
928 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x93) }, | 1011 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x93) }, |
929 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x9A) }, | 1012 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x9A) }, |
1013 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x9F) }, | ||
1014 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xE2) }, | ||
1015 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xE3) }, | ||
930 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) }, | 1016 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) }, |
931 | { } | 1017 | { } |
932 | }; | 1018 | }; |
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h index 1bfe9a3bae93..39c2516e3d31 100644 --- a/drivers/input/tablet/wacom_wac.h +++ b/drivers/input/tablet/wacom_wac.h | |||
@@ -19,7 +19,9 @@ | |||
19 | #define WACOM_PKGLEN_INTUOS 10 | 19 | #define WACOM_PKGLEN_INTUOS 10 |
20 | #define WACOM_PKGLEN_PENABLED 8 | 20 | #define WACOM_PKGLEN_PENABLED 8 |
21 | #define WACOM_PKGLEN_TPC1FG 5 | 21 | #define WACOM_PKGLEN_TPC1FG 5 |
22 | #define WACOM_PKGLEN_TPC2FG 14 | ||
22 | 23 | ||
24 | /* device IDs */ | ||
23 | #define STYLUS_DEVICE_ID 0x02 | 25 | #define STYLUS_DEVICE_ID 0x02 |
24 | #define TOUCH_DEVICE_ID 0x03 | 26 | #define TOUCH_DEVICE_ID 0x03 |
25 | #define CURSOR_DEVICE_ID 0x06 | 27 | #define CURSOR_DEVICE_ID 0x06 |
@@ -43,6 +45,7 @@ enum { | |||
43 | WACOM_BEE, | 45 | WACOM_BEE, |
44 | WACOM_MO, | 46 | WACOM_MO, |
45 | TABLETPC, | 47 | TABLETPC, |
48 | TABLETPC2FG, | ||
46 | MAX_TYPE | 49 | MAX_TYPE |
47 | }; | 50 | }; |
48 | 51 | ||
@@ -54,8 +57,11 @@ struct wacom_features { | |||
54 | int pressure_max; | 57 | int pressure_max; |
55 | int distance_max; | 58 | int distance_max; |
56 | int type; | 59 | int type; |
57 | int touch_x_max; | 60 | int device_type; |
58 | int touch_y_max; | 61 | int x_phy; |
62 | int y_phy; | ||
63 | unsigned char unit; | ||
64 | unsigned char unitExpo; | ||
59 | }; | 65 | }; |
60 | 66 | ||
61 | struct wacom_wac { | 67 | struct wacom_wac { |