hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/hid/hid-logitech-hidpp.c
....@@ -1,16 +1,12 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
2
- * HIDPP protocol for Logitech Unifying receivers
3
+ * HIDPP protocol for Logitech receivers
34 *
45 * Copyright (c) 2011 Logitech (c)
56 * Copyright (c) 2012-2013 Google (c)
67 * Copyright (c) 2013-2014 Red Hat Inc.
78 */
89
9
-/*
10
- * This program is free software; you can redistribute it and/or modify it
11
- * under the terms of the GNU General Public License as published by the Free
12
- * Software Foundation; version 2 of the License.
13
- */
1410
1511 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
1612
....@@ -21,6 +17,7 @@
2117 #include <linux/module.h>
2218 #include <linux/slab.h>
2319 #include <linux/sched.h>
20
+#include <linux/sched/clock.h>
2421 #include <linux/kfifo.h>
2522 #include <linux/input/mt.h>
2623 #include <linux/workqueue.h>
....@@ -50,7 +47,15 @@
5047
5148 #define HIDPP_REPORT_SHORT_LENGTH 7
5249 #define HIDPP_REPORT_LONG_LENGTH 20
53
-#define HIDPP_REPORT_VERY_LONG_LENGTH 64
50
+#define HIDPP_REPORT_VERY_LONG_MAX_LENGTH 64
51
+
52
+#define HIDPP_REPORT_SHORT_SUPPORTED BIT(0)
53
+#define HIDPP_REPORT_LONG_SUPPORTED BIT(1)
54
+#define HIDPP_REPORT_VERY_LONG_SUPPORTED BIT(2)
55
+
56
+#define HIDPP_SUB_ID_CONSUMER_VENDOR_KEYS 0x03
57
+#define HIDPP_SUB_ID_ROLLER 0x05
58
+#define HIDPP_SUB_ID_MOUSE_EXTRA_BTNS 0x06
5459
5560 #define HIDPP_QUIRK_CLASS_WTP BIT(0)
5661 #define HIDPP_QUIRK_CLASS_M560 BIT(1)
....@@ -64,6 +69,21 @@
6469 #define HIDPP_QUIRK_NO_HIDINPUT BIT(23)
6570 #define HIDPP_QUIRK_FORCE_OUTPUT_REPORTS BIT(24)
6671 #define HIDPP_QUIRK_UNIFYING BIT(25)
72
+#define HIDPP_QUIRK_HI_RES_SCROLL_1P0 BIT(26)
73
+#define HIDPP_QUIRK_HI_RES_SCROLL_X2120 BIT(27)
74
+#define HIDPP_QUIRK_HI_RES_SCROLL_X2121 BIT(28)
75
+#define HIDPP_QUIRK_HIDPP_WHEELS BIT(29)
76
+#define HIDPP_QUIRK_HIDPP_EXTRA_MOUSE_BTNS BIT(30)
77
+#define HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS BIT(31)
78
+
79
+/* These are just aliases for now */
80
+#define HIDPP_QUIRK_KBD_SCROLL_WHEEL HIDPP_QUIRK_HIDPP_WHEELS
81
+#define HIDPP_QUIRK_KBD_ZOOM_WHEEL HIDPP_QUIRK_HIDPP_WHEELS
82
+
83
+/* Convenience constant to check for any high-res support. */
84
+#define HIDPP_QUIRK_HI_RES_SCROLL (HIDPP_QUIRK_HI_RES_SCROLL_1P0 | \
85
+ HIDPP_QUIRK_HI_RES_SCROLL_X2120 | \
86
+ HIDPP_QUIRK_HI_RES_SCROLL_X2121)
6787
6888 #define HIDPP_QUIRK_DELAYED_INIT HIDPP_QUIRK_NO_HIDINPUT
6989
....@@ -71,6 +91,9 @@
7191 #define HIDPP_CAPABILITY_HIDPP20_BATTERY BIT(1)
7292 #define HIDPP_CAPABILITY_BATTERY_MILEAGE BIT(2)
7393 #define HIDPP_CAPABILITY_BATTERY_LEVEL_STATUS BIT(3)
94
+#define HIDPP_CAPABILITY_BATTERY_VOLTAGE BIT(4)
95
+
96
+#define lg_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
7497
7598 /*
7699 * There are two hidpp protocols in use, the first version hidpp10 is known
....@@ -97,13 +120,13 @@
97120 struct fap {
98121 u8 feature_index;
99122 u8 funcindex_clientid;
100
- u8 params[HIDPP_REPORT_VERY_LONG_LENGTH - 4U];
123
+ u8 params[HIDPP_REPORT_VERY_LONG_MAX_LENGTH - 4U];
101124 };
102125
103126 struct rap {
104127 u8 sub_id;
105128 u8 reg_address;
106
- u8 params[HIDPP_REPORT_VERY_LONG_LENGTH - 4U];
129
+ u8 params[HIDPP_REPORT_VERY_LONG_MAX_LENGTH - 4U];
107130 };
108131
109132 struct hidpp_report {
....@@ -119,21 +142,44 @@
119142 struct hidpp_battery {
120143 u8 feature_index;
121144 u8 solar_feature_index;
145
+ u8 voltage_feature_index;
122146 struct power_supply_desc desc;
123147 struct power_supply *ps;
124148 char name[64];
125149 int status;
126150 int capacity;
127151 int level;
152
+ int voltage;
153
+ int charge_type;
128154 bool online;
155
+};
156
+
157
+/**
158
+ * struct hidpp_scroll_counter - Utility class for processing high-resolution
159
+ * scroll events.
160
+ * @dev: the input device for which events should be reported.
161
+ * @wheel_multiplier: the scalar multiplier to be applied to each wheel event
162
+ * @remainder: counts the number of high-resolution units moved since the last
163
+ * low-resolution event (REL_WHEEL or REL_HWHEEL) was sent. Should
164
+ * only be used by class methods.
165
+ * @direction: direction of last movement (1 or -1)
166
+ * @last_time: last event time, used to reset remainder after inactivity
167
+ */
168
+struct hidpp_scroll_counter {
169
+ int wheel_multiplier;
170
+ int remainder;
171
+ int direction;
172
+ unsigned long long last_time;
129173 };
130174
131175 struct hidpp_device {
132176 struct hid_device *hid_dev;
177
+ struct input_dev *input;
133178 struct mutex send_mutex;
134179 void *send_receive_buf;
135180 char *name; /* will never be NULL and should not be freed */
136181 wait_queue_head_t wait;
182
+ int very_long_report_length;
137183 bool answer_available;
138184 u8 protocol_major;
139185 u8 protocol_minor;
....@@ -147,8 +193,12 @@
147193
148194 unsigned long quirks;
149195 unsigned long capabilities;
196
+ u8 supported_reports;
150197
151198 struct hidpp_battery battery;
199
+ struct hidpp_scroll_counter vertical_wheel_counter;
200
+
201
+ u8 wireless_feature_index;
152202 };
153203
154204 /* HID++ 1.0 error codes */
....@@ -177,8 +227,6 @@
177227 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
178228 int fields_count, ret;
179229
180
- hidpp = hid_get_drvdata(hdev);
181
-
182230 switch (hidpp_report->report_id) {
183231 case REPORT_ID_HIDPP_SHORT:
184232 fields_count = HIDPP_REPORT_SHORT_LENGTH;
....@@ -187,7 +235,7 @@
187235 fields_count = HIDPP_REPORT_LONG_LENGTH;
188236 break;
189237 case REPORT_ID_HIDPP_VERY_LONG:
190
- fields_count = HIDPP_REPORT_VERY_LONG_LENGTH;
238
+ fields_count = hidpp->very_long_report_length;
191239 break;
192240 default:
193241 return -ENODEV;
....@@ -305,6 +353,11 @@
305353 struct hidpp_report *message;
306354 int ret, max_count;
307355
356
+ /* Send as long report if short reports are not supported. */
357
+ if (report_id == REPORT_ID_HIDPP_SHORT &&
358
+ !(hidpp_dev->supported_reports & HIDPP_REPORT_SHORT_SUPPORTED))
359
+ report_id = REPORT_ID_HIDPP_LONG;
360
+
308361 switch (report_id) {
309362 case REPORT_ID_HIDPP_SHORT:
310363 max_count = HIDPP_REPORT_SHORT_LENGTH - 4;
....@@ -313,7 +366,7 @@
313366 max_count = HIDPP_REPORT_LONG_LENGTH - 4;
314367 break;
315368 case REPORT_ID_HIDPP_VERY_LONG:
316
- max_count = HIDPP_REPORT_VERY_LONG_LENGTH - 4;
369
+ max_count = hidpp_dev->very_long_report_length - 4;
317370 break;
318371 default:
319372 return -EINVAL;
....@@ -358,10 +411,13 @@
358411 (answer->fap.params[0] == question->fap.funcindex_clientid);
359412 }
360413
361
-static inline bool hidpp_report_is_connect_event(struct hidpp_report *report)
414
+static inline bool hidpp_report_is_connect_event(struct hidpp_device *hidpp,
415
+ struct hidpp_report *report)
362416 {
363
- return (report->report_id == REPORT_ID_HIDPP_SHORT) &&
364
- (report->rap.sub_id == 0x41);
417
+ return (hidpp->wireless_feature_index &&
418
+ (report->fap.feature_index == hidpp->wireless_feature_index)) ||
419
+ ((report->report_id == REPORT_ID_HIDPP_SHORT) &&
420
+ (report->rap.sub_id == 0x41));
365421 }
366422
367423 /**
....@@ -391,6 +447,68 @@
391447 *name = new_name;
392448 }
393449
450
+/**
451
+ * hidpp_scroll_counter_handle_scroll() - Send high- and low-resolution scroll
452
+ * events given a high-resolution wheel
453
+ * movement.
454
+ * @counter: a hid_scroll_counter struct describing the wheel.
455
+ * @hi_res_value: the movement of the wheel, in the mouse's high-resolution
456
+ * units.
457
+ *
458
+ * Given a high-resolution movement, this function converts the movement into
459
+ * fractions of 120 and emits high-resolution scroll events for the input
460
+ * device. It also uses the multiplier from &struct hid_scroll_counter to
461
+ * emit low-resolution scroll events when appropriate for
462
+ * backwards-compatibility with userspace input libraries.
463
+ */
464
+static void hidpp_scroll_counter_handle_scroll(struct input_dev *input_dev,
465
+ struct hidpp_scroll_counter *counter,
466
+ int hi_res_value)
467
+{
468
+ int low_res_value, remainder, direction;
469
+ unsigned long long now, previous;
470
+
471
+ hi_res_value = hi_res_value * 120/counter->wheel_multiplier;
472
+ input_report_rel(input_dev, REL_WHEEL_HI_RES, hi_res_value);
473
+
474
+ remainder = counter->remainder;
475
+ direction = hi_res_value > 0 ? 1 : -1;
476
+
477
+ now = sched_clock();
478
+ previous = counter->last_time;
479
+ counter->last_time = now;
480
+ /*
481
+ * Reset the remainder after a period of inactivity or when the
482
+ * direction changes. This prevents the REL_WHEEL emulation point
483
+ * from sliding for devices that don't always provide the same
484
+ * number of movements per detent.
485
+ */
486
+ if (now - previous > 1000000000 || direction != counter->direction)
487
+ remainder = 0;
488
+
489
+ counter->direction = direction;
490
+ remainder += hi_res_value;
491
+
492
+ /* Some wheels will rest 7/8ths of a detent from the previous detent
493
+ * after slow movement, so we want the threshold for low-res events to
494
+ * be in the middle between two detents (e.g. after 4/8ths) as
495
+ * opposed to on the detents themselves (8/8ths).
496
+ */
497
+ if (abs(remainder) >= 60) {
498
+ /* Add (or subtract) 1 because we want to trigger when the wheel
499
+ * is half-way to the next detent (i.e. scroll 1 detent after a
500
+ * 1/2 detent movement, 2 detents after a 1 1/2 detent movement,
501
+ * etc.).
502
+ */
503
+ low_res_value = remainder / 120;
504
+ if (low_res_value == 0)
505
+ low_res_value = (hi_res_value > 0 ? 1 : -1);
506
+ input_report_rel(input_dev, REL_WHEEL, low_res_value);
507
+ remainder -= low_res_value * 120;
508
+ }
509
+ counter->remainder = remainder;
510
+}
511
+
394512 /* -------------------------------------------------------------------------- */
395513 /* HIDP++ 1.0 commands */
396514 /* -------------------------------------------------------------------------- */
....@@ -400,32 +518,64 @@
400518 #define HIDPP_SET_LONG_REGISTER 0x82
401519 #define HIDPP_GET_LONG_REGISTER 0x83
402520
403
-#define HIDPP_REG_GENERAL 0x00
404
-
405
-static int hidpp10_enable_battery_reporting(struct hidpp_device *hidpp_dev)
521
+/**
522
+ * hidpp10_set_register - Modify a HID++ 1.0 register.
523
+ * @hidpp_dev: the device to set the register on.
524
+ * @register_address: the address of the register to modify.
525
+ * @byte: the byte of the register to modify. Should be less than 3.
526
+ * @mask: mask of the bits to modify
527
+ * @value: new values for the bits in mask
528
+ * Return: 0 if successful, otherwise a negative error code.
529
+ */
530
+static int hidpp10_set_register(struct hidpp_device *hidpp_dev,
531
+ u8 register_address, u8 byte, u8 mask, u8 value)
406532 {
407533 struct hidpp_report response;
408534 int ret;
409535 u8 params[3] = { 0 };
410536
411537 ret = hidpp_send_rap_command_sync(hidpp_dev,
412
- REPORT_ID_HIDPP_SHORT,
413
- HIDPP_GET_REGISTER,
414
- HIDPP_REG_GENERAL,
415
- NULL, 0, &response);
538
+ REPORT_ID_HIDPP_SHORT,
539
+ HIDPP_GET_REGISTER,
540
+ register_address,
541
+ NULL, 0, &response);
416542 if (ret)
417543 return ret;
418544
419545 memcpy(params, response.rap.params, 3);
420546
421
- /* Set the battery bit */
422
- params[0] |= BIT(4);
547
+ params[byte] &= ~mask;
548
+ params[byte] |= value & mask;
423549
424550 return hidpp_send_rap_command_sync(hidpp_dev,
425
- REPORT_ID_HIDPP_SHORT,
426
- HIDPP_SET_REGISTER,
427
- HIDPP_REG_GENERAL,
428
- params, 3, &response);
551
+ REPORT_ID_HIDPP_SHORT,
552
+ HIDPP_SET_REGISTER,
553
+ register_address,
554
+ params, 3, &response);
555
+}
556
+
557
+#define HIDPP_REG_ENABLE_REPORTS 0x00
558
+#define HIDPP_ENABLE_CONSUMER_REPORT BIT(0)
559
+#define HIDPP_ENABLE_WHEEL_REPORT BIT(2)
560
+#define HIDPP_ENABLE_MOUSE_EXTRA_BTN_REPORT BIT(3)
561
+#define HIDPP_ENABLE_BAT_REPORT BIT(4)
562
+#define HIDPP_ENABLE_HWHEEL_REPORT BIT(5)
563
+
564
+static int hidpp10_enable_battery_reporting(struct hidpp_device *hidpp_dev)
565
+{
566
+ return hidpp10_set_register(hidpp_dev, HIDPP_REG_ENABLE_REPORTS, 0,
567
+ HIDPP_ENABLE_BAT_REPORT, HIDPP_ENABLE_BAT_REPORT);
568
+}
569
+
570
+#define HIDPP_REG_FEATURES 0x01
571
+#define HIDPP_ENABLE_SPECIAL_BUTTON_FUNC BIT(1)
572
+#define HIDPP_ENABLE_FAST_SCROLL BIT(6)
573
+
574
+/* On HID++ 1.0 devices, high-res scroll was called "scrolling acceleration". */
575
+static int hidpp10_enable_scrolling_acceleration(struct hidpp_device *hidpp_dev)
576
+{
577
+ return hidpp10_set_register(hidpp_dev, HIDPP_REG_FEATURES, 0,
578
+ HIDPP_ENABLE_FAST_SCROLL, HIDPP_ENABLE_FAST_SCROLL);
429579 }
430580
431581 #define HIDPP_REG_BATTERY_STATUS 0x07
....@@ -630,6 +780,9 @@
630780 if (2 + len > sizeof(response.rap.params))
631781 return NULL;
632782
783
+ if (len < 4) /* logitech devices are usually at least Xddd */
784
+ return NULL;
785
+
633786 name = kzalloc(len + 1, GFP_KERNEL);
634787 if (!name)
635788 return NULL;
....@@ -675,8 +828,7 @@
675828 if (ret)
676829 return ret;
677830
678
- snprintf(hdev->uniq, sizeof(hdev->uniq), "%04x-%4phD",
679
- hdev->product, &serial);
831
+ snprintf(hdev->uniq, sizeof(hdev->uniq), "%4phD", &serial);
680832 dbg_hid("HID++ Unifying: Got serial: %s\n", hdev->uniq);
681833
682834 name = hidpp_unifying_get_name(hidpp);
....@@ -739,7 +891,7 @@
739891 if (ret == HIDPP_ERROR_INVALID_SUBID) {
740892 hidpp->protocol_major = 1;
741893 hidpp->protocol_minor = 0;
742
- return 0;
894
+ goto print_version;
743895 }
744896
745897 /* the device might not be connected */
....@@ -763,18 +915,58 @@
763915 hidpp->protocol_major = response.rap.params[0];
764916 hidpp->protocol_minor = response.rap.params[1];
765917
766
- return ret;
918
+print_version:
919
+ hid_info(hidpp->hid_dev, "HID++ %u.%u device connected.\n",
920
+ hidpp->protocol_major, hidpp->protocol_minor);
921
+ return 0;
767922 }
768923
769
-static bool hidpp_is_connected(struct hidpp_device *hidpp)
924
+/* -------------------------------------------------------------------------- */
925
+/* 0x0003: Device Information */
926
+/* -------------------------------------------------------------------------- */
927
+
928
+#define HIDPP_PAGE_DEVICE_INFORMATION 0x0003
929
+
930
+#define CMD_GET_DEVICE_INFO 0x00
931
+
932
+static int hidpp_get_serial(struct hidpp_device *hidpp, u32 *serial)
770933 {
934
+ struct hidpp_report response;
935
+ u8 feature_type;
936
+ u8 feature_index;
771937 int ret;
772938
773
- ret = hidpp_root_get_protocol_version(hidpp);
774
- if (!ret)
775
- hid_dbg(hidpp->hid_dev, "HID++ %u.%u device connected.\n",
776
- hidpp->protocol_major, hidpp->protocol_minor);
777
- return ret == 0;
939
+ ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_DEVICE_INFORMATION,
940
+ &feature_index,
941
+ &feature_type);
942
+ if (ret)
943
+ return ret;
944
+
945
+ ret = hidpp_send_fap_command_sync(hidpp, feature_index,
946
+ CMD_GET_DEVICE_INFO,
947
+ NULL, 0, &response);
948
+ if (ret)
949
+ return ret;
950
+
951
+ /* See hidpp_unifying_get_serial() */
952
+ *serial = *((u32 *)&response.rap.params[1]);
953
+ return 0;
954
+}
955
+
956
+static int hidpp_serial_init(struct hidpp_device *hidpp)
957
+{
958
+ struct hid_device *hdev = hidpp->hid_dev;
959
+ u32 serial;
960
+ int ret;
961
+
962
+ ret = hidpp_get_serial(hidpp, &serial);
963
+ if (ret)
964
+ return ret;
965
+
966
+ snprintf(hdev->uniq, sizeof(hdev->uniq), "%4phD", &serial);
967
+ dbg_hid("HID++ DeviceInformation: Got serial: %s\n", hdev->uniq);
968
+
969
+ return 0;
778970 }
779971
780972 /* -------------------------------------------------------------------------- */
....@@ -830,7 +1022,7 @@
8301022
8311023 switch (response.report_id) {
8321024 case REPORT_ID_HIDPP_VERY_LONG:
833
- count = HIDPP_REPORT_VERY_LONG_LENGTH - 4;
1025
+ count = hidpp->very_long_report_length - 4;
8341026 break;
8351027 case REPORT_ID_HIDPP_LONG:
8361028 count = HIDPP_REPORT_LONG_LENGTH - 4;
....@@ -1098,6 +1290,144 @@
10981290 return 0;
10991291 }
11001292
1293
+/* -------------------------------------------------------------------------- */
1294
+/* 0x1001: Battery voltage */
1295
+/* -------------------------------------------------------------------------- */
1296
+
1297
+#define HIDPP_PAGE_BATTERY_VOLTAGE 0x1001
1298
+
1299
+#define CMD_BATTERY_VOLTAGE_GET_BATTERY_VOLTAGE 0x00
1300
+
1301
+#define EVENT_BATTERY_VOLTAGE_STATUS_BROADCAST 0x00
1302
+
1303
+static int hidpp20_battery_map_status_voltage(u8 data[3], int *voltage,
1304
+ int *level, int *charge_type)
1305
+{
1306
+ int status;
1307
+
1308
+ long flags = (long) data[2];
1309
+ *level = POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN;
1310
+
1311
+ if (flags & 0x80)
1312
+ switch (flags & 0x07) {
1313
+ case 0:
1314
+ status = POWER_SUPPLY_STATUS_CHARGING;
1315
+ break;
1316
+ case 1:
1317
+ status = POWER_SUPPLY_STATUS_FULL;
1318
+ *level = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
1319
+ break;
1320
+ case 2:
1321
+ status = POWER_SUPPLY_STATUS_NOT_CHARGING;
1322
+ break;
1323
+ default:
1324
+ status = POWER_SUPPLY_STATUS_UNKNOWN;
1325
+ break;
1326
+ }
1327
+ else
1328
+ status = POWER_SUPPLY_STATUS_DISCHARGING;
1329
+
1330
+ *charge_type = POWER_SUPPLY_CHARGE_TYPE_STANDARD;
1331
+ if (test_bit(3, &flags)) {
1332
+ *charge_type = POWER_SUPPLY_CHARGE_TYPE_FAST;
1333
+ }
1334
+ if (test_bit(4, &flags)) {
1335
+ *charge_type = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
1336
+ }
1337
+ if (test_bit(5, &flags)) {
1338
+ *level = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
1339
+ }
1340
+
1341
+ *voltage = get_unaligned_be16(data);
1342
+
1343
+ return status;
1344
+}
1345
+
1346
+static int hidpp20_battery_get_battery_voltage(struct hidpp_device *hidpp,
1347
+ u8 feature_index,
1348
+ int *status, int *voltage,
1349
+ int *level, int *charge_type)
1350
+{
1351
+ struct hidpp_report response;
1352
+ int ret;
1353
+ u8 *params = (u8 *)response.fap.params;
1354
+
1355
+ ret = hidpp_send_fap_command_sync(hidpp, feature_index,
1356
+ CMD_BATTERY_VOLTAGE_GET_BATTERY_VOLTAGE,
1357
+ NULL, 0, &response);
1358
+
1359
+ if (ret > 0) {
1360
+ hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n",
1361
+ __func__, ret);
1362
+ return -EPROTO;
1363
+ }
1364
+ if (ret)
1365
+ return ret;
1366
+
1367
+ hidpp->capabilities |= HIDPP_CAPABILITY_BATTERY_VOLTAGE;
1368
+
1369
+ *status = hidpp20_battery_map_status_voltage(params, voltage,
1370
+ level, charge_type);
1371
+
1372
+ return 0;
1373
+}
1374
+
1375
+static int hidpp20_query_battery_voltage_info(struct hidpp_device *hidpp)
1376
+{
1377
+ u8 feature_type;
1378
+ int ret;
1379
+ int status, voltage, level, charge_type;
1380
+
1381
+ if (hidpp->battery.voltage_feature_index == 0xff) {
1382
+ ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_BATTERY_VOLTAGE,
1383
+ &hidpp->battery.voltage_feature_index,
1384
+ &feature_type);
1385
+ if (ret)
1386
+ return ret;
1387
+ }
1388
+
1389
+ ret = hidpp20_battery_get_battery_voltage(hidpp,
1390
+ hidpp->battery.voltage_feature_index,
1391
+ &status, &voltage, &level, &charge_type);
1392
+
1393
+ if (ret)
1394
+ return ret;
1395
+
1396
+ hidpp->battery.status = status;
1397
+ hidpp->battery.voltage = voltage;
1398
+ hidpp->battery.level = level;
1399
+ hidpp->battery.charge_type = charge_type;
1400
+ hidpp->battery.online = status != POWER_SUPPLY_STATUS_NOT_CHARGING;
1401
+
1402
+ return 0;
1403
+}
1404
+
1405
+static int hidpp20_battery_voltage_event(struct hidpp_device *hidpp,
1406
+ u8 *data, int size)
1407
+{
1408
+ struct hidpp_report *report = (struct hidpp_report *)data;
1409
+ int status, voltage, level, charge_type;
1410
+
1411
+ if (report->fap.feature_index != hidpp->battery.voltage_feature_index ||
1412
+ report->fap.funcindex_clientid != EVENT_BATTERY_VOLTAGE_STATUS_BROADCAST)
1413
+ return 0;
1414
+
1415
+ status = hidpp20_battery_map_status_voltage(report->fap.params, &voltage,
1416
+ &level, &charge_type);
1417
+
1418
+ hidpp->battery.online = status != POWER_SUPPLY_STATUS_NOT_CHARGING;
1419
+
1420
+ if (voltage != hidpp->battery.voltage || status != hidpp->battery.status) {
1421
+ hidpp->battery.voltage = voltage;
1422
+ hidpp->battery.status = status;
1423
+ hidpp->battery.level = level;
1424
+ hidpp->battery.charge_type = charge_type;
1425
+ if (hidpp->battery.ps)
1426
+ power_supply_changed(hidpp->battery.ps);
1427
+ }
1428
+ return 0;
1429
+}
1430
+
11011431 static enum power_supply_property hidpp_battery_props[] = {
11021432 POWER_SUPPLY_PROP_ONLINE,
11031433 POWER_SUPPLY_PROP_STATUS,
....@@ -1107,6 +1437,7 @@
11071437 POWER_SUPPLY_PROP_SERIAL_NUMBER,
11081438 0, /* placeholder for POWER_SUPPLY_PROP_CAPACITY, */
11091439 0, /* placeholder for POWER_SUPPLY_PROP_CAPACITY_LEVEL, */
1440
+ 0, /* placeholder for POWER_SUPPLY_PROP_VOLTAGE_NOW, */
11101441 };
11111442
11121443 static int hidpp_battery_get_property(struct power_supply *psy,
....@@ -1144,12 +1475,130 @@
11441475 case POWER_SUPPLY_PROP_SERIAL_NUMBER:
11451476 val->strval = hidpp->hid_dev->uniq;
11461477 break;
1478
+ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
1479
+ /* hardware reports voltage in in mV. sysfs expects uV */
1480
+ val->intval = hidpp->battery.voltage * 1000;
1481
+ break;
1482
+ case POWER_SUPPLY_PROP_CHARGE_TYPE:
1483
+ val->intval = hidpp->battery.charge_type;
1484
+ break;
11471485 default:
11481486 ret = -EINVAL;
11491487 break;
11501488 }
11511489
11521490 return ret;
1491
+}
1492
+
1493
+/* -------------------------------------------------------------------------- */
1494
+/* 0x1d4b: Wireless device status */
1495
+/* -------------------------------------------------------------------------- */
1496
+#define HIDPP_PAGE_WIRELESS_DEVICE_STATUS 0x1d4b
1497
+
1498
+static int hidpp_set_wireless_feature_index(struct hidpp_device *hidpp)
1499
+{
1500
+ u8 feature_type;
1501
+ int ret;
1502
+
1503
+ ret = hidpp_root_get_feature(hidpp,
1504
+ HIDPP_PAGE_WIRELESS_DEVICE_STATUS,
1505
+ &hidpp->wireless_feature_index,
1506
+ &feature_type);
1507
+
1508
+ return ret;
1509
+}
1510
+
1511
+/* -------------------------------------------------------------------------- */
1512
+/* 0x2120: Hi-resolution scrolling */
1513
+/* -------------------------------------------------------------------------- */
1514
+
1515
+#define HIDPP_PAGE_HI_RESOLUTION_SCROLLING 0x2120
1516
+
1517
+#define CMD_HI_RESOLUTION_SCROLLING_SET_HIGHRES_SCROLLING_MODE 0x10
1518
+
1519
+static int hidpp_hrs_set_highres_scrolling_mode(struct hidpp_device *hidpp,
1520
+ bool enabled, u8 *multiplier)
1521
+{
1522
+ u8 feature_index;
1523
+ u8 feature_type;
1524
+ int ret;
1525
+ u8 params[1];
1526
+ struct hidpp_report response;
1527
+
1528
+ ret = hidpp_root_get_feature(hidpp,
1529
+ HIDPP_PAGE_HI_RESOLUTION_SCROLLING,
1530
+ &feature_index,
1531
+ &feature_type);
1532
+ if (ret)
1533
+ return ret;
1534
+
1535
+ params[0] = enabled ? BIT(0) : 0;
1536
+ ret = hidpp_send_fap_command_sync(hidpp, feature_index,
1537
+ CMD_HI_RESOLUTION_SCROLLING_SET_HIGHRES_SCROLLING_MODE,
1538
+ params, sizeof(params), &response);
1539
+ if (ret)
1540
+ return ret;
1541
+ *multiplier = response.fap.params[1];
1542
+ return 0;
1543
+}
1544
+
1545
+/* -------------------------------------------------------------------------- */
1546
+/* 0x2121: HiRes Wheel */
1547
+/* -------------------------------------------------------------------------- */
1548
+
1549
+#define HIDPP_PAGE_HIRES_WHEEL 0x2121
1550
+
1551
+#define CMD_HIRES_WHEEL_GET_WHEEL_CAPABILITY 0x00
1552
+#define CMD_HIRES_WHEEL_SET_WHEEL_MODE 0x20
1553
+
1554
+static int hidpp_hrw_get_wheel_capability(struct hidpp_device *hidpp,
1555
+ u8 *multiplier)
1556
+{
1557
+ u8 feature_index;
1558
+ u8 feature_type;
1559
+ int ret;
1560
+ struct hidpp_report response;
1561
+
1562
+ ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_HIRES_WHEEL,
1563
+ &feature_index, &feature_type);
1564
+ if (ret)
1565
+ goto return_default;
1566
+
1567
+ ret = hidpp_send_fap_command_sync(hidpp, feature_index,
1568
+ CMD_HIRES_WHEEL_GET_WHEEL_CAPABILITY,
1569
+ NULL, 0, &response);
1570
+ if (ret)
1571
+ goto return_default;
1572
+
1573
+ *multiplier = response.fap.params[0];
1574
+ return 0;
1575
+return_default:
1576
+ hid_warn(hidpp->hid_dev,
1577
+ "Couldn't get wheel multiplier (error %d)\n", ret);
1578
+ return ret;
1579
+}
1580
+
1581
+static int hidpp_hrw_set_wheel_mode(struct hidpp_device *hidpp, bool invert,
1582
+ bool high_resolution, bool use_hidpp)
1583
+{
1584
+ u8 feature_index;
1585
+ u8 feature_type;
1586
+ int ret;
1587
+ u8 params[1];
1588
+ struct hidpp_report response;
1589
+
1590
+ ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_HIRES_WHEEL,
1591
+ &feature_index, &feature_type);
1592
+ if (ret)
1593
+ return ret;
1594
+
1595
+ params[0] = (invert ? BIT(2) : 0) |
1596
+ (high_resolution ? BIT(1) : 0) |
1597
+ (use_hidpp ? BIT(0) : 0);
1598
+
1599
+ return hidpp_send_fap_command_sync(hidpp, feature_index,
1600
+ CMD_HIRES_WHEEL_SET_WHEEL_MODE,
1601
+ params, sizeof(params), &response);
11531602 }
11541603
11551604 /* -------------------------------------------------------------------------- */
....@@ -1455,6 +1904,7 @@
14551904
14561905 #define HIDPP_FF_EFFECTID_NONE -1
14571906 #define HIDPP_FF_EFFECTID_AUTOCENTER -2
1907
+#define HIDPP_AUTOCENTER_PARAMS_LENGTH 18
14581908
14591909 #define HIDPP_FF_MAX_PARAMS 20
14601910 #define HIDPP_FF_RESERVED_SLOTS 1
....@@ -1481,7 +1931,7 @@
14811931 u8 size;
14821932 };
14831933
1484
-static const signed short hiddpp_ff_effects[] = {
1934
+static const signed short hidpp_ff_effects[] = {
14851935 FF_CONSTANT,
14861936 FF_PERIODIC,
14871937 FF_SINE,
....@@ -1496,7 +1946,7 @@
14961946 -1
14971947 };
14981948
1499
-static const signed short hiddpp_ff_effects_v2[] = {
1949
+static const signed short hidpp_ff_effects_v2[] = {
15001950 FF_RAMP,
15011951 FF_FRICTION,
15021952 FF_INERTIA,
....@@ -1795,7 +2245,7 @@
17952245 static void hidpp_ff_set_autocenter(struct input_dev *dev, u16 magnitude)
17962246 {
17972247 struct hidpp_ff_private_data *data = dev->ff->private;
1798
- u8 params[18];
2248
+ u8 params[HIDPP_AUTOCENTER_PARAMS_LENGTH];
17992249
18002250 dbg_hid("Setting autocenter to %d.\n", magnitude);
18012251
....@@ -1863,11 +2313,17 @@
18632313 static void hidpp_ff_destroy(struct ff_device *ff)
18642314 {
18652315 struct hidpp_ff_private_data *data = ff->private;
2316
+ struct hid_device *hid = data->hidpp->hid_dev;
18662317
2318
+ hid_info(hid, "Unloading HID++ force feedback.\n");
2319
+
2320
+ device_remove_file(&hid->dev, &dev_attr_range);
2321
+ destroy_workqueue(data->wq);
18672322 kfree(data->effect_ids);
18682323 }
18692324
1870
-static int hidpp_ff_init(struct hidpp_device *hidpp, u8 feature_index)
2325
+static int hidpp_ff_init(struct hidpp_device *hidpp,
2326
+ struct hidpp_ff_private_data *data)
18712327 {
18722328 struct hid_device *hid = hidpp->hid_dev;
18732329 struct hid_input *hidinput;
....@@ -1875,9 +2331,7 @@
18752331 const struct usb_device_descriptor *udesc = &(hid_to_usb_dev(hid)->descriptor);
18762332 const u16 bcdDevice = le16_to_cpu(udesc->bcdDevice);
18772333 struct ff_device *ff;
1878
- struct hidpp_report response;
1879
- struct hidpp_ff_private_data *data;
1880
- int error, j, num_slots;
2334
+ int error, j, num_slots = data->num_effects;
18812335 u8 version;
18822336
18832337 if (list_empty(&hid->inputs)) {
....@@ -1896,24 +2350,11 @@
18962350 version = bcdDevice & 255;
18972351
18982352 /* Set supported force feedback capabilities */
1899
- for (j = 0; hiddpp_ff_effects[j] >= 0; j++)
1900
- set_bit(hiddpp_ff_effects[j], dev->ffbit);
2353
+ for (j = 0; hidpp_ff_effects[j] >= 0; j++)
2354
+ set_bit(hidpp_ff_effects[j], dev->ffbit);
19012355 if (version > 1)
1902
- for (j = 0; hiddpp_ff_effects_v2[j] >= 0; j++)
1903
- set_bit(hiddpp_ff_effects_v2[j], dev->ffbit);
1904
-
1905
- /* Read number of slots available in device */
1906
- error = hidpp_send_fap_command_sync(hidpp, feature_index,
1907
- HIDPP_FF_GET_INFO, NULL, 0, &response);
1908
- if (error) {
1909
- if (error < 0)
1910
- return error;
1911
- hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n",
1912
- __func__, error);
1913
- return -EPROTO;
1914
- }
1915
-
1916
- num_slots = response.fap.params[0] - HIDPP_FF_RESERVED_SLOTS;
2356
+ for (j = 0; hidpp_ff_effects_v2[j] >= 0; j++)
2357
+ set_bit(hidpp_ff_effects_v2[j], dev->ffbit);
19172358
19182359 error = input_ff_create(dev, num_slots);
19192360
....@@ -1921,8 +2362,11 @@
19212362 hid_err(dev, "Failed to create FF device!\n");
19222363 return error;
19232364 }
1924
-
1925
- data = kzalloc(sizeof(*data), GFP_KERNEL);
2365
+ /*
2366
+ * Create a copy of passed data, so we can transfer memory
2367
+ * ownership to FF core
2368
+ */
2369
+ data = kmemdup(data, sizeof(*data), GFP_KERNEL);
19262370 if (!data)
19272371 return -ENOMEM;
19282372 data->effect_ids = kcalloc(num_slots, sizeof(int), GFP_KERNEL);
....@@ -1938,10 +2382,7 @@
19382382 }
19392383
19402384 data->hidpp = hidpp;
1941
- data->feature_index = feature_index;
19422385 data->version = version;
1943
- data->slot_autocenter = 0;
1944
- data->num_effects = num_slots;
19452386 for (j = 0; j < num_slots; j++)
19462387 data->effect_ids[j] = -1;
19472388
....@@ -1955,67 +2396,19 @@
19552396 ff->set_autocenter = hidpp_ff_set_autocenter;
19562397 ff->destroy = hidpp_ff_destroy;
19572398
1958
-
1959
- /* reset all forces */
1960
- error = hidpp_send_fap_command_sync(hidpp, feature_index,
1961
- HIDPP_FF_RESET_ALL, NULL, 0, &response);
1962
-
1963
- /* Read current Range */
1964
- error = hidpp_send_fap_command_sync(hidpp, feature_index,
1965
- HIDPP_FF_GET_APERTURE, NULL, 0, &response);
1966
- if (error)
1967
- hid_warn(hidpp->hid_dev, "Failed to read range from device!\n");
1968
- data->range = error ? 900 : get_unaligned_be16(&response.fap.params[0]);
1969
-
19702399 /* Create sysfs interface */
19712400 error = device_create_file(&(hidpp->hid_dev->dev), &dev_attr_range);
19722401 if (error)
19732402 hid_warn(hidpp->hid_dev, "Unable to create sysfs interface for \"range\", errno %d!\n", error);
19742403
1975
- /* Read the current gain values */
1976
- error = hidpp_send_fap_command_sync(hidpp, feature_index,
1977
- HIDPP_FF_GET_GLOBAL_GAINS, NULL, 0, &response);
1978
- if (error)
1979
- hid_warn(hidpp->hid_dev, "Failed to read gain values from device!\n");
1980
- data->gain = error ? 0xffff : get_unaligned_be16(&response.fap.params[0]);
1981
- /* ignore boost value at response.fap.params[2] */
1982
-
19832404 /* init the hardware command queue */
19842405 atomic_set(&data->workqueue_size, 0);
1985
-
1986
- /* initialize with zero autocenter to get wheel in usable state */
1987
- hidpp_ff_set_autocenter(dev, 0);
19882406
19892407 hid_info(hid, "Force feedback support loaded (firmware release %d).\n",
19902408 version);
19912409
19922410 return 0;
19932411 }
1994
-
1995
-static int hidpp_ff_deinit(struct hid_device *hid)
1996
-{
1997
- struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
1998
- struct input_dev *dev = hidinput->input;
1999
- struct hidpp_ff_private_data *data;
2000
-
2001
- if (!dev) {
2002
- hid_err(hid, "Struct input_dev not found!\n");
2003
- return -EINVAL;
2004
- }
2005
-
2006
- hid_info(hid, "Unloading HID++ force feedback.\n");
2007
- data = dev->ff->private;
2008
- if (!data) {
2009
- hid_err(hid, "Private data not found!\n");
2010
- return -EINVAL;
2011
- }
2012
-
2013
- destroy_workqueue(data->wq);
2014
- device_remove_file(&hid->dev, &dev_attr_range);
2015
-
2016
- return 0;
2017
-}
2018
-
20192412
20202413 /* ************************************************************************** */
20212414 /* */
....@@ -2030,7 +2423,6 @@
20302423 #define WTP_MANUAL_RESOLUTION 39
20312424
20322425 struct wtp_data {
2033
- struct input_dev *input;
20342426 u16 x_size, y_size;
20352427 u8 finger_count;
20362428 u8 mt_feature_index;
....@@ -2048,7 +2440,7 @@
20482440 }
20492441
20502442 static void wtp_populate_input(struct hidpp_device *hidpp,
2051
- struct input_dev *input_dev, bool origin_is_hid_core)
2443
+ struct input_dev *input_dev)
20522444 {
20532445 struct wtp_data *wd = hidpp->private_data;
20542446
....@@ -2074,31 +2466,30 @@
20742466
20752467 input_mt_init_slots(input_dev, wd->maxcontacts, INPUT_MT_POINTER |
20762468 INPUT_MT_DROP_UNUSED);
2077
-
2078
- wd->input = input_dev;
20792469 }
20802470
2081
-static void wtp_touch_event(struct wtp_data *wd,
2471
+static void wtp_touch_event(struct hidpp_device *hidpp,
20822472 struct hidpp_touchpad_raw_xy_finger *touch_report)
20832473 {
2474
+ struct wtp_data *wd = hidpp->private_data;
20842475 int slot;
20852476
20862477 if (!touch_report->finger_id || touch_report->contact_type)
20872478 /* no actual data */
20882479 return;
20892480
2090
- slot = input_mt_get_slot_by_key(wd->input, touch_report->finger_id);
2481
+ slot = input_mt_get_slot_by_key(hidpp->input, touch_report->finger_id);
20912482
2092
- input_mt_slot(wd->input, slot);
2093
- input_mt_report_slot_state(wd->input, MT_TOOL_FINGER,
2483
+ input_mt_slot(hidpp->input, slot);
2484
+ input_mt_report_slot_state(hidpp->input, MT_TOOL_FINGER,
20942485 touch_report->contact_status);
20952486 if (touch_report->contact_status) {
2096
- input_event(wd->input, EV_ABS, ABS_MT_POSITION_X,
2487
+ input_event(hidpp->input, EV_ABS, ABS_MT_POSITION_X,
20972488 touch_report->x);
2098
- input_event(wd->input, EV_ABS, ABS_MT_POSITION_Y,
2489
+ input_event(hidpp->input, EV_ABS, ABS_MT_POSITION_Y,
20992490 wd->flip_y ? wd->y_size - touch_report->y :
21002491 touch_report->y);
2101
- input_event(wd->input, EV_ABS, ABS_MT_PRESSURE,
2492
+ input_event(hidpp->input, EV_ABS, ABS_MT_PRESSURE,
21022493 touch_report->area);
21032494 }
21042495 }
....@@ -2106,19 +2497,18 @@
21062497 static void wtp_send_raw_xy_event(struct hidpp_device *hidpp,
21072498 struct hidpp_touchpad_raw_xy *raw)
21082499 {
2109
- struct wtp_data *wd = hidpp->private_data;
21102500 int i;
21112501
21122502 for (i = 0; i < 2; i++)
2113
- wtp_touch_event(wd, &(raw->fingers[i]));
2503
+ wtp_touch_event(hidpp, &(raw->fingers[i]));
21142504
21152505 if (raw->end_of_frame &&
21162506 !(hidpp->quirks & HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS))
2117
- input_event(wd->input, EV_KEY, BTN_LEFT, raw->button);
2507
+ input_event(hidpp->input, EV_KEY, BTN_LEFT, raw->button);
21182508
21192509 if (raw->end_of_frame || raw->finger_count <= 2) {
2120
- input_mt_sync_frame(wd->input);
2121
- input_sync(wd->input);
2510
+ input_mt_sync_frame(hidpp->input);
2511
+ input_sync(hidpp->input);
21222512 }
21232513 }
21242514
....@@ -2168,7 +2558,7 @@
21682558 struct hidpp_report *report = (struct hidpp_report *)data;
21692559 struct hidpp_touchpad_raw_xy raw;
21702560
2171
- if (!wd || !wd->input)
2561
+ if (!wd || !hidpp->input)
21722562 return 1;
21732563
21742564 switch (data[0]) {
....@@ -2179,11 +2569,11 @@
21792569 return 1;
21802570 }
21812571 if (hidpp->quirks & HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS) {
2182
- input_event(wd->input, EV_KEY, BTN_LEFT,
2572
+ input_event(hidpp->input, EV_KEY, BTN_LEFT,
21832573 !!(data[1] & 0x01));
2184
- input_event(wd->input, EV_KEY, BTN_RIGHT,
2574
+ input_event(hidpp->input, EV_KEY, BTN_RIGHT,
21852575 !!(data[1] & 0x02));
2186
- input_sync(wd->input);
2576
+ input_sync(hidpp->input);
21872577 return 0;
21882578 } else {
21892579 if (size < 21)
....@@ -2301,10 +2691,6 @@
23012691
23022692 static const u8 m560_config_parameter[] = {0x00, 0xaf, 0x03};
23032693
2304
-struct m560_private_data {
2305
- struct input_dev *input;
2306
-};
2307
-
23082694 /* how buttons are mapped in the report */
23092695 #define M560_MOUSE_BTN_LEFT 0x01
23102696 #define M560_MOUSE_BTN_RIGHT 0x02
....@@ -2332,28 +2718,12 @@
23322718 );
23332719 }
23342720
2335
-static int m560_allocate(struct hid_device *hdev)
2336
-{
2337
- struct hidpp_device *hidpp = hid_get_drvdata(hdev);
2338
- struct m560_private_data *d;
2339
-
2340
- d = devm_kzalloc(&hdev->dev, sizeof(struct m560_private_data),
2341
- GFP_KERNEL);
2342
- if (!d)
2343
- return -ENOMEM;
2344
-
2345
- hidpp->private_data = d;
2346
-
2347
- return 0;
2348
-};
2349
-
23502721 static int m560_raw_event(struct hid_device *hdev, u8 *data, int size)
23512722 {
23522723 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
2353
- struct m560_private_data *mydata = hidpp->private_data;
23542724
23552725 /* sanity check */
2356
- if (!mydata || !mydata->input) {
2726
+ if (!hidpp->input) {
23572727 hid_err(hdev, "error in parameter\n");
23582728 return -EINVAL;
23592729 }
....@@ -2380,24 +2750,24 @@
23802750
23812751 switch (data[5]) {
23822752 case 0xaf:
2383
- input_report_key(mydata->input, BTN_MIDDLE, 1);
2753
+ input_report_key(hidpp->input, BTN_MIDDLE, 1);
23842754 break;
23852755 case 0xb0:
2386
- input_report_key(mydata->input, BTN_FORWARD, 1);
2756
+ input_report_key(hidpp->input, BTN_FORWARD, 1);
23872757 break;
23882758 case 0xae:
2389
- input_report_key(mydata->input, BTN_BACK, 1);
2759
+ input_report_key(hidpp->input, BTN_BACK, 1);
23902760 break;
23912761 case 0x00:
2392
- input_report_key(mydata->input, BTN_BACK, 0);
2393
- input_report_key(mydata->input, BTN_FORWARD, 0);
2394
- input_report_key(mydata->input, BTN_MIDDLE, 0);
2762
+ input_report_key(hidpp->input, BTN_BACK, 0);
2763
+ input_report_key(hidpp->input, BTN_FORWARD, 0);
2764
+ input_report_key(hidpp->input, BTN_MIDDLE, 0);
23952765 break;
23962766 default:
23972767 hid_err(hdev, "error in report\n");
23982768 return 0;
23992769 }
2400
- input_sync(mydata->input);
2770
+ input_sync(hidpp->input);
24012771
24022772 } else if (data[0] == 0x02) {
24032773 /*
....@@ -2411,50 +2781,55 @@
24112781
24122782 int v;
24132783
2414
- input_report_key(mydata->input, BTN_LEFT,
2784
+ input_report_key(hidpp->input, BTN_LEFT,
24152785 !!(data[1] & M560_MOUSE_BTN_LEFT));
2416
- input_report_key(mydata->input, BTN_RIGHT,
2786
+ input_report_key(hidpp->input, BTN_RIGHT,
24172787 !!(data[1] & M560_MOUSE_BTN_RIGHT));
24182788
2419
- if (data[1] & M560_MOUSE_BTN_WHEEL_LEFT)
2420
- input_report_rel(mydata->input, REL_HWHEEL, -1);
2421
- else if (data[1] & M560_MOUSE_BTN_WHEEL_RIGHT)
2422
- input_report_rel(mydata->input, REL_HWHEEL, 1);
2789
+ if (data[1] & M560_MOUSE_BTN_WHEEL_LEFT) {
2790
+ input_report_rel(hidpp->input, REL_HWHEEL, -1);
2791
+ input_report_rel(hidpp->input, REL_HWHEEL_HI_RES,
2792
+ -120);
2793
+ } else if (data[1] & M560_MOUSE_BTN_WHEEL_RIGHT) {
2794
+ input_report_rel(hidpp->input, REL_HWHEEL, 1);
2795
+ input_report_rel(hidpp->input, REL_HWHEEL_HI_RES,
2796
+ 120);
2797
+ }
24232798
24242799 v = hid_snto32(hid_field_extract(hdev, data+3, 0, 12), 12);
2425
- input_report_rel(mydata->input, REL_X, v);
2800
+ input_report_rel(hidpp->input, REL_X, v);
24262801
24272802 v = hid_snto32(hid_field_extract(hdev, data+3, 12, 12), 12);
2428
- input_report_rel(mydata->input, REL_Y, v);
2803
+ input_report_rel(hidpp->input, REL_Y, v);
24292804
24302805 v = hid_snto32(data[6], 8);
2431
- input_report_rel(mydata->input, REL_WHEEL, v);
2806
+ if (v != 0)
2807
+ hidpp_scroll_counter_handle_scroll(hidpp->input,
2808
+ &hidpp->vertical_wheel_counter, v);
24322809
2433
- input_sync(mydata->input);
2810
+ input_sync(hidpp->input);
24342811 }
24352812
24362813 return 1;
24372814 }
24382815
24392816 static void m560_populate_input(struct hidpp_device *hidpp,
2440
- struct input_dev *input_dev, bool origin_is_hid_core)
2817
+ struct input_dev *input_dev)
24412818 {
2442
- struct m560_private_data *mydata = hidpp->private_data;
2819
+ __set_bit(EV_KEY, input_dev->evbit);
2820
+ __set_bit(BTN_MIDDLE, input_dev->keybit);
2821
+ __set_bit(BTN_RIGHT, input_dev->keybit);
2822
+ __set_bit(BTN_LEFT, input_dev->keybit);
2823
+ __set_bit(BTN_BACK, input_dev->keybit);
2824
+ __set_bit(BTN_FORWARD, input_dev->keybit);
24432825
2444
- mydata->input = input_dev;
2445
-
2446
- __set_bit(EV_KEY, mydata->input->evbit);
2447
- __set_bit(BTN_MIDDLE, mydata->input->keybit);
2448
- __set_bit(BTN_RIGHT, mydata->input->keybit);
2449
- __set_bit(BTN_LEFT, mydata->input->keybit);
2450
- __set_bit(BTN_BACK, mydata->input->keybit);
2451
- __set_bit(BTN_FORWARD, mydata->input->keybit);
2452
-
2453
- __set_bit(EV_REL, mydata->input->evbit);
2454
- __set_bit(REL_X, mydata->input->relbit);
2455
- __set_bit(REL_Y, mydata->input->relbit);
2456
- __set_bit(REL_WHEEL, mydata->input->relbit);
2457
- __set_bit(REL_HWHEEL, mydata->input->relbit);
2826
+ __set_bit(EV_REL, input_dev->evbit);
2827
+ __set_bit(REL_X, input_dev->relbit);
2828
+ __set_bit(REL_Y, input_dev->relbit);
2829
+ __set_bit(REL_WHEEL, input_dev->relbit);
2830
+ __set_bit(REL_HWHEEL, input_dev->relbit);
2831
+ __set_bit(REL_WHEEL_HI_RES, input_dev->relbit);
2832
+ __set_bit(REL_HWHEEL_HI_RES, input_dev->relbit);
24582833 }
24592834
24602835 static int m560_input_mapping(struct hid_device *hdev, struct hid_input *hi,
....@@ -2536,23 +2911,312 @@
25362911
25372912 #define HIDPP_PAGE_G920_FORCE_FEEDBACK 0x8123
25382913
2539
-static int g920_get_config(struct hidpp_device *hidpp)
2914
+static int g920_ff_set_autocenter(struct hidpp_device *hidpp,
2915
+ struct hidpp_ff_private_data *data)
25402916 {
2541
- u8 feature_type;
2542
- u8 feature_index;
2917
+ struct hidpp_report response;
2918
+ u8 params[HIDPP_AUTOCENTER_PARAMS_LENGTH] = {
2919
+ [1] = HIDPP_FF_EFFECT_SPRING | HIDPP_FF_EFFECT_AUTOSTART,
2920
+ };
25432921 int ret;
2922
+
2923
+ /* initialize with zero autocenter to get wheel in usable state */
2924
+
2925
+ dbg_hid("Setting autocenter to 0.\n");
2926
+ ret = hidpp_send_fap_command_sync(hidpp, data->feature_index,
2927
+ HIDPP_FF_DOWNLOAD_EFFECT,
2928
+ params, ARRAY_SIZE(params),
2929
+ &response);
2930
+ if (ret)
2931
+ hid_warn(hidpp->hid_dev, "Failed to autocenter device!\n");
2932
+ else
2933
+ data->slot_autocenter = response.fap.params[0];
2934
+
2935
+ return ret;
2936
+}
2937
+
2938
+static int g920_get_config(struct hidpp_device *hidpp,
2939
+ struct hidpp_ff_private_data *data)
2940
+{
2941
+ struct hidpp_report response;
2942
+ u8 feature_type;
2943
+ int ret;
2944
+
2945
+ memset(data, 0, sizeof(*data));
25442946
25452947 /* Find feature and store for later use */
25462948 ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_G920_FORCE_FEEDBACK,
2547
- &feature_index, &feature_type);
2949
+ &data->feature_index, &feature_type);
25482950 if (ret)
25492951 return ret;
25502952
2551
- ret = hidpp_ff_init(hidpp, feature_index);
2552
- if (ret)
2553
- hid_warn(hidpp->hid_dev, "Unable to initialize force feedback support, errno %d\n",
2554
- ret);
2953
+ /* Read number of slots available in device */
2954
+ ret = hidpp_send_fap_command_sync(hidpp, data->feature_index,
2955
+ HIDPP_FF_GET_INFO,
2956
+ NULL, 0,
2957
+ &response);
2958
+ if (ret) {
2959
+ if (ret < 0)
2960
+ return ret;
2961
+ hid_err(hidpp->hid_dev,
2962
+ "%s: received protocol error 0x%02x\n", __func__, ret);
2963
+ return -EPROTO;
2964
+ }
25552965
2966
+ data->num_effects = response.fap.params[0] - HIDPP_FF_RESERVED_SLOTS;
2967
+
2968
+ /* reset all forces */
2969
+ ret = hidpp_send_fap_command_sync(hidpp, data->feature_index,
2970
+ HIDPP_FF_RESET_ALL,
2971
+ NULL, 0,
2972
+ &response);
2973
+ if (ret)
2974
+ hid_warn(hidpp->hid_dev, "Failed to reset all forces!\n");
2975
+
2976
+ ret = hidpp_send_fap_command_sync(hidpp, data->feature_index,
2977
+ HIDPP_FF_GET_APERTURE,
2978
+ NULL, 0,
2979
+ &response);
2980
+ if (ret) {
2981
+ hid_warn(hidpp->hid_dev,
2982
+ "Failed to read range from device!\n");
2983
+ }
2984
+ data->range = ret ?
2985
+ 900 : get_unaligned_be16(&response.fap.params[0]);
2986
+
2987
+ /* Read the current gain values */
2988
+ ret = hidpp_send_fap_command_sync(hidpp, data->feature_index,
2989
+ HIDPP_FF_GET_GLOBAL_GAINS,
2990
+ NULL, 0,
2991
+ &response);
2992
+ if (ret)
2993
+ hid_warn(hidpp->hid_dev,
2994
+ "Failed to read gain values from device!\n");
2995
+ data->gain = ret ?
2996
+ 0xffff : get_unaligned_be16(&response.fap.params[0]);
2997
+
2998
+ /* ignore boost value at response.fap.params[2] */
2999
+
3000
+ return g920_ff_set_autocenter(hidpp, data);
3001
+}
3002
+
3003
+/* -------------------------------------------------------------------------- */
3004
+/* Logitech Dinovo Mini keyboard with builtin touchpad */
3005
+/* -------------------------------------------------------------------------- */
3006
+#define DINOVO_MINI_PRODUCT_ID 0xb30c
3007
+
3008
+static int lg_dinovo_input_mapping(struct hid_device *hdev, struct hid_input *hi,
3009
+ struct hid_field *field, struct hid_usage *usage,
3010
+ unsigned long **bit, int *max)
3011
+{
3012
+ if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR)
3013
+ return 0;
3014
+
3015
+ switch (usage->hid & HID_USAGE) {
3016
+ case 0x00d: lg_map_key_clear(KEY_MEDIA); break;
3017
+ default:
3018
+ return 0;
3019
+ }
3020
+ return 1;
3021
+}
3022
+
3023
+/* -------------------------------------------------------------------------- */
3024
+/* HID++1.0 devices which use HID++ reports for their wheels */
3025
+/* -------------------------------------------------------------------------- */
3026
+static int hidpp10_wheel_connect(struct hidpp_device *hidpp)
3027
+{
3028
+ return hidpp10_set_register(hidpp, HIDPP_REG_ENABLE_REPORTS, 0,
3029
+ HIDPP_ENABLE_WHEEL_REPORT | HIDPP_ENABLE_HWHEEL_REPORT,
3030
+ HIDPP_ENABLE_WHEEL_REPORT | HIDPP_ENABLE_HWHEEL_REPORT);
3031
+}
3032
+
3033
+static int hidpp10_wheel_raw_event(struct hidpp_device *hidpp,
3034
+ u8 *data, int size)
3035
+{
3036
+ s8 value, hvalue;
3037
+
3038
+ if (!hidpp->input)
3039
+ return -EINVAL;
3040
+
3041
+ if (size < 7)
3042
+ return 0;
3043
+
3044
+ if (data[0] != REPORT_ID_HIDPP_SHORT || data[2] != HIDPP_SUB_ID_ROLLER)
3045
+ return 0;
3046
+
3047
+ value = data[3];
3048
+ hvalue = data[4];
3049
+
3050
+ input_report_rel(hidpp->input, REL_WHEEL, value);
3051
+ input_report_rel(hidpp->input, REL_WHEEL_HI_RES, value * 120);
3052
+ input_report_rel(hidpp->input, REL_HWHEEL, hvalue);
3053
+ input_report_rel(hidpp->input, REL_HWHEEL_HI_RES, hvalue * 120);
3054
+ input_sync(hidpp->input);
3055
+
3056
+ return 1;
3057
+}
3058
+
3059
+static void hidpp10_wheel_populate_input(struct hidpp_device *hidpp,
3060
+ struct input_dev *input_dev)
3061
+{
3062
+ __set_bit(EV_REL, input_dev->evbit);
3063
+ __set_bit(REL_WHEEL, input_dev->relbit);
3064
+ __set_bit(REL_WHEEL_HI_RES, input_dev->relbit);
3065
+ __set_bit(REL_HWHEEL, input_dev->relbit);
3066
+ __set_bit(REL_HWHEEL_HI_RES, input_dev->relbit);
3067
+}
3068
+
3069
+/* -------------------------------------------------------------------------- */
3070
+/* HID++1.0 mice which use HID++ reports for extra mouse buttons */
3071
+/* -------------------------------------------------------------------------- */
3072
+static int hidpp10_extra_mouse_buttons_connect(struct hidpp_device *hidpp)
3073
+{
3074
+ return hidpp10_set_register(hidpp, HIDPP_REG_ENABLE_REPORTS, 0,
3075
+ HIDPP_ENABLE_MOUSE_EXTRA_BTN_REPORT,
3076
+ HIDPP_ENABLE_MOUSE_EXTRA_BTN_REPORT);
3077
+}
3078
+
3079
+static int hidpp10_extra_mouse_buttons_raw_event(struct hidpp_device *hidpp,
3080
+ u8 *data, int size)
3081
+{
3082
+ int i;
3083
+
3084
+ if (!hidpp->input)
3085
+ return -EINVAL;
3086
+
3087
+ if (size < 7)
3088
+ return 0;
3089
+
3090
+ if (data[0] != REPORT_ID_HIDPP_SHORT ||
3091
+ data[2] != HIDPP_SUB_ID_MOUSE_EXTRA_BTNS)
3092
+ return 0;
3093
+
3094
+ /*
3095
+ * Buttons are either delivered through the regular mouse report *or*
3096
+ * through the extra buttons report. At least for button 6 how it is
3097
+ * delivered differs per receiver firmware version. Even receivers with
3098
+ * the same usb-id show different behavior, so we handle both cases.
3099
+ */
3100
+ for (i = 0; i < 8; i++)
3101
+ input_report_key(hidpp->input, BTN_MOUSE + i,
3102
+ (data[3] & (1 << i)));
3103
+
3104
+ /* Some mice report events on button 9+, use BTN_MISC */
3105
+ for (i = 0; i < 8; i++)
3106
+ input_report_key(hidpp->input, BTN_MISC + i,
3107
+ (data[4] & (1 << i)));
3108
+
3109
+ input_sync(hidpp->input);
3110
+ return 1;
3111
+}
3112
+
3113
+static void hidpp10_extra_mouse_buttons_populate_input(
3114
+ struct hidpp_device *hidpp, struct input_dev *input_dev)
3115
+{
3116
+ /* BTN_MOUSE - BTN_MOUSE+7 are set already by the descriptor */
3117
+ __set_bit(BTN_0, input_dev->keybit);
3118
+ __set_bit(BTN_1, input_dev->keybit);
3119
+ __set_bit(BTN_2, input_dev->keybit);
3120
+ __set_bit(BTN_3, input_dev->keybit);
3121
+ __set_bit(BTN_4, input_dev->keybit);
3122
+ __set_bit(BTN_5, input_dev->keybit);
3123
+ __set_bit(BTN_6, input_dev->keybit);
3124
+ __set_bit(BTN_7, input_dev->keybit);
3125
+}
3126
+
3127
+/* -------------------------------------------------------------------------- */
3128
+/* HID++1.0 kbds which only report 0x10xx consumer usages through sub-id 0x03 */
3129
+/* -------------------------------------------------------------------------- */
3130
+
3131
+/* Find the consumer-page input report desc and change Maximums to 0x107f */
3132
+static u8 *hidpp10_consumer_keys_report_fixup(struct hidpp_device *hidpp,
3133
+ u8 *_rdesc, unsigned int *rsize)
3134
+{
3135
+ /* Note 0 terminated so we can use strnstr to search for this. */
3136
+ static const char consumer_rdesc_start[] = {
3137
+ 0x05, 0x0C, /* USAGE_PAGE (Consumer Devices) */
3138
+ 0x09, 0x01, /* USAGE (Consumer Control) */
3139
+ 0xA1, 0x01, /* COLLECTION (Application) */
3140
+ 0x85, 0x03, /* REPORT_ID = 3 */
3141
+ 0x75, 0x10, /* REPORT_SIZE (16) */
3142
+ 0x95, 0x02, /* REPORT_COUNT (2) */
3143
+ 0x15, 0x01, /* LOGICAL_MIN (1) */
3144
+ 0x26, 0x00 /* LOGICAL_MAX (... */
3145
+ };
3146
+ char *consumer_rdesc, *rdesc = (char *)_rdesc;
3147
+ unsigned int size;
3148
+
3149
+ consumer_rdesc = strnstr(rdesc, consumer_rdesc_start, *rsize);
3150
+ size = *rsize - (consumer_rdesc - rdesc);
3151
+ if (consumer_rdesc && size >= 25) {
3152
+ consumer_rdesc[15] = 0x7f;
3153
+ consumer_rdesc[16] = 0x10;
3154
+ consumer_rdesc[20] = 0x7f;
3155
+ consumer_rdesc[21] = 0x10;
3156
+ }
3157
+ return _rdesc;
3158
+}
3159
+
3160
+static int hidpp10_consumer_keys_connect(struct hidpp_device *hidpp)
3161
+{
3162
+ return hidpp10_set_register(hidpp, HIDPP_REG_ENABLE_REPORTS, 0,
3163
+ HIDPP_ENABLE_CONSUMER_REPORT,
3164
+ HIDPP_ENABLE_CONSUMER_REPORT);
3165
+}
3166
+
3167
+static int hidpp10_consumer_keys_raw_event(struct hidpp_device *hidpp,
3168
+ u8 *data, int size)
3169
+{
3170
+ u8 consumer_report[5];
3171
+
3172
+ if (size < 7)
3173
+ return 0;
3174
+
3175
+ if (data[0] != REPORT_ID_HIDPP_SHORT ||
3176
+ data[2] != HIDPP_SUB_ID_CONSUMER_VENDOR_KEYS)
3177
+ return 0;
3178
+
3179
+ /*
3180
+ * Build a normal consumer report (3) out of the data, this detour
3181
+ * is necessary to get some keyboards to report their 0x10xx usages.
3182
+ */
3183
+ consumer_report[0] = 0x03;
3184
+ memcpy(&consumer_report[1], &data[3], 4);
3185
+ /* We are called from atomic context */
3186
+ hid_report_raw_event(hidpp->hid_dev, HID_INPUT_REPORT,
3187
+ consumer_report, 5, 1);
3188
+
3189
+ return 1;
3190
+}
3191
+
3192
+/* -------------------------------------------------------------------------- */
3193
+/* High-resolution scroll wheels */
3194
+/* -------------------------------------------------------------------------- */
3195
+
3196
+static int hi_res_scroll_enable(struct hidpp_device *hidpp)
3197
+{
3198
+ int ret;
3199
+ u8 multiplier = 1;
3200
+
3201
+ if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL_X2121) {
3202
+ ret = hidpp_hrw_set_wheel_mode(hidpp, false, true, false);
3203
+ if (ret == 0)
3204
+ ret = hidpp_hrw_get_wheel_capability(hidpp, &multiplier);
3205
+ } else if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL_X2120) {
3206
+ ret = hidpp_hrs_set_highres_scrolling_mode(hidpp, true,
3207
+ &multiplier);
3208
+ } else /* if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL_1P0) */ {
3209
+ ret = hidpp10_enable_scrolling_acceleration(hidpp);
3210
+ multiplier = 8;
3211
+ }
3212
+ if (ret)
3213
+ return ret;
3214
+
3215
+ if (multiplier == 0)
3216
+ multiplier = 1;
3217
+
3218
+ hidpp->vertical_wheel_counter.wheel_multiplier = multiplier;
3219
+ hid_dbg(hidpp->hid_dev, "wheel multiplier = %d\n", multiplier);
25563220 return 0;
25573221 }
25583222
....@@ -2560,17 +3224,39 @@
25603224 /* Generic HID++ devices */
25613225 /* -------------------------------------------------------------------------- */
25623226
3227
+static u8 *hidpp_report_fixup(struct hid_device *hdev, u8 *rdesc,
3228
+ unsigned int *rsize)
3229
+{
3230
+ struct hidpp_device *hidpp = hid_get_drvdata(hdev);
3231
+
3232
+ if (!hidpp)
3233
+ return rdesc;
3234
+
3235
+ /* For 27 MHz keyboards the quirk gets set after hid_parse. */
3236
+ if (hdev->group == HID_GROUP_LOGITECH_27MHZ_DEVICE ||
3237
+ (hidpp->quirks & HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS))
3238
+ rdesc = hidpp10_consumer_keys_report_fixup(hidpp, rdesc, rsize);
3239
+
3240
+ return rdesc;
3241
+}
3242
+
25633243 static int hidpp_input_mapping(struct hid_device *hdev, struct hid_input *hi,
25643244 struct hid_field *field, struct hid_usage *usage,
25653245 unsigned long **bit, int *max)
25663246 {
25673247 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
25683248
3249
+ if (!hidpp)
3250
+ return 0;
3251
+
25693252 if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)
25703253 return wtp_input_mapping(hdev, hi, field, usage, bit, max);
25713254 else if (hidpp->quirks & HIDPP_QUIRK_CLASS_M560 &&
25723255 field->application != HID_GD_MOUSE)
25733256 return m560_input_mapping(hdev, hi, field, usage, bit, max);
3257
+
3258
+ if (hdev->product == DINOVO_MINI_PRODUCT_ID)
3259
+ return lg_dinovo_input_mapping(hdev, hi, field, usage, bit, max);
25743260
25753261 return 0;
25763262 }
....@@ -2580,6 +3266,9 @@
25803266 unsigned long **bit, int *max)
25813267 {
25823268 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
3269
+
3270
+ if (!hidpp)
3271
+ return 0;
25833272
25843273 /* Ensure that Logitech G920 is not given a default fuzz/flat value */
25853274 if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) {
....@@ -2595,12 +3284,20 @@
25953284
25963285
25973286 static void hidpp_populate_input(struct hidpp_device *hidpp,
2598
- struct input_dev *input, bool origin_is_hid_core)
3287
+ struct input_dev *input)
25993288 {
3289
+ hidpp->input = input;
3290
+
26003291 if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)
2601
- wtp_populate_input(hidpp, input, origin_is_hid_core);
3292
+ wtp_populate_input(hidpp, input);
26023293 else if (hidpp->quirks & HIDPP_QUIRK_CLASS_M560)
2603
- m560_populate_input(hidpp, input, origin_is_hid_core);
3294
+ m560_populate_input(hidpp, input);
3295
+
3296
+ if (hidpp->quirks & HIDPP_QUIRK_HIDPP_WHEELS)
3297
+ hidpp10_wheel_populate_input(hidpp, input);
3298
+
3299
+ if (hidpp->quirks & HIDPP_QUIRK_HIDPP_EXTRA_MOUSE_BTNS)
3300
+ hidpp10_extra_mouse_buttons_populate_input(hidpp, input);
26043301 }
26053302
26063303 static int hidpp_input_configured(struct hid_device *hdev,
....@@ -2609,7 +3306,10 @@
26093306 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
26103307 struct input_dev *input = hidinput->input;
26113308
2612
- hidpp_populate_input(hidpp, input, true);
3309
+ if (!hidpp)
3310
+ return 0;
3311
+
3312
+ hidpp_populate_input(hidpp, input);
26133313
26143314 return 0;
26153315 }
....@@ -2646,7 +3346,7 @@
26463346 }
26473347 }
26483348
2649
- if (unlikely(hidpp_report_is_connect_event(report))) {
3349
+ if (unlikely(hidpp_report_is_connect_event(hidpp, report))) {
26503350 atomic_set(&hidpp->connected,
26513351 !(report->rap.params[0] & (1 << 6)));
26523352 if (schedule_work(&hidpp->work) == 0)
....@@ -2661,10 +3361,31 @@
26613361 ret = hidpp_solar_battery_event(hidpp, data, size);
26623362 if (ret != 0)
26633363 return ret;
3364
+ ret = hidpp20_battery_voltage_event(hidpp, data, size);
3365
+ if (ret != 0)
3366
+ return ret;
26643367 }
26653368
26663369 if (hidpp->capabilities & HIDPP_CAPABILITY_HIDPP10_BATTERY) {
26673370 ret = hidpp10_battery_event(hidpp, data, size);
3371
+ if (ret != 0)
3372
+ return ret;
3373
+ }
3374
+
3375
+ if (hidpp->quirks & HIDPP_QUIRK_HIDPP_WHEELS) {
3376
+ ret = hidpp10_wheel_raw_event(hidpp, data, size);
3377
+ if (ret != 0)
3378
+ return ret;
3379
+ }
3380
+
3381
+ if (hidpp->quirks & HIDPP_QUIRK_HIDPP_EXTRA_MOUSE_BTNS) {
3382
+ ret = hidpp10_extra_mouse_buttons_raw_event(hidpp, data, size);
3383
+ if (ret != 0)
3384
+ return ret;
3385
+ }
3386
+
3387
+ if (hidpp->quirks & HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS) {
3388
+ ret = hidpp10_consumer_keys_raw_event(hidpp, data, size);
26683389 if (ret != 0)
26693390 return ret;
26703391 }
....@@ -2678,10 +3399,13 @@
26783399 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
26793400 int ret = 0;
26803401
3402
+ if (!hidpp)
3403
+ return 0;
3404
+
26813405 /* Generic HID++ processing. */
26823406 switch (data[0]) {
26833407 case REPORT_ID_HIDPP_VERY_LONG:
2684
- if (size != HIDPP_REPORT_VERY_LONG_LENGTH) {
3408
+ if (size != hidpp->very_long_report_length) {
26853409 hid_err(hdev, "received hid++ report of bad size (%d)",
26863410 size);
26873411 return 1;
....@@ -2719,6 +3443,32 @@
27193443 return 0;
27203444 }
27213445
3446
+static int hidpp_event(struct hid_device *hdev, struct hid_field *field,
3447
+ struct hid_usage *usage, __s32 value)
3448
+{
3449
+ /* This function will only be called for scroll events, due to the
3450
+ * restriction imposed in hidpp_usages.
3451
+ */
3452
+ struct hidpp_device *hidpp = hid_get_drvdata(hdev);
3453
+ struct hidpp_scroll_counter *counter;
3454
+
3455
+ if (!hidpp)
3456
+ return 0;
3457
+
3458
+ counter = &hidpp->vertical_wheel_counter;
3459
+ /* A scroll event may occur before the multiplier has been retrieved or
3460
+ * the input device set, or high-res scroll enabling may fail. In such
3461
+ * cases we must return early (falling back to default behaviour) to
3462
+ * avoid a crash in hidpp_scroll_counter_handle_scroll.
3463
+ */
3464
+ if (!(hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL) || value == 0
3465
+ || hidpp->input == NULL || counter->wheel_multiplier == 0)
3466
+ return 0;
3467
+
3468
+ hidpp_scroll_counter_handle_scroll(hidpp->input, counter, value);
3469
+ return 1;
3470
+}
3471
+
27223472 static int hidpp_initialize_battery(struct hidpp_device *hidpp)
27233473 {
27243474 static atomic_t battery_no = ATOMIC_INIT(0);
....@@ -2735,12 +3485,16 @@
27353485
27363486 hidpp->battery.feature_index = 0xff;
27373487 hidpp->battery.solar_feature_index = 0xff;
3488
+ hidpp->battery.voltage_feature_index = 0xff;
27383489
27393490 if (hidpp->protocol_major >= 2) {
27403491 if (hidpp->quirks & HIDPP_QUIRK_CLASS_K750)
27413492 ret = hidpp_solar_request_battery_event(hidpp);
2742
- else
2743
- ret = hidpp20_query_battery_info(hidpp);
3493
+ else {
3494
+ ret = hidpp20_query_battery_voltage_info(hidpp);
3495
+ if (ret)
3496
+ ret = hidpp20_query_battery_info(hidpp);
3497
+ }
27443498
27453499 if (ret)
27463500 return ret;
....@@ -2765,7 +3519,7 @@
27653519 if (!battery_props)
27663520 return -ENOMEM;
27673521
2768
- num_battery_props = ARRAY_SIZE(hidpp_battery_props) - 2;
3522
+ num_battery_props = ARRAY_SIZE(hidpp_battery_props) - 3;
27693523
27703524 if (hidpp->capabilities & HIDPP_CAPABILITY_BATTERY_MILEAGE)
27713525 battery_props[num_battery_props++] =
....@@ -2774,6 +3528,10 @@
27743528 if (hidpp->capabilities & HIDPP_CAPABILITY_BATTERY_LEVEL_STATUS)
27753529 battery_props[num_battery_props++] =
27763530 POWER_SUPPLY_PROP_CAPACITY_LEVEL;
3531
+
3532
+ if (hidpp->capabilities & HIDPP_CAPABILITY_BATTERY_VOLTAGE)
3533
+ battery_props[num_battery_props++] =
3534
+ POWER_SUPPLY_PROP_VOLTAGE_NOW;
27773535
27783536 battery = &hidpp->battery;
27793537
....@@ -2887,32 +3645,45 @@
28873645 return;
28883646 }
28893647
3648
+ if (hidpp->quirks & HIDPP_QUIRK_HIDPP_WHEELS) {
3649
+ ret = hidpp10_wheel_connect(hidpp);
3650
+ if (ret)
3651
+ return;
3652
+ }
3653
+
3654
+ if (hidpp->quirks & HIDPP_QUIRK_HIDPP_EXTRA_MOUSE_BTNS) {
3655
+ ret = hidpp10_extra_mouse_buttons_connect(hidpp);
3656
+ if (ret)
3657
+ return;
3658
+ }
3659
+
3660
+ if (hidpp->quirks & HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS) {
3661
+ ret = hidpp10_consumer_keys_connect(hidpp);
3662
+ if (ret)
3663
+ return;
3664
+ }
3665
+
28903666 /* the device is already connected, we can ask for its name and
28913667 * protocol */
28923668 if (!hidpp->protocol_major) {
2893
- ret = !hidpp_is_connected(hidpp);
3669
+ ret = hidpp_root_get_protocol_version(hidpp);
28943670 if (ret) {
28953671 hid_err(hdev, "Can not get the protocol version.\n");
28963672 return;
28973673 }
2898
- hid_info(hdev, "HID++ %u.%u device connected.\n",
2899
- hidpp->protocol_major, hidpp->protocol_minor);
29003674 }
29013675
29023676 if (hidpp->name == hdev->name && hidpp->protocol_major >= 2) {
29033677 name = hidpp_get_device_name(hidpp);
2904
- if (!name) {
2905
- hid_err(hdev,
2906
- "unable to retrieve the name of the device");
2907
- return;
3678
+ if (name) {
3679
+ devm_name = devm_kasprintf(&hdev->dev, GFP_KERNEL,
3680
+ "%s", name);
3681
+ kfree(name);
3682
+ if (!devm_name)
3683
+ return;
3684
+
3685
+ hidpp->name = devm_name;
29083686 }
2909
-
2910
- devm_name = devm_kasprintf(&hdev->dev, GFP_KERNEL, "%s", name);
2911
- kfree(name);
2912
- if (!devm_name)
2913
- return;
2914
-
2915
- hidpp->name = devm_name;
29163687 }
29173688
29183689 hidpp_initialize_battery(hidpp);
....@@ -2925,10 +3696,16 @@
29253696 else
29263697 hidpp10_query_battery_status(hidpp);
29273698 } else if (hidpp->capabilities & HIDPP_CAPABILITY_HIDPP20_BATTERY) {
2928
- hidpp20_query_battery_info(hidpp);
3699
+ if (hidpp->capabilities & HIDPP_CAPABILITY_BATTERY_VOLTAGE)
3700
+ hidpp20_query_battery_voltage_info(hidpp);
3701
+ else
3702
+ hidpp20_query_battery_info(hidpp);
29293703 }
29303704 if (hidpp->battery.ps)
29313705 power_supply_changed(hidpp->battery.ps);
3706
+
3707
+ if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL)
3708
+ hi_res_scroll_enable(hidpp);
29323709
29333710 if (!(hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT) || hidpp->delayed_input)
29343711 /* if the input nodes are already created, we can stop now */
....@@ -2940,7 +3717,7 @@
29403717 return;
29413718 }
29423719
2943
- hidpp_populate_input(hidpp, input, false);
3720
+ hidpp_populate_input(hidpp, input);
29443721
29453722 ret = input_register_device(input);
29463723 if (ret)
....@@ -2960,26 +3737,119 @@
29603737 .attrs = sysfs_attrs
29613738 };
29623739
3740
+static int hidpp_get_report_length(struct hid_device *hdev, int id)
3741
+{
3742
+ struct hid_report_enum *re;
3743
+ struct hid_report *report;
3744
+
3745
+ re = &(hdev->report_enum[HID_OUTPUT_REPORT]);
3746
+ report = re->report_id_hash[id];
3747
+ if (!report)
3748
+ return 0;
3749
+
3750
+ return report->field[0]->report_count + 1;
3751
+}
3752
+
3753
+static u8 hidpp_validate_device(struct hid_device *hdev)
3754
+{
3755
+ struct hidpp_device *hidpp = hid_get_drvdata(hdev);
3756
+ int id, report_length;
3757
+ u8 supported_reports = 0;
3758
+
3759
+ id = REPORT_ID_HIDPP_SHORT;
3760
+ report_length = hidpp_get_report_length(hdev, id);
3761
+ if (report_length) {
3762
+ if (report_length < HIDPP_REPORT_SHORT_LENGTH)
3763
+ goto bad_device;
3764
+
3765
+ supported_reports |= HIDPP_REPORT_SHORT_SUPPORTED;
3766
+ }
3767
+
3768
+ id = REPORT_ID_HIDPP_LONG;
3769
+ report_length = hidpp_get_report_length(hdev, id);
3770
+ if (report_length) {
3771
+ if (report_length < HIDPP_REPORT_LONG_LENGTH)
3772
+ goto bad_device;
3773
+
3774
+ supported_reports |= HIDPP_REPORT_LONG_SUPPORTED;
3775
+ }
3776
+
3777
+ id = REPORT_ID_HIDPP_VERY_LONG;
3778
+ report_length = hidpp_get_report_length(hdev, id);
3779
+ if (report_length) {
3780
+ if (report_length < HIDPP_REPORT_LONG_LENGTH ||
3781
+ report_length > HIDPP_REPORT_VERY_LONG_MAX_LENGTH)
3782
+ goto bad_device;
3783
+
3784
+ supported_reports |= HIDPP_REPORT_VERY_LONG_SUPPORTED;
3785
+ hidpp->very_long_report_length = report_length;
3786
+ }
3787
+
3788
+ return supported_reports;
3789
+
3790
+bad_device:
3791
+ hid_warn(hdev, "not enough values in hidpp report %d\n", id);
3792
+ return false;
3793
+}
3794
+
3795
+static bool hidpp_application_equals(struct hid_device *hdev,
3796
+ unsigned int application)
3797
+{
3798
+ struct list_head *report_list;
3799
+ struct hid_report *report;
3800
+
3801
+ report_list = &hdev->report_enum[HID_INPUT_REPORT].report_list;
3802
+ report = list_first_entry_or_null(report_list, struct hid_report, list);
3803
+ return report && report->application == application;
3804
+}
3805
+
29633806 static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
29643807 {
29653808 struct hidpp_device *hidpp;
29663809 int ret;
29673810 bool connected;
29683811 unsigned int connect_mask = HID_CONNECT_DEFAULT;
3812
+ struct hidpp_ff_private_data data;
3813
+ bool will_restart = false;
29693814
2970
- hidpp = devm_kzalloc(&hdev->dev, sizeof(struct hidpp_device),
2971
- GFP_KERNEL);
3815
+ /* report_fixup needs drvdata to be set before we call hid_parse */
3816
+ hidpp = devm_kzalloc(&hdev->dev, sizeof(*hidpp), GFP_KERNEL);
29723817 if (!hidpp)
29733818 return -ENOMEM;
29743819
29753820 hidpp->hid_dev = hdev;
29763821 hidpp->name = hdev->name;
3822
+ hidpp->quirks = id->driver_data;
29773823 hid_set_drvdata(hdev, hidpp);
29783824
2979
- hidpp->quirks = id->driver_data;
3825
+ ret = hid_parse(hdev);
3826
+ if (ret) {
3827
+ hid_err(hdev, "%s:parse failed\n", __func__);
3828
+ return ret;
3829
+ }
3830
+
3831
+ /*
3832
+ * Make sure the device is HID++ capable, otherwise treat as generic HID
3833
+ */
3834
+ hidpp->supported_reports = hidpp_validate_device(hdev);
3835
+
3836
+ if (!hidpp->supported_reports) {
3837
+ hid_set_drvdata(hdev, NULL);
3838
+ devm_kfree(&hdev->dev, hidpp);
3839
+ return hid_hw_start(hdev, HID_CONNECT_DEFAULT);
3840
+ }
29803841
29813842 if (id->group == HID_GROUP_LOGITECH_DJ_DEVICE)
29823843 hidpp->quirks |= HIDPP_QUIRK_UNIFYING;
3844
+
3845
+ if (id->group == HID_GROUP_LOGITECH_27MHZ_DEVICE &&
3846
+ hidpp_application_equals(hdev, HID_GD_MOUSE))
3847
+ hidpp->quirks |= HIDPP_QUIRK_HIDPP_WHEELS |
3848
+ HIDPP_QUIRK_HIDPP_EXTRA_MOUSE_BTNS;
3849
+
3850
+ if (id->group == HID_GROUP_LOGITECH_27MHZ_DEVICE &&
3851
+ hidpp_application_equals(hdev, HID_GD_KEYBOARD))
3852
+ hidpp->quirks |= HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS;
29833853
29843854 if (disable_raw_mode) {
29853855 hidpp->quirks &= ~HIDPP_QUIRK_CLASS_WTP;
....@@ -2989,16 +3859,16 @@
29893859 if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) {
29903860 ret = wtp_allocate(hdev, id);
29913861 if (ret)
2992
- goto allocate_fail;
2993
- } else if (hidpp->quirks & HIDPP_QUIRK_CLASS_M560) {
2994
- ret = m560_allocate(hdev);
2995
- if (ret)
2996
- goto allocate_fail;
3862
+ return ret;
29973863 } else if (hidpp->quirks & HIDPP_QUIRK_CLASS_K400) {
29983864 ret = k400_allocate(hdev);
29993865 if (ret)
3000
- goto allocate_fail;
3866
+ return ret;
30013867 }
3868
+
3869
+ if (hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT ||
3870
+ hidpp->quirks & HIDPP_QUIRK_UNIFYING)
3871
+ will_restart = true;
30023872
30033873 INIT_WORK(&hidpp->work, delayed_work_cb);
30043874 mutex_init(&hidpp->send_mutex);
....@@ -3010,66 +3880,74 @@
30103880 hid_warn(hdev, "Cannot allocate sysfs group for %s\n",
30113881 hdev->name);
30123882
3013
- ret = hid_parse(hdev);
3883
+ /*
3884
+ * Plain USB connections need to actually call start and open
3885
+ * on the transport driver to allow incoming data.
3886
+ */
3887
+ ret = hid_hw_start(hdev, will_restart ? 0 : connect_mask);
30143888 if (ret) {
3015
- hid_err(hdev, "%s:parse failed\n", __func__);
3016
- goto hid_parse_fail;
3889
+ hid_err(hdev, "hw start failed\n");
3890
+ goto hid_hw_start_fail;
30173891 }
30183892
3019
- if (hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT)
3020
- connect_mask &= ~HID_CONNECT_HIDINPUT;
3021
-
3022
- if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) {
3023
- ret = hid_hw_start(hdev, connect_mask);
3024
- if (ret) {
3025
- hid_err(hdev, "hw start failed\n");
3026
- goto hid_hw_start_fail;
3027
- }
3028
- ret = hid_hw_open(hdev);
3029
- if (ret < 0) {
3030
- dev_err(&hdev->dev, "%s:hid_hw_open returned error:%d\n",
3031
- __func__, ret);
3032
- hid_hw_stop(hdev);
3033
- goto hid_hw_start_fail;
3034
- }
3893
+ ret = hid_hw_open(hdev);
3894
+ if (ret < 0) {
3895
+ dev_err(&hdev->dev, "%s:hid_hw_open returned error:%d\n",
3896
+ __func__, ret);
3897
+ goto hid_hw_open_fail;
30353898 }
3036
-
30373899
30383900 /* Allow incoming packets */
30393901 hid_device_io_start(hdev);
30403902
30413903 if (hidpp->quirks & HIDPP_QUIRK_UNIFYING)
30423904 hidpp_unifying_init(hidpp);
3905
+ else if (hid_is_usb(hidpp->hid_dev))
3906
+ hidpp_serial_init(hidpp);
30433907
3044
- connected = hidpp_is_connected(hidpp);
3908
+ connected = hidpp_root_get_protocol_version(hidpp) == 0;
30453909 atomic_set(&hidpp->connected, connected);
30463910 if (!(hidpp->quirks & HIDPP_QUIRK_UNIFYING)) {
30473911 if (!connected) {
30483912 ret = -ENODEV;
30493913 hid_err(hdev, "Device not connected");
3050
- goto hid_hw_open_failed;
3914
+ goto hid_hw_init_fail;
30513915 }
30523916
3053
- hid_info(hdev, "HID++ %u.%u device connected.\n",
3054
- hidpp->protocol_major, hidpp->protocol_minor);
3055
-
30563917 hidpp_overwrite_name(hdev);
3918
+ }
3919
+
3920
+ if (connected && hidpp->protocol_major >= 2) {
3921
+ ret = hidpp_set_wireless_feature_index(hidpp);
3922
+ if (ret == -ENOENT)
3923
+ hidpp->wireless_feature_index = 0;
3924
+ else if (ret)
3925
+ goto hid_hw_init_fail;
3926
+ ret = 0;
30573927 }
30583928
30593929 if (connected && (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)) {
30603930 ret = wtp_get_config(hidpp);
30613931 if (ret)
3062
- goto hid_hw_open_failed;
3932
+ goto hid_hw_init_fail;
30633933 } else if (connected && (hidpp->quirks & HIDPP_QUIRK_CLASS_G920)) {
3064
- ret = g920_get_config(hidpp);
3934
+ ret = g920_get_config(hidpp, &data);
30653935 if (ret)
3066
- goto hid_hw_open_failed;
3936
+ goto hid_hw_init_fail;
30673937 }
30683938
3069
- /* Block incoming packets */
3070
- hid_device_io_stop(hdev);
3939
+ hidpp_connect_event(hidpp);
30713940
3072
- if (!(hidpp->quirks & HIDPP_QUIRK_CLASS_G920)) {
3941
+ if (will_restart) {
3942
+ /* Reset the HID node state */
3943
+ hid_device_io_stop(hdev);
3944
+ hid_hw_close(hdev);
3945
+ hid_hw_stop(hdev);
3946
+
3947
+ if (hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT)
3948
+ connect_mask &= ~HID_CONNECT_HIDINPUT;
3949
+
3950
+ /* Now export the actual inputs and hidraw nodes to the world */
30733951 ret = hid_hw_start(hdev, connect_mask);
30743952 if (ret) {
30753953 hid_err(hdev, "%s:hid_hw_start returned error\n", __func__);
....@@ -3077,26 +3955,24 @@
30773955 }
30783956 }
30793957
3080
- /* Allow incoming packets */
3081
- hid_device_io_start(hdev);
3082
-
3083
- hidpp_connect_event(hidpp);
3958
+ if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) {
3959
+ ret = hidpp_ff_init(hidpp, &data);
3960
+ if (ret)
3961
+ hid_warn(hidpp->hid_dev,
3962
+ "Unable to initialize force feedback support, errno %d\n",
3963
+ ret);
3964
+ }
30843965
30853966 return ret;
30863967
3087
-hid_hw_open_failed:
3088
- hid_device_io_stop(hdev);
3089
- if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) {
3090
- hid_hw_close(hdev);
3091
- hid_hw_stop(hdev);
3092
- }
3968
+hid_hw_init_fail:
3969
+ hid_hw_close(hdev);
3970
+hid_hw_open_fail:
3971
+ hid_hw_stop(hdev);
30933972 hid_hw_start_fail:
3094
-hid_parse_fail:
30953973 sysfs_remove_group(&hdev->dev.kobj, &ps_attribute_group);
30963974 cancel_work_sync(&hidpp->work);
30973975 mutex_destroy(&hidpp->send_mutex);
3098
-allocate_fail:
3099
- hid_set_drvdata(hdev, NULL);
31003976 return ret;
31013977 }
31023978
....@@ -3104,60 +3980,161 @@
31043980 {
31053981 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
31063982
3983
+ if (!hidpp)
3984
+ return hid_hw_stop(hdev);
3985
+
31073986 sysfs_remove_group(&hdev->dev.kobj, &ps_attribute_group);
31083987
3109
- if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) {
3110
- hidpp_ff_deinit(hdev);
3111
- hid_hw_close(hdev);
3112
- }
31133988 hid_hw_stop(hdev);
31143989 cancel_work_sync(&hidpp->work);
31153990 mutex_destroy(&hidpp->send_mutex);
31163991 }
31173992
3993
+#define LDJ_DEVICE(product) \
3994
+ HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, \
3995
+ USB_VENDOR_ID_LOGITECH, (product))
3996
+
3997
+#define L27MHZ_DEVICE(product) \
3998
+ HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_27MHZ_DEVICE, \
3999
+ USB_VENDOR_ID_LOGITECH, (product))
4000
+
31184001 static const struct hid_device_id hidpp_devices[] = {
31194002 { /* wireless touchpad */
3120
- HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
3121
- USB_VENDOR_ID_LOGITECH, 0x4011),
4003
+ LDJ_DEVICE(0x4011),
31224004 .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT |
31234005 HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS },
31244006 { /* wireless touchpad T650 */
3125
- HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
3126
- USB_VENDOR_ID_LOGITECH, 0x4101),
4007
+ LDJ_DEVICE(0x4101),
31274008 .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT },
31284009 { /* wireless touchpad T651 */
31294010 HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH,
31304011 USB_DEVICE_ID_LOGITECH_T651),
3131
- .driver_data = HIDPP_QUIRK_CLASS_WTP },
4012
+ .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT },
4013
+ { /* Mouse Logitech Anywhere MX */
4014
+ LDJ_DEVICE(0x1017), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_1P0 },
4015
+ { /* Mouse Logitech Cube */
4016
+ LDJ_DEVICE(0x4010), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2120 },
4017
+ { /* Mouse Logitech M335 */
4018
+ LDJ_DEVICE(0x4050), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
4019
+ { /* Mouse Logitech M515 */
4020
+ LDJ_DEVICE(0x4007), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2120 },
31324021 { /* Mouse logitech M560 */
3133
- HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
3134
- USB_VENDOR_ID_LOGITECH, 0x402d),
3135
- .driver_data = HIDPP_QUIRK_DELAYED_INIT | HIDPP_QUIRK_CLASS_M560 },
4022
+ LDJ_DEVICE(0x402d),
4023
+ .driver_data = HIDPP_QUIRK_DELAYED_INIT | HIDPP_QUIRK_CLASS_M560
4024
+ | HIDPP_QUIRK_HI_RES_SCROLL_X2120 },
4025
+ { /* Mouse Logitech M705 (firmware RQM17) */
4026
+ LDJ_DEVICE(0x101b), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_1P0 },
4027
+ { /* Mouse Logitech M705 (firmware RQM67) */
4028
+ LDJ_DEVICE(0x406d), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
4029
+ { /* Mouse Logitech M720 */
4030
+ LDJ_DEVICE(0x405e), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
4031
+ { /* Mouse Logitech MX Anywhere 2 */
4032
+ LDJ_DEVICE(0x404a), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
4033
+ { LDJ_DEVICE(0x4072), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
4034
+ { LDJ_DEVICE(0xb013), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
4035
+ { LDJ_DEVICE(0xb018), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
4036
+ { LDJ_DEVICE(0xb01f), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
4037
+ { /* Mouse Logitech MX Anywhere 2S */
4038
+ LDJ_DEVICE(0x406a), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
4039
+ { /* Mouse Logitech MX Master */
4040
+ LDJ_DEVICE(0x4041), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
4041
+ { LDJ_DEVICE(0x4060), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
4042
+ { LDJ_DEVICE(0x4071), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
4043
+ { /* Mouse Logitech MX Master 2S */
4044
+ LDJ_DEVICE(0x4069), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
4045
+ { /* Mouse Logitech MX Master 3 */
4046
+ LDJ_DEVICE(0x4082), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
4047
+ { /* Mouse Logitech Performance MX */
4048
+ LDJ_DEVICE(0x101a), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_1P0 },
31364049 { /* Keyboard logitech K400 */
3137
- HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
3138
- USB_VENDOR_ID_LOGITECH, 0x4024),
4050
+ LDJ_DEVICE(0x4024),
31394051 .driver_data = HIDPP_QUIRK_CLASS_K400 },
31404052 { /* Solar Keyboard Logitech K750 */
3141
- HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
3142
- USB_VENDOR_ID_LOGITECH, 0x4002),
4053
+ LDJ_DEVICE(0x4002),
31434054 .driver_data = HIDPP_QUIRK_CLASS_K750 },
4055
+ { /* Keyboard MX5000 (Bluetooth-receiver in HID proxy mode) */
4056
+ LDJ_DEVICE(0xb305),
4057
+ .driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS },
4058
+ { /* Dinovo Edge (Bluetooth-receiver in HID proxy mode) */
4059
+ LDJ_DEVICE(0xb309),
4060
+ .driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS },
4061
+ { /* Keyboard MX5500 (Bluetooth-receiver in HID proxy mode) */
4062
+ LDJ_DEVICE(0xb30b),
4063
+ .driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS },
31444064
3145
- { HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
3146
- USB_VENDOR_ID_LOGITECH, HID_ANY_ID)},
4065
+ { LDJ_DEVICE(HID_ANY_ID) },
31474066
3148
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G920_WHEEL),
4067
+ { /* Keyboard LX501 (Y-RR53) */
4068
+ L27MHZ_DEVICE(0x0049),
4069
+ .driver_data = HIDPP_QUIRK_KBD_ZOOM_WHEEL },
4070
+ { /* Keyboard MX3000 (Y-RAM74) */
4071
+ L27MHZ_DEVICE(0x0057),
4072
+ .driver_data = HIDPP_QUIRK_KBD_SCROLL_WHEEL },
4073
+ { /* Keyboard MX3200 (Y-RAV80) */
4074
+ L27MHZ_DEVICE(0x005c),
4075
+ .driver_data = HIDPP_QUIRK_KBD_ZOOM_WHEEL },
4076
+ { /* S510 Media Remote */
4077
+ L27MHZ_DEVICE(0x00fe),
4078
+ .driver_data = HIDPP_QUIRK_KBD_SCROLL_WHEEL },
4079
+
4080
+ { L27MHZ_DEVICE(HID_ANY_ID) },
4081
+
4082
+ { /* Logitech G403 Wireless Gaming Mouse over USB */
4083
+ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC082) },
4084
+ { /* Logitech G703 Gaming Mouse over USB */
4085
+ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC087) },
4086
+ { /* Logitech G703 Hero Gaming Mouse over USB */
4087
+ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC090) },
4088
+ { /* Logitech G900 Gaming Mouse over USB */
4089
+ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC081) },
4090
+ { /* Logitech G903 Gaming Mouse over USB */
4091
+ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC086) },
4092
+ { /* Logitech G903 Hero Gaming Mouse over USB */
4093
+ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC091) },
4094
+ { /* Logitech G920 Wheel over USB */
4095
+ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G920_WHEEL),
31494096 .driver_data = HIDPP_QUIRK_CLASS_G920 | HIDPP_QUIRK_FORCE_OUTPUT_REPORTS},
4097
+ { /* Logitech G Pro Gaming Mouse over USB */
4098
+ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC088) },
4099
+
4100
+ { /* MX5000 keyboard over Bluetooth */
4101
+ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb305),
4102
+ .driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS },
4103
+ { /* Dinovo Edge keyboard over Bluetooth */
4104
+ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb309),
4105
+ .driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS },
4106
+ { /* MX5500 keyboard over Bluetooth */
4107
+ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb30b),
4108
+ .driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS },
4109
+ { /* MX Master mouse over Bluetooth */
4110
+ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb012),
4111
+ .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
4112
+ { /* MX Ergo trackball over Bluetooth */
4113
+ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb01d) },
4114
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb01e),
4115
+ .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
4116
+ { /* MX Master 3 mouse over Bluetooth */
4117
+ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb023),
4118
+ .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
31504119 {}
31514120 };
31524121
31534122 MODULE_DEVICE_TABLE(hid, hidpp_devices);
31544123
4124
+static const struct hid_usage_id hidpp_usages[] = {
4125
+ { HID_GD_WHEEL, EV_REL, REL_WHEEL_HI_RES },
4126
+ { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1}
4127
+};
4128
+
31554129 static struct hid_driver hidpp_driver = {
31564130 .name = "logitech-hidpp-device",
31574131 .id_table = hidpp_devices,
4132
+ .report_fixup = hidpp_report_fixup,
31584133 .probe = hidpp_probe,
31594134 .remove = hidpp_remove,
31604135 .raw_event = hidpp_raw_event,
4136
+ .usage_table = hidpp_usages,
4137
+ .event = hidpp_event,
31614138 .input_configured = hidpp_input_configured,
31624139 .input_mapping = hidpp_input_mapping,
31634140 .input_mapped = hidpp_input_mapped,