Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+40 −36
Original line number Diff line number Diff line
@@ -108,6 +108,7 @@ struct mt_device {
	int cc_value_index;	/* contact count value index in the field */
	unsigned last_slot_field;	/* the last field of a slot */
	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_index;	/* InputMode HID feature index in the report */
	__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)
	u8 *buf;

	/*
	 * Only fetch the feature report if initial reports are not already
	 * been retrieved. Currently this is only done for Windows 8 touch
	 * devices.
	 * Do not fetch the feature report if the device has been explicitly
	 * marked as non-capable.
	 */
	if (!(hdev->quirks & HID_QUIRK_NO_INIT_REPORTS))
		return;
	if (td->mtclass.name != MT_CLS_WIN_8)
	if (td->initial_quirks & HID_QUIRK_NO_INIT_REPORTS)
		return;

	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)
		}
	}

	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
	 * 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)
	hdev->quirks |= HID_QUIRK_MULTI_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
	 * reports. Fortunately, the Win8 spec says that all touches
	 * 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
	 * 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)
	 */
	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);
	if (ret != 0)
		return ret;
@@ -1206,8 +1207,11 @@ static int mt_resume(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);
	hid_hw_stop(hdev);
	hdev->quirks = td->initial_quirks;
}

/*