diff options
author | Jason Gerecke <killertofu@gmail.com> | 2015-11-30 20:13:47 -0500 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2015-12-02 15:44:50 -0500 |
commit | c7f0522a1ad1c2a1a23872c96955d60890f453e4 (patch) | |
tree | 4a54db11b0f9cf5d54a24a3d3f354fd2ab040777 | |
parent | fb013a01d48d71a68cd14ea30181754f93acae21 (diff) |
HID: wacom: Slim down wacom_intuos_pad processing
Seperate the function into two halves: first gather data from the packet,
next report all gathered data. The input subsystem should automatically
mute any events that aren't actually declared for the tablet at hand.
Signed-off-by: Jason Gerecke <jason.gerecke@wacom.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r-- | drivers/hid/wacom_wac.c | 277 |
1 files changed, 86 insertions, 191 deletions
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index c611ea5b83c8..ec1e13e55ae9 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c | |||
@@ -34,6 +34,9 @@ | |||
34 | */ | 34 | */ |
35 | #define WACOM_CONTACT_AREA_SCALE 2607 | 35 | #define WACOM_CONTACT_AREA_SCALE 2607 |
36 | 36 | ||
37 | static void wacom_report_numbered_buttons(struct input_dev *input_dev, | ||
38 | int button_count, int mask); | ||
39 | |||
37 | /* | 40 | /* |
38 | * Percent of battery capacity for Graphire. | 41 | * Percent of battery capacity for Graphire. |
39 | * 8th value means AC online and show 100% capacity. | 42 | * 8th value means AC online and show 100% capacity. |
@@ -451,6 +454,12 @@ static int wacom_intuos_pad(struct wacom_wac *wacom) | |||
451 | struct wacom_features *features = &wacom->features; | 454 | struct wacom_features *features = &wacom->features; |
452 | unsigned char *data = wacom->data; | 455 | unsigned char *data = wacom->data; |
453 | struct input_dev *input = wacom->pad_input; | 456 | struct input_dev *input = wacom->pad_input; |
457 | int i; | ||
458 | int buttons = 0, nbuttons = features->numbered_buttons; | ||
459 | int keys = 0, nkeys = 0; | ||
460 | int ring1 = 0, ring2 = 0; | ||
461 | int strip1 = 0, strip2 = 0; | ||
462 | bool prox = false; | ||
454 | 463 | ||
455 | /* pad packets. Works as a second tool and is always in prox */ | 464 | /* pad packets. Works as a second tool and is always in prox */ |
456 | if (!(data[0] == WACOM_REPORT_INTUOSPAD || data[0] == WACOM_REPORT_INTUOS5PAD || | 465 | if (!(data[0] == WACOM_REPORT_INTUOSPAD || data[0] == WACOM_REPORT_INTUOS5PAD || |
@@ -458,72 +467,16 @@ static int wacom_intuos_pad(struct wacom_wac *wacom) | |||
458 | return 0; | 467 | return 0; |
459 | 468 | ||
460 | if (features->type >= INTUOS4S && features->type <= INTUOS4L) { | 469 | if (features->type >= INTUOS4S && features->type <= INTUOS4L) { |
461 | input_report_key(input, BTN_0, (data[2] & 0x01)); | 470 | buttons = (data[3] << 1) | (data[2] & 0x01); |
462 | input_report_key(input, BTN_1, (data[3] & 0x01)); | 471 | ring1 = data[1]; |
463 | input_report_key(input, BTN_2, (data[3] & 0x02)); | ||
464 | input_report_key(input, BTN_3, (data[3] & 0x04)); | ||
465 | input_report_key(input, BTN_4, (data[3] & 0x08)); | ||
466 | input_report_key(input, BTN_5, (data[3] & 0x10)); | ||
467 | input_report_key(input, BTN_6, (data[3] & 0x20)); | ||
468 | if (data[1] & 0x80) { | ||
469 | input_report_abs(input, ABS_WHEEL, (data[1] & 0x7f)); | ||
470 | } else { | ||
471 | /* Out of proximity, clear wheel value. */ | ||
472 | input_report_abs(input, ABS_WHEEL, 0); | ||
473 | } | ||
474 | if (features->type != INTUOS4S) { | ||
475 | input_report_key(input, BTN_7, (data[3] & 0x40)); | ||
476 | input_report_key(input, BTN_8, (data[3] & 0x80)); | ||
477 | } | ||
478 | if (data[1] | (data[2] & 0x01) | data[3]) { | ||
479 | input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); | ||
480 | } else { | ||
481 | input_report_abs(input, ABS_MISC, 0); | ||
482 | } | ||
483 | } else if (features->type == DTK) { | 472 | } else if (features->type == DTK) { |
484 | input_report_key(input, BTN_0, (data[6] & 0x01)); | 473 | buttons = data[6]; |
485 | input_report_key(input, BTN_1, (data[6] & 0x02)); | ||
486 | input_report_key(input, BTN_2, (data[6] & 0x04)); | ||
487 | input_report_key(input, BTN_3, (data[6] & 0x08)); | ||
488 | input_report_key(input, BTN_4, (data[6] & 0x10)); | ||
489 | input_report_key(input, BTN_5, (data[6] & 0x20)); | ||
490 | if (data[6] & 0x3f) { | ||
491 | input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); | ||
492 | } else { | ||
493 | input_report_abs(input, ABS_MISC, 0); | ||
494 | } | ||
495 | } else if (features->type == WACOM_13HD) { | 474 | } else if (features->type == WACOM_13HD) { |
496 | input_report_key(input, BTN_0, (data[3] & 0x01)); | 475 | buttons = (data[4] << 1) | (data[3] & 0x01); |
497 | input_report_key(input, BTN_1, (data[4] & 0x01)); | ||
498 | input_report_key(input, BTN_2, (data[4] & 0x02)); | ||
499 | input_report_key(input, BTN_3, (data[4] & 0x04)); | ||
500 | input_report_key(input, BTN_4, (data[4] & 0x08)); | ||
501 | input_report_key(input, BTN_5, (data[4] & 0x10)); | ||
502 | input_report_key(input, BTN_6, (data[4] & 0x20)); | ||
503 | input_report_key(input, BTN_7, (data[4] & 0x40)); | ||
504 | input_report_key(input, BTN_8, (data[4] & 0x80)); | ||
505 | if ((data[3] & 0x01) | data[4]) { | ||
506 | input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); | ||
507 | } else { | ||
508 | input_report_abs(input, ABS_MISC, 0); | ||
509 | } | ||
510 | } else if (features->type == WACOM_24HD) { | 476 | } else if (features->type == WACOM_24HD) { |
511 | input_report_key(input, BTN_0, (data[6] & 0x01)); | 477 | buttons = (data[8] << 8) | data[6]; |
512 | input_report_key(input, BTN_1, (data[6] & 0x02)); | 478 | ring1 = data[1]; |
513 | input_report_key(input, BTN_2, (data[6] & 0x04)); | 479 | ring2 = data[2]; |
514 | input_report_key(input, BTN_3, (data[6] & 0x08)); | ||
515 | input_report_key(input, BTN_4, (data[6] & 0x10)); | ||
516 | input_report_key(input, BTN_5, (data[6] & 0x20)); | ||
517 | input_report_key(input, BTN_6, (data[6] & 0x40)); | ||
518 | input_report_key(input, BTN_7, (data[6] & 0x80)); | ||
519 | input_report_key(input, BTN_8, (data[8] & 0x01)); | ||
520 | input_report_key(input, BTN_9, (data[8] & 0x02)); | ||
521 | input_report_key(input, BTN_A, (data[8] & 0x04)); | ||
522 | input_report_key(input, BTN_B, (data[8] & 0x08)); | ||
523 | input_report_key(input, BTN_C, (data[8] & 0x10)); | ||
524 | input_report_key(input, BTN_X, (data[8] & 0x20)); | ||
525 | input_report_key(input, BTN_Y, (data[8] & 0x40)); | ||
526 | input_report_key(input, BTN_Z, (data[8] & 0x80)); | ||
527 | 480 | ||
528 | /* | 481 | /* |
529 | * Three "buttons" are available on the 24HD which are | 482 | * Three "buttons" are available on the 24HD which are |
@@ -532,160 +485,89 @@ static int wacom_intuos_pad(struct wacom_wac *wacom) | |||
532 | * The raw touchstrip bits are stored at: | 485 | * The raw touchstrip bits are stored at: |
533 | * ((data[3] & 0x1f) << 8) | data[4]) | 486 | * ((data[3] & 0x1f) << 8) | data[4]) |
534 | */ | 487 | */ |
535 | input_report_key(input, KEY_PROG1, data[4] & 0x07); | 488 | nkeys = 3; |
536 | input_report_key(input, KEY_PROG2, data[4] & 0xE0); | 489 | keys = ((data[3] & 0x1C) ? 1<<2 : 0) | |
537 | input_report_key(input, KEY_PROG3, data[3] & 0x1C); | 490 | ((data[4] & 0xE0) ? 1<<1 : 0) | |
538 | 491 | ((data[4] & 0x07) ? 1<<0 : 0); | |
539 | if (data[1] & 0x80) { | ||
540 | input_report_abs(input, ABS_WHEEL, (data[1] & 0x7f)); | ||
541 | } else { | ||
542 | /* Out of proximity, clear wheel value. */ | ||
543 | input_report_abs(input, ABS_WHEEL, 0); | ||
544 | } | ||
545 | |||
546 | if (data[2] & 0x80) { | ||
547 | input_report_abs(input, ABS_THROTTLE, (data[2] & 0x7f)); | ||
548 | } else { | ||
549 | /* Out of proximity, clear second wheel value. */ | ||
550 | input_report_abs(input, ABS_THROTTLE, 0); | ||
551 | } | ||
552 | |||
553 | if (data[1] | data[2] | (data[3] & 0x1f) | data[4] | data[6] | data[8]) { | ||
554 | input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); | ||
555 | } else { | ||
556 | input_report_abs(input, ABS_MISC, 0); | ||
557 | } | ||
558 | } else if (features->type == WACOM_27QHD) { | 492 | } else if (features->type == WACOM_27QHD) { |
559 | input_report_key(input, KEY_PROG1, data[2] & 0x01); | 493 | nkeys = 3; |
560 | input_report_key(input, KEY_PROG2, data[2] & 0x02); | 494 | keys = data[2] & 0x07; |
561 | input_report_key(input, KEY_PROG3, data[2] & 0x04); | ||
562 | 495 | ||
563 | input_report_abs(input, ABS_X, be16_to_cpup((__be16 *)&data[4])); | 496 | input_report_abs(input, ABS_X, be16_to_cpup((__be16 *)&data[4])); |
564 | input_report_abs(input, ABS_Y, be16_to_cpup((__be16 *)&data[6])); | 497 | input_report_abs(input, ABS_Y, be16_to_cpup((__be16 *)&data[6])); |
565 | input_report_abs(input, ABS_Z, be16_to_cpup((__be16 *)&data[8])); | 498 | input_report_abs(input, ABS_Z, be16_to_cpup((__be16 *)&data[8])); |
566 | if ((data[2] & 0x07) | data[4] | data[5] | data[6] | data[7] | data[8] | data[9]) { | ||
567 | input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); | ||
568 | } else { | ||
569 | input_report_abs(input, ABS_MISC, 0); | ||
570 | } | ||
571 | } else if (features->type == CINTIQ_HYBRID) { | 499 | } else if (features->type == CINTIQ_HYBRID) { |
572 | /* | 500 | /* |
573 | * Do not send hardware buttons under Android. They | 501 | * Do not send hardware buttons under Android. They |
574 | * are already sent to the system through GPIO (and | 502 | * are already sent to the system through GPIO (and |
575 | * have different meaning). | 503 | * have different meaning). |
504 | * | ||
505 | * d-pad right -> data[4] & 0x10 | ||
506 | * d-pad up -> data[4] & 0x20 | ||
507 | * d-pad left -> data[4] & 0x40 | ||
508 | * d-pad down -> data[4] & 0x80 | ||
509 | * d-pad center -> data[3] & 0x01 | ||
576 | */ | 510 | */ |
577 | input_report_key(input, BTN_1, (data[4] & 0x01)); | 511 | buttons = (data[4] << 1) | (data[3] & 0x01); |
578 | input_report_key(input, BTN_2, (data[4] & 0x02)); | ||
579 | input_report_key(input, BTN_3, (data[4] & 0x04)); | ||
580 | input_report_key(input, BTN_4, (data[4] & 0x08)); | ||
581 | |||
582 | input_report_key(input, BTN_5, (data[4] & 0x10)); /* Right */ | ||
583 | input_report_key(input, BTN_6, (data[4] & 0x20)); /* Up */ | ||
584 | input_report_key(input, BTN_7, (data[4] & 0x40)); /* Left */ | ||
585 | input_report_key(input, BTN_8, (data[4] & 0x80)); /* Down */ | ||
586 | input_report_key(input, BTN_0, (data[3] & 0x01)); /* Center */ | ||
587 | |||
588 | if (data[4] | (data[3] & 0x01)) { | ||
589 | input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); | ||
590 | } else { | ||
591 | input_report_abs(input, ABS_MISC, 0); | ||
592 | } | ||
593 | |||
594 | } else if (features->type == CINTIQ_COMPANION_2) { | 512 | } else if (features->type == CINTIQ_COMPANION_2) { |
595 | input_report_key(input, BTN_1, (data[1] & 0x02)); | 513 | /* d-pad right -> data[4] & 0x10 |
596 | input_report_key(input, BTN_2, (data[2] & 0x01)); | 514 | * d-pad up -> data[4] & 0x20 |
597 | input_report_key(input, BTN_3, (data[2] & 0x02)); | 515 | * d-pad left -> data[4] & 0x40 |
598 | input_report_key(input, BTN_4, (data[2] & 0x04)); | 516 | * d-pad down -> data[4] & 0x80 |
599 | input_report_key(input, BTN_5, (data[2] & 0x08)); | 517 | * d-pad center -> data[3] & 0x01 |
600 | input_report_key(input, BTN_6, (data[1] & 0x04)); | 518 | */ |
601 | 519 | buttons = ((data[2] & 0xF0) << 7) | | |
602 | input_report_key(input, BTN_7, (data[2] & 0x10)); /* Right */ | 520 | ((data[1] & 0x04) << 6) | |
603 | input_report_key(input, BTN_8, (data[2] & 0x20)); /* Up */ | 521 | ((data[2] & 0x0F) << 2) | |
604 | input_report_key(input, BTN_9, (data[2] & 0x40)); /* Left */ | 522 | (data[1] & 0x03); |
605 | input_report_key(input, BTN_A, (data[2] & 0x80)); /* Down */ | ||
606 | input_report_key(input, BTN_0, (data[1] & 0x01)); /* Center */ | ||
607 | |||
608 | if (data[2] | (data[1] & 0x07)) { | ||
609 | input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); | ||
610 | } else { | ||
611 | input_report_abs(input, ABS_MISC, 0); | ||
612 | } | ||
613 | |||
614 | } else if (features->type >= INTUOS5S && features->type <= INTUOSPL) { | 523 | } else if (features->type >= INTUOS5S && features->type <= INTUOSPL) { |
615 | int i; | ||
616 | |||
617 | /* Touch ring mode switch has no capacitive sensor */ | ||
618 | input_report_key(input, BTN_0, (data[3] & 0x01)); | ||
619 | |||
620 | /* | 524 | /* |
621 | * ExpressKeys on Intuos5/Intuos Pro have a capacitive sensor in | 525 | * ExpressKeys on Intuos5/Intuos Pro have a capacitive sensor in |
622 | * addition to the mechanical switch. Switch data is | 526 | * addition to the mechanical switch. Switch data is |
623 | * stored in data[4], capacitive data in data[5]. | 527 | * stored in data[4], capacitive data in data[5]. |
528 | * | ||
529 | * Touch ring mode switch (data[3]) has no capacitive sensor | ||
624 | */ | 530 | */ |
625 | for (i = 0; i < 8; i++) | 531 | buttons = (data[4] << 1) | (data[3] & 0x01); |
626 | input_report_key(input, BTN_1 + i, data[4] & (1 << i)); | 532 | ring1 = data[2]; |
627 | |||
628 | if (data[2] & 0x80) { | ||
629 | input_report_abs(input, ABS_WHEEL, (data[2] & 0x7f)); | ||
630 | } else { | ||
631 | /* Out of proximity, clear wheel value. */ | ||
632 | input_report_abs(input, ABS_WHEEL, 0); | ||
633 | } | ||
634 | |||
635 | if (data[2] | (data[3] & 0x01) | data[4] | data[5]) { | ||
636 | input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); | ||
637 | } else { | ||
638 | input_report_abs(input, ABS_MISC, 0); | ||
639 | } | ||
640 | } else { | 533 | } else { |
641 | if (features->type == WACOM_21UX2 || features->type == WACOM_22HD) { | 534 | if (features->type == WACOM_21UX2 || features->type == WACOM_22HD) { |
642 | input_report_key(input, BTN_0, (data[5] & 0x01)); | 535 | buttons = (data[8] << 10) | ((data[7] & 0x01) << 9) | |
643 | input_report_key(input, BTN_1, (data[6] & 0x01)); | 536 | (data[6] << 1) | (data[5] & 0x01); |
644 | input_report_key(input, BTN_2, (data[6] & 0x02)); | ||
645 | input_report_key(input, BTN_3, (data[6] & 0x04)); | ||
646 | input_report_key(input, BTN_4, (data[6] & 0x08)); | ||
647 | input_report_key(input, BTN_5, (data[6] & 0x10)); | ||
648 | input_report_key(input, BTN_6, (data[6] & 0x20)); | ||
649 | input_report_key(input, BTN_7, (data[6] & 0x40)); | ||
650 | input_report_key(input, BTN_8, (data[6] & 0x80)); | ||
651 | input_report_key(input, BTN_9, (data[7] & 0x01)); | ||
652 | input_report_key(input, BTN_A, (data[8] & 0x01)); | ||
653 | input_report_key(input, BTN_B, (data[8] & 0x02)); | ||
654 | input_report_key(input, BTN_C, (data[8] & 0x04)); | ||
655 | input_report_key(input, BTN_X, (data[8] & 0x08)); | ||
656 | input_report_key(input, BTN_Y, (data[8] & 0x10)); | ||
657 | input_report_key(input, BTN_Z, (data[8] & 0x20)); | ||
658 | input_report_key(input, BTN_BASE, (data[8] & 0x40)); | ||
659 | input_report_key(input, BTN_BASE2, (data[8] & 0x80)); | ||
660 | 537 | ||
661 | if (features->type == WACOM_22HD) { | 538 | if (features->type == WACOM_22HD) { |
662 | input_report_key(input, KEY_PROG1, data[9] & 0x01); | 539 | nkeys = 3; |
663 | input_report_key(input, KEY_PROG2, data[9] & 0x02); | 540 | keys = data[9] & 0x07; |
664 | input_report_key(input, KEY_PROG3, data[9] & 0x04); | ||
665 | } | 541 | } |
666 | } else { | 542 | } else { |
667 | input_report_key(input, BTN_0, (data[5] & 0x01)); | 543 | buttons = ((data[6] & 0x10) << 10) | |
668 | input_report_key(input, BTN_1, (data[5] & 0x02)); | 544 | ((data[5] & 0x10) << 9) | |
669 | input_report_key(input, BTN_2, (data[5] & 0x04)); | 545 | ((data[6] & 0x0F) << 4) | |
670 | input_report_key(input, BTN_3, (data[5] & 0x08)); | 546 | (data[5] & 0x0F); |
671 | input_report_key(input, BTN_4, (data[6] & 0x01)); | ||
672 | input_report_key(input, BTN_5, (data[6] & 0x02)); | ||
673 | input_report_key(input, BTN_6, (data[6] & 0x04)); | ||
674 | input_report_key(input, BTN_7, (data[6] & 0x08)); | ||
675 | input_report_key(input, BTN_8, (data[5] & 0x10)); | ||
676 | input_report_key(input, BTN_9, (data[6] & 0x10)); | ||
677 | } | ||
678 | input_report_abs(input, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]); | ||
679 | input_report_abs(input, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]); | ||
680 | |||
681 | if ((data[5] & 0x1f) | data[6] | (data[1] & 0x1f) | | ||
682 | data[2] | (data[3] & 0x1f) | data[4] | data[8] | | ||
683 | (data[7] & 0x01)) { | ||
684 | input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); | ||
685 | } else { | ||
686 | input_report_abs(input, ABS_MISC, 0); | ||
687 | } | 547 | } |
548 | strip1 = (data[1] << 8) || data[2]; | ||
549 | strip2 = (data[3] << 8) || data[4]; | ||
688 | } | 550 | } |
551 | |||
552 | prox = (buttons & ~(~0 << nbuttons)) || (keys & ~(~0 << nkeys)) || | ||
553 | (ring1 & 0x80) || (ring2 & 0x80) || strip1 || strip2; | ||
554 | |||
555 | wacom_report_numbered_buttons(input, nbuttons, buttons); | ||
556 | |||
557 | for (i = 0; i < nkeys; i++) | ||
558 | input_report_key(input, KEY_PROG1 + i, keys & (1 << i)); | ||
559 | |||
560 | input_report_abs(input, ABS_RX, strip1); | ||
561 | input_report_abs(input, ABS_RX, strip2); | ||
562 | |||
563 | input_report_abs(input, ABS_WHEEL, ring1 & 0x7f ? ring1 : 0); | ||
564 | input_report_abs(input, ABS_THROTTLE, ring2 & 0x07 ? ring2 : 0); | ||
565 | |||
566 | input_report_key(input, wacom->tool[1], prox ? 1 : 0); | ||
567 | input_report_abs(input, ABS_MISC, prox ? PAD_DEVICE_ID : 0); | ||
568 | |||
569 | input_event(input, EV_MSC, MSC_SERIAL, 0xffffffff); | ||
570 | |||
689 | return 1; | 571 | return 1; |
690 | } | 572 | } |
691 | 573 | ||
@@ -2818,6 +2700,19 @@ static void wacom_setup_numbered_buttons(struct input_dev *input_dev, | |||
2818 | __set_bit(BTN_BASE + (i-16), input_dev->keybit); | 2700 | __set_bit(BTN_BASE + (i-16), input_dev->keybit); |
2819 | } | 2701 | } |
2820 | 2702 | ||
2703 | static void wacom_report_numbered_buttons(struct input_dev *input_dev, | ||
2704 | int button_count, int mask) | ||
2705 | { | ||
2706 | int i; | ||
2707 | |||
2708 | for (i = 0; i < button_count && i < 10; i++) | ||
2709 | input_report_key(input_dev, BTN_0 + i, mask & (1 << i)); | ||
2710 | for (i = 10; i < button_count && i < 16; i++) | ||
2711 | input_report_key(input_dev, BTN_A + (i-10), mask & (1 << i)); | ||
2712 | for (i = 16; i < button_count && i < 18; i++) | ||
2713 | input_report_key(input_dev, BTN_BASE + (i-16), mask & (1 << i)); | ||
2714 | } | ||
2715 | |||
2821 | int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, | 2716 | int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, |
2822 | struct wacom_wac *wacom_wac) | 2717 | struct wacom_wac *wacom_wac) |
2823 | { | 2718 | { |