diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-10-05 13:28:12 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-10-05 13:28:12 -0400 |
| commit | 77ede3a014a32746002f7889211f0cecf4803163 (patch) | |
| tree | 7ebe216b6b19c6a598950534fba7767b54c7c551 | |
| parent | 9a431ef9629fa6276aa8bd9ea87fb0728922bd6d (diff) | |
| parent | 66dcdafe8e251a3edc5d84cf725835567bd3dd35 (diff) | |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
Pull HID subsystem fixes from Jiri Kosina:
- buffer management size fix for i2c-hid driver, from Adrian Salido
- tool ID regression fixes for Wacom driver from Jason Gerecke
- a few small assorted fixes and a few device ID additions
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid:
Revert "HID: multitouch: Support ALPS PTP stick with pid 0x120A"
HID: hidraw: fix power sequence when closing device
HID: wacom: Always increment hdev refcount within wacom_get_hdev_data
HID: wacom: generic: Clear ABS_MISC when tool leaves proximity
HID: wacom: generic: Send MSC_SERIAL and ABS_MISC when leaving prox
HID: i2c-hid: allocate hid buffers for real worst case
HID: rmi: Make sure the HID device is opened on resume
HID: multitouch: Support ALPS PTP stick with pid 0x120A
HID: multitouch: support buttons and trackpoint on Lenovo X1 Tab Gen2
HID: wacom: Correct coordinate system of touchring and pen twist
HID: wacom: Properly report negative values from Intuos Pro 2 Bluetooth
HID: multitouch: Fix system-control buttons not working
HID: add multi-input quirk for IDC6680 touchscreen
HID: wacom: leds: Don't try to control the EKR's read-only LEDs
HID: wacom: bits shifted too much for 9th and 10th buttons
| -rw-r--r-- | drivers/hid/hid-ids.h | 2 | ||||
| -rw-r--r-- | drivers/hid/hid-multitouch.c | 7 | ||||
| -rw-r--r-- | drivers/hid/hid-rmi.c | 13 | ||||
| -rw-r--r-- | drivers/hid/hidraw.c | 2 | ||||
| -rw-r--r-- | drivers/hid/i2c-hid/i2c-hid.c | 3 | ||||
| -rw-r--r-- | drivers/hid/usbhid/hid-quirks.c | 1 | ||||
| -rw-r--r-- | drivers/hid/wacom_sys.c | 7 | ||||
| -rw-r--r-- | drivers/hid/wacom_wac.c | 110 |
8 files changed, 118 insertions, 27 deletions
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index b397a14ab970..a98919199858 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
| @@ -533,6 +533,7 @@ | |||
| 533 | #define USB_VENDOR_ID_IDEACOM 0x1cb6 | 533 | #define USB_VENDOR_ID_IDEACOM 0x1cb6 |
| 534 | #define USB_DEVICE_ID_IDEACOM_IDC6650 0x6650 | 534 | #define USB_DEVICE_ID_IDEACOM_IDC6650 0x6650 |
| 535 | #define USB_DEVICE_ID_IDEACOM_IDC6651 0x6651 | 535 | #define USB_DEVICE_ID_IDEACOM_IDC6651 0x6651 |
| 536 | #define USB_DEVICE_ID_IDEACOM_IDC6680 0x6680 | ||
| 536 | 537 | ||
| 537 | #define USB_VENDOR_ID_ILITEK 0x222a | 538 | #define USB_VENDOR_ID_ILITEK 0x222a |
| 538 | #define USB_DEVICE_ID_ILITEK_MULTITOUCH 0x0001 | 539 | #define USB_DEVICE_ID_ILITEK_MULTITOUCH 0x0001 |
| @@ -660,6 +661,7 @@ | |||
| 660 | #define USB_DEVICE_ID_LENOVO_CBTKBD 0x6048 | 661 | #define USB_DEVICE_ID_LENOVO_CBTKBD 0x6048 |
| 661 | #define USB_DEVICE_ID_LENOVO_TPPRODOCK 0x6067 | 662 | #define USB_DEVICE_ID_LENOVO_TPPRODOCK 0x6067 |
| 662 | #define USB_DEVICE_ID_LENOVO_X1_COVER 0x6085 | 663 | #define USB_DEVICE_ID_LENOVO_X1_COVER 0x6085 |
| 664 | #define USB_DEVICE_ID_LENOVO_X1_TAB 0x60a3 | ||
| 663 | 665 | ||
| 664 | #define USB_VENDOR_ID_LG 0x1fd2 | 666 | #define USB_VENDOR_ID_LG 0x1fd2 |
| 665 | #define USB_DEVICE_ID_LG_MULTITOUCH 0x0064 | 667 | #define USB_DEVICE_ID_LG_MULTITOUCH 0x0064 |
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 440b999304a5..9e8c4d2ba11d 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c | |||
| @@ -930,6 +930,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
| 930 | field->application != HID_DG_PEN && | 930 | field->application != HID_DG_PEN && |
| 931 | field->application != HID_DG_TOUCHPAD && | 931 | field->application != HID_DG_TOUCHPAD && |
| 932 | field->application != HID_GD_KEYBOARD && | 932 | field->application != HID_GD_KEYBOARD && |
| 933 | field->application != HID_GD_SYSTEM_CONTROL && | ||
| 933 | field->application != HID_CP_CONSUMER_CONTROL && | 934 | field->application != HID_CP_CONSUMER_CONTROL && |
| 934 | field->application != HID_GD_WIRELESS_RADIO_CTLS && | 935 | field->application != HID_GD_WIRELESS_RADIO_CTLS && |
| 935 | !(field->application == HID_VD_ASUS_CUSTOM_MEDIA_KEYS && | 936 | !(field->application == HID_VD_ASUS_CUSTOM_MEDIA_KEYS && |
| @@ -1419,6 +1420,12 @@ static const struct hid_device_id mt_devices[] = { | |||
| 1419 | USB_VENDOR_ID_ALPS_JP, | 1420 | USB_VENDOR_ID_ALPS_JP, |
| 1420 | HID_DEVICE_ID_ALPS_U1_DUAL_3BTN_PTP) }, | 1421 | HID_DEVICE_ID_ALPS_U1_DUAL_3BTN_PTP) }, |
| 1421 | 1422 | ||
| 1423 | /* Lenovo X1 TAB Gen 2 */ | ||
| 1424 | { .driver_data = MT_CLS_WIN_8_DUAL, | ||
| 1425 | HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH_WIN_8, | ||
| 1426 | USB_VENDOR_ID_LENOVO, | ||
| 1427 | USB_DEVICE_ID_LENOVO_X1_TAB) }, | ||
| 1428 | |||
| 1422 | /* Anton devices */ | 1429 | /* Anton devices */ |
| 1423 | { .driver_data = MT_CLS_EXPORT_ALL_INPUTS, | 1430 | { .driver_data = MT_CLS_EXPORT_ALL_INPUTS, |
| 1424 | MT_USB_DEVICE(USB_VENDOR_ID_ANTON, | 1431 | MT_USB_DEVICE(USB_VENDOR_ID_ANTON, |
diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c index 5b40c2614599..ef241d66562e 100644 --- a/drivers/hid/hid-rmi.c +++ b/drivers/hid/hid-rmi.c | |||
| @@ -436,17 +436,24 @@ static int rmi_post_resume(struct hid_device *hdev) | |||
| 436 | if (!(data->device_flags & RMI_DEVICE)) | 436 | if (!(data->device_flags & RMI_DEVICE)) |
| 437 | return 0; | 437 | return 0; |
| 438 | 438 | ||
| 439 | ret = rmi_reset_attn_mode(hdev); | 439 | /* Make sure the HID device is ready to receive events */ |
| 440 | ret = hid_hw_open(hdev); | ||
| 440 | if (ret) | 441 | if (ret) |
| 441 | return ret; | 442 | return ret; |
| 442 | 443 | ||
| 444 | ret = rmi_reset_attn_mode(hdev); | ||
| 445 | if (ret) | ||
| 446 | goto out; | ||
| 447 | |||
| 443 | ret = rmi_driver_resume(rmi_dev, false); | 448 | ret = rmi_driver_resume(rmi_dev, false); |
| 444 | if (ret) { | 449 | if (ret) { |
| 445 | hid_warn(hdev, "Failed to resume device: %d\n", ret); | 450 | hid_warn(hdev, "Failed to resume device: %d\n", ret); |
| 446 | return ret; | 451 | goto out; |
| 447 | } | 452 | } |
| 448 | 453 | ||
| 449 | return 0; | 454 | out: |
| 455 | hid_hw_close(hdev); | ||
| 456 | return ret; | ||
| 450 | } | 457 | } |
| 451 | #endif /* CONFIG_PM */ | 458 | #endif /* CONFIG_PM */ |
| 452 | 459 | ||
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index ec530454e6f6..5fbe0f81ab2e 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c | |||
| @@ -337,8 +337,8 @@ static void drop_ref(struct hidraw *hidraw, int exists_bit) | |||
| 337 | kfree(hidraw); | 337 | kfree(hidraw); |
| 338 | } else { | 338 | } else { |
| 339 | /* close device for last reader */ | 339 | /* close device for last reader */ |
| 340 | hid_hw_power(hidraw->hid, PM_HINT_NORMAL); | ||
| 341 | hid_hw_close(hidraw->hid); | 340 | hid_hw_close(hidraw->hid); |
| 341 | hid_hw_power(hidraw->hid, PM_HINT_NORMAL); | ||
| 342 | } | 342 | } |
| 343 | } | 343 | } |
| 344 | } | 344 | } |
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index 77396145d2d0..9145c2129a96 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c | |||
| @@ -543,7 +543,8 @@ static int i2c_hid_alloc_buffers(struct i2c_hid *ihid, size_t report_size) | |||
| 543 | { | 543 | { |
| 544 | /* the worst case is computed from the set_report command with a | 544 | /* the worst case is computed from the set_report command with a |
| 545 | * reportID > 15 and the maximum report length */ | 545 | * reportID > 15 and the maximum report length */ |
| 546 | int args_len = sizeof(__u8) + /* optional ReportID byte */ | 546 | int args_len = sizeof(__u8) + /* ReportID */ |
| 547 | sizeof(__u8) + /* optional ReportID byte */ | ||
| 547 | sizeof(__u16) + /* data register */ | 548 | sizeof(__u16) + /* data register */ |
| 548 | sizeof(__u16) + /* size of the report */ | 549 | sizeof(__u16) + /* size of the report */ |
| 549 | report_size; /* report */ | 550 | report_size; /* report */ |
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index a83fa76655b9..f489a5cfcb48 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c | |||
| @@ -99,6 +99,7 @@ static const struct hid_blacklist { | |||
| 99 | { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A, HID_QUIRK_ALWAYS_POLL }, | 99 | { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A, HID_QUIRK_ALWAYS_POLL }, |
| 100 | { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A, HID_QUIRK_ALWAYS_POLL }, | 100 | { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A, HID_QUIRK_ALWAYS_POLL }, |
| 101 | { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL }, | 101 | { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL }, |
| 102 | { USB_VENDOR_ID_IDEACOM, USB_DEVICE_ID_IDEACOM_IDC6680, HID_QUIRK_MULTI_INPUT }, | ||
| 102 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C007, HID_QUIRK_ALWAYS_POLL }, | 103 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C007, HID_QUIRK_ALWAYS_POLL }, |
| 103 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C077, HID_QUIRK_ALWAYS_POLL }, | 104 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C077, HID_QUIRK_ALWAYS_POLL }, |
| 104 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KEYBOARD_G710_PLUS, HID_QUIRK_NOGET }, | 105 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KEYBOARD_G710_PLUS, HID_QUIRK_NOGET }, |
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index e82a696a1d07..906e654fb0ba 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c | |||
| @@ -668,8 +668,10 @@ static struct wacom_hdev_data *wacom_get_hdev_data(struct hid_device *hdev) | |||
| 668 | 668 | ||
| 669 | /* Try to find an already-probed interface from the same device */ | 669 | /* Try to find an already-probed interface from the same device */ |
| 670 | list_for_each_entry(data, &wacom_udev_list, list) { | 670 | list_for_each_entry(data, &wacom_udev_list, list) { |
| 671 | if (compare_device_paths(hdev, data->dev, '/')) | 671 | if (compare_device_paths(hdev, data->dev, '/')) { |
| 672 | kref_get(&data->kref); | ||
| 672 | return data; | 673 | return data; |
| 674 | } | ||
| 673 | } | 675 | } |
| 674 | 676 | ||
| 675 | /* Fallback to finding devices that appear to be "siblings" */ | 677 | /* Fallback to finding devices that appear to be "siblings" */ |
| @@ -766,6 +768,9 @@ static int wacom_led_control(struct wacom *wacom) | |||
| 766 | if (!wacom->led.groups) | 768 | if (!wacom->led.groups) |
| 767 | return -ENOTSUPP; | 769 | return -ENOTSUPP; |
| 768 | 770 | ||
| 771 | if (wacom->wacom_wac.features.type == REMOTE) | ||
| 772 | return -ENOTSUPP; | ||
| 773 | |||
| 769 | if (wacom->wacom_wac.pid) { /* wireless connected */ | 774 | if (wacom->wacom_wac.pid) { /* wireless connected */ |
| 770 | report_id = WAC_CMD_WL_LED_CONTROL; | 775 | report_id = WAC_CMD_WL_LED_CONTROL; |
| 771 | buf_size = 13; | 776 | buf_size = 13; |
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index bb17d7bbefd3..aa692e28b2cd 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c | |||
| @@ -567,8 +567,8 @@ static int wacom_intuos_pad(struct wacom_wac *wacom) | |||
| 567 | keys = data[9] & 0x07; | 567 | keys = data[9] & 0x07; |
| 568 | } | 568 | } |
| 569 | } else { | 569 | } else { |
| 570 | buttons = ((data[6] & 0x10) << 10) | | 570 | buttons = ((data[6] & 0x10) << 5) | |
| 571 | ((data[5] & 0x10) << 9) | | 571 | ((data[5] & 0x10) << 4) | |
| 572 | ((data[6] & 0x0F) << 4) | | 572 | ((data[6] & 0x0F) << 4) | |
| 573 | (data[5] & 0x0F); | 573 | (data[5] & 0x0F); |
| 574 | } | 574 | } |
| @@ -1227,11 +1227,17 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom) | |||
| 1227 | continue; | 1227 | continue; |
| 1228 | 1228 | ||
| 1229 | if (range) { | 1229 | if (range) { |
| 1230 | /* Fix rotation alignment: userspace expects zero at left */ | ||
| 1231 | int16_t rotation = (int16_t)get_unaligned_le16(&frame[9]); | ||
| 1232 | rotation += 1800/4; | ||
| 1233 | if (rotation > 899) | ||
| 1234 | rotation -= 1800; | ||
| 1235 | |||
| 1230 | input_report_abs(pen_input, ABS_X, get_unaligned_le16(&frame[1])); | 1236 | input_report_abs(pen_input, ABS_X, get_unaligned_le16(&frame[1])); |
| 1231 | input_report_abs(pen_input, ABS_Y, get_unaligned_le16(&frame[3])); | 1237 | input_report_abs(pen_input, ABS_Y, get_unaligned_le16(&frame[3])); |
| 1232 | input_report_abs(pen_input, ABS_TILT_X, frame[7]); | 1238 | input_report_abs(pen_input, ABS_TILT_X, (char)frame[7]); |
| 1233 | input_report_abs(pen_input, ABS_TILT_Y, frame[8]); | 1239 | input_report_abs(pen_input, ABS_TILT_Y, (char)frame[8]); |
| 1234 | input_report_abs(pen_input, ABS_Z, get_unaligned_le16(&frame[9])); | 1240 | input_report_abs(pen_input, ABS_Z, rotation); |
| 1235 | input_report_abs(pen_input, ABS_WHEEL, get_unaligned_le16(&frame[11])); | 1241 | input_report_abs(pen_input, ABS_WHEEL, get_unaligned_le16(&frame[11])); |
| 1236 | } | 1242 | } |
| 1237 | input_report_abs(pen_input, ABS_PRESSURE, get_unaligned_le16(&frame[5])); | 1243 | input_report_abs(pen_input, ABS_PRESSURE, get_unaligned_le16(&frame[5])); |
| @@ -1319,12 +1325,19 @@ static void wacom_intuos_pro2_bt_pad(struct wacom_wac *wacom) | |||
| 1319 | unsigned char *data = wacom->data; | 1325 | unsigned char *data = wacom->data; |
| 1320 | 1326 | ||
| 1321 | int buttons = (data[282] << 1) | ((data[281] >> 6) & 0x01); | 1327 | int buttons = (data[282] << 1) | ((data[281] >> 6) & 0x01); |
| 1322 | int ring = data[285]; | 1328 | int ring = data[285] & 0x7F; |
| 1323 | int prox = buttons | (ring & 0x80); | 1329 | bool ringstatus = data[285] & 0x80; |
| 1330 | bool prox = buttons || ringstatus; | ||
| 1331 | |||
| 1332 | /* Fix touchring data: userspace expects 0 at left and increasing clockwise */ | ||
| 1333 | ring = 71 - ring; | ||
| 1334 | ring += 3*72/16; | ||
| 1335 | if (ring > 71) | ||
| 1336 | ring -= 72; | ||
| 1324 | 1337 | ||
| 1325 | wacom_report_numbered_buttons(pad_input, 9, buttons); | 1338 | wacom_report_numbered_buttons(pad_input, 9, buttons); |
| 1326 | 1339 | ||
| 1327 | input_report_abs(pad_input, ABS_WHEEL, (ring & 0x80) ? (ring & 0x7f) : 0); | 1340 | input_report_abs(pad_input, ABS_WHEEL, ringstatus ? ring : 0); |
| 1328 | 1341 | ||
| 1329 | input_report_key(pad_input, wacom->tool[1], prox ? 1 : 0); | 1342 | input_report_key(pad_input, wacom->tool[1], prox ? 1 : 0); |
| 1330 | input_report_abs(pad_input, ABS_MISC, prox ? PAD_DEVICE_ID : 0); | 1343 | input_report_abs(pad_input, ABS_MISC, prox ? PAD_DEVICE_ID : 0); |
| @@ -1616,6 +1629,20 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len) | |||
| 1616 | return 0; | 1629 | return 0; |
| 1617 | } | 1630 | } |
| 1618 | 1631 | ||
| 1632 | static int wacom_offset_rotation(struct input_dev *input, struct hid_usage *usage, | ||
| 1633 | int value, int num, int denom) | ||
| 1634 | { | ||
| 1635 | struct input_absinfo *abs = &input->absinfo[usage->code]; | ||
| 1636 | int range = (abs->maximum - abs->minimum + 1); | ||
| 1637 | |||
| 1638 | value += num*range/denom; | ||
| 1639 | if (value > abs->maximum) | ||
| 1640 | value -= range; | ||
| 1641 | else if (value < abs->minimum) | ||
| 1642 | value += range; | ||
| 1643 | return value; | ||
| 1644 | } | ||
| 1645 | |||
| 1619 | int wacom_equivalent_usage(int usage) | 1646 | int wacom_equivalent_usage(int usage) |
| 1620 | { | 1647 | { |
| 1621 | if ((usage & HID_USAGE_PAGE) == WACOM_HID_UP_WACOMDIGITIZER) { | 1648 | if ((usage & HID_USAGE_PAGE) == WACOM_HID_UP_WACOMDIGITIZER) { |
| @@ -1898,6 +1925,7 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field | |||
| 1898 | unsigned equivalent_usage = wacom_equivalent_usage(usage->hid); | 1925 | unsigned equivalent_usage = wacom_equivalent_usage(usage->hid); |
| 1899 | int i; | 1926 | int i; |
| 1900 | bool is_touch_on = value; | 1927 | bool is_touch_on = value; |
| 1928 | bool do_report = false; | ||
| 1901 | 1929 | ||
| 1902 | /* | 1930 | /* |
| 1903 | * Avoid reporting this event and setting inrange_state if this usage | 1931 | * Avoid reporting this event and setting inrange_state if this usage |
| @@ -1912,6 +1940,29 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field | |||
| 1912 | } | 1940 | } |
| 1913 | 1941 | ||
| 1914 | switch (equivalent_usage) { | 1942 | switch (equivalent_usage) { |
| 1943 | case WACOM_HID_WD_TOUCHRING: | ||
| 1944 | /* | ||
| 1945 | * Userspace expects touchrings to increase in value with | ||
| 1946 | * clockwise gestures and have their zero point at the | ||
| 1947 | * tablet's left. HID events "should" be clockwise- | ||
| 1948 | * increasing and zero at top, though the MobileStudio | ||
| 1949 | * Pro and 2nd-gen Intuos Pro don't do this... | ||
| 1950 | */ | ||
| 1951 | if (hdev->vendor == 0x56a && | ||
| 1952 | (hdev->product == 0x34d || hdev->product == 0x34e || /* MobileStudio Pro */ | ||
| 1953 | hdev->product == 0x357 || hdev->product == 0x358)) { /* Intuos Pro 2 */ | ||
| 1954 | value = (field->logical_maximum - value); | ||
| 1955 | |||
| 1956 | if (hdev->product == 0x357 || hdev->product == 0x358) | ||
| 1957 | value = wacom_offset_rotation(input, usage, value, 3, 16); | ||
| 1958 | else if (hdev->product == 0x34d || hdev->product == 0x34e) | ||
| 1959 | value = wacom_offset_rotation(input, usage, value, 1, 2); | ||
| 1960 | } | ||
| 1961 | else { | ||
| 1962 | value = wacom_offset_rotation(input, usage, value, 1, 4); | ||
| 1963 | } | ||
| 1964 | do_report = true; | ||
| 1965 | break; | ||
| 1915 | case WACOM_HID_WD_TOUCHRINGSTATUS: | 1966 | case WACOM_HID_WD_TOUCHRINGSTATUS: |
| 1916 | if (!value) | 1967 | if (!value) |
| 1917 | input_event(input, usage->type, usage->code, 0); | 1968 | input_event(input, usage->type, usage->code, 0); |
| @@ -1945,10 +1996,14 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field | |||
| 1945 | value, i); | 1996 | value, i); |
| 1946 | /* fall through*/ | 1997 | /* fall through*/ |
| 1947 | default: | 1998 | default: |
| 1999 | do_report = true; | ||
| 2000 | break; | ||
| 2001 | } | ||
| 2002 | |||
| 2003 | if (do_report) { | ||
| 1948 | input_event(input, usage->type, usage->code, value); | 2004 | input_event(input, usage->type, usage->code, value); |
| 1949 | if (value) | 2005 | if (value) |
| 1950 | wacom_wac->hid_data.pad_input_event_flag = true; | 2006 | wacom_wac->hid_data.pad_input_event_flag = true; |
| 1951 | break; | ||
| 1952 | } | 2007 | } |
| 1953 | } | 2008 | } |
| 1954 | 2009 | ||
| @@ -2086,22 +2141,34 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field | |||
| 2086 | wacom_wac->hid_data.tipswitch |= value; | 2141 | wacom_wac->hid_data.tipswitch |= value; |
| 2087 | return; | 2142 | return; |
| 2088 | case HID_DG_TOOLSERIALNUMBER: | 2143 | case HID_DG_TOOLSERIALNUMBER: |
| 2089 | wacom_wac->serial[0] = (wacom_wac->serial[0] & ~0xFFFFFFFFULL); | 2144 | if (value) { |
| 2090 | wacom_wac->serial[0] |= (__u32)value; | 2145 | wacom_wac->serial[0] = (wacom_wac->serial[0] & ~0xFFFFFFFFULL); |
| 2146 | wacom_wac->serial[0] |= (__u32)value; | ||
| 2147 | } | ||
| 2091 | return; | 2148 | return; |
| 2149 | case HID_DG_TWIST: | ||
| 2150 | /* | ||
| 2151 | * Userspace expects pen twist to have its zero point when | ||
| 2152 | * the buttons/finger is on the tablet's left. HID values | ||
| 2153 | * are zero when buttons are toward the top. | ||
| 2154 | */ | ||
| 2155 | value = wacom_offset_rotation(input, usage, value, 1, 4); | ||
| 2156 | break; | ||
| 2092 | case WACOM_HID_WD_SENSE: | 2157 | case WACOM_HID_WD_SENSE: |
| 2093 | wacom_wac->hid_data.sense_state = value; | 2158 | wacom_wac->hid_data.sense_state = value; |
| 2094 | return; | 2159 | return; |
| 2095 | case WACOM_HID_WD_SERIALHI: | 2160 | case WACOM_HID_WD_SERIALHI: |
| 2096 | wacom_wac->serial[0] = (wacom_wac->serial[0] & 0xFFFFFFFF); | 2161 | if (value) { |
| 2097 | wacom_wac->serial[0] |= ((__u64)value) << 32; | 2162 | wacom_wac->serial[0] = (wacom_wac->serial[0] & 0xFFFFFFFF); |
| 2098 | /* | 2163 | wacom_wac->serial[0] |= ((__u64)value) << 32; |
| 2099 | * Non-USI EMR devices may contain additional tool type | 2164 | /* |
| 2100 | * information here. See WACOM_HID_WD_TOOLTYPE case for | 2165 | * Non-USI EMR devices may contain additional tool type |
| 2101 | * more details. | 2166 | * information here. See WACOM_HID_WD_TOOLTYPE case for |
| 2102 | */ | 2167 | * more details. |
| 2103 | if (value >> 20 == 1) { | 2168 | */ |
| 2104 | wacom_wac->id[0] |= value & 0xFFFFF; | 2169 | if (value >> 20 == 1) { |
| 2170 | wacom_wac->id[0] |= value & 0xFFFFF; | ||
| 2171 | } | ||
| 2105 | } | 2172 | } |
| 2106 | return; | 2173 | return; |
| 2107 | case WACOM_HID_WD_TOOLTYPE: | 2174 | case WACOM_HID_WD_TOOLTYPE: |
| @@ -2205,7 +2272,7 @@ static void wacom_wac_pen_report(struct hid_device *hdev, | |||
| 2205 | input_report_key(input, wacom_wac->tool[0], prox); | 2272 | input_report_key(input, wacom_wac->tool[0], prox); |
| 2206 | if (wacom_wac->serial[0]) { | 2273 | if (wacom_wac->serial[0]) { |
| 2207 | input_event(input, EV_MSC, MSC_SERIAL, wacom_wac->serial[0]); | 2274 | input_event(input, EV_MSC, MSC_SERIAL, wacom_wac->serial[0]); |
| 2208 | input_report_abs(input, ABS_MISC, id); | 2275 | input_report_abs(input, ABS_MISC, prox ? id : 0); |
| 2209 | } | 2276 | } |
| 2210 | 2277 | ||
| 2211 | wacom_wac->hid_data.tipswitch = false; | 2278 | wacom_wac->hid_data.tipswitch = false; |
| @@ -2216,6 +2283,7 @@ static void wacom_wac_pen_report(struct hid_device *hdev, | |||
| 2216 | if (!prox) { | 2283 | if (!prox) { |
| 2217 | wacom_wac->tool[0] = 0; | 2284 | wacom_wac->tool[0] = 0; |
| 2218 | wacom_wac->id[0] = 0; | 2285 | wacom_wac->id[0] = 0; |
| 2286 | wacom_wac->serial[0] = 0; | ||
| 2219 | } | 2287 | } |
| 2220 | } | 2288 | } |
| 2221 | 2289 | ||
