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

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

HID: multitouch: implement precision touchpad latency and switches

The Win 8.1 precision touchpad spec introduce new modes for touchpads
that can come in handy[1].

Implement the settings of these modes, so we are not taken off-guard if
a firmware decides to enforce them.

[1] https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/windows-precision-touchpad-required-hid-top-level-collections



Signed-off-by: default avatarBenjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent 7f81c8db
Loading
Loading
Loading
Loading
+29 −5
Original line number Diff line number Diff line
@@ -81,6 +81,11 @@ MODULE_LICENSE("GPL");

#define MT_BUTTONTYPE_CLICKPAD		0

enum latency_mode {
	HID_LATENCY_NORMAL = 0,
	HID_LATENCY_HIGH = 1,
};

#define MT_IO_FLAGS_RUNNING		0
#define MT_IO_FLAGS_ACTIVE_SLOTS	1
#define MT_IO_FLAGS_PENDING_SLOTS	2
@@ -1156,7 +1161,10 @@ static void mt_report(struct hid_device *hid, struct hid_report *report)

static bool mt_need_to_apply_feature(struct hid_device *hdev,
				     struct hid_field *field,
				     struct hid_usage *usage)
				     struct hid_usage *usage,
				     enum latency_mode latency,
				     bool surface_switch,
				     bool button_switch)
{
	struct mt_device *td = hid_get_drvdata(hdev);
	struct mt_class *cls = &td->mtclass;
@@ -1195,12 +1203,25 @@ static bool mt_need_to_apply_feature(struct hid_device *hdev,
			}
		}
		break;

	case HID_DG_LATENCYMODE:
		field->value[index] = latency;
		return 1;

	case HID_DG_SURFACESWITCH:
		field->value[index] = surface_switch;
		return 1;

	case HID_DG_BUTTONSWITCH:
		field->value[index] = button_switch;
		return 1;
	}

	return false; /* no need to update the report */
}

static void mt_set_modes(struct hid_device *hdev)
static void mt_set_modes(struct hid_device *hdev, enum latency_mode latency,
			 bool surface_switch, bool button_switch)
{
	struct hid_report_enum *rep_enum;
	struct hid_report *rep;
@@ -1222,7 +1243,10 @@ static void mt_set_modes(struct hid_device *hdev)

				if (mt_need_to_apply_feature(hdev,
							     rep->field[i],
							     usage))
							     usage,
							     latency,
							     surface_switch,
							     button_switch))
					update_report = true;
			}
		}
@@ -1467,7 +1491,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
		dev_warn(&hdev->dev, "Cannot allocate sysfs group for %s\n",
				hdev->name);

	mt_set_modes(hdev);
	mt_set_modes(hdev, HID_LATENCY_NORMAL, true, true);

	/* release .fields memory as it is not used anymore */
	devm_kfree(&hdev->dev, td->fields);
@@ -1480,7 +1504,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
static int mt_reset_resume(struct hid_device *hdev)
{
	mt_release_contacts(hdev);
	mt_set_modes(hdev);
	mt_set_modes(hdev, HID_LATENCY_NORMAL, true, true);
	return 0;
}

+3 −0
Original line number Diff line number Diff line
@@ -292,9 +292,12 @@ struct hid_item {
#define HID_DG_CONTACTCOUNT	0x000d0054
#define HID_DG_CONTACTMAX	0x000d0055
#define HID_DG_SCANTIME		0x000d0056
#define HID_DG_SURFACESWITCH	0x000d0057
#define HID_DG_BUTTONSWITCH	0x000d0058
#define HID_DG_BUTTONTYPE	0x000d0059
#define HID_DG_BARRELSWITCH2	0x000d005a
#define HID_DG_TOOLSERIALNUMBER	0x000d005b
#define HID_DG_LATENCYMODE	0x000d0060

#define HID_VD_ASUS_CUSTOM_MEDIA_KEYS	0xff310076
/*