Skip to content

Commit 8414947

Browse files
aduggan-synaJiri Kosina
authored andcommitted
HID: rmi: Check for additional ACM registers appended to F11 data report
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 <[email protected]> Signed-off-by: Jiri Kosina <[email protected]>
1 parent 6b07974 commit 8414947

File tree

1 file changed

+52
-9
lines changed

1 file changed

+52
-9
lines changed

drivers/hid/hid-rmi.c

Lines changed: 52 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -584,11 +584,15 @@ static int rmi_populate_f11(struct hid_device *hdev)
584584
bool has_query10 = false;
585585
bool has_query11;
586586
bool has_query12;
587+
bool has_query27;
588+
bool has_query28;
589+
bool has_query36 = false;
587590
bool has_physical_props;
588591
bool has_gestures;
589592
bool has_rel;
593+
bool has_data40 = false;
590594
unsigned x_size, y_size;
591-
u16 query12_offset;
595+
u16 query_offset;
592596

593597
if (!data->f11.query_base_addr) {
594598
hid_err(hdev, "No 2D sensor found, giving up.\n");
@@ -604,6 +608,8 @@ static int rmi_populate_f11(struct hid_device *hdev)
604608
has_query9 = !!(buf[0] & BIT(3));
605609
has_query11 = !!(buf[0] & BIT(4));
606610
has_query12 = !!(buf[0] & BIT(5));
611+
has_query27 = !!(buf[0] & BIT(6));
612+
has_query28 = !!(buf[0] & BIT(7));
607613

608614
/* query 1 to get the max number of fingers */
609615
ret = rmi_read(hdev, data->f11.query_base_addr + 1, buf);
@@ -642,37 +648,38 @@ static int rmi_populate_f11(struct hid_device *hdev)
642648
* +1 for query 5 which is present since absolute events are
643649
* reported and +1 for query 12.
644650
*/
645-
query12_offset = 6;
651+
query_offset = 6;
646652

647653
if (has_rel)
648-
++query12_offset; /* query 6 is present */
654+
++query_offset; /* query 6 is present */
649655

650656
if (has_gestures)
651-
query12_offset += 2; /* query 7 and 8 are present */
657+
query_offset += 2; /* query 7 and 8 are present */
652658

653659
if (has_query9)
654-
++query12_offset;
660+
++query_offset;
655661

656662
if (has_query10)
657-
++query12_offset;
663+
++query_offset;
658664

659665
if (has_query11)
660-
++query12_offset;
666+
++query_offset;
661667

662668
/* query 12 to know if the physical properties are reported */
663669
if (has_query12) {
664670
ret = rmi_read(hdev, data->f11.query_base_addr
665-
+ query12_offset, buf);
671+
+ query_offset, buf);
666672
if (ret) {
667673
hid_err(hdev, "can not get query 12: %d.\n", ret);
668674
return ret;
669675
}
670676
has_physical_props = !!(buf[0] & BIT(5));
671677

672678
if (has_physical_props) {
679+
query_offset += 1;
673680
ret = rmi_read_block(hdev,
674681
data->f11.query_base_addr
675-
+ query12_offset + 1, buf, 4);
682+
+ query_offset, buf, 4);
676683
if (ret) {
677684
hid_err(hdev, "can not read query 15-18: %d.\n",
678685
ret);
@@ -687,9 +694,45 @@ static int rmi_populate_f11(struct hid_device *hdev)
687694

688695
hid_info(hdev, "%s: size in mm: %d x %d\n",
689696
__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;
703+
}
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;
690727
}
728+
729+
has_data40 = !!(buf[0] & BIT(5));
691730
}
692731

732+
733+
if (has_data40)
734+
data->f11.report_size += data->max_fingers * 2;
735+
693736
/*
694737
* retrieve the ctrl registers
695738
* the ctrl register has a size of 20 but a fw bug split it into 16 + 4,

0 commit comments

Comments
 (0)