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: Jason Gerecke <killertofu@gmail.com> Tested-by: Aaron Skomra <Aaron.Skomra@wacom.com> Reviewed-by: Carl Worth <cworth@cworth.org> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
This commit is contained in:
parent
91ae0e7783
commit
5866d9e3b7
|
@ -22,23 +22,17 @@
|
||||||
#define HID_USAGE_PAGE_DIGITIZER 0x0d
|
#define HID_USAGE_PAGE_DIGITIZER 0x0d
|
||||||
#define HID_USAGE_PAGE_DESKTOP 0x01
|
#define HID_USAGE_PAGE_DESKTOP 0x01
|
||||||
#define HID_USAGE 0x09
|
#define HID_USAGE 0x09
|
||||||
#define HID_USAGE_X 0x30
|
#define HID_USAGE_X ((HID_USAGE_PAGE_DESKTOP << 16) | 0x30)
|
||||||
#define HID_USAGE_Y 0x31
|
#define HID_USAGE_Y ((HID_USAGE_PAGE_DESKTOP << 16) | 0x31)
|
||||||
#define HID_USAGE_X_TILT 0x3d
|
#define HID_USAGE_X_TILT ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x3d)
|
||||||
#define HID_USAGE_Y_TILT 0x3e
|
#define HID_USAGE_Y_TILT ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x3e)
|
||||||
#define HID_USAGE_FINGER 0x22
|
#define HID_USAGE_FINGER ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x22)
|
||||||
#define HID_USAGE_STYLUS 0x20
|
#define HID_USAGE_STYLUS ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x20)
|
||||||
#define HID_USAGE_CONTACTMAX 0x55
|
#define HID_USAGE_CONTACTMAX ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x55)
|
||||||
#define HID_COLLECTION 0xa1
|
#define HID_COLLECTION 0xa1
|
||||||
#define HID_COLLECTION_LOGICAL 0x02
|
#define HID_COLLECTION_LOGICAL 0x02
|
||||||
#define HID_COLLECTION_END 0xc0
|
#define HID_COLLECTION_END 0xc0
|
||||||
|
|
||||||
enum {
|
|
||||||
WCM_UNDEFINED = 0,
|
|
||||||
WCM_DESKTOP,
|
|
||||||
WCM_DIGITIZER,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct hid_descriptor {
|
struct hid_descriptor {
|
||||||
struct usb_descriptor_header header;
|
struct usb_descriptor_header header;
|
||||||
__le16 bcdHID;
|
__le16 bcdHID;
|
||||||
|
@ -305,7 +299,7 @@ static int wacom_parse_hid(struct usb_interface *intf,
|
||||||
char limit = 0;
|
char limit = 0;
|
||||||
/* result has to be defined as int for some devices */
|
/* result has to be defined as int for some devices */
|
||||||
int result = 0, touch_max = 0;
|
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;
|
unsigned char *report;
|
||||||
|
|
||||||
report = kzalloc(hid_desc->wDescriptorLength, GFP_KERNEL);
|
report = kzalloc(hid_desc->wDescriptorLength, GFP_KERNEL);
|
||||||
|
@ -332,134 +326,121 @@ static int wacom_parse_hid(struct usb_interface *intf,
|
||||||
|
|
||||||
switch (report[i]) {
|
switch (report[i]) {
|
||||||
case HID_USAGE_PAGE:
|
case HID_USAGE_PAGE:
|
||||||
switch (report[i + 1]) {
|
page = report[i + 1];
|
||||||
case HID_USAGE_PAGE_DIGITIZER:
|
i++;
|
||||||
usage = WCM_DIGITIZER;
|
|
||||||
i++;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HID_USAGE_PAGE_DESKTOP:
|
|
||||||
usage = WCM_DESKTOP;
|
|
||||||
i++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HID_USAGE:
|
case HID_USAGE:
|
||||||
switch (report[i + 1]) {
|
switch (page << 16 | report[i + 1]) {
|
||||||
case HID_USAGE_X:
|
case HID_USAGE_X:
|
||||||
if (usage == WCM_DESKTOP) {
|
if (finger) {
|
||||||
if (finger) {
|
features->device_type = BTN_TOOL_FINGER;
|
||||||
features->device_type = BTN_TOOL_FINGER;
|
/* touch device at least supports one touch point */
|
||||||
/* touch device at least supports one touch point */
|
touch_max = 1;
|
||||||
touch_max = 1;
|
switch (features->type) {
|
||||||
switch (features->type) {
|
case TABLETPC2FG:
|
||||||
case TABLETPC2FG:
|
features->pktlen = WACOM_PKGLEN_TPC2FG;
|
||||||
features->pktlen = WACOM_PKGLEN_TPC2FG;
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
case MTSCREEN:
|
case MTSCREEN:
|
||||||
case WACOM_24HDT:
|
case WACOM_24HDT:
|
||||||
features->pktlen = WACOM_PKGLEN_MTOUCH;
|
features->pktlen = WACOM_PKGLEN_MTOUCH;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MTTPC:
|
case MTTPC:
|
||||||
features->pktlen = WACOM_PKGLEN_MTTPC;
|
features->pktlen = WACOM_PKGLEN_MTTPC;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BAMBOO_PT:
|
case BAMBOO_PT:
|
||||||
features->pktlen = WACOM_PKGLEN_BBTOUCH;
|
features->pktlen = WACOM_PKGLEN_BBTOUCH;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
features->pktlen = WACOM_PKGLEN_GRAPHIRE;
|
features->pktlen = WACOM_PKGLEN_GRAPHIRE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (features->type) {
|
switch (features->type) {
|
||||||
case BAMBOO_PT:
|
case BAMBOO_PT:
|
||||||
features->x_phy =
|
features->x_phy =
|
||||||
get_unaligned_le16(&report[i + 5]);
|
get_unaligned_le16(&report[i + 5]);
|
||||||
features->x_max =
|
features->x_max =
|
||||||
get_unaligned_le16(&report[i + 8]);
|
get_unaligned_le16(&report[i + 8]);
|
||||||
i += 15;
|
i += 15;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WACOM_24HDT:
|
case WACOM_24HDT:
|
||||||
features->x_max =
|
|
||||||
get_unaligned_le16(&report[i + 3]);
|
|
||||||
features->x_phy =
|
|
||||||
get_unaligned_le16(&report[i + 8]);
|
|
||||||
features->unit = report[i - 1];
|
|
||||||
features->unitExpo = report[i - 3];
|
|
||||||
i += 12;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
features->x_max =
|
|
||||||
get_unaligned_le16(&report[i + 3]);
|
|
||||||
features->x_phy =
|
|
||||||
get_unaligned_le16(&report[i + 6]);
|
|
||||||
features->unit = report[i + 9];
|
|
||||||
features->unitExpo = report[i + 11];
|
|
||||||
i += 12;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if (pen) {
|
|
||||||
/* penabled only accepts exact bytes of data */
|
|
||||||
if (features->type >= TABLETPC)
|
|
||||||
features->pktlen = WACOM_PKGLEN_GRAPHIRE;
|
|
||||||
features->device_type = BTN_TOOL_PEN;
|
|
||||||
features->x_max =
|
features->x_max =
|
||||||
get_unaligned_le16(&report[i + 3]);
|
get_unaligned_le16(&report[i + 3]);
|
||||||
i += 4;
|
features->x_phy =
|
||||||
|
get_unaligned_le16(&report[i + 8]);
|
||||||
|
features->unit = report[i - 1];
|
||||||
|
features->unitExpo = report[i - 3];
|
||||||
|
i += 12;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
features->x_max =
|
||||||
|
get_unaligned_le16(&report[i + 3]);
|
||||||
|
features->x_phy =
|
||||||
|
get_unaligned_le16(&report[i + 6]);
|
||||||
|
features->unit = report[i + 9];
|
||||||
|
features->unitExpo = report[i + 11];
|
||||||
|
i += 12;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
} else if (pen) {
|
||||||
|
/* penabled only accepts exact bytes of data */
|
||||||
|
if (features->type >= TABLETPC)
|
||||||
|
features->pktlen = WACOM_PKGLEN_GRAPHIRE;
|
||||||
|
features->device_type = BTN_TOOL_PEN;
|
||||||
|
features->x_max =
|
||||||
|
get_unaligned_le16(&report[i + 3]);
|
||||||
|
i += 4;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HID_USAGE_Y:
|
case HID_USAGE_Y:
|
||||||
if (usage == WCM_DESKTOP) {
|
if (finger) {
|
||||||
if (finger) {
|
switch (features->type) {
|
||||||
switch (features->type) {
|
case TABLETPC2FG:
|
||||||
case TABLETPC2FG:
|
case MTSCREEN:
|
||||||
case MTSCREEN:
|
case MTTPC:
|
||||||
case MTTPC:
|
|
||||||
features->y_max =
|
|
||||||
get_unaligned_le16(&report[i + 3]);
|
|
||||||
features->y_phy =
|
|
||||||
get_unaligned_le16(&report[i + 6]);
|
|
||||||
i += 7;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WACOM_24HDT:
|
|
||||||
features->y_max =
|
|
||||||
get_unaligned_le16(&report[i + 3]);
|
|
||||||
features->y_phy =
|
|
||||||
get_unaligned_le16(&report[i - 2]);
|
|
||||||
i += 7;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BAMBOO_PT:
|
|
||||||
features->y_phy =
|
|
||||||
get_unaligned_le16(&report[i + 3]);
|
|
||||||
features->y_max =
|
|
||||||
get_unaligned_le16(&report[i + 6]);
|
|
||||||
i += 12;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
features->y_max =
|
|
||||||
features->x_max;
|
|
||||||
features->y_phy =
|
|
||||||
get_unaligned_le16(&report[i + 3]);
|
|
||||||
i += 4;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if (pen) {
|
|
||||||
features->y_max =
|
features->y_max =
|
||||||
get_unaligned_le16(&report[i + 3]);
|
get_unaligned_le16(&report[i + 3]);
|
||||||
|
features->y_phy =
|
||||||
|
get_unaligned_le16(&report[i + 6]);
|
||||||
|
i += 7;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WACOM_24HDT:
|
||||||
|
features->y_max =
|
||||||
|
get_unaligned_le16(&report[i + 3]);
|
||||||
|
features->y_phy =
|
||||||
|
get_unaligned_le16(&report[i - 2]);
|
||||||
|
i += 7;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BAMBOO_PT:
|
||||||
|
features->y_phy =
|
||||||
|
get_unaligned_le16(&report[i + 3]);
|
||||||
|
features->y_max =
|
||||||
|
get_unaligned_le16(&report[i + 6]);
|
||||||
|
i += 12;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
features->y_max =
|
||||||
|
features->x_max;
|
||||||
|
features->y_phy =
|
||||||
|
get_unaligned_le16(&report[i + 3]);
|
||||||
i += 4;
|
i += 4;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
} else if (pen) {
|
||||||
|
features->y_max =
|
||||||
|
get_unaligned_le16(&report[i + 3]);
|
||||||
|
i += 4;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -489,7 +470,7 @@ static int wacom_parse_hid(struct usb_interface *intf,
|
||||||
|
|
||||||
case HID_COLLECTION_END:
|
case HID_COLLECTION_END:
|
||||||
/* reset UsagePage and Finger */
|
/* reset UsagePage and Finger */
|
||||||
finger = usage = 0;
|
finger = page = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HID_COLLECTION:
|
case HID_COLLECTION:
|
||||||
|
|
Loading…
Reference in New Issue