diff options
-rw-r--r-- | drivers/hid/wacom_sys.c | 92 |
1 files changed, 54 insertions, 38 deletions
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 6b67c6907caa..3a4cf2666a7c 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -210,6 +210,57 @@ static int wacom_calc_hid_res(int logical_extents, int physical_extents, return hidinput_calc_abs_res(&field, ABS_X); } +static void wacom_hid_usage_quirk(struct hid_device *hdev, + struct hid_field *field, struct hid_usage *usage) +{ + struct wacom *wacom = hid_get_drvdata(hdev); + struct wacom_features *features = &wacom->wacom_wac.features; + unsigned int equivalent_usage = wacom_equivalent_usage(usage->hid); + + /* + * The Dell Canvas 27 needs to be switched to its vendor-defined + * report to provide the best resolution. + */ + if (hdev->vendor == USB_VENDOR_ID_WACOM && + hdev->product == 0x4200 && + field->application == HID_UP_MSVENDOR) { + wacom->wacom_wac.mode_report = field->report->id; + wacom->wacom_wac.mode_value = 2; + } + + /* + * ISDv4 devices which predate HID's adoption of the + * HID_DG_BARELSWITCH2 usage use 0x000D0000 in its + * position instead. We can accurately detect if a + * usage with that value should be HID_DG_BARRELSWITCH2 + * based on the surrounding usages, which have remained + * constant across generations. + */ + if (features->type == HID_GENERIC && + usage->hid == 0x000D0000 && + field->application == HID_DG_PEN && + field->physical == HID_DG_STYLUS) { + int i = usage->usage_index; + + if (i-4 >= 0 && i+1 < field->maxusage && + field->usage[i-4].hid == HID_DG_TIPSWITCH && + field->usage[i-3].hid == HID_DG_BARRELSWITCH && + field->usage[i-2].hid == HID_DG_ERASER && + field->usage[i-1].hid == HID_DG_INVERT && + field->usage[i+1].hid == HID_DG_INRANGE) { + usage->hid = HID_DG_BARRELSWITCH2; + } + } + + /* 2nd-generation Intuos Pro Large has incorrect Y maximum */ + if (hdev->vendor == USB_VENDOR_ID_WACOM && + hdev->product == 0x0358 && + WACOM_PEN_FIELD(field) && + equivalent_usage == HID_GD_Y) { + field->logical_maximum = 43200; + } +} + static void wacom_feature_mapping(struct hid_device *hdev, struct hid_field *field, struct hid_usage *usage) { @@ -221,6 +272,8 @@ static void wacom_feature_mapping(struct hid_device *hdev, int ret; u32 n; + wacom_hid_usage_quirk(hdev, field, usage); + switch (equivalent_usage) { case HID_DG_CONTACTMAX: /* leave touch_max as is if predefined */ @@ -300,13 +353,6 @@ static void wacom_feature_mapping(struct hid_device *hdev, kfree(data); break; } - - if (hdev->vendor == USB_VENDOR_ID_WACOM && - hdev->product == 0x4200 /* Dell Canvas 27 */ && - field->application == HID_UP_MSVENDOR) { - wacom->wacom_wac.mode_report = field->report->id; - wacom->wacom_wac.mode_value = 2; - } } /* @@ -361,37 +407,7 @@ static void wacom_usage_mapping(struct hid_device *hdev, else return; - /* - * ISDv4 devices which predate HID's adoption of the - * HID_DG_BARELSWITCH2 usage use 0x000D0000 in its - * position instead. We can accurately detect if a - * usage with that value should be HID_DG_BARRELSWITCH2 - * based on the surrounding usages, which have remained - * constant across generations. - */ - if (features->type == HID_GENERIC && - usage->hid == 0x000D0000 && - field->application == HID_DG_PEN && - field->physical == HID_DG_STYLUS) { - int i = usage->usage_index; - - if (i-4 >= 0 && i+1 < field->maxusage && - field->usage[i-4].hid == HID_DG_TIPSWITCH && - field->usage[i-3].hid == HID_DG_BARRELSWITCH && - field->usage[i-2].hid == HID_DG_ERASER && - field->usage[i-1].hid == HID_DG_INVERT && - field->usage[i+1].hid == HID_DG_INRANGE) { - usage->hid = HID_DG_BARRELSWITCH2; - } - } - - /* 2nd-generation Intuos Pro Large has incorrect Y maximum */ - if (hdev->vendor == USB_VENDOR_ID_WACOM && - hdev->product == 0x0358 && - WACOM_PEN_FIELD(field) && - wacom_equivalent_usage(usage->hid) == HID_GD_Y) { - field->logical_maximum = 43200; - } + wacom_hid_usage_quirk(hdev, field, usage); switch (usage->hid) { case HID_GD_X: |