30
30
MODULE_LICENSE ("GPL" );
31
31
MODULE_AUTHOR (
"Benjamin Tissoires <[email protected] >" );
32
32
MODULE_AUTHOR (
"Nestor Lopez Casado <[email protected] >" );
33
-
34
- static bool disable_raw_mode ;
35
- module_param (disable_raw_mode , bool , 0644 );
36
- MODULE_PARM_DESC (disable_raw_mode ,
37
- "Disable Raw mode reporting for touchpads and keep firmware gestures." );
33
+ MODULE_AUTHOR (
"Bastien Nocera <[email protected] >" );
38
34
39
35
static bool disable_tap_to_click ;
40
36
module_param (disable_tap_to_click , bool , 0644 );
@@ -71,12 +67,13 @@ MODULE_PARM_DESC(disable_tap_to_click,
71
67
/* bits 2..20 are reserved for classes */
72
68
/* #define HIDPP_QUIRK_CONNECT_EVENTS BIT(21) disabled */
73
69
#define HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS BIT(22)
74
- #define HIDPP_QUIRK_NO_HIDINPUT BIT(23)
70
+ #define HIDPP_QUIRK_DELAYED_INIT BIT(23)
75
71
#define HIDPP_QUIRK_FORCE_OUTPUT_REPORTS BIT(24)
76
72
#define HIDPP_QUIRK_UNIFYING BIT(25)
77
73
#define HIDPP_QUIRK_HIDPP_WHEELS BIT(26)
78
74
#define HIDPP_QUIRK_HIDPP_EXTRA_MOUSE_BTNS BIT(27)
79
75
#define HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS BIT(28)
76
+ #define HIDPP_QUIRK_HI_RES_SCROLL_1P0 BIT(29)
80
77
81
78
/* These are just aliases for now */
82
79
#define HIDPP_QUIRK_KBD_SCROLL_WHEEL HIDPP_QUIRK_HIDPP_WHEELS
@@ -87,8 +84,6 @@ MODULE_PARM_DESC(disable_tap_to_click,
87
84
HIDPP_CAPABILITY_HIDPP20_HI_RES_SCROLL | \
88
85
HIDPP_CAPABILITY_HIDPP20_HI_RES_WHEEL)
89
86
90
- #define HIDPP_QUIRK_DELAYED_INIT HIDPP_QUIRK_NO_HIDINPUT
91
-
92
87
#define HIDPP_CAPABILITY_HIDPP10_BATTERY BIT(0)
93
88
#define HIDPP_CAPABILITY_HIDPP20_BATTERY BIT(1)
94
89
#define HIDPP_CAPABILITY_BATTERY_MILEAGE BIT(2)
@@ -225,6 +220,16 @@ struct hidpp_device {
225
220
#define HIDPP_ERROR_INVALID_PARAM_VALUE 0x0b
226
221
#define HIDPP_ERROR_WRONG_PIN_CODE 0x0c
227
222
/* HID++ 2.0 error codes */
223
+ #define HIDPP20_ERROR_NO_ERROR 0x00
224
+ #define HIDPP20_ERROR_UNKNOWN 0x01
225
+ #define HIDPP20_ERROR_INVALID_ARGS 0x02
226
+ #define HIDPP20_ERROR_OUT_OF_RANGE 0x03
227
+ #define HIDPP20_ERROR_HW_ERROR 0x04
228
+ #define HIDPP20_ERROR_LOGITECH_INTERNAL 0x05
229
+ #define HIDPP20_ERROR_INVALID_FEATURE_INDEX 0x06
230
+ #define HIDPP20_ERROR_INVALID_FUNCTION_ID 0x07
231
+ #define HIDPP20_ERROR_BUSY 0x08
232
+ #define HIDPP20_ERROR_UNSUPPORTED 0x09
228
233
#define HIDPP20_ERROR 0xff
229
234
230
235
static void hidpp_connect_event (struct hidpp_device * hidpp_dev );
@@ -279,6 +284,7 @@ static int hidpp_send_message_sync(struct hidpp_device *hidpp,
279
284
struct hidpp_report * response )
280
285
{
281
286
int ret ;
287
+ int max_retries = 3 ;
282
288
283
289
mutex_lock (& hidpp -> send_mutex );
284
290
@@ -291,34 +297,39 @@ static int hidpp_send_message_sync(struct hidpp_device *hidpp,
291
297
*/
292
298
* response = * message ;
293
299
294
- ret = __hidpp_send_report (hidpp -> hid_dev , message );
300
+ for (; max_retries != 0 ; max_retries -- ) {
301
+ ret = __hidpp_send_report (hidpp -> hid_dev , message );
295
302
296
- if (ret ) {
297
- dbg_hid ("__hidpp_send_report returned err: %d\n" , ret );
298
- memset (response , 0 , sizeof (struct hidpp_report ));
299
- goto exit ;
300
- }
303
+ if (ret ) {
304
+ dbg_hid ("__hidpp_send_report returned err: %d\n" , ret );
305
+ memset (response , 0 , sizeof (struct hidpp_report ));
306
+ goto exit ;
307
+ }
301
308
302
- if (!wait_event_timeout (hidpp -> wait , hidpp -> answer_available ,
303
- 5 * HZ )) {
304
- dbg_hid ("%s:timeout waiting for response\n" , __func__ );
305
- memset (response , 0 , sizeof (struct hidpp_report ));
306
- ret = - ETIMEDOUT ;
307
- }
309
+ if (!wait_event_timeout (hidpp -> wait , hidpp -> answer_available ,
310
+ 5 * HZ )) {
311
+ dbg_hid ("%s:timeout waiting for response\n" , __func__ );
312
+ memset (response , 0 , sizeof (struct hidpp_report ));
313
+ ret = - ETIMEDOUT ;
314
+ }
308
315
309
- if (response -> report_id == REPORT_ID_HIDPP_SHORT &&
310
- response -> rap .sub_id == HIDPP_ERROR ) {
311
- ret = response -> rap .params [1 ];
312
- dbg_hid ("%s:got hidpp error %02X\n" , __func__ , ret );
313
- goto exit ;
314
- }
316
+ if (response -> report_id == REPORT_ID_HIDPP_SHORT &&
317
+ response -> rap .sub_id == HIDPP_ERROR ) {
318
+ ret = response -> rap .params [1 ];
319
+ dbg_hid ("%s:got hidpp error %02X\n" , __func__ , ret );
320
+ goto exit ;
321
+ }
315
322
316
- if ((response -> report_id == REPORT_ID_HIDPP_LONG ||
317
- response -> report_id == REPORT_ID_HIDPP_VERY_LONG ) &&
318
- response -> fap .feature_index == HIDPP20_ERROR ) {
319
- ret = response -> fap .params [1 ];
320
- dbg_hid ("%s:got hidpp 2.0 error %02X\n" , __func__ , ret );
321
- goto exit ;
323
+ if ((response -> report_id == REPORT_ID_HIDPP_LONG ||
324
+ response -> report_id == REPORT_ID_HIDPP_VERY_LONG ) &&
325
+ response -> fap .feature_index == HIDPP20_ERROR ) {
326
+ ret = response -> fap .params [1 ];
327
+ if (ret != HIDPP20_ERROR_BUSY ) {
328
+ dbg_hid ("%s:got hidpp 2.0 error %02X\n" , __func__ , ret );
329
+ goto exit ;
330
+ }
331
+ dbg_hid ("%s:got busy hidpp 2.0 error %02X, retrying\n" , __func__ , ret );
332
+ }
322
333
}
323
334
324
335
exit :
@@ -334,8 +345,13 @@ static int hidpp_send_fap_command_sync(struct hidpp_device *hidpp,
334
345
struct hidpp_report * message ;
335
346
int ret ;
336
347
337
- if (param_count > sizeof (message -> fap .params ))
348
+ if (param_count > sizeof (message -> fap .params )) {
349
+ hid_dbg (hidpp -> hid_dev ,
350
+ "Invalid number of parameters passed to command (%d != %llu)\n" ,
351
+ param_count ,
352
+ (unsigned long long ) sizeof (message -> fap .params ));
338
353
return - EINVAL ;
354
+ }
339
355
340
356
message = kzalloc (sizeof (struct hidpp_report ), GFP_KERNEL );
341
357
if (!message )
@@ -3436,11 +3452,17 @@ static int hi_res_scroll_enable(struct hidpp_device *hidpp)
3436
3452
ret = hidpp10_enable_scrolling_acceleration (hidpp );
3437
3453
multiplier = 8 ;
3438
3454
}
3439
- if (ret )
3455
+ if (ret ) {
3456
+ hid_dbg (hidpp -> hid_dev ,
3457
+ "Could not enable hi-res scrolling: %d\n" , ret );
3440
3458
return ret ;
3459
+ }
3441
3460
3442
- if (multiplier == 0 )
3461
+ if (multiplier == 0 ) {
3462
+ hid_dbg (hidpp -> hid_dev ,
3463
+ "Invalid multiplier 0 from device, setting it to 1\n" );
3443
3464
multiplier = 1 ;
3465
+ }
3444
3466
3445
3467
hidpp -> vertical_wheel_counter .wheel_multiplier = multiplier ;
3446
3468
hid_dbg (hidpp -> hid_dev , "wheel multiplier = %d\n" , multiplier );
@@ -3472,14 +3494,8 @@ static int hidpp_initialize_hires_scroll(struct hidpp_device *hidpp)
3472
3494
hid_dbg (hidpp -> hid_dev , "Detected HID++ 2.0 hi-res scrolling\n" );
3473
3495
}
3474
3496
} else {
3475
- struct hidpp_report response ;
3476
-
3477
- ret = hidpp_send_rap_command_sync (hidpp ,
3478
- REPORT_ID_HIDPP_SHORT ,
3479
- HIDPP_GET_REGISTER ,
3480
- HIDPP_ENABLE_FAST_SCROLL ,
3481
- NULL , 0 , & response );
3482
- if (!ret ) {
3497
+ /* We cannot detect fast scrolling support on HID++ 1.0 devices */
3498
+ if (hidpp -> quirks & HIDPP_QUIRK_HI_RES_SCROLL_1P0 ) {
3483
3499
hidpp -> capabilities |= HIDPP_CAPABILITY_HIDPP10_FAST_SCROLL ;
3484
3500
hid_dbg (hidpp -> hid_dev , "Detected HID++ 1.0 fast scroll\n" );
3485
3501
}
@@ -4002,7 +4018,7 @@ static void hidpp_connect_event(struct hidpp_device *hidpp)
4002
4018
if (hidpp -> capabilities & HIDPP_CAPABILITY_HI_RES_SCROLL )
4003
4019
hi_res_scroll_enable (hidpp );
4004
4020
4005
- if (!(hidpp -> quirks & HIDPP_QUIRK_NO_HIDINPUT ) || hidpp -> delayed_input )
4021
+ if (!(hidpp -> quirks & HIDPP_QUIRK_DELAYED_INIT ) || hidpp -> delayed_input )
4006
4022
/* if the input nodes are already created, we can stop now */
4007
4023
return ;
4008
4024
@@ -4107,6 +4123,7 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
4107
4123
bool connected ;
4108
4124
unsigned int connect_mask = HID_CONNECT_DEFAULT ;
4109
4125
struct hidpp_ff_private_data data ;
4126
+ bool will_restart = false;
4110
4127
4111
4128
/* report_fixup needs drvdata to be set before we call hid_parse */
4112
4129
hidpp = devm_kzalloc (& hdev -> dev , sizeof (* hidpp ), GFP_KERNEL );
@@ -4147,11 +4164,6 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
4147
4164
hidpp_application_equals (hdev , HID_GD_KEYBOARD ))
4148
4165
hidpp -> quirks |= HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS ;
4149
4166
4150
- if (disable_raw_mode ) {
4151
- hidpp -> quirks &= ~HIDPP_QUIRK_CLASS_WTP ;
4152
- hidpp -> quirks &= ~HIDPP_QUIRK_NO_HIDINPUT ;
4153
- }
4154
-
4155
4167
if (hidpp -> quirks & HIDPP_QUIRK_CLASS_WTP ) {
4156
4168
ret = wtp_allocate (hdev , id );
4157
4169
if (ret )
@@ -4162,6 +4174,10 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
4162
4174
return ret ;
4163
4175
}
4164
4176
4177
+ if (hidpp -> quirks & HIDPP_QUIRK_DELAYED_INIT ||
4178
+ hidpp -> quirks & HIDPP_QUIRK_UNIFYING )
4179
+ will_restart = true;
4180
+
4165
4181
INIT_WORK (& hidpp -> work , delayed_work_cb );
4166
4182
mutex_init (& hidpp -> send_mutex );
4167
4183
init_waitqueue_head (& hidpp -> wait );
@@ -4176,7 +4192,7 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
4176
4192
* Plain USB connections need to actually call start and open
4177
4193
* on the transport driver to allow incoming data.
4178
4194
*/
4179
- ret = hid_hw_start (hdev , 0 );
4195
+ ret = hid_hw_start (hdev , will_restart ? 0 : connect_mask );
4180
4196
if (ret ) {
4181
4197
hid_err (hdev , "hw start failed\n" );
4182
4198
goto hid_hw_start_fail ;
@@ -4213,6 +4229,7 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
4213
4229
hidpp -> wireless_feature_index = 0 ;
4214
4230
else if (ret )
4215
4231
goto hid_hw_init_fail ;
4232
+ ret = 0 ;
4216
4233
}
4217
4234
4218
4235
if (connected && (hidpp -> quirks & HIDPP_QUIRK_CLASS_WTP )) {
@@ -4227,19 +4244,21 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
4227
4244
4228
4245
hidpp_connect_event (hidpp );
4229
4246
4230
- /* Reset the HID node state */
4231
- hid_device_io_stop (hdev );
4232
- hid_hw_close (hdev );
4233
- hid_hw_stop (hdev );
4247
+ if (will_restart ) {
4248
+ /* Reset the HID node state */
4249
+ hid_device_io_stop (hdev );
4250
+ hid_hw_close (hdev );
4251
+ hid_hw_stop (hdev );
4234
4252
4235
- if (hidpp -> quirks & HIDPP_QUIRK_NO_HIDINPUT )
4236
- connect_mask &= ~HID_CONNECT_HIDINPUT ;
4253
+ if (hidpp -> quirks & HIDPP_QUIRK_DELAYED_INIT )
4254
+ connect_mask &= ~HID_CONNECT_HIDINPUT ;
4237
4255
4238
- /* Now export the actual inputs and hidraw nodes to the world */
4239
- ret = hid_hw_start (hdev , connect_mask );
4240
- if (ret ) {
4241
- hid_err (hdev , "%s:hid_hw_start returned error\n" , __func__ );
4242
- goto hid_hw_start_fail ;
4256
+ /* Now export the actual inputs and hidraw nodes to the world */
4257
+ ret = hid_hw_start (hdev , connect_mask );
4258
+ if (ret ) {
4259
+ hid_err (hdev , "%s:hid_hw_start returned error\n" , __func__ );
4260
+ goto hid_hw_start_fail ;
4261
+ }
4243
4262
}
4244
4263
4245
4264
if (hidpp -> quirks & HIDPP_QUIRK_CLASS_G920 ) {
@@ -4297,9 +4316,15 @@ static const struct hid_device_id hidpp_devices[] = {
4297
4316
HID_BLUETOOTH_DEVICE (USB_VENDOR_ID_LOGITECH ,
4298
4317
USB_DEVICE_ID_LOGITECH_T651 ),
4299
4318
.driver_data = HIDPP_QUIRK_CLASS_WTP },
4319
+ { /* Mouse Logitech Anywhere MX */
4320
+ LDJ_DEVICE (0x1017 ), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_1P0 },
4300
4321
{ /* Mouse logitech M560 */
4301
4322
LDJ_DEVICE (0x402d ),
4302
4323
.driver_data = HIDPP_QUIRK_DELAYED_INIT | HIDPP_QUIRK_CLASS_M560 },
4324
+ { /* Mouse Logitech M705 (firmware RQM17) */
4325
+ LDJ_DEVICE (0x101b ), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_1P0 },
4326
+ { /* Mouse Logitech Performance MX */
4327
+ LDJ_DEVICE (0x101a ), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_1P0 },
4303
4328
{ /* Keyboard logitech K400 */
4304
4329
LDJ_DEVICE (0x4024 ),
4305
4330
.driver_data = HIDPP_QUIRK_CLASS_K400 },
@@ -4348,6 +4373,9 @@ static const struct hid_device_id hidpp_devices[] = {
4348
4373
{ /* Logitech G920 Wheel over USB */
4349
4374
HID_USB_DEVICE (USB_VENDOR_ID_LOGITECH , USB_DEVICE_ID_LOGITECH_G920_WHEEL ),
4350
4375
.driver_data = HIDPP_QUIRK_CLASS_G920 | HIDPP_QUIRK_FORCE_OUTPUT_REPORTS },
4376
+ { /* Logitech G923 Wheel (Xbox version) over USB */
4377
+ HID_USB_DEVICE (USB_VENDOR_ID_LOGITECH , USB_DEVICE_ID_LOGITECH_G923_XBOX_WHEEL ),
4378
+ .driver_data = HIDPP_QUIRK_CLASS_G920 | HIDPP_QUIRK_FORCE_OUTPUT_REPORTS },
4351
4379
{ /* Logitech G Pro Gaming Mouse over USB */
4352
4380
HID_USB_DEVICE (USB_VENDOR_ID_LOGITECH , 0xC088 ) },
4353
4381
@@ -4367,6 +4395,8 @@ static const struct hid_device_id hidpp_devices[] = {
4367
4395
{ /* MX Ergo trackball over Bluetooth */
4368
4396
HID_BLUETOOTH_DEVICE (USB_VENDOR_ID_LOGITECH , 0xb01d ) },
4369
4397
{ HID_BLUETOOTH_DEVICE (USB_VENDOR_ID_LOGITECH , 0xb01e ) },
4398
+ { /* Signature M650 over Bluetooth */
4399
+ HID_BLUETOOTH_DEVICE (USB_VENDOR_ID_LOGITECH , 0xb02a ) },
4370
4400
{ /* MX Master 3 mouse over Bluetooth */
4371
4401
HID_BLUETOOTH_DEVICE (USB_VENDOR_ID_LOGITECH , 0xb023 ) },
4372
4402
{}
0 commit comments