aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/input/event-codes.rst11
-rw-r--r--drivers/hid/hid-input.c45
-rw-r--r--drivers/hid/hid-logitech-hidpp.c309
-rw-r--r--include/linux/hid.h28
-rw-r--r--include/uapi/linux/input-event-codes.h18
5 files changed, 383 insertions, 28 deletions
diff --git a/Documentation/input/event-codes.rst b/Documentation/input/event-codes.rst
index a8c0873beb95..cef220c176a4 100644
--- a/Documentation/input/event-codes.rst
+++ b/Documentation/input/event-codes.rst
@@ -190,7 +190,16 @@ A few EV_REL codes have special meanings:
190* REL_WHEEL, REL_HWHEEL: 190* REL_WHEEL, REL_HWHEEL:
191 191
192 - These codes are used for vertical and horizontal scroll wheels, 192 - These codes are used for vertical and horizontal scroll wheels,
193 respectively. 193 respectively. The value is the number of "notches" moved on the wheel, the
194 physical size of which varies by device. For high-resolution wheels (which
195 report multiple events for each notch of movement, or do not have notches)
196 this may be an approximation based on the high-resolution scroll events.
197
198* REL_WHEEL_HI_RES:
199
200 - If a vertical scroll wheel supports high-resolution scrolling, this code
201 will be emitted in addition to REL_WHEEL. The value is the (approximate)
202 distance travelled by the user's finger, in microns.
194 203
195EV_ABS 204EV_ABS
196------ 205------
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index ad823a01bd65..567c3bf64515 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -1838,3 +1838,48 @@ void hidinput_disconnect(struct hid_device *hid)
1838} 1838}
1839EXPORT_SYMBOL_GPL(hidinput_disconnect); 1839EXPORT_SYMBOL_GPL(hidinput_disconnect);
1840 1840
1841/**
1842 * hid_scroll_counter_handle_scroll() - Send high- and low-resolution scroll
1843 * events given a high-resolution wheel
1844 * movement.
1845 * @counter: a hid_scroll_counter struct describing the wheel.
1846 * @hi_res_value: the movement of the wheel, in the mouse's high-resolution
1847 * units.
1848 *
1849 * Given a high-resolution movement, this function converts the movement into
1850 * microns and emits high-resolution scroll events for the input device. It also
1851 * uses the multiplier from &struct hid_scroll_counter to emit low-resolution
1852 * scroll events when appropriate for backwards-compatibility with userspace
1853 * input libraries.
1854 */
1855void hid_scroll_counter_handle_scroll(struct hid_scroll_counter *counter,
1856 int hi_res_value)
1857{
1858 int low_res_scroll_amount;
1859 /* Some wheels will rest 7/8ths of a notch from the previous notch
1860 * after slow movement, so we want the threshold for low-res events to
1861 * be in the middle of the notches (e.g. after 4/8ths) as opposed to on
1862 * the notches themselves (8/8ths).
1863 */
1864 int threshold = counter->resolution_multiplier / 2;
1865
1866 input_report_rel(counter->dev, REL_WHEEL_HI_RES,
1867 hi_res_value * counter->microns_per_hi_res_unit);
1868
1869 counter->remainder += hi_res_value;
1870 if (abs(counter->remainder) >= threshold) {
1871 /* Add (or subtract) 1 because we want to trigger when the wheel
1872 * is half-way to the next notch (i.e. scroll 1 notch after a
1873 * 1/2 notch movement, 2 notches after a 1 1/2 notch movement,
1874 * etc.).
1875 */
1876 low_res_scroll_amount =
1877 counter->remainder / counter->resolution_multiplier
1878 + (hi_res_value > 0 ? 1 : -1);
1879 input_report_rel(counter->dev, REL_WHEEL,
1880 low_res_scroll_amount);
1881 counter->remainder -=
1882 low_res_scroll_amount * counter->resolution_multiplier;
1883 }
1884}
1885EXPORT_SYMBOL_GPL(hid_scroll_counter_handle_scroll);
diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
index 19cc980eebce..f01280898b24 100644
--- a/drivers/hid/hid-logitech-hidpp.c
+++ b/drivers/hid/hid-logitech-hidpp.c
@@ -64,6 +64,14 @@ MODULE_PARM_DESC(disable_tap_to_click,
64#define HIDPP_QUIRK_NO_HIDINPUT BIT(23) 64#define HIDPP_QUIRK_NO_HIDINPUT BIT(23)
65#define HIDPP_QUIRK_FORCE_OUTPUT_REPORTS BIT(24) 65#define HIDPP_QUIRK_FORCE_OUTPUT_REPORTS BIT(24)
66#define HIDPP_QUIRK_UNIFYING BIT(25) 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)
67 75
68#define HIDPP_QUIRK_DELAYED_INIT HIDPP_QUIRK_NO_HIDINPUT 76#define HIDPP_QUIRK_DELAYED_INIT HIDPP_QUIRK_NO_HIDINPUT
69 77
@@ -149,6 +157,7 @@ struct hidpp_device {
149 unsigned long capabilities; 157 unsigned long capabilities;
150 158
151 struct hidpp_battery battery; 159 struct hidpp_battery battery;
160 struct hid_scroll_counter vertical_wheel_counter;
152}; 161};
153 162
154/* HID++ 1.0 error codes */ 163/* HID++ 1.0 error codes */
@@ -400,32 +409,53 @@ static void hidpp_prefix_name(char **name, int name_length)
400#define HIDPP_SET_LONG_REGISTER 0x82 409#define HIDPP_SET_LONG_REGISTER 0x82
401#define HIDPP_GET_LONG_REGISTER 0x83 410#define HIDPP_GET_LONG_REGISTER 0x83
402 411
403#define HIDPP_REG_GENERAL 0x00 412/**
404 413 * hidpp10_set_register_bit() - Sets a single bit in a HID++ 1.0 register.
405static int hidpp10_enable_battery_reporting(struct hidpp_device *hidpp_dev) 414 * @hidpp_dev: the device to set the register on.
415 * @register_address: the address of the register to modify.
416 * @byte: the byte of the register to modify. Should be less than 3.
417 * Return: 0 if successful, otherwise a negative error code.
418 */
419static int hidpp10_set_register_bit(struct hidpp_device *hidpp_dev,
420 u8 register_address, u8 byte, u8 bit)
406{ 421{
407 struct hidpp_report response; 422 struct hidpp_report response;
408 int ret; 423 int ret;
409 u8 params[3] = { 0 }; 424 u8 params[3] = { 0 };
410 425
411 ret = hidpp_send_rap_command_sync(hidpp_dev, 426 ret = hidpp_send_rap_command_sync(hidpp_dev,
412 REPORT_ID_HIDPP_SHORT, 427 REPORT_ID_HIDPP_SHORT,
413 HIDPP_GET_REGISTER, 428 HIDPP_GET_REGISTER,
414 HIDPP_REG_GENERAL, 429 register_address,
415 NULL, 0, &response); 430 NULL, 0, &response);
416 if (ret) 431 if (ret)
417 return ret; 432 return ret;
418 433
419 memcpy(params, response.rap.params, 3); 434 memcpy(params, response.rap.params, 3);
420 435
421 /* Set the battery bit */ 436 params[byte] |= BIT(bit);
422 params[0] |= BIT(4);
423 437
424 return hidpp_send_rap_command_sync(hidpp_dev, 438 return hidpp_send_rap_command_sync(hidpp_dev,
425 REPORT_ID_HIDPP_SHORT, 439 REPORT_ID_HIDPP_SHORT,
426 HIDPP_SET_REGISTER, 440 HIDPP_SET_REGISTER,
427 HIDPP_REG_GENERAL, 441 register_address,
428 params, 3, &response); 442 params, 3, &response);
443}
444
445
446#define HIDPP_REG_GENERAL 0x00
447
448static int hidpp10_enable_battery_reporting(struct hidpp_device *hidpp_dev)
449{
450 return hidpp10_set_register_bit(hidpp_dev, HIDPP_REG_GENERAL, 0, 4);
451}
452
453#define HIDPP_REG_FEATURES 0x01
454
455/* On HID++ 1.0 devices, high-res scroll was called "scrolling acceleration". */
456static int hidpp10_enable_scrolling_acceleration(struct hidpp_device *hidpp_dev)
457{
458 return hidpp10_set_register_bit(hidpp_dev, HIDPP_REG_FEATURES, 0, 6);
429} 459}
430 460
431#define HIDPP_REG_BATTERY_STATUS 0x07 461#define HIDPP_REG_BATTERY_STATUS 0x07
@@ -1137,6 +1167,100 @@ static int hidpp_battery_get_property(struct power_supply *psy,
1137} 1167}
1138 1168
1139/* -------------------------------------------------------------------------- */ 1169/* -------------------------------------------------------------------------- */
1170/* 0x2120: Hi-resolution scrolling */
1171/* -------------------------------------------------------------------------- */
1172
1173#define HIDPP_PAGE_HI_RESOLUTION_SCROLLING 0x2120
1174
1175#define CMD_HI_RESOLUTION_SCROLLING_SET_HIGHRES_SCROLLING_MODE 0x10
1176
1177static int hidpp_hrs_set_highres_scrolling_mode(struct hidpp_device *hidpp,
1178 bool enabled, u8 *multiplier)
1179{
1180 u8 feature_index;
1181 u8 feature_type;
1182 int ret;
1183 u8 params[1];
1184 struct hidpp_report response;
1185
1186 ret = hidpp_root_get_feature(hidpp,
1187 HIDPP_PAGE_HI_RESOLUTION_SCROLLING,
1188 &feature_index,
1189 &feature_type);
1190 if (ret)
1191 return ret;
1192
1193 params[0] = enabled ? BIT(0) : 0;
1194 ret = hidpp_send_fap_command_sync(hidpp, feature_index,
1195 CMD_HI_RESOLUTION_SCROLLING_SET_HIGHRES_SCROLLING_MODE,
1196 params, sizeof(params), &response);
1197 if (ret)
1198 return ret;
1199 *multiplier = response.fap.params[1];
1200 return 0;
1201}
1202
1203/* -------------------------------------------------------------------------- */
1204/* 0x2121: HiRes Wheel */
1205/* -------------------------------------------------------------------------- */
1206
1207#define HIDPP_PAGE_HIRES_WHEEL 0x2121
1208
1209#define CMD_HIRES_WHEEL_GET_WHEEL_CAPABILITY 0x00
1210#define CMD_HIRES_WHEEL_SET_WHEEL_MODE 0x20
1211
1212static int hidpp_hrw_get_wheel_capability(struct hidpp_device *hidpp,
1213 u8 *multiplier)
1214{
1215 u8 feature_index;
1216 u8 feature_type;
1217 int ret;
1218 struct hidpp_report response;
1219
1220 ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_HIRES_WHEEL,
1221 &feature_index, &feature_type);
1222 if (ret)
1223 goto return_default;
1224
1225 ret = hidpp_send_fap_command_sync(hidpp, feature_index,
1226 CMD_HIRES_WHEEL_GET_WHEEL_CAPABILITY,
1227 NULL, 0, &response);
1228 if (ret)
1229 goto return_default;
1230
1231 *multiplier = response.fap.params[0];
1232 return 0;
1233return_default:
1234 hid_warn(hidpp->hid_dev,
1235 "Couldn't get wheel multiplier (error %d), assuming %d.\n",
1236 ret, *multiplier);
1237 return ret;
1238}
1239
1240static int hidpp_hrw_set_wheel_mode(struct hidpp_device *hidpp, bool invert,
1241 bool high_resolution, bool use_hidpp)
1242{
1243 u8 feature_index;
1244 u8 feature_type;
1245 int ret;
1246 u8 params[1];
1247 struct hidpp_report response;
1248
1249 ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_HIRES_WHEEL,
1250 &feature_index, &feature_type);
1251 if (ret)
1252 return ret;
1253
1254 params[0] = (invert ? BIT(2) : 0) |
1255 (high_resolution ? BIT(1) : 0) |
1256 (use_hidpp ? BIT(0) : 0);
1257
1258 return hidpp_send_fap_command_sync(hidpp, feature_index,
1259 CMD_HIRES_WHEEL_SET_WHEEL_MODE,
1260 params, sizeof(params), &response);
1261}
1262
1263/* -------------------------------------------------------------------------- */
1140/* 0x4301: Solar Keyboard */ 1264/* 0x4301: Solar Keyboard */
1141/* -------------------------------------------------------------------------- */ 1265/* -------------------------------------------------------------------------- */
1142 1266
@@ -2399,7 +2523,8 @@ static int m560_raw_event(struct hid_device *hdev, u8 *data, int size)
2399 input_report_rel(mydata->input, REL_Y, v); 2523 input_report_rel(mydata->input, REL_Y, v);
2400 2524
2401 v = hid_snto32(data[6], 8); 2525 v = hid_snto32(data[6], 8);
2402 input_report_rel(mydata->input, REL_WHEEL, v); 2526 hid_scroll_counter_handle_scroll(
2527 &hidpp->vertical_wheel_counter, v);
2403 2528
2404 input_sync(mydata->input); 2529 input_sync(mydata->input);
2405 } 2530 }
@@ -2528,6 +2653,72 @@ static int g920_get_config(struct hidpp_device *hidpp)
2528} 2653}
2529 2654
2530/* -------------------------------------------------------------------------- */ 2655/* -------------------------------------------------------------------------- */
2656/* High-resolution scroll wheels */
2657/* -------------------------------------------------------------------------- */
2658
2659/**
2660 * struct hi_res_scroll_info - Stores info on a device's high-res scroll wheel.
2661 * @product_id: the HID product ID of the device being described.
2662 * @microns_per_hi_res_unit: the distance moved by the user's finger for each
2663 * high-resolution unit reported by the device, in
2664 * 256ths of a millimetre.
2665 */
2666struct hi_res_scroll_info {
2667 __u32 product_id;
2668 int microns_per_hi_res_unit;
2669};
2670
2671static struct hi_res_scroll_info hi_res_scroll_devices[] = {
2672 { /* Anywhere MX */
2673 .product_id = 0x1017, .microns_per_hi_res_unit = 445 },
2674 { /* Performance MX */
2675 .product_id = 0x101a, .microns_per_hi_res_unit = 406 },
2676 { /* M560 */
2677 .product_id = 0x402d, .microns_per_hi_res_unit = 435 },
2678 { /* MX Master 2S */
2679 .product_id = 0x4069, .microns_per_hi_res_unit = 406 },
2680};
2681
2682static int hi_res_scroll_look_up_microns(__u32 product_id)
2683{
2684 int i;
2685 int num_devices = sizeof(hi_res_scroll_devices)
2686 / sizeof(hi_res_scroll_devices[0]);
2687 for (i = 0; i < num_devices; i++) {
2688 if (hi_res_scroll_devices[i].product_id == product_id)
2689 return hi_res_scroll_devices[i].microns_per_hi_res_unit;
2690 }
2691 /* We don't have a value for this device, so use a sensible default. */
2692 return 406;
2693}
2694
2695static int hi_res_scroll_enable(struct hidpp_device *hidpp)
2696{
2697 int ret;
2698 u8 multiplier = 8;
2699
2700 if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL_X2121) {
2701 ret = hidpp_hrw_set_wheel_mode(hidpp, false, true, false);
2702 hidpp_hrw_get_wheel_capability(hidpp, &multiplier);
2703 } else if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL_X2120) {
2704 ret = hidpp_hrs_set_highres_scrolling_mode(hidpp, true,
2705 &multiplier);
2706 } else /* if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL_1P0) */
2707 ret = hidpp10_enable_scrolling_acceleration(hidpp);
2708
2709 if (ret)
2710 return ret;
2711
2712 hidpp->vertical_wheel_counter.resolution_multiplier = multiplier;
2713 hidpp->vertical_wheel_counter.microns_per_hi_res_unit =
2714 hi_res_scroll_look_up_microns(hidpp->hid_dev->product);
2715 hid_info(hidpp->hid_dev, "multiplier = %d, microns = %d\n",
2716 multiplier,
2717 hidpp->vertical_wheel_counter.microns_per_hi_res_unit);
2718 return 0;
2719}
2720
2721/* -------------------------------------------------------------------------- */
2531/* Generic HID++ devices */ 2722/* Generic HID++ devices */
2532/* -------------------------------------------------------------------------- */ 2723/* -------------------------------------------------------------------------- */
2533 2724
@@ -2572,6 +2763,11 @@ static void hidpp_populate_input(struct hidpp_device *hidpp,
2572 wtp_populate_input(hidpp, input, origin_is_hid_core); 2763 wtp_populate_input(hidpp, input, origin_is_hid_core);
2573 else if (hidpp->quirks & HIDPP_QUIRK_CLASS_M560) 2764 else if (hidpp->quirks & HIDPP_QUIRK_CLASS_M560)
2574 m560_populate_input(hidpp, input, origin_is_hid_core); 2765 m560_populate_input(hidpp, input, origin_is_hid_core);
2766
2767 if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL) {
2768 input_set_capability(input, EV_REL, REL_WHEEL_HI_RES);
2769 hidpp->vertical_wheel_counter.dev = input;
2770 }
2575} 2771}
2576 2772
2577static int hidpp_input_configured(struct hid_device *hdev, 2773static int hidpp_input_configured(struct hid_device *hdev,
@@ -2690,6 +2886,27 @@ static int hidpp_raw_event(struct hid_device *hdev, struct hid_report *report,
2690 return 0; 2886 return 0;
2691} 2887}
2692 2888
2889static int hidpp_event(struct hid_device *hdev, struct hid_field *field,
2890 struct hid_usage *usage, __s32 value)
2891{
2892 /* This function will only be called for scroll events, due to the
2893 * restriction imposed in hidpp_usages.
2894 */
2895 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
2896 struct hid_scroll_counter *counter = &hidpp->vertical_wheel_counter;
2897 /* A scroll event may occur before the multiplier has been retrieved or
2898 * the input device set, or high-res scroll enabling may fail. In such
2899 * cases we must return early (falling back to default behaviour) to
2900 * avoid a crash in hid_scroll_counter_handle_scroll.
2901 */
2902 if (!(hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL) || value == 0
2903 || counter->dev == NULL || counter->resolution_multiplier == 0)
2904 return 0;
2905
2906 hid_scroll_counter_handle_scroll(counter, value);
2907 return 1;
2908}
2909
2693static int hidpp_initialize_battery(struct hidpp_device *hidpp) 2910static int hidpp_initialize_battery(struct hidpp_device *hidpp)
2694{ 2911{
2695 static atomic_t battery_no = ATOMIC_INIT(0); 2912 static atomic_t battery_no = ATOMIC_INIT(0);
@@ -2901,6 +3118,9 @@ static void hidpp_connect_event(struct hidpp_device *hidpp)
2901 if (hidpp->battery.ps) 3118 if (hidpp->battery.ps)
2902 power_supply_changed(hidpp->battery.ps); 3119 power_supply_changed(hidpp->battery.ps);
2903 3120
3121 if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL)
3122 hi_res_scroll_enable(hidpp);
3123
2904 if (!(hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT) || hidpp->delayed_input) 3124 if (!(hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT) || hidpp->delayed_input)
2905 /* if the input nodes are already created, we can stop now */ 3125 /* if the input nodes are already created, we can stop now */
2906 return; 3126 return;
@@ -3086,35 +3306,63 @@ static void hidpp_remove(struct hid_device *hdev)
3086 mutex_destroy(&hidpp->send_mutex); 3306 mutex_destroy(&hidpp->send_mutex);
3087} 3307}
3088 3308
3309#define LDJ_DEVICE(product) \
3310 HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, \
3311 USB_VENDOR_ID_LOGITECH, (product))
3312
3089static const struct hid_device_id hidpp_devices[] = { 3313static const struct hid_device_id hidpp_devices[] = {
3090 { /* wireless touchpad */ 3314 { /* wireless touchpad */
3091 HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, 3315 LDJ_DEVICE(0x4011),
3092 USB_VENDOR_ID_LOGITECH, 0x4011),
3093 .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT | 3316 .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT |
3094 HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS }, 3317 HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS },
3095 { /* wireless touchpad T650 */ 3318 { /* wireless touchpad T650 */
3096 HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, 3319 LDJ_DEVICE(0x4101),
3097 USB_VENDOR_ID_LOGITECH, 0x4101),
3098 .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT }, 3320 .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT },
3099 { /* wireless touchpad T651 */ 3321 { /* wireless touchpad T651 */
3100 HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 3322 HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH,
3101 USB_DEVICE_ID_LOGITECH_T651), 3323 USB_DEVICE_ID_LOGITECH_T651),
3102 .driver_data = HIDPP_QUIRK_CLASS_WTP }, 3324 .driver_data = HIDPP_QUIRK_CLASS_WTP },
3325 { /* Mouse Logitech Anywhere MX */
3326 LDJ_DEVICE(0x1017), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_1P0 },
3327 { /* Mouse Logitech Cube */
3328 LDJ_DEVICE(0x4010), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2120 },
3329 { /* Mouse Logitech M335 */
3330 LDJ_DEVICE(0x4050), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
3331 { /* Mouse Logitech M515 */
3332 LDJ_DEVICE(0x4007), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2120 },
3103 { /* Mouse logitech M560 */ 3333 { /* Mouse logitech M560 */
3104 HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, 3334 LDJ_DEVICE(0x402d),
3105 USB_VENDOR_ID_LOGITECH, 0x402d), 3335 .driver_data = HIDPP_QUIRK_DELAYED_INIT | HIDPP_QUIRK_CLASS_M560
3106 .driver_data = HIDPP_QUIRK_DELAYED_INIT | HIDPP_QUIRK_CLASS_M560 }, 3336 | HIDPP_QUIRK_HI_RES_SCROLL_X2120 },
3337 { /* Mouse Logitech M705 (firmware RQM17) */
3338 LDJ_DEVICE(0x101b), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_1P0 },
3339 { /* Mouse Logitech M705 (firmware RQM67) */
3340 LDJ_DEVICE(0x406d), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
3341 { /* Mouse Logitech M720 */
3342 LDJ_DEVICE(0x405e), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
3343 { /* Mouse Logitech MX Anywhere 2 */
3344 LDJ_DEVICE(0x404a), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
3345 { LDJ_DEVICE(0xb013), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
3346 { LDJ_DEVICE(0xb018), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
3347 { LDJ_DEVICE(0xb01f), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
3348 { /* Mouse Logitech MX Anywhere 2S */
3349 LDJ_DEVICE(0x406a), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
3350 { /* Mouse Logitech MX Master */
3351 LDJ_DEVICE(0x4041), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
3352 { LDJ_DEVICE(0x4060), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
3353 { LDJ_DEVICE(0x4071), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
3354 { /* Mouse Logitech MX Master 2S */
3355 LDJ_DEVICE(0x4069), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
3356 { /* Mouse Logitech Performance MX */
3357 LDJ_DEVICE(0x101a), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_1P0 },
3107 { /* Keyboard logitech K400 */ 3358 { /* Keyboard logitech K400 */
3108 HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, 3359 LDJ_DEVICE(0x4024),
3109 USB_VENDOR_ID_LOGITECH, 0x4024),
3110 .driver_data = HIDPP_QUIRK_CLASS_K400 }, 3360 .driver_data = HIDPP_QUIRK_CLASS_K400 },
3111 { /* Solar Keyboard Logitech K750 */ 3361 { /* Solar Keyboard Logitech K750 */
3112 HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, 3362 LDJ_DEVICE(0x4002),
3113 USB_VENDOR_ID_LOGITECH, 0x4002),
3114 .driver_data = HIDPP_QUIRK_CLASS_K750 }, 3363 .driver_data = HIDPP_QUIRK_CLASS_K750 },
3115 3364
3116 { HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, 3365 { LDJ_DEVICE(HID_ANY_ID) },
3117 USB_VENDOR_ID_LOGITECH, HID_ANY_ID)},
3118 3366
3119 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G920_WHEEL), 3367 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G920_WHEEL),
3120 .driver_data = HIDPP_QUIRK_CLASS_G920 | HIDPP_QUIRK_FORCE_OUTPUT_REPORTS}, 3368 .driver_data = HIDPP_QUIRK_CLASS_G920 | HIDPP_QUIRK_FORCE_OUTPUT_REPORTS},
@@ -3123,12 +3371,19 @@ static const struct hid_device_id hidpp_devices[] = {
3123 3371
3124MODULE_DEVICE_TABLE(hid, hidpp_devices); 3372MODULE_DEVICE_TABLE(hid, hidpp_devices);
3125 3373
3374static const struct hid_usage_id hidpp_usages[] = {
3375 { HID_GD_WHEEL, EV_REL, REL_WHEEL },
3376 { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1}
3377};
3378
3126static struct hid_driver hidpp_driver = { 3379static struct hid_driver hidpp_driver = {
3127 .name = "logitech-hidpp-device", 3380 .name = "logitech-hidpp-device",
3128 .id_table = hidpp_devices, 3381 .id_table = hidpp_devices,
3129 .probe = hidpp_probe, 3382 .probe = hidpp_probe,
3130 .remove = hidpp_remove, 3383 .remove = hidpp_remove,
3131 .raw_event = hidpp_raw_event, 3384 .raw_event = hidpp_raw_event,
3385 .usage_table = hidpp_usages,
3386 .event = hidpp_event,
3132 .input_configured = hidpp_input_configured, 3387 .input_configured = hidpp_input_configured,
3133 .input_mapping = hidpp_input_mapping, 3388 .input_mapping = hidpp_input_mapping,
3134 .input_mapped = hidpp_input_mapped, 3389 .input_mapped = hidpp_input_mapped,
diff --git a/include/linux/hid.h b/include/linux/hid.h
index d44a78362942..2827b87590d8 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -1139,6 +1139,34 @@ static inline u32 hid_report_len(struct hid_report *report)
1139int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size, 1139int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size,
1140 int interrupt); 1140 int interrupt);
1141 1141
1142
1143/**
1144 * struct hid_scroll_counter - Utility class for processing high-resolution
1145 * scroll events.
1146 * @dev: the input device for which events should be reported.
1147 * @microns_per_hi_res_unit: the amount moved by the user's finger for each
1148 * high-resolution unit reported by the mouse, in
1149 * microns.
1150 * @resolution_multiplier: the wheel's resolution in high-resolution mode as a
1151 * multiple of its lower resolution. For example, if
1152 * moving the wheel by one "notch" would result in a
1153 * value of 1 in low-resolution mode but 8 in
1154 * high-resolution, the multiplier is 8.
1155 * @remainder: counts the number of high-resolution units moved since the last
1156 * low-resolution event (REL_WHEEL or REL_HWHEEL) was sent. Should
1157 * only be used by class methods.
1158 */
1159struct hid_scroll_counter {
1160 struct input_dev *dev;
1161 int microns_per_hi_res_unit;
1162 int resolution_multiplier;
1163
1164 int remainder;
1165};
1166
1167void hid_scroll_counter_handle_scroll(struct hid_scroll_counter *counter,
1168 int hi_res_value);
1169
1142/* HID quirks API */ 1170/* HID quirks API */
1143unsigned long hid_lookup_quirk(const struct hid_device *hdev); 1171unsigned long hid_lookup_quirk(const struct hid_device *hdev);
1144int hid_quirks_init(char **quirks_param, __u16 bus, int count); 1172int hid_quirks_init(char **quirks_param, __u16 bus, int count);
diff --git a/include/uapi/linux/input-event-codes.h b/include/uapi/linux/input-event-codes.h
index 53fbae27b280..6d180cc60a5d 100644
--- a/include/uapi/linux/input-event-codes.h
+++ b/include/uapi/linux/input-event-codes.h
@@ -708,6 +708,15 @@
708#define REL_DIAL 0x07 708#define REL_DIAL 0x07
709#define REL_WHEEL 0x08 709#define REL_WHEEL 0x08
710#define REL_MISC 0x09 710#define REL_MISC 0x09
711/*
712 * 0x0a is reserved and should not be used in input drivers.
713 * It was used by HID as REL_MISC+1 and userspace needs to detect if
714 * the next REL_* event is correct or is just REL_MISC + n.
715 * We define here REL_RESERVED so userspace can rely on it and detect
716 * the situation described above.
717 */
718#define REL_RESERVED 0x0a
719#define REL_WHEEL_HI_RES 0x0b
711#define REL_MAX 0x0f 720#define REL_MAX 0x0f
712#define REL_CNT (REL_MAX+1) 721#define REL_CNT (REL_MAX+1)
713 722
@@ -744,6 +753,15 @@
744 753
745#define ABS_MISC 0x28 754#define ABS_MISC 0x28
746 755
756/*
757 * 0x2e is reserved and should not be used in input drivers.
758 * It was used by HID as ABS_MISC+6 and userspace needs to detect if
759 * the next ABS_* event is correct or is just ABS_MISC + n.
760 * We define here ABS_RESERVED so userspace can rely on it and detect
761 * the situation described above.
762 */
763#define ABS_RESERVED 0x2e
764
747#define ABS_MT_SLOT 0x2f /* MT slot being modified */ 765#define ABS_MT_SLOT 0x2f /* MT slot being modified */
748#define ABS_MT_TOUCH_MAJOR 0x30 /* Major axis of touching ellipse */ 766#define ABS_MT_TOUCH_MAJOR 0x30 /* Major axis of touching ellipse */
749#define ABS_MT_TOUCH_MINOR 0x31 /* Minor axis (omit if circular) */ 767#define ABS_MT_TOUCH_MINOR 0x31 /* Minor axis (omit if circular) */