Commit 427a5746b4215b154efb85b07781799b79f8958c

Authored by Andrew Duggan
Committed by Greg Kroah-Hartman
1 parent ce9555406a

HID: rmi: Check for additional ACM registers appended to F11 data report

commit 8414947a2018a98cf3adc975dc279f41ba30ab11 upstream.

If a touchpad reports the F11 data40 register then this indicates that the touchpad reports
additional ACM (Accidental Contact Mitigation) data after the F11 data in the HID attention
report. These additional bytes shift the position of the F30 button data causing the driver
to incorrectly report button state when this functionality is present. This patch accounts
for the additional data in the report.

Fixes:
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1398533

Signed-off-by: Andrew Duggan <aduggan@synaptics.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Cc: Joseph Salisbury <joseph.salisbury@canonical.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

Showing 1 changed file with 52 additions and 9 deletions Side-by-side Diff

drivers/hid/hid-rmi.c
... ... @@ -584,11 +584,15 @@
584 584 bool has_query10 = false;
585 585 bool has_query11;
586 586 bool has_query12;
  587 + bool has_query27;
  588 + bool has_query28;
  589 + bool has_query36 = false;
587 590 bool has_physical_props;
588 591 bool has_gestures;
589 592 bool has_rel;
  593 + bool has_data40 = false;
590 594 unsigned x_size, y_size;
591   - u16 query12_offset;
  595 + u16 query_offset;
592 596  
593 597 if (!data->f11.query_base_addr) {
594 598 hid_err(hdev, "No 2D sensor found, giving up.\n");
... ... @@ -604,6 +608,8 @@
604 608 has_query9 = !!(buf[0] & BIT(3));
605 609 has_query11 = !!(buf[0] & BIT(4));
606 610 has_query12 = !!(buf[0] & BIT(5));
  611 + has_query27 = !!(buf[0] & BIT(6));
  612 + has_query28 = !!(buf[0] & BIT(7));
607 613  
608 614 /* query 1 to get the max number of fingers */
609 615 ret = rmi_read(hdev, data->f11.query_base_addr + 1, buf);
610 616  
611 617  
612 618  
613 619  
614 620  
615 621  
... ... @@ -642,27 +648,27 @@
642 648 * +1 for query 5 which is present since absolute events are
643 649 * reported and +1 for query 12.
644 650 */
645   - query12_offset = 6;
  651 + query_offset = 6;
646 652  
647 653 if (has_rel)
648   - ++query12_offset; /* query 6 is present */
  654 + ++query_offset; /* query 6 is present */
649 655  
650 656 if (has_gestures)
651   - query12_offset += 2; /* query 7 and 8 are present */
  657 + query_offset += 2; /* query 7 and 8 are present */
652 658  
653 659 if (has_query9)
654   - ++query12_offset;
  660 + ++query_offset;
655 661  
656 662 if (has_query10)
657   - ++query12_offset;
  663 + ++query_offset;
658 664  
659 665 if (has_query11)
660   - ++query12_offset;
  666 + ++query_offset;
661 667  
662 668 /* query 12 to know if the physical properties are reported */
663 669 if (has_query12) {
664 670 ret = rmi_read(hdev, data->f11.query_base_addr
665   - + query12_offset, buf);
  671 + + query_offset, buf);
666 672 if (ret) {
667 673 hid_err(hdev, "can not get query 12: %d.\n", ret);
668 674 return ret;
669 675  
... ... @@ -670,9 +676,10 @@
670 676 has_physical_props = !!(buf[0] & BIT(5));
671 677  
672 678 if (has_physical_props) {
  679 + query_offset += 1;
673 680 ret = rmi_read_block(hdev,
674 681 data->f11.query_base_addr
675   - + query12_offset + 1, buf, 4);
  682 + + query_offset, buf, 4);
676 683 if (ret) {
677 684 hid_err(hdev, "can not read query 15-18: %d.\n",
678 685 ret);
679 686  
... ... @@ -687,8 +694,44 @@
687 694  
688 695 hid_info(hdev, "%s: size in mm: %d x %d\n",
689 696 __func__, data->x_size_mm, data->y_size_mm);
  697 +
  698 + /*
  699 + * query 15 - 18 contain the size of the sensor
  700 + * and query 19 - 26 contain bezel dimensions
  701 + */
  702 + query_offset += 12;
690 703 }
691 704 }
  705 +
  706 + if (has_query27)
  707 + ++query_offset;
  708 +
  709 + if (has_query28) {
  710 + ret = rmi_read(hdev, data->f11.query_base_addr
  711 + + query_offset, buf);
  712 + if (ret) {
  713 + hid_err(hdev, "can not get query 28: %d.\n", ret);
  714 + return ret;
  715 + }
  716 +
  717 + has_query36 = !!(buf[0] & BIT(6));
  718 + }
  719 +
  720 + if (has_query36) {
  721 + query_offset += 2;
  722 + ret = rmi_read(hdev, data->f11.query_base_addr
  723 + + query_offset, buf);
  724 + if (ret) {
  725 + hid_err(hdev, "can not get query 36: %d.\n", ret);
  726 + return ret;
  727 + }
  728 +
  729 + has_data40 = !!(buf[0] & BIT(5));
  730 + }
  731 +
  732 +
  733 + if (has_data40)
  734 + data->f11.report_size += data->max_fingers * 2;
692 735  
693 736 /*
694 737 * retrieve the ctrl registers