forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
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;
....@@ -739,7 +892,7 @@
739892 if (ret == HIDPP_ERROR_INVALID_SUBID) {
740893 hidpp->protocol_major = 1;
741894 hidpp->protocol_minor = 0;
742
- return 0;
895
+ goto print_version;
743896 }
744897
745898 /* the device might not be connected */
....@@ -763,18 +916,10 @@
763916 hidpp->protocol_major = response.rap.params[0];
764917 hidpp->protocol_minor = response.rap.params[1];
765918
766
- return ret;
767
-}
768
-
769
-static bool hidpp_is_connected(struct hidpp_device *hidpp)
770
-{
771
- int ret;
772
-
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;
919
+print_version:
920
+ hid_info(hidpp->hid_dev, "HID++ %u.%u device connected.\n",
921
+ hidpp->protocol_major, hidpp->protocol_minor);
922
+ return 0;
778923 }
779924
780925 /* -------------------------------------------------------------------------- */
....@@ -830,7 +975,7 @@
830975
831976 switch (response.report_id) {
832977 case REPORT_ID_HIDPP_VERY_LONG:
833
- count = HIDPP_REPORT_VERY_LONG_LENGTH - 4;
978
+ count = hidpp->very_long_report_length - 4;
834979 break;
835980 case REPORT_ID_HIDPP_LONG:
836981 count = HIDPP_REPORT_LONG_LENGTH - 4;
....@@ -1098,6 +1243,144 @@
10981243 return 0;
10991244 }
11001245
1246
+/* -------------------------------------------------------------------------- */
1247
+/* 0x1001: Battery voltage */
1248
+/* -------------------------------------------------------------------------- */
1249
+
1250
+#define HIDPP_PAGE_BATTERY_VOLTAGE 0x1001
1251
+
1252
+#define CMD_BATTERY_VOLTAGE_GET_BATTERY_VOLTAGE 0x00
1253
+
1254
+#define EVENT_BATTERY_VOLTAGE_STATUS_BROADCAST 0x00
1255
+
1256
+static int hidpp20_battery_map_status_voltage(u8 data[3], int *voltage,
1257
+ int *level, int *charge_type)
1258
+{
1259
+ int status;
1260
+
1261
+ long flags = (long) data[2];
1262
+ *level = POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN;
1263
+
1264
+ if (flags & 0x80)
1265
+ switch (flags & 0x07) {
1266
+ case 0:
1267
+ status = POWER_SUPPLY_STATUS_CHARGING;
1268
+ break;
1269
+ case 1:
1270
+ status = POWER_SUPPLY_STATUS_FULL;
1271
+ *level = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
1272
+ break;
1273
+ case 2:
1274
+ status = POWER_SUPPLY_STATUS_NOT_CHARGING;
1275
+ break;
1276
+ default:
1277
+ status = POWER_SUPPLY_STATUS_UNKNOWN;
1278
+ break;
1279
+ }
1280
+ else
1281
+ status = POWER_SUPPLY_STATUS_DISCHARGING;
1282
+
1283
+ *charge_type = POWER_SUPPLY_CHARGE_TYPE_STANDARD;
1284
+ if (test_bit(3, &flags)) {
1285
+ *charge_type = POWER_SUPPLY_CHARGE_TYPE_FAST;
1286
+ }
1287
+ if (test_bit(4, &flags)) {
1288
+ *charge_type = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
1289
+ }
1290
+ if (test_bit(5, &flags)) {
1291
+ *level = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
1292
+ }
1293
+
1294
+ *voltage = get_unaligned_be16(data);
1295
+
1296
+ return status;
1297
+}
1298
+
1299
+static int hidpp20_battery_get_battery_voltage(struct hidpp_device *hidpp,
1300
+ u8 feature_index,
1301
+ int *status, int *voltage,
1302
+ int *level, int *charge_type)
1303
+{
1304
+ struct hidpp_report response;
1305
+ int ret;
1306
+ u8 *params = (u8 *)response.fap.params;
1307
+
1308
+ ret = hidpp_send_fap_command_sync(hidpp, feature_index,
1309
+ CMD_BATTERY_VOLTAGE_GET_BATTERY_VOLTAGE,
1310
+ NULL, 0, &response);
1311
+
1312
+ if (ret > 0) {
1313
+ hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n",
1314
+ __func__, ret);
1315
+ return -EPROTO;
1316
+ }
1317
+ if (ret)
1318
+ return ret;
1319
+
1320
+ hidpp->capabilities |= HIDPP_CAPABILITY_BATTERY_VOLTAGE;
1321
+
1322
+ *status = hidpp20_battery_map_status_voltage(params, voltage,
1323
+ level, charge_type);
1324
+
1325
+ return 0;
1326
+}
1327
+
1328
+static int hidpp20_query_battery_voltage_info(struct hidpp_device *hidpp)
1329
+{
1330
+ u8 feature_type;
1331
+ int ret;
1332
+ int status, voltage, level, charge_type;
1333
+
1334
+ if (hidpp->battery.voltage_feature_index == 0xff) {
1335
+ ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_BATTERY_VOLTAGE,
1336
+ &hidpp->battery.voltage_feature_index,
1337
+ &feature_type);
1338
+ if (ret)
1339
+ return ret;
1340
+ }
1341
+
1342
+ ret = hidpp20_battery_get_battery_voltage(hidpp,
1343
+ hidpp->battery.voltage_feature_index,
1344
+ &status, &voltage, &level, &charge_type);
1345
+
1346
+ if (ret)
1347
+ return ret;
1348
+
1349
+ hidpp->battery.status = status;
1350
+ hidpp->battery.voltage = voltage;
1351
+ hidpp->battery.level = level;
1352
+ hidpp->battery.charge_type = charge_type;
1353
+ hidpp->battery.online = status != POWER_SUPPLY_STATUS_NOT_CHARGING;
1354
+
1355
+ return 0;
1356
+}
1357
+
1358
+static int hidpp20_battery_voltage_event(struct hidpp_device *hidpp,
1359
+ u8 *data, int size)
1360
+{
1361
+ struct hidpp_report *report = (struct hidpp_report *)data;
1362
+ int status, voltage, level, charge_type;
1363
+
1364
+ if (report->fap.feature_index != hidpp->battery.voltage_feature_index ||
1365
+ report->fap.funcindex_clientid != EVENT_BATTERY_VOLTAGE_STATUS_BROADCAST)
1366
+ return 0;
1367
+
1368
+ status = hidpp20_battery_map_status_voltage(report->fap.params, &voltage,
1369
+ &level, &charge_type);
1370
+
1371
+ hidpp->battery.online = status != POWER_SUPPLY_STATUS_NOT_CHARGING;
1372
+
1373
+ if (voltage != hidpp->battery.voltage || status != hidpp->battery.status) {
1374
+ hidpp->battery.voltage = voltage;
1375
+ hidpp->battery.status = status;
1376
+ hidpp->battery.level = level;
1377
+ hidpp->battery.charge_type = charge_type;
1378
+ if (hidpp->battery.ps)
1379
+ power_supply_changed(hidpp->battery.ps);
1380
+ }
1381
+ return 0;
1382
+}
1383
+
11011384 static enum power_supply_property hidpp_battery_props[] = {
11021385 POWER_SUPPLY_PROP_ONLINE,
11031386 POWER_SUPPLY_PROP_STATUS,
....@@ -1107,6 +1390,7 @@
11071390 POWER_SUPPLY_PROP_SERIAL_NUMBER,
11081391 0, /* placeholder for POWER_SUPPLY_PROP_CAPACITY, */
11091392 0, /* placeholder for POWER_SUPPLY_PROP_CAPACITY_LEVEL, */
1393
+ 0, /* placeholder for POWER_SUPPLY_PROP_VOLTAGE_NOW, */
11101394 };
11111395
11121396 static int hidpp_battery_get_property(struct power_supply *psy,
....@@ -1144,12 +1428,130 @@
11441428 case POWER_SUPPLY_PROP_SERIAL_NUMBER:
11451429 val->strval = hidpp->hid_dev->uniq;
11461430 break;
1431
+ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
1432
+ /* hardware reports voltage in in mV. sysfs expects uV */
1433
+ val->intval = hidpp->battery.voltage * 1000;
1434
+ break;
1435
+ case POWER_SUPPLY_PROP_CHARGE_TYPE:
1436
+ val->intval = hidpp->battery.charge_type;
1437
+ break;
11471438 default:
11481439 ret = -EINVAL;
11491440 break;
11501441 }
11511442
11521443 return ret;
1444
+}
1445
+
1446
+/* -------------------------------------------------------------------------- */
1447
+/* 0x1d4b: Wireless device status */
1448
+/* -------------------------------------------------------------------------- */
1449
+#define HIDPP_PAGE_WIRELESS_DEVICE_STATUS 0x1d4b
1450
+
1451
+static int hidpp_set_wireless_feature_index(struct hidpp_device *hidpp)
1452
+{
1453
+ u8 feature_type;
1454
+ int ret;
1455
+
1456
+ ret = hidpp_root_get_feature(hidpp,
1457
+ HIDPP_PAGE_WIRELESS_DEVICE_STATUS,
1458
+ &hidpp->wireless_feature_index,
1459
+ &feature_type);
1460
+
1461
+ return ret;
1462
+}
1463
+
1464
+/* -------------------------------------------------------------------------- */
1465
+/* 0x2120: Hi-resolution scrolling */
1466
+/* -------------------------------------------------------------------------- */
1467
+
1468
+#define HIDPP_PAGE_HI_RESOLUTION_SCROLLING 0x2120
1469
+
1470
+#define CMD_HI_RESOLUTION_SCROLLING_SET_HIGHRES_SCROLLING_MODE 0x10
1471
+
1472
+static int hidpp_hrs_set_highres_scrolling_mode(struct hidpp_device *hidpp,
1473
+ bool enabled, u8 *multiplier)
1474
+{
1475
+ u8 feature_index;
1476
+ u8 feature_type;
1477
+ int ret;
1478
+ u8 params[1];
1479
+ struct hidpp_report response;
1480
+
1481
+ ret = hidpp_root_get_feature(hidpp,
1482
+ HIDPP_PAGE_HI_RESOLUTION_SCROLLING,
1483
+ &feature_index,
1484
+ &feature_type);
1485
+ if (ret)
1486
+ return ret;
1487
+
1488
+ params[0] = enabled ? BIT(0) : 0;
1489
+ ret = hidpp_send_fap_command_sync(hidpp, feature_index,
1490
+ CMD_HI_RESOLUTION_SCROLLING_SET_HIGHRES_SCROLLING_MODE,
1491
+ params, sizeof(params), &response);
1492
+ if (ret)
1493
+ return ret;
1494
+ *multiplier = response.fap.params[1];
1495
+ return 0;
1496
+}
1497
+
1498
+/* -------------------------------------------------------------------------- */
1499
+/* 0x2121: HiRes Wheel */
1500
+/* -------------------------------------------------------------------------- */
1501
+
1502
+#define HIDPP_PAGE_HIRES_WHEEL 0x2121
1503
+
1504
+#define CMD_HIRES_WHEEL_GET_WHEEL_CAPABILITY 0x00
1505
+#define CMD_HIRES_WHEEL_SET_WHEEL_MODE 0x20
1506
+
1507
+static int hidpp_hrw_get_wheel_capability(struct hidpp_device *hidpp,
1508
+ u8 *multiplier)
1509
+{
1510
+ u8 feature_index;
1511
+ u8 feature_type;
1512
+ int ret;
1513
+ struct hidpp_report response;
1514
+
1515
+ ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_HIRES_WHEEL,
1516
+ &feature_index, &feature_type);
1517
+ if (ret)
1518
+ goto return_default;
1519
+
1520
+ ret = hidpp_send_fap_command_sync(hidpp, feature_index,
1521
+ CMD_HIRES_WHEEL_GET_WHEEL_CAPABILITY,
1522
+ NULL, 0, &response);
1523
+ if (ret)
1524
+ goto return_default;
1525
+
1526
+ *multiplier = response.fap.params[0];
1527
+ return 0;
1528
+return_default:
1529
+ hid_warn(hidpp->hid_dev,
1530
+ "Couldn't get wheel multiplier (error %d)\n", ret);
1531
+ return ret;
1532
+}
1533
+
1534
+static int hidpp_hrw_set_wheel_mode(struct hidpp_device *hidpp, bool invert,
1535
+ bool high_resolution, bool use_hidpp)
1536
+{
1537
+ u8 feature_index;
1538
+ u8 feature_type;
1539
+ int ret;
1540
+ u8 params[1];
1541
+ struct hidpp_report response;
1542
+
1543
+ ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_HIRES_WHEEL,
1544
+ &feature_index, &feature_type);
1545
+ if (ret)
1546
+ return ret;
1547
+
1548
+ params[0] = (invert ? BIT(2) : 0) |
1549
+ (high_resolution ? BIT(1) : 0) |
1550
+ (use_hidpp ? BIT(0) : 0);
1551
+
1552
+ return hidpp_send_fap_command_sync(hidpp, feature_index,
1553
+ CMD_HIRES_WHEEL_SET_WHEEL_MODE,
1554
+ params, sizeof(params), &response);
11531555 }
11541556
11551557 /* -------------------------------------------------------------------------- */
....@@ -1455,6 +1857,7 @@
14551857
14561858 #define HIDPP_FF_EFFECTID_NONE -1
14571859 #define HIDPP_FF_EFFECTID_AUTOCENTER -2
1860
+#define HIDPP_AUTOCENTER_PARAMS_LENGTH 18
14581861
14591862 #define HIDPP_FF_MAX_PARAMS 20
14601863 #define HIDPP_FF_RESERVED_SLOTS 1
....@@ -1481,7 +1884,7 @@
14811884 u8 size;
14821885 };
14831886
1484
-static const signed short hiddpp_ff_effects[] = {
1887
+static const signed short hidpp_ff_effects[] = {
14851888 FF_CONSTANT,
14861889 FF_PERIODIC,
14871890 FF_SINE,
....@@ -1496,7 +1899,7 @@
14961899 -1
14971900 };
14981901
1499
-static const signed short hiddpp_ff_effects_v2[] = {
1902
+static const signed short hidpp_ff_effects_v2[] = {
15001903 FF_RAMP,
15011904 FF_FRICTION,
15021905 FF_INERTIA,
....@@ -1795,7 +2198,7 @@
17952198 static void hidpp_ff_set_autocenter(struct input_dev *dev, u16 magnitude)
17962199 {
17972200 struct hidpp_ff_private_data *data = dev->ff->private;
1798
- u8 params[18];
2201
+ u8 params[HIDPP_AUTOCENTER_PARAMS_LENGTH];
17992202
18002203 dbg_hid("Setting autocenter to %d.\n", magnitude);
18012204
....@@ -1863,11 +2266,17 @@
18632266 static void hidpp_ff_destroy(struct ff_device *ff)
18642267 {
18652268 struct hidpp_ff_private_data *data = ff->private;
2269
+ struct hid_device *hid = data->hidpp->hid_dev;
18662270
2271
+ hid_info(hid, "Unloading HID++ force feedback.\n");
2272
+
2273
+ device_remove_file(&hid->dev, &dev_attr_range);
2274
+ destroy_workqueue(data->wq);
18672275 kfree(data->effect_ids);
18682276 }
18692277
1870
-static int hidpp_ff_init(struct hidpp_device *hidpp, u8 feature_index)
2278
+static int hidpp_ff_init(struct hidpp_device *hidpp,
2279
+ struct hidpp_ff_private_data *data)
18712280 {
18722281 struct hid_device *hid = hidpp->hid_dev;
18732282 struct hid_input *hidinput;
....@@ -1875,9 +2284,7 @@
18752284 const struct usb_device_descriptor *udesc = &(hid_to_usb_dev(hid)->descriptor);
18762285 const u16 bcdDevice = le16_to_cpu(udesc->bcdDevice);
18772286 struct ff_device *ff;
1878
- struct hidpp_report response;
1879
- struct hidpp_ff_private_data *data;
1880
- int error, j, num_slots;
2287
+ int error, j, num_slots = data->num_effects;
18812288 u8 version;
18822289
18832290 if (list_empty(&hid->inputs)) {
....@@ -1896,24 +2303,11 @@
18962303 version = bcdDevice & 255;
18972304
18982305 /* Set supported force feedback capabilities */
1899
- for (j = 0; hiddpp_ff_effects[j] >= 0; j++)
1900
- set_bit(hiddpp_ff_effects[j], dev->ffbit);
2306
+ for (j = 0; hidpp_ff_effects[j] >= 0; j++)
2307
+ set_bit(hidpp_ff_effects[j], dev->ffbit);
19012308 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;
2309
+ for (j = 0; hidpp_ff_effects_v2[j] >= 0; j++)
2310
+ set_bit(hidpp_ff_effects_v2[j], dev->ffbit);
19172311
19182312 error = input_ff_create(dev, num_slots);
19192313
....@@ -1921,8 +2315,11 @@
19212315 hid_err(dev, "Failed to create FF device!\n");
19222316 return error;
19232317 }
1924
-
1925
- data = kzalloc(sizeof(*data), GFP_KERNEL);
2318
+ /*
2319
+ * Create a copy of passed data, so we can transfer memory
2320
+ * ownership to FF core
2321
+ */
2322
+ data = kmemdup(data, sizeof(*data), GFP_KERNEL);
19262323 if (!data)
19272324 return -ENOMEM;
19282325 data->effect_ids = kcalloc(num_slots, sizeof(int), GFP_KERNEL);
....@@ -1938,10 +2335,7 @@
19382335 }
19392336
19402337 data->hidpp = hidpp;
1941
- data->feature_index = feature_index;
19422338 data->version = version;
1943
- data->slot_autocenter = 0;
1944
- data->num_effects = num_slots;
19452339 for (j = 0; j < num_slots; j++)
19462340 data->effect_ids[j] = -1;
19472341
....@@ -1955,67 +2349,19 @@
19552349 ff->set_autocenter = hidpp_ff_set_autocenter;
19562350 ff->destroy = hidpp_ff_destroy;
19572351
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
-
19702352 /* Create sysfs interface */
19712353 error = device_create_file(&(hidpp->hid_dev->dev), &dev_attr_range);
19722354 if (error)
19732355 hid_warn(hidpp->hid_dev, "Unable to create sysfs interface for \"range\", errno %d!\n", error);
19742356
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
-
19832357 /* init the hardware command queue */
19842358 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);
19882359
19892360 hid_info(hid, "Force feedback support loaded (firmware release %d).\n",
19902361 version);
19912362
19922363 return 0;
19932364 }
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
-
20192365
20202366 /* ************************************************************************** */
20212367 /* */
....@@ -2030,7 +2376,6 @@
20302376 #define WTP_MANUAL_RESOLUTION 39
20312377
20322378 struct wtp_data {
2033
- struct input_dev *input;
20342379 u16 x_size, y_size;
20352380 u8 finger_count;
20362381 u8 mt_feature_index;
....@@ -2048,7 +2393,7 @@
20482393 }
20492394
20502395 static void wtp_populate_input(struct hidpp_device *hidpp,
2051
- struct input_dev *input_dev, bool origin_is_hid_core)
2396
+ struct input_dev *input_dev)
20522397 {
20532398 struct wtp_data *wd = hidpp->private_data;
20542399
....@@ -2074,31 +2419,30 @@
20742419
20752420 input_mt_init_slots(input_dev, wd->maxcontacts, INPUT_MT_POINTER |
20762421 INPUT_MT_DROP_UNUSED);
2077
-
2078
- wd->input = input_dev;
20792422 }
20802423
2081
-static void wtp_touch_event(struct wtp_data *wd,
2424
+static void wtp_touch_event(struct hidpp_device *hidpp,
20822425 struct hidpp_touchpad_raw_xy_finger *touch_report)
20832426 {
2427
+ struct wtp_data *wd = hidpp->private_data;
20842428 int slot;
20852429
20862430 if (!touch_report->finger_id || touch_report->contact_type)
20872431 /* no actual data */
20882432 return;
20892433
2090
- slot = input_mt_get_slot_by_key(wd->input, touch_report->finger_id);
2434
+ slot = input_mt_get_slot_by_key(hidpp->input, touch_report->finger_id);
20912435
2092
- input_mt_slot(wd->input, slot);
2093
- input_mt_report_slot_state(wd->input, MT_TOOL_FINGER,
2436
+ input_mt_slot(hidpp->input, slot);
2437
+ input_mt_report_slot_state(hidpp->input, MT_TOOL_FINGER,
20942438 touch_report->contact_status);
20952439 if (touch_report->contact_status) {
2096
- input_event(wd->input, EV_ABS, ABS_MT_POSITION_X,
2440
+ input_event(hidpp->input, EV_ABS, ABS_MT_POSITION_X,
20972441 touch_report->x);
2098
- input_event(wd->input, EV_ABS, ABS_MT_POSITION_Y,
2442
+ input_event(hidpp->input, EV_ABS, ABS_MT_POSITION_Y,
20992443 wd->flip_y ? wd->y_size - touch_report->y :
21002444 touch_report->y);
2101
- input_event(wd->input, EV_ABS, ABS_MT_PRESSURE,
2445
+ input_event(hidpp->input, EV_ABS, ABS_MT_PRESSURE,
21022446 touch_report->area);
21032447 }
21042448 }
....@@ -2106,19 +2450,18 @@
21062450 static void wtp_send_raw_xy_event(struct hidpp_device *hidpp,
21072451 struct hidpp_touchpad_raw_xy *raw)
21082452 {
2109
- struct wtp_data *wd = hidpp->private_data;
21102453 int i;
21112454
21122455 for (i = 0; i < 2; i++)
2113
- wtp_touch_event(wd, &(raw->fingers[i]));
2456
+ wtp_touch_event(hidpp, &(raw->fingers[i]));
21142457
21152458 if (raw->end_of_frame &&
21162459 !(hidpp->quirks & HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS))
2117
- input_event(wd->input, EV_KEY, BTN_LEFT, raw->button);
2460
+ input_event(hidpp->input, EV_KEY, BTN_LEFT, raw->button);
21182461
21192462 if (raw->end_of_frame || raw->finger_count <= 2) {
2120
- input_mt_sync_frame(wd->input);
2121
- input_sync(wd->input);
2463
+ input_mt_sync_frame(hidpp->input);
2464
+ input_sync(hidpp->input);
21222465 }
21232466 }
21242467
....@@ -2168,7 +2511,7 @@
21682511 struct hidpp_report *report = (struct hidpp_report *)data;
21692512 struct hidpp_touchpad_raw_xy raw;
21702513
2171
- if (!wd || !wd->input)
2514
+ if (!wd || !hidpp->input)
21722515 return 1;
21732516
21742517 switch (data[0]) {
....@@ -2179,11 +2522,11 @@
21792522 return 1;
21802523 }
21812524 if (hidpp->quirks & HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS) {
2182
- input_event(wd->input, EV_KEY, BTN_LEFT,
2525
+ input_event(hidpp->input, EV_KEY, BTN_LEFT,
21832526 !!(data[1] & 0x01));
2184
- input_event(wd->input, EV_KEY, BTN_RIGHT,
2527
+ input_event(hidpp->input, EV_KEY, BTN_RIGHT,
21852528 !!(data[1] & 0x02));
2186
- input_sync(wd->input);
2529
+ input_sync(hidpp->input);
21872530 return 0;
21882531 } else {
21892532 if (size < 21)
....@@ -2301,10 +2644,6 @@
23012644
23022645 static const u8 m560_config_parameter[] = {0x00, 0xaf, 0x03};
23032646
2304
-struct m560_private_data {
2305
- struct input_dev *input;
2306
-};
2307
-
23082647 /* how buttons are mapped in the report */
23092648 #define M560_MOUSE_BTN_LEFT 0x01
23102649 #define M560_MOUSE_BTN_RIGHT 0x02
....@@ -2332,28 +2671,12 @@
23322671 );
23332672 }
23342673
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
-
23502674 static int m560_raw_event(struct hid_device *hdev, u8 *data, int size)
23512675 {
23522676 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
2353
- struct m560_private_data *mydata = hidpp->private_data;
23542677
23552678 /* sanity check */
2356
- if (!mydata || !mydata->input) {
2679
+ if (!hidpp->input) {
23572680 hid_err(hdev, "error in parameter\n");
23582681 return -EINVAL;
23592682 }
....@@ -2380,24 +2703,24 @@
23802703
23812704 switch (data[5]) {
23822705 case 0xaf:
2383
- input_report_key(mydata->input, BTN_MIDDLE, 1);
2706
+ input_report_key(hidpp->input, BTN_MIDDLE, 1);
23842707 break;
23852708 case 0xb0:
2386
- input_report_key(mydata->input, BTN_FORWARD, 1);
2709
+ input_report_key(hidpp->input, BTN_FORWARD, 1);
23872710 break;
23882711 case 0xae:
2389
- input_report_key(mydata->input, BTN_BACK, 1);
2712
+ input_report_key(hidpp->input, BTN_BACK, 1);
23902713 break;
23912714 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);
2715
+ input_report_key(hidpp->input, BTN_BACK, 0);
2716
+ input_report_key(hidpp->input, BTN_FORWARD, 0);
2717
+ input_report_key(hidpp->input, BTN_MIDDLE, 0);
23952718 break;
23962719 default:
23972720 hid_err(hdev, "error in report\n");
23982721 return 0;
23992722 }
2400
- input_sync(mydata->input);
2723
+ input_sync(hidpp->input);
24012724
24022725 } else if (data[0] == 0x02) {
24032726 /*
....@@ -2411,50 +2734,55 @@
24112734
24122735 int v;
24132736
2414
- input_report_key(mydata->input, BTN_LEFT,
2737
+ input_report_key(hidpp->input, BTN_LEFT,
24152738 !!(data[1] & M560_MOUSE_BTN_LEFT));
2416
- input_report_key(mydata->input, BTN_RIGHT,
2739
+ input_report_key(hidpp->input, BTN_RIGHT,
24172740 !!(data[1] & M560_MOUSE_BTN_RIGHT));
24182741
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);
2742
+ if (data[1] & M560_MOUSE_BTN_WHEEL_LEFT) {
2743
+ input_report_rel(hidpp->input, REL_HWHEEL, -1);
2744
+ input_report_rel(hidpp->input, REL_HWHEEL_HI_RES,
2745
+ -120);
2746
+ } else if (data[1] & M560_MOUSE_BTN_WHEEL_RIGHT) {
2747
+ input_report_rel(hidpp->input, REL_HWHEEL, 1);
2748
+ input_report_rel(hidpp->input, REL_HWHEEL_HI_RES,
2749
+ 120);
2750
+ }
24232751
24242752 v = hid_snto32(hid_field_extract(hdev, data+3, 0, 12), 12);
2425
- input_report_rel(mydata->input, REL_X, v);
2753
+ input_report_rel(hidpp->input, REL_X, v);
24262754
24272755 v = hid_snto32(hid_field_extract(hdev, data+3, 12, 12), 12);
2428
- input_report_rel(mydata->input, REL_Y, v);
2756
+ input_report_rel(hidpp->input, REL_Y, v);
24292757
24302758 v = hid_snto32(data[6], 8);
2431
- input_report_rel(mydata->input, REL_WHEEL, v);
2759
+ if (v != 0)
2760
+ hidpp_scroll_counter_handle_scroll(hidpp->input,
2761
+ &hidpp->vertical_wheel_counter, v);
24322762
2433
- input_sync(mydata->input);
2763
+ input_sync(hidpp->input);
24342764 }
24352765
24362766 return 1;
24372767 }
24382768
24392769 static void m560_populate_input(struct hidpp_device *hidpp,
2440
- struct input_dev *input_dev, bool origin_is_hid_core)
2770
+ struct input_dev *input_dev)
24412771 {
2442
- struct m560_private_data *mydata = hidpp->private_data;
2772
+ __set_bit(EV_KEY, input_dev->evbit);
2773
+ __set_bit(BTN_MIDDLE, input_dev->keybit);
2774
+ __set_bit(BTN_RIGHT, input_dev->keybit);
2775
+ __set_bit(BTN_LEFT, input_dev->keybit);
2776
+ __set_bit(BTN_BACK, input_dev->keybit);
2777
+ __set_bit(BTN_FORWARD, input_dev->keybit);
24432778
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);
2779
+ __set_bit(EV_REL, input_dev->evbit);
2780
+ __set_bit(REL_X, input_dev->relbit);
2781
+ __set_bit(REL_Y, input_dev->relbit);
2782
+ __set_bit(REL_WHEEL, input_dev->relbit);
2783
+ __set_bit(REL_HWHEEL, input_dev->relbit);
2784
+ __set_bit(REL_WHEEL_HI_RES, input_dev->relbit);
2785
+ __set_bit(REL_HWHEEL_HI_RES, input_dev->relbit);
24582786 }
24592787
24602788 static int m560_input_mapping(struct hid_device *hdev, struct hid_input *hi,
....@@ -2536,23 +2864,312 @@
25362864
25372865 #define HIDPP_PAGE_G920_FORCE_FEEDBACK 0x8123
25382866
2539
-static int g920_get_config(struct hidpp_device *hidpp)
2867
+static int g920_ff_set_autocenter(struct hidpp_device *hidpp,
2868
+ struct hidpp_ff_private_data *data)
25402869 {
2541
- u8 feature_type;
2542
- u8 feature_index;
2870
+ struct hidpp_report response;
2871
+ u8 params[HIDPP_AUTOCENTER_PARAMS_LENGTH] = {
2872
+ [1] = HIDPP_FF_EFFECT_SPRING | HIDPP_FF_EFFECT_AUTOSTART,
2873
+ };
25432874 int ret;
2875
+
2876
+ /* initialize with zero autocenter to get wheel in usable state */
2877
+
2878
+ dbg_hid("Setting autocenter to 0.\n");
2879
+ ret = hidpp_send_fap_command_sync(hidpp, data->feature_index,
2880
+ HIDPP_FF_DOWNLOAD_EFFECT,
2881
+ params, ARRAY_SIZE(params),
2882
+ &response);
2883
+ if (ret)
2884
+ hid_warn(hidpp->hid_dev, "Failed to autocenter device!\n");
2885
+ else
2886
+ data->slot_autocenter = response.fap.params[0];
2887
+
2888
+ return ret;
2889
+}
2890
+
2891
+static int g920_get_config(struct hidpp_device *hidpp,
2892
+ struct hidpp_ff_private_data *data)
2893
+{
2894
+ struct hidpp_report response;
2895
+ u8 feature_type;
2896
+ int ret;
2897
+
2898
+ memset(data, 0, sizeof(*data));
25442899
25452900 /* Find feature and store for later use */
25462901 ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_G920_FORCE_FEEDBACK,
2547
- &feature_index, &feature_type);
2902
+ &data->feature_index, &feature_type);
25482903 if (ret)
25492904 return ret;
25502905
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);
2906
+ /* Read number of slots available in device */
2907
+ ret = hidpp_send_fap_command_sync(hidpp, data->feature_index,
2908
+ HIDPP_FF_GET_INFO,
2909
+ NULL, 0,
2910
+ &response);
2911
+ if (ret) {
2912
+ if (ret < 0)
2913
+ return ret;
2914
+ hid_err(hidpp->hid_dev,
2915
+ "%s: received protocol error 0x%02x\n", __func__, ret);
2916
+ return -EPROTO;
2917
+ }
25552918
2919
+ data->num_effects = response.fap.params[0] - HIDPP_FF_RESERVED_SLOTS;
2920
+
2921
+ /* reset all forces */
2922
+ ret = hidpp_send_fap_command_sync(hidpp, data->feature_index,
2923
+ HIDPP_FF_RESET_ALL,
2924
+ NULL, 0,
2925
+ &response);
2926
+ if (ret)
2927
+ hid_warn(hidpp->hid_dev, "Failed to reset all forces!\n");
2928
+
2929
+ ret = hidpp_send_fap_command_sync(hidpp, data->feature_index,
2930
+ HIDPP_FF_GET_APERTURE,
2931
+ NULL, 0,
2932
+ &response);
2933
+ if (ret) {
2934
+ hid_warn(hidpp->hid_dev,
2935
+ "Failed to read range from device!\n");
2936
+ }
2937
+ data->range = ret ?
2938
+ 900 : get_unaligned_be16(&response.fap.params[0]);
2939
+
2940
+ /* Read the current gain values */
2941
+ ret = hidpp_send_fap_command_sync(hidpp, data->feature_index,
2942
+ HIDPP_FF_GET_GLOBAL_GAINS,
2943
+ NULL, 0,
2944
+ &response);
2945
+ if (ret)
2946
+ hid_warn(hidpp->hid_dev,
2947
+ "Failed to read gain values from device!\n");
2948
+ data->gain = ret ?
2949
+ 0xffff : get_unaligned_be16(&response.fap.params[0]);
2950
+
2951
+ /* ignore boost value at response.fap.params[2] */
2952
+
2953
+ return g920_ff_set_autocenter(hidpp, data);
2954
+}
2955
+
2956
+/* -------------------------------------------------------------------------- */
2957
+/* Logitech Dinovo Mini keyboard with builtin touchpad */
2958
+/* -------------------------------------------------------------------------- */
2959
+#define DINOVO_MINI_PRODUCT_ID 0xb30c
2960
+
2961
+static int lg_dinovo_input_mapping(struct hid_device *hdev, struct hid_input *hi,
2962
+ struct hid_field *field, struct hid_usage *usage,
2963
+ unsigned long **bit, int *max)
2964
+{
2965
+ if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR)
2966
+ return 0;
2967
+
2968
+ switch (usage->hid & HID_USAGE) {
2969
+ case 0x00d: lg_map_key_clear(KEY_MEDIA); break;
2970
+ default:
2971
+ return 0;
2972
+ }
2973
+ return 1;
2974
+}
2975
+
2976
+/* -------------------------------------------------------------------------- */
2977
+/* HID++1.0 devices which use HID++ reports for their wheels */
2978
+/* -------------------------------------------------------------------------- */
2979
+static int hidpp10_wheel_connect(struct hidpp_device *hidpp)
2980
+{
2981
+ return hidpp10_set_register(hidpp, HIDPP_REG_ENABLE_REPORTS, 0,
2982
+ HIDPP_ENABLE_WHEEL_REPORT | HIDPP_ENABLE_HWHEEL_REPORT,
2983
+ HIDPP_ENABLE_WHEEL_REPORT | HIDPP_ENABLE_HWHEEL_REPORT);
2984
+}
2985
+
2986
+static int hidpp10_wheel_raw_event(struct hidpp_device *hidpp,
2987
+ u8 *data, int size)
2988
+{
2989
+ s8 value, hvalue;
2990
+
2991
+ if (!hidpp->input)
2992
+ return -EINVAL;
2993
+
2994
+ if (size < 7)
2995
+ return 0;
2996
+
2997
+ if (data[0] != REPORT_ID_HIDPP_SHORT || data[2] != HIDPP_SUB_ID_ROLLER)
2998
+ return 0;
2999
+
3000
+ value = data[3];
3001
+ hvalue = data[4];
3002
+
3003
+ input_report_rel(hidpp->input, REL_WHEEL, value);
3004
+ input_report_rel(hidpp->input, REL_WHEEL_HI_RES, value * 120);
3005
+ input_report_rel(hidpp->input, REL_HWHEEL, hvalue);
3006
+ input_report_rel(hidpp->input, REL_HWHEEL_HI_RES, hvalue * 120);
3007
+ input_sync(hidpp->input);
3008
+
3009
+ return 1;
3010
+}
3011
+
3012
+static void hidpp10_wheel_populate_input(struct hidpp_device *hidpp,
3013
+ struct input_dev *input_dev)
3014
+{
3015
+ __set_bit(EV_REL, input_dev->evbit);
3016
+ __set_bit(REL_WHEEL, input_dev->relbit);
3017
+ __set_bit(REL_WHEEL_HI_RES, input_dev->relbit);
3018
+ __set_bit(REL_HWHEEL, input_dev->relbit);
3019
+ __set_bit(REL_HWHEEL_HI_RES, input_dev->relbit);
3020
+}
3021
+
3022
+/* -------------------------------------------------------------------------- */
3023
+/* HID++1.0 mice which use HID++ reports for extra mouse buttons */
3024
+/* -------------------------------------------------------------------------- */
3025
+static int hidpp10_extra_mouse_buttons_connect(struct hidpp_device *hidpp)
3026
+{
3027
+ return hidpp10_set_register(hidpp, HIDPP_REG_ENABLE_REPORTS, 0,
3028
+ HIDPP_ENABLE_MOUSE_EXTRA_BTN_REPORT,
3029
+ HIDPP_ENABLE_MOUSE_EXTRA_BTN_REPORT);
3030
+}
3031
+
3032
+static int hidpp10_extra_mouse_buttons_raw_event(struct hidpp_device *hidpp,
3033
+ u8 *data, int size)
3034
+{
3035
+ int i;
3036
+
3037
+ if (!hidpp->input)
3038
+ return -EINVAL;
3039
+
3040
+ if (size < 7)
3041
+ return 0;
3042
+
3043
+ if (data[0] != REPORT_ID_HIDPP_SHORT ||
3044
+ data[2] != HIDPP_SUB_ID_MOUSE_EXTRA_BTNS)
3045
+ return 0;
3046
+
3047
+ /*
3048
+ * Buttons are either delivered through the regular mouse report *or*
3049
+ * through the extra buttons report. At least for button 6 how it is
3050
+ * delivered differs per receiver firmware version. Even receivers with
3051
+ * the same usb-id show different behavior, so we handle both cases.
3052
+ */
3053
+ for (i = 0; i < 8; i++)
3054
+ input_report_key(hidpp->input, BTN_MOUSE + i,
3055
+ (data[3] & (1 << i)));
3056
+
3057
+ /* Some mice report events on button 9+, use BTN_MISC */
3058
+ for (i = 0; i < 8; i++)
3059
+ input_report_key(hidpp->input, BTN_MISC + i,
3060
+ (data[4] & (1 << i)));
3061
+
3062
+ input_sync(hidpp->input);
3063
+ return 1;
3064
+}
3065
+
3066
+static void hidpp10_extra_mouse_buttons_populate_input(
3067
+ struct hidpp_device *hidpp, struct input_dev *input_dev)
3068
+{
3069
+ /* BTN_MOUSE - BTN_MOUSE+7 are set already by the descriptor */
3070
+ __set_bit(BTN_0, input_dev->keybit);
3071
+ __set_bit(BTN_1, input_dev->keybit);
3072
+ __set_bit(BTN_2, input_dev->keybit);
3073
+ __set_bit(BTN_3, input_dev->keybit);
3074
+ __set_bit(BTN_4, input_dev->keybit);
3075
+ __set_bit(BTN_5, input_dev->keybit);
3076
+ __set_bit(BTN_6, input_dev->keybit);
3077
+ __set_bit(BTN_7, input_dev->keybit);
3078
+}
3079
+
3080
+/* -------------------------------------------------------------------------- */
3081
+/* HID++1.0 kbds which only report 0x10xx consumer usages through sub-id 0x03 */
3082
+/* -------------------------------------------------------------------------- */
3083
+
3084
+/* Find the consumer-page input report desc and change Maximums to 0x107f */
3085
+static u8 *hidpp10_consumer_keys_report_fixup(struct hidpp_device *hidpp,
3086
+ u8 *_rdesc, unsigned int *rsize)
3087
+{
3088
+ /* Note 0 terminated so we can use strnstr to search for this. */
3089
+ static const char consumer_rdesc_start[] = {
3090
+ 0x05, 0x0C, /* USAGE_PAGE (Consumer Devices) */
3091
+ 0x09, 0x01, /* USAGE (Consumer Control) */
3092
+ 0xA1, 0x01, /* COLLECTION (Application) */
3093
+ 0x85, 0x03, /* REPORT_ID = 3 */
3094
+ 0x75, 0x10, /* REPORT_SIZE (16) */
3095
+ 0x95, 0x02, /* REPORT_COUNT (2) */
3096
+ 0x15, 0x01, /* LOGICAL_MIN (1) */
3097
+ 0x26, 0x00 /* LOGICAL_MAX (... */
3098
+ };
3099
+ char *consumer_rdesc, *rdesc = (char *)_rdesc;
3100
+ unsigned int size;
3101
+
3102
+ consumer_rdesc = strnstr(rdesc, consumer_rdesc_start, *rsize);
3103
+ size = *rsize - (consumer_rdesc - rdesc);
3104
+ if (consumer_rdesc && size >= 25) {
3105
+ consumer_rdesc[15] = 0x7f;
3106
+ consumer_rdesc[16] = 0x10;
3107
+ consumer_rdesc[20] = 0x7f;
3108
+ consumer_rdesc[21] = 0x10;
3109
+ }
3110
+ return _rdesc;
3111
+}
3112
+
3113
+static int hidpp10_consumer_keys_connect(struct hidpp_device *hidpp)
3114
+{
3115
+ return hidpp10_set_register(hidpp, HIDPP_REG_ENABLE_REPORTS, 0,
3116
+ HIDPP_ENABLE_CONSUMER_REPORT,
3117
+ HIDPP_ENABLE_CONSUMER_REPORT);
3118
+}
3119
+
3120
+static int hidpp10_consumer_keys_raw_event(struct hidpp_device *hidpp,
3121
+ u8 *data, int size)
3122
+{
3123
+ u8 consumer_report[5];
3124
+
3125
+ if (size < 7)
3126
+ return 0;
3127
+
3128
+ if (data[0] != REPORT_ID_HIDPP_SHORT ||
3129
+ data[2] != HIDPP_SUB_ID_CONSUMER_VENDOR_KEYS)
3130
+ return 0;
3131
+
3132
+ /*
3133
+ * Build a normal consumer report (3) out of the data, this detour
3134
+ * is necessary to get some keyboards to report their 0x10xx usages.
3135
+ */
3136
+ consumer_report[0] = 0x03;
3137
+ memcpy(&consumer_report[1], &data[3], 4);
3138
+ /* We are called from atomic context */
3139
+ hid_report_raw_event(hidpp->hid_dev, HID_INPUT_REPORT,
3140
+ consumer_report, 5, 1);
3141
+
3142
+ return 1;
3143
+}
3144
+
3145
+/* -------------------------------------------------------------------------- */
3146
+/* High-resolution scroll wheels */
3147
+/* -------------------------------------------------------------------------- */
3148
+
3149
+static int hi_res_scroll_enable(struct hidpp_device *hidpp)
3150
+{
3151
+ int ret;
3152
+ u8 multiplier = 1;
3153
+
3154
+ if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL_X2121) {
3155
+ ret = hidpp_hrw_set_wheel_mode(hidpp, false, true, false);
3156
+ if (ret == 0)
3157
+ ret = hidpp_hrw_get_wheel_capability(hidpp, &multiplier);
3158
+ } else if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL_X2120) {
3159
+ ret = hidpp_hrs_set_highres_scrolling_mode(hidpp, true,
3160
+ &multiplier);
3161
+ } else /* if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL_1P0) */ {
3162
+ ret = hidpp10_enable_scrolling_acceleration(hidpp);
3163
+ multiplier = 8;
3164
+ }
3165
+ if (ret)
3166
+ return ret;
3167
+
3168
+ if (multiplier == 0)
3169
+ multiplier = 1;
3170
+
3171
+ hidpp->vertical_wheel_counter.wheel_multiplier = multiplier;
3172
+ hid_dbg(hidpp->hid_dev, "wheel multiplier = %d\n", multiplier);
25563173 return 0;
25573174 }
25583175
....@@ -2560,17 +3177,39 @@
25603177 /* Generic HID++ devices */
25613178 /* -------------------------------------------------------------------------- */
25623179
3180
+static u8 *hidpp_report_fixup(struct hid_device *hdev, u8 *rdesc,
3181
+ unsigned int *rsize)
3182
+{
3183
+ struct hidpp_device *hidpp = hid_get_drvdata(hdev);
3184
+
3185
+ if (!hidpp)
3186
+ return rdesc;
3187
+
3188
+ /* For 27 MHz keyboards the quirk gets set after hid_parse. */
3189
+ if (hdev->group == HID_GROUP_LOGITECH_27MHZ_DEVICE ||
3190
+ (hidpp->quirks & HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS))
3191
+ rdesc = hidpp10_consumer_keys_report_fixup(hidpp, rdesc, rsize);
3192
+
3193
+ return rdesc;
3194
+}
3195
+
25633196 static int hidpp_input_mapping(struct hid_device *hdev, struct hid_input *hi,
25643197 struct hid_field *field, struct hid_usage *usage,
25653198 unsigned long **bit, int *max)
25663199 {
25673200 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
25683201
3202
+ if (!hidpp)
3203
+ return 0;
3204
+
25693205 if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)
25703206 return wtp_input_mapping(hdev, hi, field, usage, bit, max);
25713207 else if (hidpp->quirks & HIDPP_QUIRK_CLASS_M560 &&
25723208 field->application != HID_GD_MOUSE)
25733209 return m560_input_mapping(hdev, hi, field, usage, bit, max);
3210
+
3211
+ if (hdev->product == DINOVO_MINI_PRODUCT_ID)
3212
+ return lg_dinovo_input_mapping(hdev, hi, field, usage, bit, max);
25743213
25753214 return 0;
25763215 }
....@@ -2580,6 +3219,9 @@
25803219 unsigned long **bit, int *max)
25813220 {
25823221 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
3222
+
3223
+ if (!hidpp)
3224
+ return 0;
25833225
25843226 /* Ensure that Logitech G920 is not given a default fuzz/flat value */
25853227 if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) {
....@@ -2595,12 +3237,20 @@
25953237
25963238
25973239 static void hidpp_populate_input(struct hidpp_device *hidpp,
2598
- struct input_dev *input, bool origin_is_hid_core)
3240
+ struct input_dev *input)
25993241 {
3242
+ hidpp->input = input;
3243
+
26003244 if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)
2601
- wtp_populate_input(hidpp, input, origin_is_hid_core);
3245
+ wtp_populate_input(hidpp, input);
26023246 else if (hidpp->quirks & HIDPP_QUIRK_CLASS_M560)
2603
- m560_populate_input(hidpp, input, origin_is_hid_core);
3247
+ m560_populate_input(hidpp, input);
3248
+
3249
+ if (hidpp->quirks & HIDPP_QUIRK_HIDPP_WHEELS)
3250
+ hidpp10_wheel_populate_input(hidpp, input);
3251
+
3252
+ if (hidpp->quirks & HIDPP_QUIRK_HIDPP_EXTRA_MOUSE_BTNS)
3253
+ hidpp10_extra_mouse_buttons_populate_input(hidpp, input);
26043254 }
26053255
26063256 static int hidpp_input_configured(struct hid_device *hdev,
....@@ -2609,7 +3259,10 @@
26093259 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
26103260 struct input_dev *input = hidinput->input;
26113261
2612
- hidpp_populate_input(hidpp, input, true);
3262
+ if (!hidpp)
3263
+ return 0;
3264
+
3265
+ hidpp_populate_input(hidpp, input);
26133266
26143267 return 0;
26153268 }
....@@ -2646,7 +3299,7 @@
26463299 }
26473300 }
26483301
2649
- if (unlikely(hidpp_report_is_connect_event(report))) {
3302
+ if (unlikely(hidpp_report_is_connect_event(hidpp, report))) {
26503303 atomic_set(&hidpp->connected,
26513304 !(report->rap.params[0] & (1 << 6)));
26523305 if (schedule_work(&hidpp->work) == 0)
....@@ -2661,10 +3314,31 @@
26613314 ret = hidpp_solar_battery_event(hidpp, data, size);
26623315 if (ret != 0)
26633316 return ret;
3317
+ ret = hidpp20_battery_voltage_event(hidpp, data, size);
3318
+ if (ret != 0)
3319
+ return ret;
26643320 }
26653321
26663322 if (hidpp->capabilities & HIDPP_CAPABILITY_HIDPP10_BATTERY) {
26673323 ret = hidpp10_battery_event(hidpp, data, size);
3324
+ if (ret != 0)
3325
+ return ret;
3326
+ }
3327
+
3328
+ if (hidpp->quirks & HIDPP_QUIRK_HIDPP_WHEELS) {
3329
+ ret = hidpp10_wheel_raw_event(hidpp, data, size);
3330
+ if (ret != 0)
3331
+ return ret;
3332
+ }
3333
+
3334
+ if (hidpp->quirks & HIDPP_QUIRK_HIDPP_EXTRA_MOUSE_BTNS) {
3335
+ ret = hidpp10_extra_mouse_buttons_raw_event(hidpp, data, size);
3336
+ if (ret != 0)
3337
+ return ret;
3338
+ }
3339
+
3340
+ if (hidpp->quirks & HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS) {
3341
+ ret = hidpp10_consumer_keys_raw_event(hidpp, data, size);
26683342 if (ret != 0)
26693343 return ret;
26703344 }
....@@ -2678,10 +3352,13 @@
26783352 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
26793353 int ret = 0;
26803354
3355
+ if (!hidpp)
3356
+ return 0;
3357
+
26813358 /* Generic HID++ processing. */
26823359 switch (data[0]) {
26833360 case REPORT_ID_HIDPP_VERY_LONG:
2684
- if (size != HIDPP_REPORT_VERY_LONG_LENGTH) {
3361
+ if (size != hidpp->very_long_report_length) {
26853362 hid_err(hdev, "received hid++ report of bad size (%d)",
26863363 size);
26873364 return 1;
....@@ -2719,6 +3396,32 @@
27193396 return 0;
27203397 }
27213398
3399
+static int hidpp_event(struct hid_device *hdev, struct hid_field *field,
3400
+ struct hid_usage *usage, __s32 value)
3401
+{
3402
+ /* This function will only be called for scroll events, due to the
3403
+ * restriction imposed in hidpp_usages.
3404
+ */
3405
+ struct hidpp_device *hidpp = hid_get_drvdata(hdev);
3406
+ struct hidpp_scroll_counter *counter;
3407
+
3408
+ if (!hidpp)
3409
+ return 0;
3410
+
3411
+ counter = &hidpp->vertical_wheel_counter;
3412
+ /* A scroll event may occur before the multiplier has been retrieved or
3413
+ * the input device set, or high-res scroll enabling may fail. In such
3414
+ * cases we must return early (falling back to default behaviour) to
3415
+ * avoid a crash in hidpp_scroll_counter_handle_scroll.
3416
+ */
3417
+ if (!(hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL) || value == 0
3418
+ || hidpp->input == NULL || counter->wheel_multiplier == 0)
3419
+ return 0;
3420
+
3421
+ hidpp_scroll_counter_handle_scroll(hidpp->input, counter, value);
3422
+ return 1;
3423
+}
3424
+
27223425 static int hidpp_initialize_battery(struct hidpp_device *hidpp)
27233426 {
27243427 static atomic_t battery_no = ATOMIC_INIT(0);
....@@ -2735,12 +3438,16 @@
27353438
27363439 hidpp->battery.feature_index = 0xff;
27373440 hidpp->battery.solar_feature_index = 0xff;
3441
+ hidpp->battery.voltage_feature_index = 0xff;
27383442
27393443 if (hidpp->protocol_major >= 2) {
27403444 if (hidpp->quirks & HIDPP_QUIRK_CLASS_K750)
27413445 ret = hidpp_solar_request_battery_event(hidpp);
2742
- else
2743
- ret = hidpp20_query_battery_info(hidpp);
3446
+ else {
3447
+ ret = hidpp20_query_battery_voltage_info(hidpp);
3448
+ if (ret)
3449
+ ret = hidpp20_query_battery_info(hidpp);
3450
+ }
27443451
27453452 if (ret)
27463453 return ret;
....@@ -2765,7 +3472,7 @@
27653472 if (!battery_props)
27663473 return -ENOMEM;
27673474
2768
- num_battery_props = ARRAY_SIZE(hidpp_battery_props) - 2;
3475
+ num_battery_props = ARRAY_SIZE(hidpp_battery_props) - 3;
27693476
27703477 if (hidpp->capabilities & HIDPP_CAPABILITY_BATTERY_MILEAGE)
27713478 battery_props[num_battery_props++] =
....@@ -2774,6 +3481,10 @@
27743481 if (hidpp->capabilities & HIDPP_CAPABILITY_BATTERY_LEVEL_STATUS)
27753482 battery_props[num_battery_props++] =
27763483 POWER_SUPPLY_PROP_CAPACITY_LEVEL;
3484
+
3485
+ if (hidpp->capabilities & HIDPP_CAPABILITY_BATTERY_VOLTAGE)
3486
+ battery_props[num_battery_props++] =
3487
+ POWER_SUPPLY_PROP_VOLTAGE_NOW;
27773488
27783489 battery = &hidpp->battery;
27793490
....@@ -2887,32 +3598,45 @@
28873598 return;
28883599 }
28893600
3601
+ if (hidpp->quirks & HIDPP_QUIRK_HIDPP_WHEELS) {
3602
+ ret = hidpp10_wheel_connect(hidpp);
3603
+ if (ret)
3604
+ return;
3605
+ }
3606
+
3607
+ if (hidpp->quirks & HIDPP_QUIRK_HIDPP_EXTRA_MOUSE_BTNS) {
3608
+ ret = hidpp10_extra_mouse_buttons_connect(hidpp);
3609
+ if (ret)
3610
+ return;
3611
+ }
3612
+
3613
+ if (hidpp->quirks & HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS) {
3614
+ ret = hidpp10_consumer_keys_connect(hidpp);
3615
+ if (ret)
3616
+ return;
3617
+ }
3618
+
28903619 /* the device is already connected, we can ask for its name and
28913620 * protocol */
28923621 if (!hidpp->protocol_major) {
2893
- ret = !hidpp_is_connected(hidpp);
3622
+ ret = hidpp_root_get_protocol_version(hidpp);
28943623 if (ret) {
28953624 hid_err(hdev, "Can not get the protocol version.\n");
28963625 return;
28973626 }
2898
- hid_info(hdev, "HID++ %u.%u device connected.\n",
2899
- hidpp->protocol_major, hidpp->protocol_minor);
29003627 }
29013628
29023629 if (hidpp->name == hdev->name && hidpp->protocol_major >= 2) {
29033630 name = hidpp_get_device_name(hidpp);
2904
- if (!name) {
2905
- hid_err(hdev,
2906
- "unable to retrieve the name of the device");
2907
- return;
3631
+ if (name) {
3632
+ devm_name = devm_kasprintf(&hdev->dev, GFP_KERNEL,
3633
+ "%s", name);
3634
+ kfree(name);
3635
+ if (!devm_name)
3636
+ return;
3637
+
3638
+ hidpp->name = devm_name;
29083639 }
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;
29163640 }
29173641
29183642 hidpp_initialize_battery(hidpp);
....@@ -2925,10 +3649,16 @@
29253649 else
29263650 hidpp10_query_battery_status(hidpp);
29273651 } else if (hidpp->capabilities & HIDPP_CAPABILITY_HIDPP20_BATTERY) {
2928
- hidpp20_query_battery_info(hidpp);
3652
+ if (hidpp->capabilities & HIDPP_CAPABILITY_BATTERY_VOLTAGE)
3653
+ hidpp20_query_battery_voltage_info(hidpp);
3654
+ else
3655
+ hidpp20_query_battery_info(hidpp);
29293656 }
29303657 if (hidpp->battery.ps)
29313658 power_supply_changed(hidpp->battery.ps);
3659
+
3660
+ if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL)
3661
+ hi_res_scroll_enable(hidpp);
29323662
29333663 if (!(hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT) || hidpp->delayed_input)
29343664 /* if the input nodes are already created, we can stop now */
....@@ -2940,7 +3670,7 @@
29403670 return;
29413671 }
29423672
2943
- hidpp_populate_input(hidpp, input, false);
3673
+ hidpp_populate_input(hidpp, input);
29443674
29453675 ret = input_register_device(input);
29463676 if (ret)
....@@ -2960,26 +3690,118 @@
29603690 .attrs = sysfs_attrs
29613691 };
29623692
3693
+static int hidpp_get_report_length(struct hid_device *hdev, int id)
3694
+{
3695
+ struct hid_report_enum *re;
3696
+ struct hid_report *report;
3697
+
3698
+ re = &(hdev->report_enum[HID_OUTPUT_REPORT]);
3699
+ report = re->report_id_hash[id];
3700
+ if (!report)
3701
+ return 0;
3702
+
3703
+ return report->field[0]->report_count + 1;
3704
+}
3705
+
3706
+static u8 hidpp_validate_device(struct hid_device *hdev)
3707
+{
3708
+ struct hidpp_device *hidpp = hid_get_drvdata(hdev);
3709
+ int id, report_length;
3710
+ u8 supported_reports = 0;
3711
+
3712
+ id = REPORT_ID_HIDPP_SHORT;
3713
+ report_length = hidpp_get_report_length(hdev, id);
3714
+ if (report_length) {
3715
+ if (report_length < HIDPP_REPORT_SHORT_LENGTH)
3716
+ goto bad_device;
3717
+
3718
+ supported_reports |= HIDPP_REPORT_SHORT_SUPPORTED;
3719
+ }
3720
+
3721
+ id = REPORT_ID_HIDPP_LONG;
3722
+ report_length = hidpp_get_report_length(hdev, id);
3723
+ if (report_length) {
3724
+ if (report_length < HIDPP_REPORT_LONG_LENGTH)
3725
+ goto bad_device;
3726
+
3727
+ supported_reports |= HIDPP_REPORT_LONG_SUPPORTED;
3728
+ }
3729
+
3730
+ id = REPORT_ID_HIDPP_VERY_LONG;
3731
+ report_length = hidpp_get_report_length(hdev, id);
3732
+ if (report_length) {
3733
+ if (report_length < HIDPP_REPORT_LONG_LENGTH ||
3734
+ report_length > HIDPP_REPORT_VERY_LONG_MAX_LENGTH)
3735
+ goto bad_device;
3736
+
3737
+ supported_reports |= HIDPP_REPORT_VERY_LONG_SUPPORTED;
3738
+ hidpp->very_long_report_length = report_length;
3739
+ }
3740
+
3741
+ return supported_reports;
3742
+
3743
+bad_device:
3744
+ hid_warn(hdev, "not enough values in hidpp report %d\n", id);
3745
+ return false;
3746
+}
3747
+
3748
+static bool hidpp_application_equals(struct hid_device *hdev,
3749
+ unsigned int application)
3750
+{
3751
+ struct list_head *report_list;
3752
+ struct hid_report *report;
3753
+
3754
+ report_list = &hdev->report_enum[HID_INPUT_REPORT].report_list;
3755
+ report = list_first_entry_or_null(report_list, struct hid_report, list);
3756
+ return report && report->application == application;
3757
+}
3758
+
29633759 static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
29643760 {
29653761 struct hidpp_device *hidpp;
29663762 int ret;
29673763 bool connected;
29683764 unsigned int connect_mask = HID_CONNECT_DEFAULT;
3765
+ struct hidpp_ff_private_data data;
29693766
2970
- hidpp = devm_kzalloc(&hdev->dev, sizeof(struct hidpp_device),
2971
- GFP_KERNEL);
3767
+ /* report_fixup needs drvdata to be set before we call hid_parse */
3768
+ hidpp = devm_kzalloc(&hdev->dev, sizeof(*hidpp), GFP_KERNEL);
29723769 if (!hidpp)
29733770 return -ENOMEM;
29743771
29753772 hidpp->hid_dev = hdev;
29763773 hidpp->name = hdev->name;
3774
+ hidpp->quirks = id->driver_data;
29773775 hid_set_drvdata(hdev, hidpp);
29783776
2979
- hidpp->quirks = id->driver_data;
3777
+ ret = hid_parse(hdev);
3778
+ if (ret) {
3779
+ hid_err(hdev, "%s:parse failed\n", __func__);
3780
+ return ret;
3781
+ }
3782
+
3783
+ /*
3784
+ * Make sure the device is HID++ capable, otherwise treat as generic HID
3785
+ */
3786
+ hidpp->supported_reports = hidpp_validate_device(hdev);
3787
+
3788
+ if (!hidpp->supported_reports) {
3789
+ hid_set_drvdata(hdev, NULL);
3790
+ devm_kfree(&hdev->dev, hidpp);
3791
+ return hid_hw_start(hdev, HID_CONNECT_DEFAULT);
3792
+ }
29803793
29813794 if (id->group == HID_GROUP_LOGITECH_DJ_DEVICE)
29823795 hidpp->quirks |= HIDPP_QUIRK_UNIFYING;
3796
+
3797
+ if (id->group == HID_GROUP_LOGITECH_27MHZ_DEVICE &&
3798
+ hidpp_application_equals(hdev, HID_GD_MOUSE))
3799
+ hidpp->quirks |= HIDPP_QUIRK_HIDPP_WHEELS |
3800
+ HIDPP_QUIRK_HIDPP_EXTRA_MOUSE_BTNS;
3801
+
3802
+ if (id->group == HID_GROUP_LOGITECH_27MHZ_DEVICE &&
3803
+ hidpp_application_equals(hdev, HID_GD_KEYBOARD))
3804
+ hidpp->quirks |= HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS;
29833805
29843806 if (disable_raw_mode) {
29853807 hidpp->quirks &= ~HIDPP_QUIRK_CLASS_WTP;
....@@ -2989,15 +3811,11 @@
29893811 if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) {
29903812 ret = wtp_allocate(hdev, id);
29913813 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;
3814
+ return ret;
29973815 } else if (hidpp->quirks & HIDPP_QUIRK_CLASS_K400) {
29983816 ret = k400_allocate(hdev);
29993817 if (ret)
3000
- goto allocate_fail;
3818
+ return ret;
30013819 }
30023820
30033821 INIT_WORK(&hidpp->work, delayed_work_cb);
....@@ -3010,30 +3828,22 @@
30103828 hid_warn(hdev, "Cannot allocate sysfs group for %s\n",
30113829 hdev->name);
30123830
3013
- ret = hid_parse(hdev);
3831
+ /*
3832
+ * Plain USB connections need to actually call start and open
3833
+ * on the transport driver to allow incoming data.
3834
+ */
3835
+ ret = hid_hw_start(hdev, 0);
30143836 if (ret) {
3015
- hid_err(hdev, "%s:parse failed\n", __func__);
3016
- goto hid_parse_fail;
3837
+ hid_err(hdev, "hw start failed\n");
3838
+ goto hid_hw_start_fail;
30173839 }
30183840
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
- }
3841
+ ret = hid_hw_open(hdev);
3842
+ if (ret < 0) {
3843
+ dev_err(&hdev->dev, "%s:hid_hw_open returned error:%d\n",
3844
+ __func__, ret);
3845
+ goto hid_hw_open_fail;
30353846 }
3036
-
30373847
30383848 /* Allow incoming packets */
30393849 hid_device_io_start(hdev);
....@@ -3041,62 +3851,71 @@
30413851 if (hidpp->quirks & HIDPP_QUIRK_UNIFYING)
30423852 hidpp_unifying_init(hidpp);
30433853
3044
- connected = hidpp_is_connected(hidpp);
3854
+ connected = hidpp_root_get_protocol_version(hidpp) == 0;
30453855 atomic_set(&hidpp->connected, connected);
30463856 if (!(hidpp->quirks & HIDPP_QUIRK_UNIFYING)) {
30473857 if (!connected) {
30483858 ret = -ENODEV;
30493859 hid_err(hdev, "Device not connected");
3050
- goto hid_hw_open_failed;
3860
+ goto hid_hw_init_fail;
30513861 }
30523862
3053
- hid_info(hdev, "HID++ %u.%u device connected.\n",
3054
- hidpp->protocol_major, hidpp->protocol_minor);
3055
-
30563863 hidpp_overwrite_name(hdev);
3864
+ }
3865
+
3866
+ if (connected && hidpp->protocol_major >= 2) {
3867
+ ret = hidpp_set_wireless_feature_index(hidpp);
3868
+ if (ret == -ENOENT)
3869
+ hidpp->wireless_feature_index = 0;
3870
+ else if (ret)
3871
+ goto hid_hw_init_fail;
30573872 }
30583873
30593874 if (connected && (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)) {
30603875 ret = wtp_get_config(hidpp);
30613876 if (ret)
3062
- goto hid_hw_open_failed;
3877
+ goto hid_hw_init_fail;
30633878 } else if (connected && (hidpp->quirks & HIDPP_QUIRK_CLASS_G920)) {
3064
- ret = g920_get_config(hidpp);
3879
+ ret = g920_get_config(hidpp, &data);
30653880 if (ret)
3066
- goto hid_hw_open_failed;
3881
+ goto hid_hw_init_fail;
30673882 }
3068
-
3069
- /* Block incoming packets */
3070
- hid_device_io_stop(hdev);
3071
-
3072
- if (!(hidpp->quirks & HIDPP_QUIRK_CLASS_G920)) {
3073
- ret = hid_hw_start(hdev, connect_mask);
3074
- if (ret) {
3075
- hid_err(hdev, "%s:hid_hw_start returned error\n", __func__);
3076
- goto hid_hw_start_fail;
3077
- }
3078
- }
3079
-
3080
- /* Allow incoming packets */
3081
- hid_device_io_start(hdev);
30823883
30833884 hidpp_connect_event(hidpp);
30843885
3886
+ /* Reset the HID node state */
3887
+ hid_device_io_stop(hdev);
3888
+ hid_hw_close(hdev);
3889
+ hid_hw_stop(hdev);
3890
+
3891
+ if (hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT)
3892
+ connect_mask &= ~HID_CONNECT_HIDINPUT;
3893
+
3894
+ /* Now export the actual inputs and hidraw nodes to the world */
3895
+ ret = hid_hw_start(hdev, connect_mask);
3896
+ if (ret) {
3897
+ hid_err(hdev, "%s:hid_hw_start returned error\n", __func__);
3898
+ goto hid_hw_start_fail;
3899
+ }
3900
+
3901
+ if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) {
3902
+ ret = hidpp_ff_init(hidpp, &data);
3903
+ if (ret)
3904
+ hid_warn(hidpp->hid_dev,
3905
+ "Unable to initialize force feedback support, errno %d\n",
3906
+ ret);
3907
+ }
3908
+
30853909 return ret;
30863910
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
- }
3911
+hid_hw_init_fail:
3912
+ hid_hw_close(hdev);
3913
+hid_hw_open_fail:
3914
+ hid_hw_stop(hdev);
30933915 hid_hw_start_fail:
3094
-hid_parse_fail:
30953916 sysfs_remove_group(&hdev->dev.kobj, &ps_attribute_group);
30963917 cancel_work_sync(&hidpp->work);
30973918 mutex_destroy(&hidpp->send_mutex);
3098
-allocate_fail:
3099
- hid_set_drvdata(hdev, NULL);
31003919 return ret;
31013920 }
31023921
....@@ -3104,60 +3923,161 @@
31043923 {
31053924 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
31063925
3926
+ if (!hidpp)
3927
+ return hid_hw_stop(hdev);
3928
+
31073929 sysfs_remove_group(&hdev->dev.kobj, &ps_attribute_group);
31083930
3109
- if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) {
3110
- hidpp_ff_deinit(hdev);
3111
- hid_hw_close(hdev);
3112
- }
31133931 hid_hw_stop(hdev);
31143932 cancel_work_sync(&hidpp->work);
31153933 mutex_destroy(&hidpp->send_mutex);
31163934 }
31173935
3936
+#define LDJ_DEVICE(product) \
3937
+ HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, \
3938
+ USB_VENDOR_ID_LOGITECH, (product))
3939
+
3940
+#define L27MHZ_DEVICE(product) \
3941
+ HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_27MHZ_DEVICE, \
3942
+ USB_VENDOR_ID_LOGITECH, (product))
3943
+
31183944 static const struct hid_device_id hidpp_devices[] = {
31193945 { /* wireless touchpad */
3120
- HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
3121
- USB_VENDOR_ID_LOGITECH, 0x4011),
3946
+ LDJ_DEVICE(0x4011),
31223947 .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT |
31233948 HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS },
31243949 { /* wireless touchpad T650 */
3125
- HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
3126
- USB_VENDOR_ID_LOGITECH, 0x4101),
3950
+ LDJ_DEVICE(0x4101),
31273951 .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT },
31283952 { /* wireless touchpad T651 */
31293953 HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH,
31303954 USB_DEVICE_ID_LOGITECH_T651),
31313955 .driver_data = HIDPP_QUIRK_CLASS_WTP },
3956
+ { /* Mouse Logitech Anywhere MX */
3957
+ LDJ_DEVICE(0x1017), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_1P0 },
3958
+ { /* Mouse Logitech Cube */
3959
+ LDJ_DEVICE(0x4010), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2120 },
3960
+ { /* Mouse Logitech M335 */
3961
+ LDJ_DEVICE(0x4050), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
3962
+ { /* Mouse Logitech M515 */
3963
+ LDJ_DEVICE(0x4007), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2120 },
31323964 { /* 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 },
3965
+ LDJ_DEVICE(0x402d),
3966
+ .driver_data = HIDPP_QUIRK_DELAYED_INIT | HIDPP_QUIRK_CLASS_M560
3967
+ | HIDPP_QUIRK_HI_RES_SCROLL_X2120 },
3968
+ { /* Mouse Logitech M705 (firmware RQM17) */
3969
+ LDJ_DEVICE(0x101b), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_1P0 },
3970
+ { /* Mouse Logitech M705 (firmware RQM67) */
3971
+ LDJ_DEVICE(0x406d), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
3972
+ { /* Mouse Logitech M720 */
3973
+ LDJ_DEVICE(0x405e), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
3974
+ { /* Mouse Logitech MX Anywhere 2 */
3975
+ LDJ_DEVICE(0x404a), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
3976
+ { LDJ_DEVICE(0x4072), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
3977
+ { LDJ_DEVICE(0xb013), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
3978
+ { LDJ_DEVICE(0xb018), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
3979
+ { LDJ_DEVICE(0xb01f), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
3980
+ { /* Mouse Logitech MX Anywhere 2S */
3981
+ LDJ_DEVICE(0x406a), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
3982
+ { /* Mouse Logitech MX Master */
3983
+ LDJ_DEVICE(0x4041), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
3984
+ { LDJ_DEVICE(0x4060), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
3985
+ { LDJ_DEVICE(0x4071), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
3986
+ { /* Mouse Logitech MX Master 2S */
3987
+ LDJ_DEVICE(0x4069), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
3988
+ { /* Mouse Logitech MX Master 3 */
3989
+ LDJ_DEVICE(0x4082), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
3990
+ { /* Mouse Logitech Performance MX */
3991
+ LDJ_DEVICE(0x101a), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_1P0 },
31363992 { /* Keyboard logitech K400 */
3137
- HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
3138
- USB_VENDOR_ID_LOGITECH, 0x4024),
3993
+ LDJ_DEVICE(0x4024),
31393994 .driver_data = HIDPP_QUIRK_CLASS_K400 },
31403995 { /* Solar Keyboard Logitech K750 */
3141
- HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
3142
- USB_VENDOR_ID_LOGITECH, 0x4002),
3996
+ LDJ_DEVICE(0x4002),
31433997 .driver_data = HIDPP_QUIRK_CLASS_K750 },
3998
+ { /* Keyboard MX5000 (Bluetooth-receiver in HID proxy mode) */
3999
+ LDJ_DEVICE(0xb305),
4000
+ .driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS },
4001
+ { /* Dinovo Edge (Bluetooth-receiver in HID proxy mode) */
4002
+ LDJ_DEVICE(0xb309),
4003
+ .driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS },
4004
+ { /* Keyboard MX5500 (Bluetooth-receiver in HID proxy mode) */
4005
+ LDJ_DEVICE(0xb30b),
4006
+ .driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS },
31444007
3145
- { HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
3146
- USB_VENDOR_ID_LOGITECH, HID_ANY_ID)},
4008
+ { LDJ_DEVICE(HID_ANY_ID) },
31474009
3148
- { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G920_WHEEL),
4010
+ { /* Keyboard LX501 (Y-RR53) */
4011
+ L27MHZ_DEVICE(0x0049),
4012
+ .driver_data = HIDPP_QUIRK_KBD_ZOOM_WHEEL },
4013
+ { /* Keyboard MX3000 (Y-RAM74) */
4014
+ L27MHZ_DEVICE(0x0057),
4015
+ .driver_data = HIDPP_QUIRK_KBD_SCROLL_WHEEL },
4016
+ { /* Keyboard MX3200 (Y-RAV80) */
4017
+ L27MHZ_DEVICE(0x005c),
4018
+ .driver_data = HIDPP_QUIRK_KBD_ZOOM_WHEEL },
4019
+ { /* S510 Media Remote */
4020
+ L27MHZ_DEVICE(0x00fe),
4021
+ .driver_data = HIDPP_QUIRK_KBD_SCROLL_WHEEL },
4022
+
4023
+ { L27MHZ_DEVICE(HID_ANY_ID) },
4024
+
4025
+ { /* Logitech G403 Wireless Gaming Mouse over USB */
4026
+ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC082) },
4027
+ { /* Logitech G703 Gaming Mouse over USB */
4028
+ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC087) },
4029
+ { /* Logitech G703 Hero Gaming Mouse over USB */
4030
+ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC090) },
4031
+ { /* Logitech G900 Gaming Mouse over USB */
4032
+ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC081) },
4033
+ { /* Logitech G903 Gaming Mouse over USB */
4034
+ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC086) },
4035
+ { /* Logitech G903 Hero Gaming Mouse over USB */
4036
+ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC091) },
4037
+ { /* Logitech G920 Wheel over USB */
4038
+ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G920_WHEEL),
31494039 .driver_data = HIDPP_QUIRK_CLASS_G920 | HIDPP_QUIRK_FORCE_OUTPUT_REPORTS},
4040
+ { /* Logitech G Pro Gaming Mouse over USB */
4041
+ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC088) },
4042
+
4043
+ { /* MX5000 keyboard over Bluetooth */
4044
+ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb305),
4045
+ .driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS },
4046
+ { /* Dinovo Edge keyboard over Bluetooth */
4047
+ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb309),
4048
+ .driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS },
4049
+ { /* MX5500 keyboard over Bluetooth */
4050
+ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb30b),
4051
+ .driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS },
4052
+ { /* MX Master mouse over Bluetooth */
4053
+ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb012),
4054
+ .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
4055
+ { /* MX Ergo trackball over Bluetooth */
4056
+ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb01d) },
4057
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb01e),
4058
+ .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
4059
+ { /* MX Master 3 mouse over Bluetooth */
4060
+ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb023),
4061
+ .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
31504062 {}
31514063 };
31524064
31534065 MODULE_DEVICE_TABLE(hid, hidpp_devices);
31544066
4067
+static const struct hid_usage_id hidpp_usages[] = {
4068
+ { HID_GD_WHEEL, EV_REL, REL_WHEEL_HI_RES },
4069
+ { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1}
4070
+};
4071
+
31554072 static struct hid_driver hidpp_driver = {
31564073 .name = "logitech-hidpp-device",
31574074 .id_table = hidpp_devices,
4075
+ .report_fixup = hidpp_report_fixup,
31584076 .probe = hidpp_probe,
31594077 .remove = hidpp_remove,
31604078 .raw_event = hidpp_raw_event,
4079
+ .usage_table = hidpp_usages,
4080
+ .event = hidpp_event,
31614081 .input_configured = hidpp_input_configured,
31624082 .input_mapping = hidpp_input_mapping,
31634083 .input_mapped = hidpp_input_mapped,