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

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid

Pull HID fixes from Jiri Kosina:

- regression fixes (reverts) for module loading changes that turned out
to be incompatible with some userspace, from Benjamin Tissoires

- regression fix for special Logitech unifiying receiver 0xc52f, from
Hans de Goede

- a few device ID additions to logitech driver, from Hans de Goede

- fix for Bluetooth support on 2nd-gen Wacom Intuos Pro, from Jason
Gerecke

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid:
HID: logitech-dj: Fix 064d:c52f receiver support
Revert "HID: core: Call request_module before doing device_add"
Revert "HID: core: Do not call request_module() in async context"
Revert "HID: Increase maximum report size allowed by hid_field_extract()"
HID: a4tech: fix horizontal scrolling
HID: hyperv: Add a module description line
HID: logitech-hidpp: Add support for the S510 remote control
HID: multitouch: handle faulty Elo touch device
HID: wacom: Sync INTUOSP2_BT touch state after each frame if necessary
HID: wacom: Correct button numbering 2nd-gen Intuos Pro over Bluetooth
HID: wacom: Send BTN_TOUCH in response to INTUOSP2_BT eraser contact
HID: wacom: Don't report anything prior to the tool entering range
HID: wacom: Don't set tool type until we're in range
HID: rmi: Use SET_REPORT request on control endpoint for Acer Switch 3 and 5
HID: logitech-hidpp: add support for the MX5500 keyboard
HID: logitech-dj: add support for the Logitech MX5500's Bluetooth Mini-Receiver
HID: i2c-hid: add iBall Aer3 to descriptor override

