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

Commit 5866d9e3 authored by Jason Gerecke's avatar Jason Gerecke Committed by Dmitry Torokhov
Browse files

Input: wacom - use full 32-bit HID Usage value in switch statement



A HID Usage is a 32-bit value: an upper 16-bit "page" and a lower 16-bit
ID. While the two halves are normally reported seperately, only the
combination uniquely idenfifes a particular HID Usage.

The existing code performs the comparison in two steps, first performing a
switch on the ID and then verifying the page within each case. While this
works fine, it is very akward to handle two Usages that share a single ID,
such as HID_USAGE_PRESSURE and HID_USAGE_X because the case statement can
only have a single identifier.

To work around this, we now check the full 32-bit HID Usage directly rather
than first checking the ID and then the page.  This allows the switch
statement to have distinct cases for e.g. HID_USAGE_PRESSURE and
HID_USAGE_X.

Signed-off-by: default avatarJason Gerecke <killertofu@gmail.com>
Tested-by: default avatarAaron Skomra <Aaron.Skomra@wacom.com>
Reviewed-by: default avatarCarl Worth <cworth@cworth.org>
Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
parent 91ae0e77
Loading
Loading
Loading
Loading
+109 −128
Original line number Diff line number Diff line
@@ -22,23 +22,17 @@
#define HID_USAGE_PAGE_DIGITIZER	0x0d
#define HID_USAGE_PAGE_DESKTOP		0x01
#define HID_USAGE			0x09
#define HID_USAGE_X			0x30
#define HID_USAGE_Y			0x31
#define HID_USAGE_X_TILT		0x3d
#define HID_USAGE_Y_TILT		0x3e
#define HID_USAGE_FINGER		0x22
#define HID_USAGE_STYLUS		0x20
#define HID_USAGE_CONTACTMAX		0x55
#define HID_USAGE_X			((HID_USAGE_PAGE_DESKTOP << 16) | 0x30)
#define HID_USAGE_Y			((HID_USAGE_PAGE_DESKTOP << 16) | 0x31)
#define HID_USAGE_X_TILT		((HID_USAGE_PAGE_DIGITIZER << 16) | 0x3d)
#define HID_USAGE_Y_TILT		((HID_USAGE_PAGE_DIGITIZER << 16) | 0x3e)
#define HID_USAGE_FINGER		((HID_USAGE_PAGE_DIGITIZER << 16) | 0x22)
#define HID_USAGE_STYLUS		((HID_USAGE_PAGE_DIGITIZER << 16) | 0x20)
#define HID_USAGE_CONTACTMAX		((HID_USAGE_PAGE_DIGITIZER << 16) | 0x55)
#define HID_COLLECTION			0xa1
#define HID_COLLECTION_LOGICAL		0x02
#define HID_COLLECTION_END		0xc0

enum {
	WCM_UNDEFINED = 0,
	WCM_DESKTOP,
	WCM_DIGITIZER,
};

struct hid_descriptor {
	struct usb_descriptor_header header;
	__le16   bcdHID;
@@ -305,7 +299,7 @@ static int wacom_parse_hid(struct usb_interface *intf,
	char limit = 0;
	/* result has to be defined as int for some devices */
	int result = 0, touch_max = 0;
	int i = 0, usage = WCM_UNDEFINED, finger = 0, pen = 0;
	int i = 0, page = 0, finger = 0, pen = 0;
	unsigned char *report;

	report = kzalloc(hid_desc->wDescriptorLength, GFP_KERNEL);
@@ -332,23 +326,13 @@ static int wacom_parse_hid(struct usb_interface *intf,

		switch (report[i]) {
		case HID_USAGE_PAGE:
			switch (report[i + 1]) {
			case HID_USAGE_PAGE_DIGITIZER:
				usage = WCM_DIGITIZER;
			page = report[i + 1];
			i++;
			break;

			case HID_USAGE_PAGE_DESKTOP:
				usage = WCM_DESKTOP;
				i++;
				break;
			}
			break;

		case HID_USAGE:
			switch (report[i + 1]) {
			switch (page << 16 | report[i + 1]) {
			case HID_USAGE_X:
				if (usage == WCM_DESKTOP) {
				if (finger) {
					features->device_type = BTN_TOOL_FINGER;
					/* touch device at least supports one touch point */
@@ -414,11 +398,9 @@ static int wacom_parse_hid(struct usb_interface *intf,
						get_unaligned_le16(&report[i + 3]);
					i += 4;
				}
				}
				break;

			case HID_USAGE_Y:
				if (usage == WCM_DESKTOP) {
				if (finger) {
					switch (features->type) {
					case TABLETPC2FG:
@@ -460,7 +442,6 @@ static int wacom_parse_hid(struct usb_interface *intf,
						get_unaligned_le16(&report[i + 3]);
					i += 4;
				}
				}
				break;

			case HID_USAGE_FINGER:
@@ -489,7 +470,7 @@ static int wacom_parse_hid(struct usb_interface *intf,

		case HID_COLLECTION_END:
			/* reset UsagePage and Finger */
			finger = usage = 0;
			finger = page = 0;
			break;

		case HID_COLLECTION: