Commit 7106dbcf authored by Andrew Duggan's avatar Andrew Duggan Committed by Luis Henriques

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

commit 8414947a 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/1398533Signed-off-by: default avatarAndrew Duggan <aduggan@synaptics.com>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
Cc: Joseph Salisbury <joseph.salisbury@canonical.com>
Signed-off-by: default avatarLuis Henriques <luis.henriques@canonical.com>
parent 9879d63e
...@@ -584,11 +584,15 @@ static int rmi_populate_f11(struct hid_device *hdev) ...@@ -584,11 +584,15 @@ static int rmi_populate_f11(struct hid_device *hdev)
bool has_query10 = false; bool has_query10 = false;
bool has_query11; bool has_query11;
bool has_query12; bool has_query12;
bool has_query27;
bool has_query28;
bool has_query36 = false;
bool has_physical_props; bool has_physical_props;
bool has_gestures; bool has_gestures;
bool has_rel; bool has_rel;
bool has_data40 = false;
unsigned x_size, y_size; unsigned x_size, y_size;
u16 query12_offset; u16 query_offset;
if (!data->f11.query_base_addr) { if (!data->f11.query_base_addr) {
hid_err(hdev, "No 2D sensor found, giving up.\n"); hid_err(hdev, "No 2D sensor found, giving up.\n");
...@@ -604,6 +608,8 @@ static int rmi_populate_f11(struct hid_device *hdev) ...@@ -604,6 +608,8 @@ static int rmi_populate_f11(struct hid_device *hdev)
has_query9 = !!(buf[0] & BIT(3)); has_query9 = !!(buf[0] & BIT(3));
has_query11 = !!(buf[0] & BIT(4)); has_query11 = !!(buf[0] & BIT(4));
has_query12 = !!(buf[0] & BIT(5)); has_query12 = !!(buf[0] & BIT(5));
has_query27 = !!(buf[0] & BIT(6));
has_query28 = !!(buf[0] & BIT(7));
/* query 1 to get the max number of fingers */ /* query 1 to get the max number of fingers */
ret = rmi_read(hdev, data->f11.query_base_addr + 1, buf); ret = rmi_read(hdev, data->f11.query_base_addr + 1, buf);
...@@ -642,27 +648,27 @@ static int rmi_populate_f11(struct hid_device *hdev) ...@@ -642,27 +648,27 @@ static int rmi_populate_f11(struct hid_device *hdev)
* +1 for query 5 which is present since absolute events are * +1 for query 5 which is present since absolute events are
* reported and +1 for query 12. * reported and +1 for query 12.
*/ */
query12_offset = 6; query_offset = 6;
if (has_rel) if (has_rel)
++query12_offset; /* query 6 is present */ ++query_offset; /* query 6 is present */
if (has_gestures) if (has_gestures)
query12_offset += 2; /* query 7 and 8 are present */ query_offset += 2; /* query 7 and 8 are present */
if (has_query9) if (has_query9)
++query12_offset; ++query_offset;
if (has_query10) if (has_query10)
++query12_offset; ++query_offset;
if (has_query11) if (has_query11)
++query12_offset; ++query_offset;
/* query 12 to know if the physical properties are reported */ /* query 12 to know if the physical properties are reported */
if (has_query12) { if (has_query12) {
ret = rmi_read(hdev, data->f11.query_base_addr ret = rmi_read(hdev, data->f11.query_base_addr
+ query12_offset, buf); + query_offset, buf);
if (ret) { if (ret) {
hid_err(hdev, "can not get query 12: %d.\n", ret); hid_err(hdev, "can not get query 12: %d.\n", ret);
return ret; return ret;
...@@ -670,9 +676,10 @@ static int rmi_populate_f11(struct hid_device *hdev) ...@@ -670,9 +676,10 @@ static int rmi_populate_f11(struct hid_device *hdev)
has_physical_props = !!(buf[0] & BIT(5)); has_physical_props = !!(buf[0] & BIT(5));
if (has_physical_props) { if (has_physical_props) {
query_offset += 1;
ret = rmi_read_block(hdev, ret = rmi_read_block(hdev,
data->f11.query_base_addr data->f11.query_base_addr
+ query12_offset + 1, buf, 4); + query_offset, buf, 4);
if (ret) { if (ret) {
hid_err(hdev, "can not read query 15-18: %d.\n", hid_err(hdev, "can not read query 15-18: %d.\n",
ret); ret);
...@@ -687,9 +694,45 @@ static int rmi_populate_f11(struct hid_device *hdev) ...@@ -687,9 +694,45 @@ static int rmi_populate_f11(struct hid_device *hdev)
hid_info(hdev, "%s: size in mm: %d x %d\n", hid_info(hdev, "%s: size in mm: %d x %d\n",
__func__, data->x_size_mm, data->y_size_mm); __func__, data->x_size_mm, data->y_size_mm);
/*
* query 15 - 18 contain the size of the sensor
* and query 19 - 26 contain bezel dimensions
*/
query_offset += 12;
}
}
if (has_query27)
++query_offset;
if (has_query28) {
ret = rmi_read(hdev, data->f11.query_base_addr
+ query_offset, buf);
if (ret) {
hid_err(hdev, "can not get query 28: %d.\n", ret);
return ret;
} }
has_query36 = !!(buf[0] & BIT(6));
}
if (has_query36) {
query_offset += 2;
ret = rmi_read(hdev, data->f11.query_base_addr
+ query_offset, buf);
if (ret) {
hid_err(hdev, "can not get query 36: %d.\n", ret);
return ret;
}
has_data40 = !!(buf[0] & BIT(5));
} }
if (has_data40)
data->f11.report_size += data->max_fingers * 2;
/* /*
* retrieve the ctrl registers * retrieve the ctrl registers
* the ctrl register has a size of 20 but a fw bug split it into 16 + 4, * the ctrl register has a size of 20 but a fw bug split it into 16 + 4,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment