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 | ||