Commit b897f6db authored by Benjamin Tissoires's avatar Benjamin Tissoires Committed by Jiri Kosina

HID: multitouch: do not retrieve all reports for all devices

We already have in place a quirk for Windows 8 devices, but it looks
like the Surface Cover are not conforming to it.
Given that we are only interested in 3 feature reports (the ones that
the Windows driver retrieves), we should be safe to unconditionally apply
the quirk to everybody.

In case there is an issue with a controller, we can always mark it as such
in the transport driver, and hid-multitouch won't try to retrieve the
feature report.
Signed-off-by: default avatarBenjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent 8fe89ef0
...@@ -108,6 +108,7 @@ struct mt_device { ...@@ -108,6 +108,7 @@ struct mt_device {
int cc_value_index; /* contact count value index in the field */ int cc_value_index; /* contact count value index in the field */
unsigned last_slot_field; /* the last field of a slot */ unsigned last_slot_field; /* the last field of a slot */
unsigned mt_report_id; /* the report ID of the multitouch device */ unsigned mt_report_id; /* the report ID of the multitouch device */
unsigned long initial_quirks; /* initial quirks state */
__s16 inputmode; /* InputMode HID feature, -1 if non-existent */ __s16 inputmode; /* InputMode HID feature, -1 if non-existent */
__s16 inputmode_index; /* InputMode HID feature index in the report */ __s16 inputmode_index; /* InputMode HID feature index in the report */
__s16 maxcontact_report_id; /* Maximum Contact Number HID feature, __s16 maxcontact_report_id; /* Maximum Contact Number HID feature,
...@@ -318,13 +319,10 @@ static void mt_get_feature(struct hid_device *hdev, struct hid_report *report) ...@@ -318,13 +319,10 @@ static void mt_get_feature(struct hid_device *hdev, struct hid_report *report)
u8 *buf; u8 *buf;
/* /*
* Only fetch the feature report if initial reports are not already * Do not fetch the feature report if the device has been explicitly
* been retrieved. Currently this is only done for Windows 8 touch * marked as non-capable.
* devices.
*/ */
if (!(hdev->quirks & HID_QUIRK_NO_INIT_REPORTS)) if (td->initial_quirks & HID_QUIRK_NO_INIT_REPORTS)
return;
if (td->mtclass.name != MT_CLS_WIN_8)
return; return;
buf = hid_alloc_report_buf(report, GFP_KERNEL); buf = hid_alloc_report_buf(report, GFP_KERNEL);
...@@ -1085,6 +1083,34 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) ...@@ -1085,6 +1083,34 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
} }
} }
td = devm_kzalloc(&hdev->dev, sizeof(struct mt_device), GFP_KERNEL);
if (!td) {
dev_err(&hdev->dev, "cannot allocate multitouch data\n");
return -ENOMEM;
}
td->mtclass = *mtclass;
td->inputmode = -1;
td->maxcontact_report_id = -1;
td->inputmode_value = MT_INPUTMODE_TOUCHSCREEN;
td->cc_index = -1;
td->mt_report_id = -1;
hid_set_drvdata(hdev, td);
td->fields = devm_kzalloc(&hdev->dev, sizeof(struct mt_fields),
GFP_KERNEL);
if (!td->fields) {
dev_err(&hdev->dev, "cannot allocate multitouch fields data\n");
return -ENOMEM;
}
if (id->vendor == HID_ANY_ID && id->product == HID_ANY_ID)
td->serial_maybe = true;
/*
* Store the initial quirk state
*/
td->initial_quirks = hdev->quirks;
/* This allows the driver to correctly support devices /* This allows the driver to correctly support devices
* that emit events over several HID messages. * that emit events over several HID messages.
*/ */
...@@ -1098,15 +1124,13 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) ...@@ -1098,15 +1124,13 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
hdev->quirks |= HID_QUIRK_MULTI_INPUT; hdev->quirks |= HID_QUIRK_MULTI_INPUT;
hdev->quirks |= HID_QUIRK_NO_EMPTY_INPUT; hdev->quirks |= HID_QUIRK_NO_EMPTY_INPUT;
/*
* Handle special quirks for Windows 8 certified devices.
*/
if (id->group == HID_GROUP_MULTITOUCH_WIN_8)
/* /*
* Some multitouch screens do not like to be polled for input * Some multitouch screens do not like to be polled for input
* reports. Fortunately, the Win8 spec says that all touches * reports. Fortunately, the Win8 spec says that all touches
* should be sent during each report, making the initialization * should be sent during each report, making the initialization
* of input reports unnecessary. * of input reports unnecessary. For Win7 devices, well, let's hope
* they will still be happy (this is only be a problem if a touch
* was already there while probing the device).
* *
* In addition some touchpads do not behave well if we read * In addition some touchpads do not behave well if we read
* all feature reports from them. Instead we prevent * all feature reports from them. Instead we prevent
...@@ -1115,29 +1139,6 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) ...@@ -1115,29 +1139,6 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
*/ */
hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS; hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS;
td = devm_kzalloc(&hdev->dev, sizeof(struct mt_device), GFP_KERNEL);
if (!td) {
dev_err(&hdev->dev, "cannot allocate multitouch data\n");
return -ENOMEM;
}
td->mtclass = *mtclass;
td->inputmode = -1;
td->maxcontact_report_id = -1;
td->inputmode_value = MT_INPUTMODE_TOUCHSCREEN;
td->cc_index = -1;
td->mt_report_id = -1;
hid_set_drvdata(hdev, td);
td->fields = devm_kzalloc(&hdev->dev, sizeof(struct mt_fields),
GFP_KERNEL);
if (!td->fields) {
dev_err(&hdev->dev, "cannot allocate multitouch fields data\n");
return -ENOMEM;
}
if (id->vendor == HID_ANY_ID && id->product == HID_ANY_ID)
td->serial_maybe = true;
ret = hid_parse(hdev); ret = hid_parse(hdev);
if (ret != 0) if (ret != 0)
return ret; return ret;
...@@ -1206,8 +1207,11 @@ static int mt_resume(struct hid_device *hdev) ...@@ -1206,8 +1207,11 @@ static int mt_resume(struct hid_device *hdev)
static void mt_remove(struct hid_device *hdev) static void mt_remove(struct hid_device *hdev)
{ {
struct mt_device *td = hid_get_drvdata(hdev);
sysfs_remove_group(&hdev->dev.kobj, &mt_attribute_group); sysfs_remove_group(&hdev->dev.kobj, &mt_attribute_group);
hid_hw_stop(hdev); hid_hw_stop(hdev);
hdev->quirks = td->initial_quirks;
} }
/* /*
......
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