@@ -1274,54 +1274,48 @@ static int mt_input_configured(struct hid_device *hdev, struct hid_input *hi)
struct mt_device *td = hid_get_drvdata(hdev);
char *name;
const char *suffix = NULL;
- struct hid_field *field = hi->report->field[0];
+ unsigned int application = 0;
+ struct hid_report *report;
int ret;
- if (hi->report->id == td->mt_report_id) {
- ret = mt_touch_input_configured(hdev, hi);
- if (ret)
- return ret;
+ list_for_each_entry(report, &hi->reports, hidinput_list) {
+ application = report->application;
+ if (report->id == td->mt_report_id) {
+ ret = mt_touch_input_configured(hdev, hi);
+ if (ret)
+ return ret;
+ }
+
+ /*
+ * some egalax touchscreens have "application == DG_TOUCHSCREEN"
+ * for the stylus. Check this first, and then rely on
+ * the application field.
+ */
+ if (report->field[0]->physical == HID_DG_STYLUS) {
+ suffix = "Pen";
+ /* force BTN_STYLUS to allow tablet matching in udev */
+ __set_bit(BTN_STYLUS, hi->input->keybit);
+ }
}
- /*
- * some egalax touchscreens have "application == HID_DG_TOUCHSCREEN"
- * for the stylus. Check this first, and then rely on the application
- * field.
- */
- if (hi->report->field[0]->physical == HID_DG_STYLUS) {
- suffix = "Pen";
- /* force BTN_STYLUS to allow tablet matching in udev */
- __set_bit(BTN_STYLUS, hi->input->keybit);
- } else {
- switch (field->application) {
+ if (!suffix) {
+ switch (application) {
case HID_GD_KEYBOARD:
- suffix = "Keyboard";
- break;
case HID_GD_KEYPAD:
- suffix = "Keypad";
- break;
case HID_GD_MOUSE:
- suffix = "Mouse";
- break;
- case HID_DG_STYLUS:
- suffix = "Pen";
- /* force BTN_STYLUS to allow tablet matching in udev */
- __set_bit(BTN_STYLUS, hi->input->keybit);
- break;
- case HID_DG_TOUCHSCREEN:
- /* we do not set suffix = "Touchscreen" */
- break;
case HID_DG_TOUCHPAD:
- suffix = "Touchpad";
- break;
case HID_GD_SYSTEM_CONTROL:
- suffix = "System Control";
- break;
case HID_CP_CONSUMER_CONTROL:
- suffix = "Consumer Control";
- break;
case HID_GD_WIRELESS_RADIO_CTLS:
- suffix = "Wireless Radio Control";
+ /* already handled by hid core */
+ break;
+ case HID_DG_TOUCHSCREEN:
+ /* we do not set suffix = "Touchscreen" */
+ hi->input->name = hdev->name;
+ break;
+ case HID_DG_STYLUS:
+ /* force BTN_STYLUS to allow tablet matching in udev */
+ __set_bit(BTN_STYLUS, hi->input->keybit);
break;
case HID_VD_ASUS_CUSTOM_MEDIA_KEYS:
suffix = "Custom Media Keys";
@@ -1459,10 +1453,10 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
/*
* This allows the driver to handle different input sensors
- * that emits events through different reports on the same HID
+ * that emits events through different applications on the same HID
* device.
*/
- hdev->quirks |= HID_QUIRK_MULTI_INPUT;
+ hdev->quirks |= HID_QUIRK_INPUT_PER_APP;
timer_setup(&td->release_timer, mt_expired_timeout, 0);
We now have HID_QUIRK_INPUT_PER_APPLICATION that splits the devices into several devices. This helps us as we can now rely on hid-input to set the names for us. Also, this helps removing some magical numbers '0' when calling .input_configured(). The only thing to take care of is that the field .report in struct hid_input is now null. We need to iterate over the full list of reports attached to a hid_input. This is required for some Advanced Silicon touchscreen to correctly apply the HID_QUIRK_INPUT_PER_APPLICATION as they have 2 reports associated with the hidinput node. One contains the Input data, the other one contains the Output data. Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> --- drivers/hid/hid-multitouch.c | 72 ++++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 39 deletions(-)