diff options
Diffstat (limited to 'drivers/input/tablet/wacom_sys.c')
-rw-r--r-- | drivers/input/tablet/wacom_sys.c | 246 |
1 files changed, 118 insertions, 128 deletions
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index b16ebef5b911..611fc3905d00 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c | |||
@@ -22,23 +22,18 @@ | |||
22 | #define HID_USAGE_PAGE_DIGITIZER 0x0d | 22 | #define HID_USAGE_PAGE_DIGITIZER 0x0d |
23 | #define HID_USAGE_PAGE_DESKTOP 0x01 | 23 | #define HID_USAGE_PAGE_DESKTOP 0x01 |
24 | #define HID_USAGE 0x09 | 24 | #define HID_USAGE 0x09 |
25 | #define HID_USAGE_X 0x30 | 25 | #define HID_USAGE_X ((HID_USAGE_PAGE_DESKTOP << 16) | 0x30) |
26 | #define HID_USAGE_Y 0x31 | 26 | #define HID_USAGE_Y ((HID_USAGE_PAGE_DESKTOP << 16) | 0x31) |
27 | #define HID_USAGE_X_TILT 0x3d | 27 | #define HID_USAGE_PRESSURE ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x30) |
28 | #define HID_USAGE_Y_TILT 0x3e | 28 | #define HID_USAGE_X_TILT ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x3d) |
29 | #define HID_USAGE_FINGER 0x22 | 29 | #define HID_USAGE_Y_TILT ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x3e) |
30 | #define HID_USAGE_STYLUS 0x20 | 30 | #define HID_USAGE_FINGER ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x22) |
31 | #define HID_USAGE_CONTACTMAX 0x55 | 31 | #define HID_USAGE_STYLUS ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x20) |
32 | #define HID_USAGE_CONTACTMAX ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x55) | ||
32 | #define HID_COLLECTION 0xa1 | 33 | #define HID_COLLECTION 0xa1 |
33 | #define HID_COLLECTION_LOGICAL 0x02 | 34 | #define HID_COLLECTION_LOGICAL 0x02 |
34 | #define HID_COLLECTION_END 0xc0 | 35 | #define HID_COLLECTION_END 0xc0 |
35 | 36 | ||
36 | enum { | ||
37 | WCM_UNDEFINED = 0, | ||
38 | WCM_DESKTOP, | ||
39 | WCM_DIGITIZER, | ||
40 | }; | ||
41 | |||
42 | struct hid_descriptor { | 37 | struct hid_descriptor { |
43 | struct usb_descriptor_header header; | 38 | struct usb_descriptor_header header; |
44 | __le16 bcdHID; | 39 | __le16 bcdHID; |
@@ -305,7 +300,7 @@ static int wacom_parse_hid(struct usb_interface *intf, | |||
305 | char limit = 0; | 300 | char limit = 0; |
306 | /* result has to be defined as int for some devices */ | 301 | /* result has to be defined as int for some devices */ |
307 | int result = 0, touch_max = 0; | 302 | int result = 0, touch_max = 0; |
308 | int i = 0, usage = WCM_UNDEFINED, finger = 0, pen = 0; | 303 | int i = 0, page = 0, finger = 0, pen = 0; |
309 | unsigned char *report; | 304 | unsigned char *report; |
310 | 305 | ||
311 | report = kzalloc(hid_desc->wDescriptorLength, GFP_KERNEL); | 306 | report = kzalloc(hid_desc->wDescriptorLength, GFP_KERNEL); |
@@ -332,134 +327,121 @@ static int wacom_parse_hid(struct usb_interface *intf, | |||
332 | 327 | ||
333 | switch (report[i]) { | 328 | switch (report[i]) { |
334 | case HID_USAGE_PAGE: | 329 | case HID_USAGE_PAGE: |
335 | switch (report[i + 1]) { | 330 | page = report[i + 1]; |
336 | case HID_USAGE_PAGE_DIGITIZER: | 331 | i++; |
337 | usage = WCM_DIGITIZER; | ||
338 | i++; | ||
339 | break; | ||
340 | |||
341 | case HID_USAGE_PAGE_DESKTOP: | ||
342 | usage = WCM_DESKTOP; | ||
343 | i++; | ||
344 | break; | ||
345 | } | ||
346 | break; | 332 | break; |
347 | 333 | ||
348 | case HID_USAGE: | 334 | case HID_USAGE: |
349 | switch (report[i + 1]) { | 335 | switch (page << 16 | report[i + 1]) { |
350 | case HID_USAGE_X: | 336 | case HID_USAGE_X: |
351 | if (usage == WCM_DESKTOP) { | 337 | if (finger) { |
352 | if (finger) { | 338 | features->device_type = BTN_TOOL_FINGER; |
353 | features->device_type = BTN_TOOL_FINGER; | 339 | /* touch device at least supports one touch point */ |
354 | /* touch device at least supports one touch point */ | 340 | touch_max = 1; |
355 | touch_max = 1; | 341 | switch (features->type) { |
356 | switch (features->type) { | 342 | case TABLETPC2FG: |
357 | case TABLETPC2FG: | 343 | features->pktlen = WACOM_PKGLEN_TPC2FG; |
358 | features->pktlen = WACOM_PKGLEN_TPC2FG; | 344 | break; |
359 | break; | 345 | |
360 | 346 | case MTSCREEN: | |
361 | case MTSCREEN: | 347 | case WACOM_24HDT: |
362 | case WACOM_24HDT: | 348 | features->pktlen = WACOM_PKGLEN_MTOUCH; |
363 | features->pktlen = WACOM_PKGLEN_MTOUCH; | 349 | break; |
364 | break; | 350 | |
365 | 351 | case MTTPC: | |
366 | case MTTPC: | 352 | features->pktlen = WACOM_PKGLEN_MTTPC; |
367 | features->pktlen = WACOM_PKGLEN_MTTPC; | 353 | break; |
368 | break; | 354 | |
369 | 355 | case BAMBOO_PT: | |
370 | case BAMBOO_PT: | 356 | features->pktlen = WACOM_PKGLEN_BBTOUCH; |
371 | features->pktlen = WACOM_PKGLEN_BBTOUCH; | 357 | break; |
372 | break; | 358 | |
373 | 359 | default: | |
374 | default: | 360 | features->pktlen = WACOM_PKGLEN_GRAPHIRE; |
375 | features->pktlen = WACOM_PKGLEN_GRAPHIRE; | 361 | break; |
376 | break; | 362 | } |
377 | } | 363 | |
378 | 364 | switch (features->type) { | |
379 | switch (features->type) { | 365 | case BAMBOO_PT: |
380 | case BAMBOO_PT: | 366 | features->x_phy = |
381 | features->x_phy = | 367 | get_unaligned_le16(&report[i + 5]); |
382 | get_unaligned_le16(&report[i + 5]); | 368 | features->x_max = |
383 | features->x_max = | 369 | get_unaligned_le16(&report[i + 8]); |
384 | get_unaligned_le16(&report[i + 8]); | 370 | i += 15; |
385 | i += 15; | 371 | break; |
386 | break; | 372 | |
387 | 373 | case WACOM_24HDT: | |
388 | case WACOM_24HDT: | ||
389 | features->x_max = | ||
390 | get_unaligned_le16(&report[i + 3]); | ||
391 | features->x_phy = | ||
392 | get_unaligned_le16(&report[i + 8]); | ||
393 | features->unit = report[i - 1]; | ||
394 | features->unitExpo = report[i - 3]; | ||
395 | i += 12; | ||
396 | break; | ||
397 | |||
398 | default: | ||
399 | features->x_max = | ||
400 | get_unaligned_le16(&report[i + 3]); | ||
401 | features->x_phy = | ||
402 | get_unaligned_le16(&report[i + 6]); | ||
403 | features->unit = report[i + 9]; | ||
404 | features->unitExpo = report[i + 11]; | ||
405 | i += 12; | ||
406 | break; | ||
407 | } | ||
408 | } else if (pen) { | ||
409 | /* penabled only accepts exact bytes of data */ | ||
410 | if (features->type >= TABLETPC) | ||
411 | features->pktlen = WACOM_PKGLEN_GRAPHIRE; | ||
412 | features->device_type = BTN_TOOL_PEN; | ||
413 | features->x_max = | 374 | features->x_max = |
414 | get_unaligned_le16(&report[i + 3]); | 375 | get_unaligned_le16(&report[i + 3]); |
415 | i += 4; | 376 | features->x_phy = |
377 | get_unaligned_le16(&report[i + 8]); | ||
378 | features->unit = report[i - 1]; | ||
379 | features->unitExpo = report[i - 3]; | ||
380 | i += 12; | ||
381 | break; | ||
382 | |||
383 | default: | ||
384 | features->x_max = | ||
385 | get_unaligned_le16(&report[i + 3]); | ||
386 | features->x_phy = | ||
387 | get_unaligned_le16(&report[i + 6]); | ||
388 | features->unit = report[i + 9]; | ||
389 | features->unitExpo = report[i + 11]; | ||
390 | i += 12; | ||
391 | break; | ||
416 | } | 392 | } |
393 | } else if (pen) { | ||
394 | /* penabled only accepts exact bytes of data */ | ||
395 | if (features->type >= TABLETPC) | ||
396 | features->pktlen = WACOM_PKGLEN_GRAPHIRE; | ||
397 | features->device_type = BTN_TOOL_PEN; | ||
398 | features->x_max = | ||
399 | get_unaligned_le16(&report[i + 3]); | ||
400 | i += 4; | ||
417 | } | 401 | } |
418 | break; | 402 | break; |
419 | 403 | ||
420 | case HID_USAGE_Y: | 404 | case HID_USAGE_Y: |
421 | if (usage == WCM_DESKTOP) { | 405 | if (finger) { |
422 | if (finger) { | 406 | switch (features->type) { |
423 | switch (features->type) { | 407 | case TABLETPC2FG: |
424 | case TABLETPC2FG: | 408 | case MTSCREEN: |
425 | case MTSCREEN: | 409 | case MTTPC: |
426 | case MTTPC: | 410 | features->y_max = |
427 | features->y_max = | 411 | get_unaligned_le16(&report[i + 3]); |
428 | get_unaligned_le16(&report[i + 3]); | 412 | features->y_phy = |
429 | features->y_phy = | 413 | get_unaligned_le16(&report[i + 6]); |
430 | get_unaligned_le16(&report[i + 6]); | 414 | i += 7; |
431 | i += 7; | 415 | break; |
432 | break; | 416 | |
433 | 417 | case WACOM_24HDT: | |
434 | case WACOM_24HDT: | 418 | features->y_max = |
435 | features->y_max = | 419 | get_unaligned_le16(&report[i + 3]); |
436 | get_unaligned_le16(&report[i + 3]); | 420 | features->y_phy = |
437 | features->y_phy = | 421 | get_unaligned_le16(&report[i - 2]); |
438 | get_unaligned_le16(&report[i - 2]); | 422 | i += 7; |
439 | i += 7; | 423 | break; |
440 | break; | 424 | |
441 | 425 | case BAMBOO_PT: | |
442 | case BAMBOO_PT: | 426 | features->y_phy = |
443 | features->y_phy = | 427 | get_unaligned_le16(&report[i + 3]); |
444 | get_unaligned_le16(&report[i + 3]); | 428 | features->y_max = |
445 | features->y_max = | 429 | get_unaligned_le16(&report[i + 6]); |
446 | get_unaligned_le16(&report[i + 6]); | 430 | i += 12; |
447 | i += 12; | 431 | break; |
448 | break; | 432 | |
449 | 433 | default: | |
450 | default: | ||
451 | features->y_max = | ||
452 | features->x_max; | ||
453 | features->y_phy = | ||
454 | get_unaligned_le16(&report[i + 3]); | ||
455 | i += 4; | ||
456 | break; | ||
457 | } | ||
458 | } else if (pen) { | ||
459 | features->y_max = | 434 | features->y_max = |
435 | features->x_max; | ||
436 | features->y_phy = | ||
460 | get_unaligned_le16(&report[i + 3]); | 437 | get_unaligned_le16(&report[i + 3]); |
461 | i += 4; | 438 | i += 4; |
439 | break; | ||
462 | } | 440 | } |
441 | } else if (pen) { | ||
442 | features->y_max = | ||
443 | get_unaligned_le16(&report[i + 3]); | ||
444 | i += 4; | ||
463 | } | 445 | } |
464 | break; | 446 | break; |
465 | 447 | ||
@@ -484,12 +466,20 @@ static int wacom_parse_hid(struct usb_interface *intf, | |||
484 | wacom_retrieve_report_data(intf, features); | 466 | wacom_retrieve_report_data(intf, features); |
485 | i++; | 467 | i++; |
486 | break; | 468 | break; |
469 | |||
470 | case HID_USAGE_PRESSURE: | ||
471 | if (pen) { | ||
472 | features->pressure_max = | ||
473 | get_unaligned_le16(&report[i + 3]); | ||
474 | i += 4; | ||
475 | } | ||
476 | break; | ||
487 | } | 477 | } |
488 | break; | 478 | break; |
489 | 479 | ||
490 | case HID_COLLECTION_END: | 480 | case HID_COLLECTION_END: |
491 | /* reset UsagePage and Finger */ | 481 | /* reset UsagePage and Finger */ |
492 | finger = usage = 0; | 482 | finger = page = 0; |
493 | break; | 483 | break; |
494 | 484 | ||
495 | case HID_COLLECTION: | 485 | case HID_COLLECTION: |