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 updates from Jiri Kosina:

- high-resolution scrolling support that gracefully handles differences
between MS and Logitech implementations in HW, from Peter Hutterer
and Harry Cutts

- MSI IRQ support for intel-ish driver, from Song Hongyan

- support for new hardware (Cougar 700K, Odys Winbook 13, ASUS FX503VD,
ASUS T101HA) from Daniel M. Lambea, Hans de Goede and Aleix Roca
Nonell

- other small assorted fixups

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid: (22 commits)
HID: i2c-hid: Add Odys Winbook 13 to descriptor override
HID: lenovo: Add checks to fix of_led_classdev_register
HID: intel-ish-hid: add MSI interrupt support
HID: debug: Change to use DEFINE_SHOW_ATTRIBUTE macro
HID: doc: fix wrong data structure reference for UHID_OUTPUT
HID: intel-ish-hid: fixes incorrect error handling
HID: asus: Add support for the ASUS T101HA keyboard dock
HID: logitech: Use LDJ_DEVICE macro for existing Logitech mice
HID: logitech: Enable high-resolution scrolling on Logitech mice
HID: logitech: Add function to enable HID++ 1.0 "scrolling acceleration"
HID: logitech-hidpp: fix typo, hiddpp to hidpp
HID: input: use the Resolution Multiplier for high-resolution scrolling
HID: core: process the Resolution Multiplier
HID: core: store the collections as a basic tree
Input: add `REL_WHEEL_HI_RES` and `REL_HWHEEL_HI_RES`
HID: input: support Microsoft wireless radio control hotkey
HID: use macros in IS_INPUT_APPLICATION
HID: asus: Add support for the ASUS FX503VD laptop
HID: asus: Add event handler to catch unmapped Asus Vendor UsagePage codes
HID: cougar: Add support for Cougar 700K Gaming Keyboard
...