+137 -55
+8 -3
drivers/hid/hid-a4tech.c
··· 35 35 { 36 36 struct a4tech_sc *a4 = hid_get_drvdata(hdev); 37 37 38 - if (usage->type == EV_REL && usage->code == REL_WHEEL) 38 + if (usage->type == EV_REL && usage->code == REL_WHEEL_HI_RES) { 39 39 set_bit(REL_HWHEEL, *bit); 40 + set_bit(REL_HWHEEL_HI_RES, *bit); 41 + } 40 42 41 43 if ((a4->quirks & A4_2WHEEL_MOUSE_HACK_7) && usage->hid == 0x00090007) 42 44 return -1; ··· 59 57 input = field->hidinput->input; 60 58 61 59 if (a4->quirks & A4_2WHEEL_MOUSE_HACK_B8) { 62 - if (usage->type == EV_REL && usage->code == REL_WHEEL) { 60 + if (usage->type == EV_REL && usage->code == REL_WHEEL_HI_RES) { 63 61 a4->delayed_value = value; 64 62 return 1; 65 63 } ··· 67 65 if (usage->hid == 0x000100b8) { 68 66 input_event(input, EV_REL, value ? REL_HWHEEL : 69 67 REL_WHEEL, a4->delayed_value); 68 + input_event(input, EV_REL, value ? REL_HWHEEL_HI_RES : 69 + REL_WHEEL_HI_RES, a4->delayed_value * 120); 70 70 return 1; 71 71 } 72 72 } ··· 78 74 return 1; 79 75 } 80 76 81 - if (usage->code == REL_WHEEL && a4->hw_wheel) { 77 + if (usage->code == REL_WHEEL_HI_RES && a4->hw_wheel) { 82 78 input_event(input, usage->type, REL_HWHEEL, value); 79 + input_event(input, usage->type, REL_HWHEEL_HI_RES, value * 120); 83 80 return 1; 84 81 } 85 82
+3 -13
drivers/hid/hid-core.c
··· 27 27 #include <linux/vmalloc.h> 28 28 #include <linux/sched.h> 29 29 #include <linux/semaphore.h> 30 - #include <linux/async.h> 31 30 32 31 #include <linux/hid.h> 33 32 #include <linux/hiddev.h> ··· 1310 1311 u32 hid_field_extract(const struct hid_device *hid, u8 *report, 1311 1312 unsigned offset, unsigned n) 1312 1313 { 1313 - if (n > 256) { 1314 - hid_warn(hid, "hid_field_extract() called with n (%d) > 256! (%s)\n", 1314 + if (n > 32) { 1315 + hid_warn(hid, "hid_field_extract() called with n (%d) > 32! (%s)\n", 1315 1316 n, current->comm); 1316 - n = 256; 1317 + n = 32; 1317 1318 } 1318 1319 1319 1320 return __extract(report, offset, n); ··· 2360 2361 * is converted to allow more than 20 bytes as the device name? */ 2361 2362 dev_set_name(&hdev->dev, "%04X:%04X:%04X.%04X", hdev->bus, 2362 2363 hdev->vendor, hdev->product, atomic_inc_return(&id)); 2363 - 2364 - /* 2365 - * Try loading the module for the device before the add, so that we do 2366 - * not first have hid-generic binding only to have it replaced 2367 - * immediately afterwards with a specialized driver. 2368 - */ 2369 - if (!current_is_async()) 2370 - request_module("hid:b%04Xg%04Xv%08Xp%08X", hdev->bus, 2371 - hdev->group, hdev->vendor, hdev->product); 2372 2364 2373 2365 hid_debug_register(hdev, dev_name(&hdev->dev)); 2374 2366 ret = device_add(&hdev->dev);
+2
drivers/hid/hid-hyperv.c
··· 606 606 } 607 607 608 608 MODULE_LICENSE("GPL"); 609 + MODULE_DESCRIPTION("Microsoft Hyper-V Synthetic HID Driver"); 610 + 609 611 module_init(mousevsc_init); 610 612 module_exit(mousevsc_exit);
+1
drivers/hid/hid-ids.h
··· 1086 1086 #define USB_DEVICE_ID_SYNAPTICS_HD 0x0ac3 1087 1087 #define USB_DEVICE_ID_SYNAPTICS_QUAD_HD 0x1ac3 1088 1088 #define USB_DEVICE_ID_SYNAPTICS_TP_V103 0x5710 1089 + #define USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5 0x81a7 1089 1090 1090 1091 #define USB_VENDOR_ID_TEXAS_INSTRUMENTS 0x2047 1091 1092 #define USB_DEVICE_ID_TEXAS_INSTRUMENTS_LENOVO_YOGA 0x0855
+35 -15
drivers/hid/hid-logitech-dj.c
··· 113 113 recvr_type_dj, 114 114 recvr_type_hidpp, 115 115 recvr_type_gaming_hidpp, 116 + recvr_type_mouse_only, 116 117 recvr_type_27mhz, 117 118 recvr_type_bluetooth, 118 119 }; ··· 865 864 schedule_work(&djrcv_dev->work); 866 865 } 867 866 868 - static void logi_hidpp_dev_conn_notif_equad(struct hidpp_event *hidpp_report, 867 + static void logi_hidpp_dev_conn_notif_equad(struct hid_device *hdev, 868 + struct hidpp_event *hidpp_report, 869 869 struct dj_workitem *workitem) 870 870 { 871 + struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev); 872 + 871 873 workitem->type = WORKITEM_TYPE_PAIRED; 872 874 workitem->device_type = hidpp_report->params[HIDPP_PARAM_DEVICE_INFO] & 873 875 HIDPP_DEVICE_TYPE_MASK; ··· 884 880 break; 885 881 case REPORT_TYPE_MOUSE: 886 882 workitem->reports_supported |= STD_MOUSE | HIDPP; 883 + if (djrcv_dev->type == recvr_type_mouse_only) 884 + workitem->reports_supported |= MULTIMEDIA; 887 885 break; 888 886 } 889 887 } ··· 929 923 case 0x01: 930 924 device_type = "Bluetooth"; 931 925 /* Bluetooth connect packet contents is the same as (e)QUAD */ 932 - logi_hidpp_dev_conn_notif_equad(hidpp_report, &workitem); 926 + logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem); 933 927 if (!(hidpp_report->params[HIDPP_PARAM_DEVICE_INFO] & 934 928 HIDPP_MANUFACTURER_MASK)) { 935 929 hid_info(hdev, "Non Logitech device connected on slot %d\n", ··· 943 937 break; 944 938 case 0x03: 945 939 device_type = "QUAD or eQUAD"; 946 - logi_hidpp_dev_conn_notif_equad(hidpp_report, &workitem); 940 + logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem); 947 941 break; 948 942 case 0x04: 949 943 device_type = "eQUAD step 4 DJ"; 950 - logi_hidpp_dev_conn_notif_equad(hidpp_report, &workitem); 944 + logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem); 951 945 break; 952 946 case 0x05: 953 947 device_type = "DFU Lite"; 954 948 break; 955 949 case 0x06: 956 950 device_type = "eQUAD step 4 Lite"; 957 - logi_hidpp_dev_conn_notif_equad(hidpp_report, &workitem); 951 + logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem); 958 952 break; 959 953 case 0x07: 960 954 device_type = "eQUAD step 4 Gaming"; ··· 964 958 break; 965 959 case 0x0a: 966 960 device_type = "eQUAD nano Lite"; 967 - logi_hidpp_dev_conn_notif_equad(hidpp_report, &workitem); 961 + logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem); 968 962 break; 969 963 case 0x0c: 970 964 device_type = "eQUAD Lightspeed"; 971 - logi_hidpp_dev_conn_notif_equad(hidpp_report, &workitem); 965 + logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem); 972 966 workitem.reports_supported |= STD_KEYBOARD; 973 967 break; 974 968 } ··· 1319 1313 if (djdev->reports_supported & STD_MOUSE) { 1320 1314 dbg_hid("%s: sending a mouse descriptor, reports_supported: %llx\n", 1321 1315 __func__, djdev->reports_supported); 1322 - if (djdev->dj_receiver_dev->type == recvr_type_gaming_hidpp) 1316 + if (djdev->dj_receiver_dev->type == recvr_type_gaming_hidpp || 1317 + djdev->dj_receiver_dev->type == recvr_type_mouse_only) 1323 1318 rdcat(rdesc, &rsize, mse_high_res_descriptor, 1324 1319 sizeof(mse_high_res_descriptor)); 1325 1320 else if (djdev->dj_receiver_dev->type == recvr_type_27mhz) ··· 1563 1556 data[0] = data[1]; 1564 1557 data[1] = 0; 1565 1558 } 1566 - /* The 27 MHz mouse-only receiver sends unnumbered mouse data */ 1559 + /* 1560 + * Mouse-only receivers send unnumbered mouse data. The 27 MHz 1561 + * receiver uses 6 byte packets, the nano receiver 8 bytes. 1562 + */ 1567 1563 if (djrcv_dev->unnumbered_application == HID_GD_MOUSE && 1568 - size == 6) { 1569 - u8 mouse_report[7]; 1564 + size <= 8) { 1565 + u8 mouse_report[9]; 1570 1566 1571 1567 /* Prepend report id */ 1572 1568 mouse_report[0] = REPORT_TYPE_MOUSE; 1573 - memcpy(mouse_report + 1, data, 6); 1574 - logi_dj_recv_forward_input_report(hdev, mouse_report, 7); 1569 + memcpy(mouse_report + 1, data, size); 1570 + logi_dj_recv_forward_input_report(hdev, mouse_report, 1571 + size + 1); 1575 1572 } 1576 1573 1577 1574 return false; ··· 1646 1635 case recvr_type_dj: no_dj_interfaces = 3; break; 1647 1636 case recvr_type_hidpp: no_dj_interfaces = 2; break; 1648 1637 case recvr_type_gaming_hidpp: no_dj_interfaces = 3; break; 1638 + case recvr_type_mouse_only: no_dj_interfaces = 2; break; 1649 1639 case recvr_type_27mhz: no_dj_interfaces = 2; break; 1650 1640 case recvr_type_bluetooth: no_dj_interfaces = 2; break; 1651 1641 } ··· 1820 1808 {HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 1821 1809 USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER_2), 1822 1810 .driver_data = recvr_type_dj}, 1823 - { /* Logitech Nano (non DJ) receiver */ 1811 + { /* Logitech Nano mouse only receiver */ 1824 1812 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 1825 1813 USB_DEVICE_ID_LOGITECH_NANO_RECEIVER), 1826 - .driver_data = recvr_type_hidpp}, 1814 + .driver_data = recvr_type_mouse_only}, 1827 1815 { /* Logitech Nano (non DJ) receiver */ 1828 1816 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 1829 1817 USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_2), ··· 1847 1835 { /* Logitech MX5000 HID++ / bluetooth receiver mouse intf. */ 1848 1836 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 1849 1837 0xc70a), 1838 + .driver_data = recvr_type_bluetooth}, 1839 + { /* Logitech MX5500 HID++ / bluetooth receiver keyboard intf. */ 1840 + HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 1841 + 0xc71b), 1842 + .driver_data = recvr_type_bluetooth}, 1843 + { /* Logitech MX5500 HID++ / bluetooth receiver mouse intf. */ 1844 + HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 1845 + 0xc71c), 1850 1846 .driver_data = recvr_type_bluetooth}, 1851 1847 {} 1852 1848 };
+9
drivers/hid/hid-logitech-hidpp.c
··· 3728 3728 { /* Keyboard MX5000 (Bluetooth-receiver in HID proxy mode) */ 3729 3729 LDJ_DEVICE(0xb305), 3730 3730 .driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS }, 3731 + { /* Keyboard MX5500 (Bluetooth-receiver in HID proxy mode) */ 3732 + LDJ_DEVICE(0xb30b), 3733 + .driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS }, 3731 3734 3732 3735 { LDJ_DEVICE(HID_ANY_ID) }, 3733 3736 ··· 3743 3740 { /* Keyboard MX3200 (Y-RAV80) */ 3744 3741 L27MHZ_DEVICE(0x005c), 3745 3742 .driver_data = HIDPP_QUIRK_KBD_ZOOM_WHEEL }, 3743 + { /* S510 Media Remote */ 3744 + L27MHZ_DEVICE(0x00fe), 3745 + .driver_data = HIDPP_QUIRK_KBD_SCROLL_WHEEL }, 3746 3746 3747 3747 { L27MHZ_DEVICE(HID_ANY_ID) }, 3748 3748 ··· 3761 3755 3762 3756 { /* MX5000 keyboard over Bluetooth */ 3763 3757 HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb305), 3758 + .driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS }, 3759 + { /* MX5500 keyboard over Bluetooth */ 3760 + HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb30b), 3764 3761 .driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS }, 3765 3762 {} 3766 3763 };
+7
drivers/hid/hid-multitouch.c
··· 637 637 if (*target != DEFAULT_TRUE && 638 638 *target != DEFAULT_FALSE && 639 639 *target != DEFAULT_ZERO) { 640 + if (usage->contactid == DEFAULT_ZERO || 641 + usage->x == DEFAULT_ZERO || 642 + usage->y == DEFAULT_ZERO) { 643 + hid_dbg(hdev, 644 + "ignoring duplicate usage on incomplete"); 645 + return; 646 + } 640 647 usage = mt_allocate_usage(hdev, application); 641 648 if (!usage) 642 649 return;
+14 -1
drivers/hid/hid-rmi.c
··· 35 35 /* device flags */ 36 36 #define RMI_DEVICE BIT(0) 37 37 #define RMI_DEVICE_HAS_PHYS_BUTTONS BIT(1) 38 + #define RMI_DEVICE_OUTPUT_SET_REPORT BIT(2) 38 39 39 40 /* 40 41 * retrieve the ctrl registers ··· 164 163 165 164 static int rmi_write_report(struct hid_device *hdev, u8 *report, int len) 166 165 { 166 + struct rmi_data *data = hid_get_drvdata(hdev); 167 167 int ret; 168 168 169 - ret = hid_hw_output_report(hdev, (void *)report, len); 169 + if (data->device_flags & RMI_DEVICE_OUTPUT_SET_REPORT) { 170 + /* 171 + * Talk to device by using SET_REPORT requests instead. 172 + */ 173 + ret = hid_hw_raw_request(hdev, report[0], report, 174 + len, HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); 175 + } else { 176 + ret = hid_hw_output_report(hdev, (void *)report, len); 177 + } 178 + 170 179 if (ret < 0) { 171 180 dev_err(&hdev->dev, "failed to write hid report (%d)\n", ret); 172 181 return ret; ··· 758 747 .driver_data = RMI_DEVICE_HAS_PHYS_BUTTONS }, 759 748 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_X1_COVER) }, 760 749 { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_REZEL) }, 750 + { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5), 751 + .driver_data = RMI_DEVICE_OUTPUT_SET_REPORT }, 761 752 { HID_DEVICE(HID_BUS_ANY, HID_GROUP_RMI, HID_ANY_ID, HID_ANY_ID) }, 762 753 { } 763 754 };
+8
drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c
··· 354 354 }, 355 355 .driver_data = (void *)&sipodev_desc 356 356 }, 357 + { 358 + .ident = "iBall Aer3", 359 + .matches = { 360 + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "iBall"), 361 + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Aer3"), 362 + }, 363 + .driver_data = (void *)&sipodev_desc 364 + }, 357 365 { } /* Terminate list */ 358 366 }; 359 367
+50 -23
drivers/hid/wacom_wac.c
··· 1232 1232 /* Add back in missing bits of ID for non-USI pens */ 1233 1233 wacom->id[0] |= (wacom->serial[0] >> 32) & 0xFFFFF; 1234 1234 } 1235 - wacom->tool[0] = wacom_intuos_get_tool_type(wacom_intuos_id_mangle(wacom->id[0])); 1236 1235 1237 1236 for (i = 0; i < pen_frames; i++) { 1238 1237 unsigned char *frame = &data[i*pen_frame_len + 1]; 1239 1238 bool valid = frame[0] & 0x80; 1240 1239 bool prox = frame[0] & 0x40; 1241 1240 bool range = frame[0] & 0x20; 1241 + bool invert = frame[0] & 0x10; 1242 1242 1243 1243 if (!valid) 1244 1244 continue; ··· 1247 1247 wacom->shared->stylus_in_proximity = false; 1248 1248 wacom_exit_report(wacom); 1249 1249 input_sync(pen_input); 1250 + 1251 + wacom->tool[0] = 0; 1252 + wacom->id[0] = 0; 1253 + wacom->serial[0] = 0; 1250 1254 return; 1251 1255 } 1256 + 1252 1257 if (range) { 1258 + if (!wacom->tool[0]) { /* first in range */ 1259 + /* Going into range select tool */ 1260 + if (invert) 1261 + wacom->tool[0] = BTN_TOOL_RUBBER; 1262 + else if (wacom->id[0]) 1263 + wacom->tool[0] = wacom_intuos_get_tool_type(wacom->id[0]); 1264 + else 1265 + wacom->tool[0] = BTN_TOOL_PEN; 1266 + } 1267 + 1253 1268 input_report_abs(pen_input, ABS_X, get_unaligned_le16(&frame[1])); 1254 1269 input_report_abs(pen_input, ABS_Y, get_unaligned_le16(&frame[3])); 1255 1270 ··· 1286 1271 get_unaligned_le16(&frame[11])); 1287 1272 } 1288 1273 } 1289 - input_report_abs(pen_input, ABS_PRESSURE, get_unaligned_le16(&frame[5])); 1290 - if (wacom->features.type == INTUOSP2_BT) { 1291 - input_report_abs(pen_input, ABS_DISTANCE, 1292 - range ? frame[13] : wacom->features.distance_max); 1293 - } else { 1294 - input_report_abs(pen_input, ABS_DISTANCE, 1295 - range ? frame[7] : wacom->features.distance_max); 1274 + 1275 + if (wacom->tool[0]) { 1276 + input_report_abs(pen_input, ABS_PRESSURE, get_unaligned_le16(&frame[5])); 1277 + if (wacom->features.type == INTUOSP2_BT) { 1278 + input_report_abs(pen_input, ABS_DISTANCE, 1279 + range ? frame[13] : wacom->features.distance_max); 1280 + } else { 1281 + input_report_abs(pen_input, ABS_DISTANCE, 1282 + range ? frame[7] : wacom->features.distance_max); 1283 + } 1284 + 1285 + input_report_key(pen_input, BTN_TOUCH, frame[0] & 0x09); 1286 + input_report_key(pen_input, BTN_STYLUS, frame[0] & 0x02); 1287 + input_report_key(pen_input, BTN_STYLUS2, frame[0] & 0x04); 1288 + 1289 + input_report_key(pen_input, wacom->tool[0], prox); 1290 + input_event(pen_input, EV_MSC, MSC_SERIAL, wacom->serial[0]); 1291 + input_report_abs(pen_input, ABS_MISC, 1292 + wacom_intuos_id_mangle(wacom->id[0])); /* report tool id */ 1296 1293 } 1297 - 1298 - input_report_key(pen_input, BTN_TOUCH, frame[0] & 0x01); 1299 - input_report_key(pen_input, BTN_STYLUS, frame[0] & 0x02); 1300 - input_report_key(pen_input, BTN_STYLUS2, frame[0] & 0x04); 1301 - 1302 - input_report_key(pen_input, wacom->tool[0], prox); 1303 - input_event(pen_input, EV_MSC, MSC_SERIAL, wacom->serial[0]); 1304 - input_report_abs(pen_input, ABS_MISC, 1305 - wacom_intuos_id_mangle(wacom->id[0])); /* report tool id */ 1306 1294 1307 1295 wacom->shared->stylus_in_proximity = prox; 1308 1296 ··· 1367 1349 if (wacom->num_contacts_left <= 0) { 1368 1350 wacom->num_contacts_left = 0; 1369 1351 wacom->shared->touch_down = wacom_wac_finger_count_touches(wacom); 1352 + input_sync(touch_input); 1370 1353 } 1371 1354 } 1372 1355 1373 - input_report_switch(touch_input, SW_MUTE_DEVICE, !(data[281] >> 7)); 1374 - input_sync(touch_input); 1356 + if (wacom->num_contacts_left == 0) { 1357 + // Be careful that we don't accidentally call input_sync with 1358 + // only a partial set of fingers of processed 1359 + input_report_switch(touch_input, SW_MUTE_DEVICE, !(data[281] >> 7)); 1360 + input_sync(touch_input); 1361 + } 1362 + 1375 1363 } 1376 1364 1377 1365 static void wacom_intuos_pro2_bt_pad(struct wacom_wac *wacom) ··· 1385 1361 struct input_dev *pad_input = wacom->pad_input; 1386 1362 unsigned char *data = wacom->data; 1387 1363 1388 - int buttons = (data[282] << 1) | ((data[281] >> 6) & 0x01); 1364 + int buttons = data[282] | ((data[281] & 0x40) << 2); 1389 1365 int ring = data[285] & 0x7F; 1390 1366 bool ringstatus = data[285] & 0x80; 1391 1367 bool prox = buttons || ringstatus; ··· 3834 3810 static bool wacom_is_led_toggled(struct wacom *wacom, int button_count, 3835 3811 int mask, int group) 3836 3812 { 3837 - int button_per_group; 3813 + int group_button; 3838 3814 3839 3815 /* 3840 3816 * 21UX2 has LED group 1 to the left and LED group 0 ··· 3844 3820 if (wacom->wacom_wac.features.type == WACOM_21UX2) 3845 3821 group = 1 - group; 3846 3822 3847 - button_per_group = button_count/wacom->led.count; 3823 + group_button = group * (button_count/wacom->led.count); 3848 3824 3849 - return mask & (1 << (group * button_per_group)); 3825 + if (wacom->wacom_wac.features.type == INTUOSP2_BT) 3826 + group_button = 8; 3827 + 3828 + return mask & (1 << group_button); 3850 3829 } 3851 3830 3852 3831 static void wacom_update_led(struct wacom *wacom, int button_count, int mask,