Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+118 -27
+2
drivers/hid/hid-ids.h
··· 533 533 #define USB_VENDOR_ID_IDEACOM 0x1cb6 534 534 #define USB_DEVICE_ID_IDEACOM_IDC6650 0x6650 535 535 #define USB_DEVICE_ID_IDEACOM_IDC6651 0x6651 536 + #define USB_DEVICE_ID_IDEACOM_IDC6680 0x6680 536 537 537 538 #define USB_VENDOR_ID_ILITEK 0x222a 538 539 #define USB_DEVICE_ID_ILITEK_MULTITOUCH 0x0001 ··· 661 660 #define USB_DEVICE_ID_LENOVO_CBTKBD 0x6048 662 661 #define USB_DEVICE_ID_LENOVO_TPPRODOCK 0x6067 663 662 #define USB_DEVICE_ID_LENOVO_X1_COVER 0x6085 663 + #define USB_DEVICE_ID_LENOVO_X1_TAB 0x60a3 664 664 665 665 #define USB_VENDOR_ID_LG 0x1fd2 666 666 #define USB_DEVICE_ID_LG_MULTITOUCH 0x0064
+7
drivers/hid/hid-multitouch.c
··· 930 930 field->application != HID_DG_PEN && 931 931 field->application != HID_DG_TOUCHPAD && 932 932 field->application != HID_GD_KEYBOARD && 933 + field->application != HID_GD_SYSTEM_CONTROL && 933 934 field->application != HID_CP_CONSUMER_CONTROL && 934 935 field->application != HID_GD_WIRELESS_RADIO_CTLS && 935 936 !(field->application == HID_VD_ASUS_CUSTOM_MEDIA_KEYS && ··· 1419 1418 HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, 1420 1419 USB_VENDOR_ID_ALPS_JP, 1421 1420 HID_DEVICE_ID_ALPS_U1_DUAL_3BTN_PTP) }, 1421 + 1422 + /* Lenovo X1 TAB Gen 2 */ 1423 + { .driver_data = MT_CLS_WIN_8_DUAL, 1424 + HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH_WIN_8, 1425 + USB_VENDOR_ID_LENOVO, 1426 + USB_DEVICE_ID_LENOVO_X1_TAB) }, 1422 1427 1423 1428 /* Anton devices */ 1424 1429 { .driver_data = MT_CLS_EXPORT_ALL_INPUTS,
+10 -3
drivers/hid/hid-rmi.c
··· 436 436 if (!(data->device_flags & RMI_DEVICE)) 437 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 441 if (ret) 441 442 return ret; 443 + 444 + ret = rmi_reset_attn_mode(hdev); 445 + if (ret) 446 + goto out; 442 447 443 448 ret = rmi_driver_resume(rmi_dev, false); 444 449 if (ret) { 445 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 458 #endif /* CONFIG_PM */ 452 459
+1 -1
drivers/hid/hidraw.c
··· 337 337 kfree(hidraw); 338 338 } else { 339 339 /* close device for last reader */ 340 - hid_hw_power(hidraw->hid, PM_HINT_NORMAL); 341 340 hid_hw_close(hidraw->hid); 341 + hid_hw_power(hidraw->hid, PM_HINT_NORMAL); 342 342 } 343 343 } 344 344 }
+2 -1
drivers/hid/i2c-hid/i2c-hid.c
··· 543 543 { 544 544 /* the worst case is computed from the set_report command with a 545 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 548 sizeof(__u16) + /* data register */ 548 549 sizeof(__u16) + /* size of the report */ 549 550 report_size; /* report */
+1
drivers/hid/usbhid/hid-quirks.c
··· 99 99 { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A, HID_QUIRK_ALWAYS_POLL }, 100 100 { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A, HID_QUIRK_ALWAYS_POLL }, 101 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 103 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C007, HID_QUIRK_ALWAYS_POLL }, 103 104 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C077, HID_QUIRK_ALWAYS_POLL }, 104 105 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KEYBOARD_G710_PLUS, HID_QUIRK_NOGET },
+6 -1
drivers/hid/wacom_sys.c
··· 668 668 669 669 /* Try to find an already-probed interface from the same device */ 670 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 673 return data; 674 + } 673 675 } 674 676 675 677 /* Fallback to finding devices that appear to be "siblings" */ ··· 766 764 int buf_size = 9; 767 765 768 766 if (!wacom->led.groups) 767 + return -ENOTSUPP; 768 + 769 + if (wacom->wacom_wac.features.type == REMOTE) 769 770 return -ENOTSUPP; 770 771 771 772 if (wacom->wacom_wac.pid) { /* wireless connected */
+89 -21
drivers/hid/wacom_wac.c
··· 567 567 keys = data[9] & 0x07; 568 568 } 569 569 } else { 570 - buttons = ((data[6] & 0x10) << 10) | 571 - ((data[5] & 0x10) << 9) | 570 + buttons = ((data[6] & 0x10) << 5) | 571 + ((data[5] & 0x10) << 4) | 572 572 ((data[6] & 0x0F) << 4) | 573 573 (data[5] & 0x0F); 574 574 } ··· 1227 1227 continue; 1228 1228 1229 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 1236 input_report_abs(pen_input, ABS_X, get_unaligned_le16(&frame[1])); 1231 1237 input_report_abs(pen_input, ABS_Y, get_unaligned_le16(&frame[3])); 1232 - input_report_abs(pen_input, ABS_TILT_X, frame[7]); 1233 - input_report_abs(pen_input, ABS_TILT_Y, frame[8]); 1234 - input_report_abs(pen_input, ABS_Z, get_unaligned_le16(&frame[9])); 1238 + input_report_abs(pen_input, ABS_TILT_X, (char)frame[7]); 1239 + input_report_abs(pen_input, ABS_TILT_Y, (char)frame[8]); 1240 + input_report_abs(pen_input, ABS_Z, rotation); 1235 1241 input_report_abs(pen_input, ABS_WHEEL, get_unaligned_le16(&frame[11])); 1236 1242 } 1237 1243 input_report_abs(pen_input, ABS_PRESSURE, get_unaligned_le16(&frame[5])); ··· 1325 1319 unsigned char *data = wacom->data; 1326 1320 1327 1321 int buttons = (data[282] << 1) | ((data[281] >> 6) & 0x01); 1328 - int ring = data[285]; 1329 - int prox = buttons | (ring & 0x80); 1322 + int ring = data[285] & 0x7F; 1323 + bool ringstatus = data[285] & 0x80; 1324 + bool prox = buttons || ringstatus; 1325 + 1326 + /* Fix touchring data: userspace expects 0 at left and increasing clockwise */ 1327 + ring = 71 - ring; 1328 + ring += 3*72/16; 1329 + if (ring > 71) 1330 + ring -= 72; 1330 1331 1331 1332 wacom_report_numbered_buttons(pad_input, 9, buttons); 1332 1333 1333 - input_report_abs(pad_input, ABS_WHEEL, (ring & 0x80) ? (ring & 0x7f) : 0); 1334 + input_report_abs(pad_input, ABS_WHEEL, ringstatus ? ring : 0); 1334 1335 1335 1336 input_report_key(pad_input, wacom->tool[1], prox ? 1 : 0); 1336 1337 input_report_abs(pad_input, ABS_MISC, prox ? PAD_DEVICE_ID : 0); ··· 1629 1616 return 0; 1630 1617 } 1631 1618 1619 + static int wacom_offset_rotation(struct input_dev *input, struct hid_usage *usage, 1620 + int value, int num, int denom) 1621 + { 1622 + struct input_absinfo *abs = &input->absinfo[usage->code]; 1623 + int range = (abs->maximum - abs->minimum + 1); 1624 + 1625 + value += num*range/denom; 1626 + if (value > abs->maximum) 1627 + value -= range; 1628 + else if (value < abs->minimum) 1629 + value += range; 1630 + return value; 1631 + } 1632 + 1632 1633 int wacom_equivalent_usage(int usage) 1633 1634 { 1634 1635 if ((usage & HID_USAGE_PAGE) == WACOM_HID_UP_WACOMDIGITIZER) { ··· 1925 1898 unsigned equivalent_usage = wacom_equivalent_usage(usage->hid); 1926 1899 int i; 1927 1900 bool is_touch_on = value; 1901 + bool do_report = false; 1928 1902 1929 1903 /* 1930 1904 * Avoid reporting this event and setting inrange_state if this usage ··· 1940 1912 } 1941 1913 1942 1914 switch (equivalent_usage) { 1915 + case WACOM_HID_WD_TOUCHRING: 1916 + /* 1917 + * Userspace expects touchrings to increase in value with 1918 + * clockwise gestures and have their zero point at the 1919 + * tablet's left. HID events "should" be clockwise- 1920 + * increasing and zero at top, though the MobileStudio 1921 + * Pro and 2nd-gen Intuos Pro don't do this... 1922 + */ 1923 + if (hdev->vendor == 0x56a && 1924 + (hdev->product == 0x34d || hdev->product == 0x34e || /* MobileStudio Pro */ 1925 + hdev->product == 0x357 || hdev->product == 0x358)) { /* Intuos Pro 2 */ 1926 + value = (field->logical_maximum - value); 1927 + 1928 + if (hdev->product == 0x357 || hdev->product == 0x358) 1929 + value = wacom_offset_rotation(input, usage, value, 3, 16); 1930 + else if (hdev->product == 0x34d || hdev->product == 0x34e) 1931 + value = wacom_offset_rotation(input, usage, value, 1, 2); 1932 + } 1933 + else { 1934 + value = wacom_offset_rotation(input, usage, value, 1, 4); 1935 + } 1936 + do_report = true; 1937 + break; 1943 1938 case WACOM_HID_WD_TOUCHRINGSTATUS: 1944 1939 if (!value) 1945 1940 input_event(input, usage->type, usage->code, 0); ··· 1996 1945 value, i); 1997 1946 /* fall through*/ 1998 1947 default: 1948 + do_report = true; 1949 + break; 1950 + } 1951 + 1952 + if (do_report) { 1999 1953 input_event(input, usage->type, usage->code, value); 2000 1954 if (value) 2001 1955 wacom_wac->hid_data.pad_input_event_flag = true; 2002 - break; 2003 1956 } 2004 1957 } 2005 1958 ··· 2141 2086 wacom_wac->hid_data.tipswitch |= value; 2142 2087 return; 2143 2088 case HID_DG_TOOLSERIALNUMBER: 2144 - wacom_wac->serial[0] = (wacom_wac->serial[0] & ~0xFFFFFFFFULL); 2145 - wacom_wac->serial[0] |= (__u32)value; 2089 + if (value) { 2090 + wacom_wac->serial[0] = (wacom_wac->serial[0] & ~0xFFFFFFFFULL); 2091 + wacom_wac->serial[0] |= (__u32)value; 2092 + } 2146 2093 return; 2094 + case HID_DG_TWIST: 2095 + /* 2096 + * Userspace expects pen twist to have its zero point when 2097 + * the buttons/finger is on the tablet's left. HID values 2098 + * are zero when buttons are toward the top. 2099 + */ 2100 + value = wacom_offset_rotation(input, usage, value, 1, 4); 2101 + break; 2147 2102 case WACOM_HID_WD_SENSE: 2148 2103 wacom_wac->hid_data.sense_state = value; 2149 2104 return; 2150 2105 case WACOM_HID_WD_SERIALHI: 2151 - wacom_wac->serial[0] = (wacom_wac->serial[0] & 0xFFFFFFFF); 2152 - wacom_wac->serial[0] |= ((__u64)value) << 32; 2153 - /* 2154 - * Non-USI EMR devices may contain additional tool type 2155 - * information here. See WACOM_HID_WD_TOOLTYPE case for 2156 - * more details. 2157 - */ 2158 - if (value >> 20 == 1) { 2159 - wacom_wac->id[0] |= value & 0xFFFFF; 2106 + if (value) { 2107 + wacom_wac->serial[0] = (wacom_wac->serial[0] & 0xFFFFFFFF); 2108 + wacom_wac->serial[0] |= ((__u64)value) << 32; 2109 + /* 2110 + * Non-USI EMR devices may contain additional tool type 2111 + * information here. See WACOM_HID_WD_TOOLTYPE case for 2112 + * more details. 2113 + */ 2114 + if (value >> 20 == 1) { 2115 + wacom_wac->id[0] |= value & 0xFFFFF; 2116 + } 2160 2117 } 2161 2118 return; 2162 2119 case WACOM_HID_WD_TOOLTYPE: ··· 2272 2205 input_report_key(input, wacom_wac->tool[0], prox); 2273 2206 if (wacom_wac->serial[0]) { 2274 2207 input_event(input, EV_MSC, MSC_SERIAL, wacom_wac->serial[0]); 2275 - input_report_abs(input, ABS_MISC, id); 2208 + input_report_abs(input, ABS_MISC, prox ? id : 0); 2276 2209 } 2277 2210 2278 2211 wacom_wac->hid_data.tipswitch = false; ··· 2283 2216 if (!prox) { 2284 2217 wacom_wac->tool[0] = 0; 2285 2218 wacom_wac->id[0] = 0; 2219 + wacom_wac->serial[0] = 0; 2286 2220 } 2287 2221 } 2288 2222