+720 -61
+1 -1
Documentation/hid/uhid.txt
··· 160 160 UHID_OUTPUT: 161 161 This is sent if the HID device driver wants to send raw data to the I/O 162 162 device on the interrupt channel. You should read the payload and forward it to 163 - the device. The payload is of type "struct uhid_data_req". 163 + the device. The payload is of type "struct uhid_output_req". 164 164 This may be received even though you haven't received UHID_OPEN, yet. 165 165 166 166 UHID_GET_REPORT:
+20 -1
Documentation/input/event-codes.rst
··· 190 190 * REL_WHEEL, REL_HWHEEL: 191 191 192 192 - These codes are used for vertical and horizontal scroll wheels, 193 - respectively. 193 + respectively. The value is the number of detents moved on the wheel, the 194 + physical size of which varies by device. For high-resolution wheels 195 + this may be an approximation based on the high-resolution scroll events, 196 + see REL_WHEEL_HI_RES. These event codes are legacy codes and 197 + REL_WHEEL_HI_RES and REL_HWHEEL_HI_RES should be preferred where 198 + available. 199 + 200 + * REL_WHEEL_HI_RES, REL_HWHEEL_HI_RES: 201 + 202 + - High-resolution scroll wheel data. The accumulated value 120 represents 203 + movement by one detent. For devices that do not provide high-resolution 204 + scrolling, the value is always a multiple of 120. For devices with 205 + high-resolution scrolling, the value may be a fraction of 120. 206 + 207 + If a vertical scroll wheel supports high-resolution scrolling, this code 208 + will be emitted in addition to REL_WHEEL or REL_HWHEEL. The REL_WHEEL 209 + and REL_HWHEEL may be an approximation based on the high-resolution 210 + scroll events. There is no guarantee that the high-resolution data 211 + is a multiple of 120 at the time of an emulated REL_WHEEL or REL_HWHEEL 212 + event. 194 213 195 214 EV_ABS 196 215 ------
+28
drivers/hid/hid-asus.c
··· 70 70 #define QUIRK_T100_KEYBOARD BIT(6) 71 71 #define QUIRK_T100CHI BIT(7) 72 72 #define QUIRK_G752_KEYBOARD BIT(8) 73 + #define QUIRK_T101HA_DOCK BIT(9) 73 74 74 75 #define I2C_KEYBOARD_QUIRKS (QUIRK_FIX_NOTEBOOK_REPORT | \ 75 76 QUIRK_NO_INIT_REPORTS | \ ··· 240 239 input_sync(drvdat->input); 241 240 242 241 return 1; 242 + } 243 + 244 + static int asus_event(struct hid_device *hdev, struct hid_field *field, 245 + struct hid_usage *usage, __s32 value) 246 + { 247 + if ((usage->hid & HID_USAGE_PAGE) == 0xff310000 && 248 + (usage->hid & HID_USAGE) != 0x00 && !usage->type) { 249 + hid_warn(hdev, "Unmapped Asus vendor usagepage code 0x%02x\n", 250 + usage->hid & HID_USAGE); 251 + } 252 + 253 + return 0; 243 254 } 244 255 245 256 static int asus_raw_event(struct hid_device *hdev, ··· 523 510 case 0x20: asus_map_key_clear(KEY_BRIGHTNESSUP); break; 524 511 case 0x35: asus_map_key_clear(KEY_DISPLAY_OFF); break; 525 512 case 0x6c: asus_map_key_clear(KEY_SLEEP); break; 513 + case 0x7c: asus_map_key_clear(KEY_MICMUTE); break; 526 514 case 0x82: asus_map_key_clear(KEY_CAMERA); break; 527 515 case 0x88: asus_map_key_clear(KEY_RFKILL); break; 528 516 case 0xb5: asus_map_key_clear(KEY_CALC); break; ··· 541 527 542 528 /* Fn+Space Power4Gear Hybrid */ 543 529 case 0x5c: asus_map_key_clear(KEY_PROG3); break; 530 + 531 + /* Fn+F5 "fan" symbol on FX503VD */ 532 + case 0x99: asus_map_key_clear(KEY_PROG4); break; 544 533 545 534 default: 546 535 /* ASUS lazily declares 256 usages, ignore the rest, ··· 700 683 return ret; 701 684 } 702 685 686 + /* use hid-multitouch for T101HA touchpad */ 687 + if (id->driver_data & QUIRK_T101HA_DOCK && 688 + hdev->collection->usage == HID_GD_MOUSE) 689 + return -ENODEV; 690 + 703 691 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 704 692 if (ret) { 705 693 hid_err(hdev, "Asus hw start failed: %d\n", ret); ··· 828 806 { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, 829 807 USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD3), QUIRK_G752_KEYBOARD }, 830 808 { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, 809 + USB_DEVICE_ID_ASUSTEK_FX503VD_KEYBOARD), 810 + QUIRK_USE_KBD_BACKLIGHT }, 811 + { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, 831 812 USB_DEVICE_ID_ASUSTEK_T100TA_KEYBOARD), 832 813 QUIRK_T100_KEYBOARD | QUIRK_NO_CONSUMER_USAGES }, 833 814 { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, 834 815 USB_DEVICE_ID_ASUSTEK_T100TAF_KEYBOARD), 835 816 QUIRK_T100_KEYBOARD | QUIRK_NO_CONSUMER_USAGES }, 817 + { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, 818 + USB_DEVICE_ID_ASUSTEK_T101HA_KEYBOARD), QUIRK_T101HA_DOCK }, 836 819 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_ASUS_AK1D) }, 837 820 { HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_ASUS_MD_5110) }, 838 821 { HID_USB_DEVICE(USB_VENDOR_ID_JESS, USB_DEVICE_ID_ASUS_MD_5112) }, ··· 859 832 #ifdef CONFIG_PM 860 833 .reset_resume = asus_reset_resume, 861 834 #endif 835 + .event = asus_event, 862 836 .raw_event = asus_raw_event 863 837 }; 864 838 module_hid_driver(asus_driver);
+174
drivers/hid/hid-core.c
··· 172 172 collection->type = type; 173 173 collection->usage = usage; 174 174 collection->level = parser->collection_stack_ptr - 1; 175 + collection->parent = parser->active_collection; 176 + parser->active_collection = collection; 175 177 176 178 if (type == HID_COLLECTION_APPLICATION) 177 179 parser->device->maxapplication++; ··· 192 190 return -EINVAL; 193 191 } 194 192 parser->collection_stack_ptr--; 193 + if (parser->active_collection) 194 + parser->active_collection = parser->active_collection->parent; 195 195 return 0; 196 196 } 197 197 ··· 294 290 field->usage[i].collection_index = 295 291 parser->local.collection_index[j]; 296 292 field->usage[i].usage_index = i; 293 + field->usage[i].resolution_multiplier = 1; 297 294 } 298 295 299 296 field->maxusage = usages; ··· 948 943 } 949 944 EXPORT_SYMBOL_GPL(hid_validate_values); 950 945 946 + static int hid_calculate_multiplier(struct hid_device *hid, 947 + struct hid_field *multiplier) 948 + { 949 + int m; 950 + __s32 v = *multiplier->value; 951 + __s32 lmin = multiplier->logical_minimum; 952 + __s32 lmax = multiplier->logical_maximum; 953 + __s32 pmin = multiplier->physical_minimum; 954 + __s32 pmax = multiplier->physical_maximum; 955 + 956 + /* 957 + * "Because OS implementations will generally divide the control's 958 + * reported count by the Effective Resolution Multiplier, designers 959 + * should take care not to establish a potential Effective 960 + * Resolution Multiplier of zero." 961 + * HID Usage Table, v1.12, Section 4.3.1, p31 962 + */ 963 + if (lmax - lmin == 0) 964 + return 1; 965 + /* 966 + * Handling the unit exponent is left as an exercise to whoever 967 + * finds a device where that exponent is not 0. 968 + */ 969 + m = ((v - lmin)/(lmax - lmin) * (pmax - pmin) + pmin); 970 + if (unlikely(multiplier->unit_exponent != 0)) { 971 + hid_warn(hid, 972 + "unsupported Resolution Multiplier unit exponent %d\n", 973 + multiplier->unit_exponent); 974 + } 975 + 976 + /* There are no devices with an effective multiplier > 255 */ 977 + if (unlikely(m == 0 || m > 255 || m < -255)) { 978 + hid_warn(hid, "unsupported Resolution Multiplier %d\n", m); 979 + m = 1; 980 + } 981 + 982 + return m; 983 + } 984 + 985 + static void hid_apply_multiplier_to_field(struct hid_device *hid, 986 + struct hid_field *field, 987 + struct hid_collection *multiplier_collection, 988 + int effective_multiplier) 989 + { 990 + struct hid_collection *collection; 991 + struct hid_usage *usage; 992 + int i; 993 + 994 + /* 995 + * If multiplier_collection is NULL, the multiplier applies 996 + * to all fields in the report. 997 + * Otherwise, it is the Logical Collection the multiplier applies to 998 + * but our field may be in a subcollection of that collection. 999 + */ 1000 + for (i = 0; i < field->maxusage; i++) { 1001 + usage = &field->usage[i]; 1002 + 1003 + collection = &hid->collection[usage->collection_index]; 1004 + while (collection && collection != multiplier_collection) 1005 + collection = collection->parent; 1006 + 1007 + if (collection || multiplier_collection == NULL) 1008 + usage->resolution_multiplier = effective_multiplier; 1009 + 1010 + } 1011 + } 1012 + 1013 + static void hid_apply_multiplier(struct hid_device *hid, 1014 + struct hid_field *multiplier) 1015 + { 1016 + struct hid_report_enum *rep_enum; 1017 + struct hid_report *rep; 1018 + struct hid_field *field; 1019 + struct hid_collection *multiplier_collection; 1020 + int effective_multiplier; 1021 + int i; 1022 + 1023 + /* 1024 + * "The Resolution Multiplier control must be contained in the same 1025 + * Logical Collection as the control(s) to which it is to be applied. 1026 + * If no Resolution Multiplier is defined, then the Resolution 1027 + * Multiplier defaults to 1. If more than one control exists in a 1028 + * Logical Collection, the Resolution Multiplier is associated with 1029 + * all controls in the collection. If no Logical Collection is 1030 + * defined, the Resolution Multiplier is associated with all 1031 + * controls in the report." 1032 + * HID Usage Table, v1.12, Section 4.3.1, p30 1033 + * 1034 + * Thus, search from the current collection upwards until we find a 1035 + * logical collection. Then search all fields for that same parent 1036 + * collection. Those are the fields the multiplier applies to. 1037 + * 1038 + * If we have more than one multiplier, it will overwrite the 1039 + * applicable fields later. 1040 + */ 1041 + multiplier_collection = &hid->collection[multiplier->usage->collection_index]; 1042 + while (multiplier_collection && 1043 + multiplier_collection->type != HID_COLLECTION_LOGICAL) 1044 + multiplier_collection = multiplier_collection->parent; 1045 + 1046 + effective_multiplier = hid_calculate_multiplier(hid, multiplier); 1047 + 1048 + rep_enum = &hid->report_enum[HID_INPUT_REPORT]; 1049 + list_for_each_entry(rep, &rep_enum->report_list, list) { 1050 + for (i = 0; i < rep->maxfield; i++) { 1051 + field = rep->field[i]; 1052 + hid_apply_multiplier_to_field(hid, field, 1053 + multiplier_collection, 1054 + effective_multiplier); 1055 + } 1056 + } 1057 + } 1058 + 1059 + /* 1060 + * hid_setup_resolution_multiplier - set up all resolution multipliers 1061 + * 1062 + * @device: hid device 1063 + * 1064 + * Search for all Resolution Multiplier Feature Reports and apply their 1065 + * value to all matching Input items. This only updates the internal struct 1066 + * fields. 1067 + * 1068 + * The Resolution Multiplier is applied by the hardware. If the multiplier 1069 + * is anything other than 1, the hardware will send pre-multiplied events 1070 + * so that the same physical interaction generates an accumulated 1071 + * accumulated_value = value * * multiplier 1072 + * This may be achieved by sending 1073 + * - "value * multiplier" for each event, or 1074 + * - "value" but "multiplier" times as frequently, or 1075 + * - a combination of the above 1076 + * The only guarantee is that the same physical interaction always generates 1077 + * an accumulated 'value * multiplier'. 1078 + * 1079 + * This function must be called before any event processing and after 1080 + * any SetRequest to the Resolution Multiplier. 1081 + */ 1082 + void hid_setup_resolution_multiplier(struct hid_device *hid) 1083 + { 1084 + struct hid_report_enum *rep_enum; 1085 + struct hid_report *rep; 1086 + struct hid_usage *usage; 1087 + int i, j; 1088 + 1089 + rep_enum = &hid->report_enum[HID_FEATURE_REPORT]; 1090 + list_for_each_entry(rep, &rep_enum->report_list, list) { 1091 + for (i = 0; i < rep->maxfield; i++) { 1092 + /* Ignore if report count is out of bounds. */ 1093 + if (rep->field[i]->report_count < 1) 1094 + continue; 1095 + 1096 + for (j = 0; j < rep->field[i]->maxusage; j++) { 1097 + usage = &rep->field[i]->usage[j]; 1098 + if (usage->hid == HID_GD_RESOLUTION_MULTIPLIER) 1099 + hid_apply_multiplier(hid, 1100 + rep->field[i]); 1101 + } 1102 + } 1103 + } 1104 + } 1105 + EXPORT_SYMBOL_GPL(hid_setup_resolution_multiplier); 1106 + 951 1107 /** 952 1108 * hid_open_report - open a driver-specific device report 953 1109 * ··· 1205 1039 hid_err(device, "unbalanced delimiter at end of report description\n"); 1206 1040 goto err; 1207 1041 } 1042 + 1043 + /* 1044 + * fetch initial values in case the device's 1045 + * default multiplier isn't the recommended 1 1046 + */ 1047 + hid_setup_resolution_multiplier(device); 1048 + 1208 1049 kfree(parser->collection_stack); 1209 1050 vfree(parser); 1210 1051 device->status |= HID_STAT_PARSED; 1052 + 1211 1053 return 0; 1212 1054 } 1213 1055 }
+2
drivers/hid/hid-cougar.c
··· 326 326 static struct hid_device_id cougar_id_table[] = { 327 327 { HID_USB_DEVICE(USB_VENDOR_ID_SOLID_YEAR, 328 328 USB_DEVICE_ID_COUGAR_500K_GAMING_KEYBOARD) }, 329 + { HID_USB_DEVICE(USB_VENDOR_ID_SOLID_YEAR, 330 + USB_DEVICE_ID_COUGAR_700K_GAMING_KEYBOARD) }, 329 331 {} 330 332 }; 331 333 MODULE_DEVICE_TABLE(hid, cougar_id_table);
+1 -11
drivers/hid/hid-debug.c
··· 1072 1072 return 0; 1073 1073 } 1074 1074 1075 - static int hid_debug_rdesc_open(struct inode *inode, struct file *file) 1076 - { 1077 - return single_open(file, hid_debug_rdesc_show, inode->i_private); 1078 - } 1079 - 1080 1075 static int hid_debug_events_open(struct inode *inode, struct file *file) 1081 1076 { 1082 1077 int err = 0; ··· 1206 1211 return 0; 1207 1212 } 1208 1213 1209 - static const struct file_operations hid_debug_rdesc_fops = { 1210 - .open = hid_debug_rdesc_open, 1211 - .read = seq_read, 1212 - .llseek = seq_lseek, 1213 - .release = single_release, 1214 - }; 1214 + DEFINE_SHOW_ATTRIBUTE(hid_debug_rdesc); 1215 1215 1216 1216 static const struct file_operations hid_debug_events_fops = { 1217 1217 .owner = THIS_MODULE,
+3
drivers/hid/hid-ids.h
··· 187 187 #define USB_DEVICE_ID_ASUSTEK_T100TA_KEYBOARD 0x17e0 188 188 #define USB_DEVICE_ID_ASUSTEK_T100TAF_KEYBOARD 0x1807 189 189 #define USB_DEVICE_ID_ASUSTEK_T100CHI_KEYBOARD 0x8502 190 + #define USB_DEVICE_ID_ASUSTEK_T101HA_KEYBOARD 0x183d 190 191 #define USB_DEVICE_ID_ASUSTEK_T304_KEYBOARD 0x184a 191 192 #define USB_DEVICE_ID_ASUSTEK_I2C_KEYBOARD 0x8585 192 193 #define USB_DEVICE_ID_ASUSTEK_I2C_TOUCHPAD 0x0101 193 194 #define USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD1 0x1854 194 195 #define USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD2 0x1837 195 196 #define USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD3 0x1822 197 + #define USB_DEVICE_ID_ASUSTEK_FX503VD_KEYBOARD 0x1869 196 198 197 199 #define USB_VENDOR_ID_ATEN 0x0557 198 200 #define USB_DEVICE_ID_ATEN_UC100KM 0x2004 ··· 1027 1025 1028 1026 #define USB_VENDOR_ID_SOLID_YEAR 0x060b 1029 1027 #define USB_DEVICE_ID_COUGAR_500K_GAMING_KEYBOARD 0x500a 1028 + #define USB_DEVICE_ID_COUGAR_700K_GAMING_KEYBOARD 0x700a 1030 1029 1031 1030 #define USB_VENDOR_ID_SOUNDGRAPH 0x15c2 1032 1031 #define USB_DEVICE_ID_SOUNDGRAPH_IMON_FIRST 0x0034
+105 -3
drivers/hid/hid-input.c
··· 712 712 map_abs_clear(usage->hid & 0xf); 713 713 break; 714 714 715 - case HID_GD_SLIDER: case HID_GD_DIAL: case HID_GD_WHEEL: 715 + case HID_GD_WHEEL: 716 + if (field->flags & HID_MAIN_ITEM_RELATIVE) { 717 + set_bit(REL_WHEEL, input->relbit); 718 + map_rel(REL_WHEEL_HI_RES); 719 + } else { 720 + map_abs(usage->hid & 0xf); 721 + } 722 + break; 723 + case HID_GD_SLIDER: case HID_GD_DIAL: 716 724 if (field->flags & HID_MAIN_ITEM_RELATIVE) 717 725 map_rel(usage->hid & 0xf); 718 726 else ··· 1020 1012 case 0x22f: map_key_clear(KEY_ZOOMRESET); break; 1021 1013 case 0x233: map_key_clear(KEY_SCROLLUP); break; 1022 1014 case 0x234: map_key_clear(KEY_SCROLLDOWN); break; 1023 - case 0x238: map_rel(REL_HWHEEL); break; 1015 + case 0x238: /* AC Pan */ 1016 + set_bit(REL_HWHEEL, input->relbit); 1017 + map_rel(REL_HWHEEL_HI_RES); 1018 + break; 1024 1019 case 0x23d: map_key_clear(KEY_EDIT); break; 1025 1020 case 0x25f: map_key_clear(KEY_CANCEL); break; 1026 1021 case 0x269: map_key_clear(KEY_INSERT); break; ··· 1211 1200 1212 1201 } 1213 1202 1203 + static void hidinput_handle_scroll(struct hid_usage *usage, 1204 + struct input_dev *input, 1205 + __s32 value) 1206 + { 1207 + int code; 1208 + int hi_res, lo_res; 1209 + 1210 + if (value == 0) 1211 + return; 1212 + 1213 + if (usage->code == REL_WHEEL_HI_RES) 1214 + code = REL_WHEEL; 1215 + else 1216 + code = REL_HWHEEL; 1217 + 1218 + /* 1219 + * Windows reports one wheel click as value 120. Where a high-res 1220 + * scroll wheel is present, a fraction of 120 is reported instead. 1221 + * Our REL_WHEEL_HI_RES axis does the same because all HW must 1222 + * adhere to the 120 expectation. 1223 + */ 1224 + hi_res = value * 120/usage->resolution_multiplier; 1225 + 1226 + usage->wheel_accumulated += hi_res; 1227 + lo_res = usage->wheel_accumulated/120; 1228 + if (lo_res) 1229 + usage->wheel_accumulated -= lo_res * 120; 1230 + 1231 + input_event(input, EV_REL, code, lo_res); 1232 + input_event(input, EV_REL, usage->code, hi_res); 1233 + } 1234 + 1214 1235 void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value) 1215 1236 { 1216 1237 struct input_dev *input; ··· 1304 1261 1305 1262 if ((usage->type == EV_KEY) && (usage->code == 0)) /* Key 0 is "unassigned", not KEY_UNKNOWN */ 1306 1263 return; 1264 + 1265 + if ((usage->type == EV_REL) && (usage->code == REL_WHEEL_HI_RES || 1266 + usage->code == REL_HWHEEL_HI_RES)) { 1267 + hidinput_handle_scroll(usage, input, value); 1268 + return; 1269 + } 1307 1270 1308 1271 if ((usage->type == EV_ABS) && (field->flags & HID_MAIN_ITEM_RELATIVE) && 1309 1272 (usage->code == ABS_VOLUME)) { ··· 1536 1487 struct hid_device *hid = input_get_drvdata(dev); 1537 1488 1538 1489 hid_hw_close(hid); 1490 + } 1491 + 1492 + static void hidinput_change_resolution_multipliers(struct hid_device *hid) 1493 + { 1494 + struct hid_report_enum *rep_enum; 1495 + struct hid_report *rep; 1496 + struct hid_usage *usage; 1497 + int i, j; 1498 + 1499 + rep_enum = &hid->report_enum[HID_FEATURE_REPORT]; 1500 + list_for_each_entry(rep, &rep_enum->report_list, list) { 1501 + bool update_needed = false; 1502 + 1503 + if (rep->maxfield == 0) 1504 + continue; 1505 + 1506 + /* 1507 + * If we have more than one feature within this report we 1508 + * need to fill in the bits from the others before we can 1509 + * overwrite the ones for the Resolution Multiplier. 1510 + */ 1511 + if (rep->maxfield > 1) { 1512 + hid_hw_request(hid, rep, HID_REQ_GET_REPORT); 1513 + hid_hw_wait(hid); 1514 + } 1515 + 1516 + for (i = 0; i < rep->maxfield; i++) { 1517 + __s32 logical_max = rep->field[i]->logical_maximum; 1518 + 1519 + /* There is no good reason for a Resolution 1520 + * Multiplier to have a count other than 1. 1521 + * Ignore that case. 1522 + */ 1523 + if (rep->field[i]->report_count != 1) 1524 + continue; 1525 + 1526 + for (j = 0; j < rep->field[i]->maxusage; j++) { 1527 + usage = &rep->field[i]->usage[j]; 1528 + 1529 + if (usage->hid != HID_GD_RESOLUTION_MULTIPLIER) 1530 + continue; 1531 + 1532 + *rep->field[i]->value = logical_max; 1533 + update_needed = true; 1534 + } 1535 + } 1536 + if (update_needed) 1537 + hid_hw_request(hid, rep, HID_REQ_SET_REPORT); 1538 + } 1539 + 1540 + /* refresh our structs */ 1541 + hid_setup_resolution_multiplier(hid); 1539 1542 } 1540 1543 1541 1544 static void report_features(struct hid_device *hid) ··· 1883 1782 } 1884 1783 } 1885 1784 1785 + hidinput_change_resolution_multipliers(hid); 1786 + 1886 1787 list_for_each_entry_safe(hidinput, next, &hid->inputs, list) { 1887 1788 if (drv->input_configured && 1888 1789 drv->input_configured(hid, hidinput)) ··· 1943 1840 cancel_work_sync(&hid->led_work); 1944 1841 } 1945 1842 EXPORT_SYMBOL_GPL(hidinput_disconnect); 1946 -
+8 -2
drivers/hid/hid-lenovo.c
··· 743 743 data_pointer->led_mute.brightness_get = lenovo_led_brightness_get_tpkbd; 744 744 data_pointer->led_mute.brightness_set = lenovo_led_brightness_set_tpkbd; 745 745 data_pointer->led_mute.dev = dev; 746 - led_classdev_register(dev, &data_pointer->led_mute); 746 + ret = led_classdev_register(dev, &data_pointer->led_mute); 747 + if (ret < 0) 748 + goto err; 747 749 748 750 data_pointer->led_micmute.name = name_micmute; 749 751 data_pointer->led_micmute.brightness_get = ··· 753 751 data_pointer->led_micmute.brightness_set = 754 752 lenovo_led_brightness_set_tpkbd; 755 753 data_pointer->led_micmute.dev = dev; 756 - led_classdev_register(dev, &data_pointer->led_micmute); 754 + ret = led_classdev_register(dev, &data_pointer->led_micmute); 755 + if (ret < 0) { 756 + led_classdev_unregister(&data_pointer->led_mute); 757 + goto err; 758 + } 757 759 758 760 lenovo_features_set_tpkbd(hdev); 759 761
+340 -35
drivers/hid/hid-logitech-hidpp.c
··· 21 21 #include <linux/module.h> 22 22 #include <linux/slab.h> 23 23 #include <linux/sched.h> 24 + #include <linux/sched/clock.h> 24 25 #include <linux/kfifo.h> 25 26 #include <linux/input/mt.h> 26 27 #include <linux/workqueue.h> ··· 65 64 #define HIDPP_QUIRK_NO_HIDINPUT BIT(23) 66 65 #define HIDPP_QUIRK_FORCE_OUTPUT_REPORTS BIT(24) 67 66 #define HIDPP_QUIRK_UNIFYING BIT(25) 67 + #define HIDPP_QUIRK_HI_RES_SCROLL_1P0 BIT(26) 68 + #define HIDPP_QUIRK_HI_RES_SCROLL_X2120 BIT(27) 69 + #define HIDPP_QUIRK_HI_RES_SCROLL_X2121 BIT(28) 70 + 71 + /* Convenience constant to check for any high-res support. */ 72 + #define HIDPP_QUIRK_HI_RES_SCROLL (HIDPP_QUIRK_HI_RES_SCROLL_1P0 | \ 73 + HIDPP_QUIRK_HI_RES_SCROLL_X2120 | \ 74 + HIDPP_QUIRK_HI_RES_SCROLL_X2121) 68 75 69 76 #define HIDPP_QUIRK_DELAYED_INIT HIDPP_QUIRK_NO_HIDINPUT 70 77 ··· 137 128 bool online; 138 129 }; 139 130 131 + /** 132 + * struct hidpp_scroll_counter - Utility class for processing high-resolution 133 + * scroll events. 134 + * @dev: the input device for which events should be reported. 135 + * @wheel_multiplier: the scalar multiplier to be applied to each wheel event 136 + * @remainder: counts the number of high-resolution units moved since the last 137 + * low-resolution event (REL_WHEEL or REL_HWHEEL) was sent. Should 138 + * only be used by class methods. 139 + * @direction: direction of last movement (1 or -1) 140 + * @last_time: last event time, used to reset remainder after inactivity 141 + */ 142 + struct hidpp_scroll_counter { 143 + struct input_dev *dev; 144 + int wheel_multiplier; 145 + int remainder; 146 + int direction; 147 + unsigned long long last_time; 148 + }; 149 + 140 150 struct hidpp_device { 141 151 struct hid_device *hid_dev; 142 152 struct mutex send_mutex; ··· 177 149 unsigned long capabilities; 178 150 179 151 struct hidpp_battery battery; 152 + struct hidpp_scroll_counter vertical_wheel_counter; 180 153 }; 181 154 182 155 /* HID++ 1.0 error codes */ ··· 420 391 *name = new_name; 421 392 } 422 393 394 + /** 395 + * hidpp_scroll_counter_handle_scroll() - Send high- and low-resolution scroll 396 + * events given a high-resolution wheel 397 + * movement. 398 + * @counter: a hid_scroll_counter struct describing the wheel. 399 + * @hi_res_value: the movement of the wheel, in the mouse's high-resolution 400 + * units. 401 + * 402 + * Given a high-resolution movement, this function converts the movement into 403 + * fractions of 120 and emits high-resolution scroll events for the input 404 + * device. It also uses the multiplier from &struct hid_scroll_counter to 405 + * emit low-resolution scroll events when appropriate for 406 + * backwards-compatibility with userspace input libraries. 407 + */ 408 + static void hidpp_scroll_counter_handle_scroll(struct hidpp_scroll_counter *counter, 409 + int hi_res_value) 410 + { 411 + int low_res_value, remainder, direction; 412 + unsigned long long now, previous; 413 + 414 + hi_res_value = hi_res_value * 120/counter->wheel_multiplier; 415 + input_report_rel(counter->dev, REL_WHEEL_HI_RES, hi_res_value); 416 + 417 + remainder = counter->remainder; 418 + direction = hi_res_value > 0 ? 1 : -1; 419 + 420 + now = sched_clock(); 421 + previous = counter->last_time; 422 + counter->last_time = now; 423 + /* 424 + * Reset the remainder after a period of inactivity or when the 425 + * direction changes. This prevents the REL_WHEEL emulation point 426 + * from sliding for devices that don't always provide the same 427 + * number of movements per detent. 428 + */ 429 + if (now - previous > 1000000000 || direction != counter->direction) 430 + remainder = 0; 431 + 432 + counter->direction = direction; 433 + remainder += hi_res_value; 434 + 435 + /* Some wheels will rest 7/8ths of a detent from the previous detent 436 + * after slow movement, so we want the threshold for low-res events to 437 + * be in the middle between two detents (e.g. after 4/8ths) as 438 + * opposed to on the detents themselves (8/8ths). 439 + */ 440 + if (abs(remainder) >= 60) { 441 + /* Add (or subtract) 1 because we want to trigger when the wheel 442 + * is half-way to the next detent (i.e. scroll 1 detent after a 443 + * 1/2 detent movement, 2 detents after a 1 1/2 detent movement, 444 + * etc.). 445 + */ 446 + low_res_value = remainder / 120; 447 + if (low_res_value == 0) 448 + low_res_value = (hi_res_value > 0 ? 1 : -1); 449 + input_report_rel(counter->dev, REL_WHEEL, low_res_value); 450 + remainder -= low_res_value * 120; 451 + } 452 + counter->remainder = remainder; 453 + } 454 + 423 455 /* -------------------------------------------------------------------------- */ 424 456 /* HIDP++ 1.0 commands */ 425 457 /* -------------------------------------------------------------------------- */ ··· 490 400 #define HIDPP_SET_LONG_REGISTER 0x82 491 401 #define HIDPP_GET_LONG_REGISTER 0x83 492 402 493 - #define HIDPP_REG_GENERAL 0x00 494 - 495 - static int hidpp10_enable_battery_reporting(struct hidpp_device *hidpp_dev) 403 + /** 404 + * hidpp10_set_register_bit() - Sets a single bit in a HID++ 1.0 register. 405 + * @hidpp_dev: the device to set the register on. 406 + * @register_address: the address of the register to modify. 407 + * @byte: the byte of the register to modify. Should be less than 3. 408 + * Return: 0 if successful, otherwise a negative error code. 409 + */ 410 + static int hidpp10_set_register_bit(struct hidpp_device *hidpp_dev, 411 + u8 register_address, u8 byte, u8 bit) 496 412 { 497 413 struct hidpp_report response; 498 414 int ret; 499 415 u8 params[3] = { 0 }; 500 416 501 417 ret = hidpp_send_rap_command_sync(hidpp_dev, 502 - REPORT_ID_HIDPP_SHORT, 503 - HIDPP_GET_REGISTER, 504 - HIDPP_REG_GENERAL, 505 - NULL, 0, &response); 418 + REPORT_ID_HIDPP_SHORT, 419 + HIDPP_GET_REGISTER, 420 + register_address, 421 + NULL, 0, &response); 506 422 if (ret) 507 423 return ret; 508 424 509 425 memcpy(params, response.rap.params, 3); 510 426 511 - /* Set the battery bit */ 512 - params[0] |= BIT(4); 427 + params[byte] |= BIT(bit); 513 428 514 429 return hidpp_send_rap_command_sync(hidpp_dev, 515 - REPORT_ID_HIDPP_SHORT, 516 - HIDPP_SET_REGISTER, 517 - HIDPP_REG_GENERAL, 518 - params, 3, &response); 430 + REPORT_ID_HIDPP_SHORT, 431 + HIDPP_SET_REGISTER, 432 + register_address, 433 + params, 3, &response); 434 + } 435 + 436 + 437 + #define HIDPP_REG_GENERAL 0x00 438 + 439 + static int hidpp10_enable_battery_reporting(struct hidpp_device *hidpp_dev) 440 + { 441 + return hidpp10_set_register_bit(hidpp_dev, HIDPP_REG_GENERAL, 0, 4); 442 + } 443 + 444 + #define HIDPP_REG_FEATURES 0x01 445 + 446 + /* On HID++ 1.0 devices, high-res scroll was called "scrolling acceleration". */ 447 + static int hidpp10_enable_scrolling_acceleration(struct hidpp_device *hidpp_dev) 448 + { 449 + return hidpp10_set_register_bit(hidpp_dev, HIDPP_REG_FEATURES, 0, 6); 519 450 } 520 451 521 452 #define HIDPP_REG_BATTERY_STATUS 0x07 ··· 1248 1137 } 1249 1138 1250 1139 /* -------------------------------------------------------------------------- */ 1140 + /* 0x2120: Hi-resolution scrolling */ 1141 + /* -------------------------------------------------------------------------- */ 1142 + 1143 + #define HIDPP_PAGE_HI_RESOLUTION_SCROLLING 0x2120 1144 + 1145 + #define CMD_HI_RESOLUTION_SCROLLING_SET_HIGHRES_SCROLLING_MODE 0x10 1146 + 1147 + static int hidpp_hrs_set_highres_scrolling_mode(struct hidpp_device *hidpp, 1148 + bool enabled, u8 *multiplier) 1149 + { 1150 + u8 feature_index; 1151 + u8 feature_type; 1152 + int ret; 1153 + u8 params[1]; 1154 + struct hidpp_report response; 1155 + 1156 + ret = hidpp_root_get_feature(hidpp, 1157 + HIDPP_PAGE_HI_RESOLUTION_SCROLLING, 1158 + &feature_index, 1159 + &feature_type); 1160 + if (ret) 1161 + return ret; 1162 + 1163 + params[0] = enabled ? BIT(0) : 0; 1164 + ret = hidpp_send_fap_command_sync(hidpp, feature_index, 1165 + CMD_HI_RESOLUTION_SCROLLING_SET_HIGHRES_SCROLLING_MODE, 1166 + params, sizeof(params), &response); 1167 + if (ret) 1168 + return ret; 1169 + *multiplier = response.fap.params[1]; 1170 + return 0; 1171 + } 1172 + 1173 + /* -------------------------------------------------------------------------- */ 1174 + /* 0x2121: HiRes Wheel */ 1175 + /* -------------------------------------------------------------------------- */ 1176 + 1177 + #define HIDPP_PAGE_HIRES_WHEEL 0x2121 1178 + 1179 + #define CMD_HIRES_WHEEL_GET_WHEEL_CAPABILITY 0x00 1180 + #define CMD_HIRES_WHEEL_SET_WHEEL_MODE 0x20 1181 + 1182 + static int hidpp_hrw_get_wheel_capability(struct hidpp_device *hidpp, 1183 + u8 *multiplier) 1184 + { 1185 + u8 feature_index; 1186 + u8 feature_type; 1187 + int ret; 1188 + struct hidpp_report response; 1189 + 1190 + ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_HIRES_WHEEL, 1191 + &feature_index, &feature_type); 1192 + if (ret) 1193 + goto return_default; 1194 + 1195 + ret = hidpp_send_fap_command_sync(hidpp, feature_index, 1196 + CMD_HIRES_WHEEL_GET_WHEEL_CAPABILITY, 1197 + NULL, 0, &response); 1198 + if (ret) 1199 + goto return_default; 1200 + 1201 + *multiplier = response.fap.params[0]; 1202 + return 0; 1203 + return_default: 1204 + hid_warn(hidpp->hid_dev, 1205 + "Couldn't get wheel multiplier (error %d)\n", ret); 1206 + return ret; 1207 + } 1208 + 1209 + static int hidpp_hrw_set_wheel_mode(struct hidpp_device *hidpp, bool invert, 1210 + bool high_resolution, bool use_hidpp) 1211 + { 1212 + u8 feature_index; 1213 + u8 feature_type; 1214 + int ret; 1215 + u8 params[1]; 1216 + struct hidpp_report response; 1217 + 1218 + ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_HIRES_WHEEL, 1219 + &feature_index, &feature_type); 1220 + if (ret) 1221 + return ret; 1222 + 1223 + params[0] = (invert ? BIT(2) : 0) | 1224 + (high_resolution ? BIT(1) : 0) | 1225 + (use_hidpp ? BIT(0) : 0); 1226 + 1227 + return hidpp_send_fap_command_sync(hidpp, feature_index, 1228 + CMD_HIRES_WHEEL_SET_WHEEL_MODE, 1229 + params, sizeof(params), &response); 1230 + } 1231 + 1232 + /* -------------------------------------------------------------------------- */ 1251 1233 /* 0x4301: Solar Keyboard */ 1252 1234 /* -------------------------------------------------------------------------- */ 1253 1235 ··· 1669 1465 u8 size; 1670 1466 }; 1671 1467 1672 - static const signed short hiddpp_ff_effects[] = { 1468 + static const signed short hidpp_ff_effects[] = { 1673 1469 FF_CONSTANT, 1674 1470 FF_PERIODIC, 1675 1471 FF_SINE, ··· 1684 1480 -1 1685 1481 }; 1686 1482 1687 - static const signed short hiddpp_ff_effects_v2[] = { 1483 + static const signed short hidpp_ff_effects_v2[] = { 1688 1484 FF_RAMP, 1689 1485 FF_FRICTION, 1690 1486 FF_INERTIA, ··· 2077 1873 version = bcdDevice & 255; 2078 1874 2079 1875 /* Set supported force feedback capabilities */ 2080 - for (j = 0; hiddpp_ff_effects[j] >= 0; j++) 2081 - set_bit(hiddpp_ff_effects[j], dev->ffbit); 1876 + for (j = 0; hidpp_ff_effects[j] >= 0; j++) 1877 + set_bit(hidpp_ff_effects[j], dev->ffbit); 2082 1878 if (version > 1) 2083 - for (j = 0; hiddpp_ff_effects_v2[j] >= 0; j++) 2084 - set_bit(hiddpp_ff_effects_v2[j], dev->ffbit); 1879 + for (j = 0; hidpp_ff_effects_v2[j] >= 0; j++) 1880 + set_bit(hidpp_ff_effects_v2[j], dev->ffbit); 2085 1881 2086 1882 /* Read number of slots available in device */ 2087 1883 error = hidpp_send_fap_command_sync(hidpp, feature_index, ··· 2591 2387 input_report_key(mydata->input, BTN_RIGHT, 2592 2388 !!(data[1] & M560_MOUSE_BTN_RIGHT)); 2593 2389 2594 - if (data[1] & M560_MOUSE_BTN_WHEEL_LEFT) 2390 + if (data[1] & M560_MOUSE_BTN_WHEEL_LEFT) { 2595 2391 input_report_rel(mydata->input, REL_HWHEEL, -1); 2596 - else if (data[1] & M560_MOUSE_BTN_WHEEL_RIGHT) 2392 + input_report_rel(mydata->input, REL_HWHEEL_HI_RES, 2393 + -120); 2394 + } else if (data[1] & M560_MOUSE_BTN_WHEEL_RIGHT) { 2597 2395 input_report_rel(mydata->input, REL_HWHEEL, 1); 2396 + input_report_rel(mydata->input, REL_HWHEEL_HI_RES, 2397 + 120); 2398 + } 2598 2399 2599 2400 v = hid_snto32(hid_field_extract(hdev, data+3, 0, 12), 12); 2600 2401 input_report_rel(mydata->input, REL_X, v); ··· 2608 2399 input_report_rel(mydata->input, REL_Y, v); 2609 2400 2610 2401 v = hid_snto32(data[6], 8); 2611 - input_report_rel(mydata->input, REL_WHEEL, v); 2402 + hidpp_scroll_counter_handle_scroll( 2403 + &hidpp->vertical_wheel_counter, v); 2612 2404 2613 2405 input_sync(mydata->input); 2614 2406 } ··· 2636 2426 __set_bit(REL_Y, mydata->input->relbit); 2637 2427 __set_bit(REL_WHEEL, mydata->input->relbit); 2638 2428 __set_bit(REL_HWHEEL, mydata->input->relbit); 2429 + __set_bit(REL_WHEEL_HI_RES, mydata->input->relbit); 2430 + __set_bit(REL_HWHEEL_HI_RES, mydata->input->relbit); 2639 2431 } 2640 2432 2641 2433 static int m560_input_mapping(struct hid_device *hdev, struct hid_input *hi, ··· 2740 2528 } 2741 2529 2742 2530 /* -------------------------------------------------------------------------- */ 2531 + /* High-resolution scroll wheels */ 2532 + /* -------------------------------------------------------------------------- */ 2533 + 2534 + static int hi_res_scroll_enable(struct hidpp_device *hidpp) 2535 + { 2536 + int ret; 2537 + u8 multiplier = 1; 2538 + 2539 + if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL_X2121) { 2540 + ret = hidpp_hrw_set_wheel_mode(hidpp, false, true, false); 2541 + if (ret == 0) 2542 + ret = hidpp_hrw_get_wheel_capability(hidpp, &multiplier); 2543 + } else if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL_X2120) { 2544 + ret = hidpp_hrs_set_highres_scrolling_mode(hidpp, true, 2545 + &multiplier); 2546 + } else /* if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL_1P0) */ { 2547 + ret = hidpp10_enable_scrolling_acceleration(hidpp); 2548 + multiplier = 8; 2549 + } 2550 + if (ret) 2551 + return ret; 2552 + 2553 + if (multiplier == 0) 2554 + multiplier = 1; 2555 + 2556 + hidpp->vertical_wheel_counter.wheel_multiplier = multiplier; 2557 + hid_info(hidpp->hid_dev, "multiplier = %d\n", multiplier); 2558 + return 0; 2559 + } 2560 + 2561 + /* -------------------------------------------------------------------------- */ 2743 2562 /* Generic HID++ devices */ 2744 2563 /* -------------------------------------------------------------------------- */ 2745 2564 ··· 2815 2572 wtp_populate_input(hidpp, input, origin_is_hid_core); 2816 2573 else if (hidpp->quirks & HIDPP_QUIRK_CLASS_M560) 2817 2574 m560_populate_input(hidpp, input, origin_is_hid_core); 2575 + 2576 + if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL) 2577 + hidpp->vertical_wheel_counter.dev = input; 2818 2578 } 2819 2579 2820 2580 static int hidpp_input_configured(struct hid_device *hdev, ··· 2934 2688 return m560_raw_event(hdev, data, size); 2935 2689 2936 2690 return 0; 2691 + } 2692 + 2693 + static int hidpp_event(struct hid_device *hdev, struct hid_field *field, 2694 + struct hid_usage *usage, __s32 value) 2695 + { 2696 + /* This function will only be called for scroll events, due to the 2697 + * restriction imposed in hidpp_usages. 2698 + */ 2699 + struct hidpp_device *hidpp = hid_get_drvdata(hdev); 2700 + struct hidpp_scroll_counter *counter = &hidpp->vertical_wheel_counter; 2701 + /* A scroll event may occur before the multiplier has been retrieved or 2702 + * the input device set, or high-res scroll enabling may fail. In such 2703 + * cases we must return early (falling back to default behaviour) to 2704 + * avoid a crash in hidpp_scroll_counter_handle_scroll. 2705 + */ 2706 + if (!(hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL) || value == 0 2707 + || counter->dev == NULL || counter->wheel_multiplier == 0) 2708 + return 0; 2709 + 2710 + hidpp_scroll_counter_handle_scroll(counter, value); 2711 + return 1; 2937 2712 } 2938 2713 2939 2714 static int hidpp_initialize_battery(struct hidpp_device *hidpp) ··· 3168 2901 if (hidpp->battery.ps) 3169 2902 power_supply_changed(hidpp->battery.ps); 3170 2903 2904 + if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL) 2905 + hi_res_scroll_enable(hidpp); 2906 + 3171 2907 if (!(hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT) || hidpp->delayed_input) 3172 2908 /* if the input nodes are already created, we can stop now */ 3173 2909 return; ··· 3356 3086 mutex_destroy(&hidpp->send_mutex); 3357 3087 } 3358 3088 3089 + #define LDJ_DEVICE(product) \ 3090 + HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, \ 3091 + USB_VENDOR_ID_LOGITECH, (product)) 3092 + 3359 3093 static const struct hid_device_id hidpp_devices[] = { 3360 3094 { /* wireless touchpad */ 3361 - HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, 3362 - USB_VENDOR_ID_LOGITECH, 0x4011), 3095 + LDJ_DEVICE(0x4011), 3363 3096 .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT | 3364 3097 HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS }, 3365 3098 { /* wireless touchpad T650 */ 3366 - HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, 3367 - USB_VENDOR_ID_LOGITECH, 0x4101), 3099 + LDJ_DEVICE(0x4101), 3368 3100 .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT }, 3369 3101 { /* wireless touchpad T651 */ 3370 3102 HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 3371 3103 USB_DEVICE_ID_LOGITECH_T651), 3372 3104 .driver_data = HIDPP_QUIRK_CLASS_WTP }, 3105 + { /* Mouse Logitech Anywhere MX */ 3106 + LDJ_DEVICE(0x1017), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_1P0 }, 3107 + { /* Mouse Logitech Cube */ 3108 + LDJ_DEVICE(0x4010), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2120 }, 3109 + { /* Mouse Logitech M335 */ 3110 + LDJ_DEVICE(0x4050), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, 3111 + { /* Mouse Logitech M515 */ 3112 + LDJ_DEVICE(0x4007), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2120 }, 3373 3113 { /* Mouse logitech M560 */ 3374 - HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, 3375 - USB_VENDOR_ID_LOGITECH, 0x402d), 3376 - .driver_data = HIDPP_QUIRK_DELAYED_INIT | HIDPP_QUIRK_CLASS_M560 }, 3114 + LDJ_DEVICE(0x402d), 3115 + .driver_data = HIDPP_QUIRK_DELAYED_INIT | HIDPP_QUIRK_CLASS_M560 3116 + | HIDPP_QUIRK_HI_RES_SCROLL_X2120 }, 3117 + { /* Mouse Logitech M705 (firmware RQM17) */ 3118 + LDJ_DEVICE(0x101b), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_1P0 }, 3119 + { /* Mouse Logitech M705 (firmware RQM67) */ 3120 + LDJ_DEVICE(0x406d), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, 3121 + { /* Mouse Logitech M720 */ 3122 + LDJ_DEVICE(0x405e), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, 3123 + { /* Mouse Logitech MX Anywhere 2 */ 3124 + LDJ_DEVICE(0x404a), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, 3125 + { LDJ_DEVICE(0xb013), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, 3126 + { LDJ_DEVICE(0xb018), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, 3127 + { LDJ_DEVICE(0xb01f), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, 3128 + { /* Mouse Logitech MX Anywhere 2S */ 3129 + LDJ_DEVICE(0x406a), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, 3130 + { /* Mouse Logitech MX Master */ 3131 + LDJ_DEVICE(0x4041), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, 3132 + { LDJ_DEVICE(0x4060), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, 3133 + { LDJ_DEVICE(0x4071), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, 3134 + { /* Mouse Logitech MX Master 2S */ 3135 + LDJ_DEVICE(0x4069), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, 3136 + { /* Mouse Logitech Performance MX */ 3137 + LDJ_DEVICE(0x101a), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_1P0 }, 3377 3138 { /* Keyboard logitech K400 */ 3378 - HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, 3379 - USB_VENDOR_ID_LOGITECH, 0x4024), 3139 + LDJ_DEVICE(0x4024), 3380 3140 .driver_data = HIDPP_QUIRK_CLASS_K400 }, 3381 3141 { /* Solar Keyboard Logitech K750 */ 3382 - HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, 3383 - USB_VENDOR_ID_LOGITECH, 0x4002), 3142 + LDJ_DEVICE(0x4002), 3384 3143 .driver_data = HIDPP_QUIRK_CLASS_K750 }, 3385 3144 3386 - { HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, 3387 - USB_VENDOR_ID_LOGITECH, HID_ANY_ID)}, 3145 + { LDJ_DEVICE(HID_ANY_ID) }, 3388 3146 3389 3147 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G920_WHEEL), 3390 3148 .driver_data = HIDPP_QUIRK_CLASS_G920 | HIDPP_QUIRK_FORCE_OUTPUT_REPORTS}, ··· 3421 3123 3422 3124 MODULE_DEVICE_TABLE(hid, hidpp_devices); 3423 3125 3126 + static const struct hid_usage_id hidpp_usages[] = { 3127 + { HID_GD_WHEEL, EV_REL, REL_WHEEL_HI_RES }, 3128 + { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1} 3129 + }; 3130 + 3424 3131 static struct hid_driver hidpp_driver = { 3425 3132 .name = "logitech-hidpp-device", 3426 3133 .id_table = hidpp_devices, 3427 3134 .probe = hidpp_probe, 3428 3135 .remove = hidpp_remove, 3429 3136 .raw_event = hidpp_raw_event, 3137 + .usage_table = hidpp_usages, 3138 + .event = hidpp_event, 3430 3139 .input_configured = hidpp_input_configured, 3431 3140 .input_mapping = hidpp_input_mapping, 3432 3141 .input_mapped = hidpp_input_mapped,
+4 -4
drivers/hid/hidraw.c
··· 107 107 108 108 /* 109 109 * The first byte of the report buffer is expected to be a report number. 110 - * 111 - * This function is to be called with the minors_lock mutex held. 112 110 */ 113 111 static ssize_t hidraw_send_report(struct file *file, const char __user *buffer, size_t count, unsigned char report_type) 114 112 { ··· 114 116 struct hid_device *dev; 115 117 __u8 *buf; 116 118 int ret = 0; 119 + 120 + lockdep_assert_held(&minors_lock); 117 121 118 122 if (!hidraw_table[minor] || !hidraw_table[minor]->exist) { 119 123 ret = -ENODEV; ··· 181 181 * of buffer is the report number to request, or 0x0 if the defice does not 182 182 * use numbered reports. The report_type parameter can be HID_FEATURE_REPORT 183 183 * or HID_INPUT_REPORT. 184 - * 185 - * This function is to be called with the minors_lock mutex held. 186 184 */ 187 185 static ssize_t hidraw_get_report(struct file *file, char __user *buffer, size_t count, unsigned char report_type) 188 186 { ··· 189 191 __u8 *buf; 190 192 int ret = 0, len; 191 193 unsigned char report_number; 194 + 195 + lockdep_assert_held(&minors_lock); 192 196 193 197 if (!hidraw_table[minor] || !hidraw_table[minor]->exist) { 194 198 ret = -ENODEV;
+8
drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c
··· 346 346 }, 347 347 .driver_data = (void *)&sipodev_desc 348 348 }, 349 + { 350 + .ident = "Odys Winbook 13", 351 + .matches = { 352 + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AXDIA International GmbH"), 353 + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "WINBOOK 13"), 354 + }, 355 + .driver_data = (void *)&sipodev_desc 356 + }, 349 357 { } /* Terminate list */ 350 358 }; 351 359
+6 -1
drivers/hid/intel-ish-hid/ipc/pci-ish.c
··· 117 117 { 118 118 int ret; 119 119 struct ish_hw *hw; 120 + unsigned long irq_flag = 0; 120 121 struct ishtp_device *ishtp; 121 122 struct device *dev = &pdev->dev; 122 123 ··· 157 156 pdev->dev_flags |= PCI_DEV_FLAGS_NO_D3; 158 157 159 158 /* request and enable interrupt */ 159 + ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES); 160 + if (!pdev->msi_enabled && !pdev->msix_enabled) 161 + irq_flag = IRQF_SHARED; 162 + 160 163 ret = devm_request_irq(dev, pdev->irq, ish_irq_handler, 161 - IRQF_SHARED, KBUILD_MODNAME, ishtp); 164 + irq_flag, KBUILD_MODNAME, ishtp); 162 165 if (ret) { 163 166 dev_err(dev, "ISH: request IRQ %d failed\n", pdev->irq); 164 167 return ret;
+1 -1
drivers/hid/intel-ish-hid/ishtp-hid.c
··· 222 222 err_hid_device: 223 223 kfree(hid_data); 224 224 err_hid_data: 225 - kfree(hid); 225 + hid_destroy_device(hid); 226 226 return rv; 227 227 } 228 228
+16 -1
include/linux/hid.h
··· 219 219 #define HID_GD_VBRZ 0x00010045 220 220 #define HID_GD_VNO 0x00010046 221 221 #define HID_GD_FEATURE 0x00010047 222 + #define HID_GD_RESOLUTION_MULTIPLIER 0x00010048 222 223 #define HID_GD_SYSTEM_CONTROL 0x00010080 223 224 #define HID_GD_UP 0x00010090 224 225 #define HID_GD_DOWN 0x00010091 ··· 233 232 #define HID_DC_BATTERYSTRENGTH 0x00060020 234 233 235 234 #define HID_CP_CONSUMER_CONTROL 0x000c0001 235 + #define HID_CP_AC_PAN 0x000c0238 236 236 237 237 #define HID_DG_DIGITIZER 0x000d0001 238 238 #define HID_DG_PEN 0x000d0002 239 239 #define HID_DG_LIGHTPEN 0x000d0003 240 240 #define HID_DG_TOUCHSCREEN 0x000d0004 241 241 #define HID_DG_TOUCHPAD 0x000d0005 242 + #define HID_DG_WHITEBOARD 0x000d0006 242 243 #define HID_DG_STYLUS 0x000d0020 243 244 #define HID_DG_PUCK 0x000d0021 244 245 #define HID_DG_FINGER 0x000d0022 ··· 430 427 */ 431 428 432 429 struct hid_collection { 430 + struct hid_collection *parent; 433 431 unsigned type; 434 432 unsigned usage; 435 433 unsigned level; ··· 440 436 unsigned hid; /* hid usage code */ 441 437 unsigned collection_index; /* index into collection array */ 442 438 unsigned usage_index; /* index into usage array */ 439 + __s8 resolution_multiplier;/* Effective Resolution Multiplier 440 + (HUT v1.12, 4.3.1), default: 1 */ 443 441 /* hidinput data */ 442 + __s8 wheel_factor; /* 120/resolution_multiplier */ 444 443 __u16 code; /* input driver code */ 445 444 __u8 type; /* input driver type */ 446 445 __s8 hat_min; /* hat switch fun */ 447 446 __s8 hat_max; /* ditto */ 448 447 __s8 hat_dir; /* ditto */ 448 + __s16 wheel_accumulated; /* hi-res wheel */ 449 449 }; 450 450 451 451 struct hid_input; ··· 658 650 unsigned int *collection_stack; 659 651 unsigned int collection_stack_ptr; 660 652 unsigned int collection_stack_size; 653 + struct hid_collection *active_collection; 661 654 struct hid_device *device; 662 655 unsigned int scan_flags; 663 656 }; ··· 845 836 846 837 /* Applications from HID Usage Tables 4/8/99 Version 1.1 */ 847 838 /* We ignore a few input applications that are not widely used */ 848 - #define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || (a == 0x000c0001) || ((a >= 0x000d0002) && (a <= 0x000d0006))) 839 + #define IS_INPUT_APPLICATION(a) \ 840 + (((a >= HID_UP_GENDESK) && (a <= HID_GD_MULTIAXIS)) \ 841 + || ((a >= HID_DG_PEN) && (a <= HID_DG_WHITEBOARD)) \ 842 + || (a == HID_GD_SYSTEM_CONTROL) || (a == HID_CP_CONSUMER_CONTROL) \ 843 + || (a == HID_GD_WIRELESS_RADIO_CTLS)) 849 844 850 845 /* HID core API */ 851 846 ··· 905 892 unsigned int type, unsigned int id, 906 893 unsigned int field_index, 907 894 unsigned int report_counts); 895 + 896 + void hid_setup_resolution_multiplier(struct hid_device *hid); 908 897 int hid_open_report(struct hid_device *device); 909 898 int hid_check_keys_pressed(struct hid_device *hid); 910 899 int hid_connect(struct hid_device *hid, unsigned int connect_mask);
+2
include/uapi/linux/input-event-codes.h
··· 716 716 * the situation described above. 717 717 */ 718 718 #define REL_RESERVED 0x0a 719 + #define REL_WHEEL_HI_RES 0x0b 720 + #define REL_HWHEEL_HI_RES 0x0c 719 721 #define REL_MAX 0x0f 720 722 #define REL_CNT (REL_MAX+1) 721 723
+1 -1
samples/hidraw/hid-example.c
··· 119 119 if (res < 0) 120 120 perror("HIDIOCSFEATURE"); 121 121 else 122 - printf("ioctl HIDIOCGFEATURE returned: %d\n", res); 122 + printf("ioctl HIDIOCSFEATURE returned: %d\n", res); 123 123 124 124 /* Get Feature */ 125 125 buf[0] = 0x9; /* Report Number */