@@ -72,6 +72,7 @@ MODULE_PARM_DESC(disable_tap_to_click,
72
72
#define HIDPP_QUIRK_HI_RES_SCROLL_X2120 BIT(27)
73
73
#define HIDPP_QUIRK_HI_RES_SCROLL_X2121 BIT(28)
74
74
#define HIDPP_QUIRK_HIDPP_WHEELS BIT(29)
75
+ #define HIDPP_QUIRK_HIDPP_EXTRA_MOUSE_BTNS BIT(30)
75
76
76
77
/* These are just aliases for now */
77
78
#define HIDPP_QUIRK_KBD_SCROLL_WHEEL HIDPP_QUIRK_HIDPP_WHEELS
@@ -2792,6 +2793,64 @@ static void hidpp10_wheel_populate_input(struct hidpp_device *hidpp,
2792
2793
__set_bit (REL_HWHEEL_HI_RES , input_dev -> relbit );
2793
2794
}
2794
2795
2796
+ /* -------------------------------------------------------------------------- */
2797
+ /* HID++1.0 mice which use HID++ reports for extra mouse buttons */
2798
+ /* -------------------------------------------------------------------------- */
2799
+ static int hidpp10_extra_mouse_buttons_connect (struct hidpp_device * hidpp )
2800
+ {
2801
+ return hidpp10_set_register (hidpp , HIDPP_REG_ENABLE_REPORTS , 0 ,
2802
+ HIDPP_ENABLE_MOUSE_EXTRA_BTN_REPORT ,
2803
+ HIDPP_ENABLE_MOUSE_EXTRA_BTN_REPORT );
2804
+ }
2805
+
2806
+ static int hidpp10_extra_mouse_buttons_raw_event (struct hidpp_device * hidpp ,
2807
+ u8 * data , int size )
2808
+ {
2809
+ int i ;
2810
+
2811
+ if (!hidpp -> input )
2812
+ return - EINVAL ;
2813
+
2814
+ if (size < 7 )
2815
+ return 0 ;
2816
+
2817
+ if (data [0 ] != REPORT_ID_HIDPP_SHORT ||
2818
+ data [2 ] != HIDPP_SUB_ID_MOUSE_EXTRA_BTNS )
2819
+ return 0 ;
2820
+
2821
+ /*
2822
+ * Buttons are either delivered through the regular mouse report *or*
2823
+ * through the extra buttons report. At least for button 6 how it is
2824
+ * delivered differs per receiver firmware version. Even receivers with
2825
+ * the same usb-id show different behavior, so we handle both cases.
2826
+ */
2827
+ for (i = 0 ; i < 8 ; i ++ )
2828
+ input_report_key (hidpp -> input , BTN_MOUSE + i ,
2829
+ (data [3 ] & (1 << i )));
2830
+
2831
+ /* Some mice report events on button 9+, use BTN_MISC */
2832
+ for (i = 0 ; i < 8 ; i ++ )
2833
+ input_report_key (hidpp -> input , BTN_MISC + i ,
2834
+ (data [4 ] & (1 << i )));
2835
+
2836
+ input_sync (hidpp -> input );
2837
+ return 1 ;
2838
+ }
2839
+
2840
+ static void hidpp10_extra_mouse_buttons_populate_input (
2841
+ struct hidpp_device * hidpp , struct input_dev * input_dev )
2842
+ {
2843
+ /* BTN_MOUSE - BTN_MOUSE+7 are set already by the descriptor */
2844
+ __set_bit (BTN_0 , input_dev -> keybit );
2845
+ __set_bit (BTN_1 , input_dev -> keybit );
2846
+ __set_bit (BTN_2 , input_dev -> keybit );
2847
+ __set_bit (BTN_3 , input_dev -> keybit );
2848
+ __set_bit (BTN_4 , input_dev -> keybit );
2849
+ __set_bit (BTN_5 , input_dev -> keybit );
2850
+ __set_bit (BTN_6 , input_dev -> keybit );
2851
+ __set_bit (BTN_7 , input_dev -> keybit );
2852
+ }
2853
+
2795
2854
/* -------------------------------------------------------------------------- */
2796
2855
/* High-resolution scroll wheels */
2797
2856
/* -------------------------------------------------------------------------- */
@@ -2879,6 +2938,9 @@ static void hidpp_populate_input(struct hidpp_device *hidpp,
2879
2938
2880
2939
if (hidpp -> quirks & HIDPP_QUIRK_HIDPP_WHEELS )
2881
2940
hidpp10_wheel_populate_input (hidpp , input );
2941
+
2942
+ if (hidpp -> quirks & HIDPP_QUIRK_HIDPP_EXTRA_MOUSE_BTNS )
2943
+ hidpp10_extra_mouse_buttons_populate_input (hidpp , input );
2882
2944
}
2883
2945
2884
2946
static int hidpp_input_configured (struct hid_device * hdev ,
@@ -2956,6 +3018,12 @@ static int hidpp_raw_hidpp_event(struct hidpp_device *hidpp, u8 *data,
2956
3018
return ret ;
2957
3019
}
2958
3020
3021
+ if (hidpp -> quirks & HIDPP_QUIRK_HIDPP_EXTRA_MOUSE_BTNS ) {
3022
+ ret = hidpp10_extra_mouse_buttons_raw_event (hidpp , data , size );
3023
+ if (ret != 0 )
3024
+ return ret ;
3025
+ }
3026
+
2959
3027
return 0 ;
2960
3028
}
2961
3029
@@ -3209,6 +3277,12 @@ static void hidpp_connect_event(struct hidpp_device *hidpp)
3209
3277
return ;
3210
3278
}
3211
3279
3280
+ if (hidpp -> quirks & HIDPP_QUIRK_HIDPP_EXTRA_MOUSE_BTNS ) {
3281
+ ret = hidpp10_extra_mouse_buttons_connect (hidpp );
3282
+ if (ret )
3283
+ return ;
3284
+ }
3285
+
3212
3286
/* the device is already connected, we can ask for its name and
3213
3287
* protocol */
3214
3288
if (!hidpp -> protocol_major ) {
@@ -3374,7 +3448,8 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
3374
3448
3375
3449
if (id -> group == HID_GROUP_LOGITECH_27MHZ_DEVICE &&
3376
3450
hidpp_application_equals (hdev , HID_GD_MOUSE ))
3377
- hidpp -> quirks |= HIDPP_QUIRK_HIDPP_WHEELS ;
3451
+ hidpp -> quirks |= HIDPP_QUIRK_HIDPP_WHEELS |
3452
+ HIDPP_QUIRK_HIDPP_EXTRA_MOUSE_BTNS ;
3378
3453
3379
3454
if (disable_raw_mode ) {
3380
3455
hidpp -> quirks &= ~HIDPP_QUIRK_CLASS_WTP ;
0 commit comments