hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/drivers/hid/hid-input.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Copyright (c) 2000-2001 Vojtech Pavlik
34 * Copyright (c) 2006-2010 Jiri Kosina
....@@ -6,19 +7,6 @@
67 */
78
89 /*
9
- * This program is free software; you can redistribute it and/or modify
10
- * it under the terms of the GNU General Public License as published by
11
- * the Free Software Foundation; either version 2 of the License, or
12
- * (at your option) any later version.
13
- *
14
- * This program is distributed in the hope that it will be useful,
15
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
- * GNU General Public License for more details.
18
- *
19
- * You should have received a copy of the GNU General Public License
20
- * along with this program; if not, write to the Free Software
21
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2210 *
2311 * Should you need to contact me, the author, you can do so either by
2412 * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
....@@ -335,6 +323,10 @@
335323 USB_DEVICE_ID_LOGITECH_DINOVO_EDGE_KBD),
336324 HID_BATTERY_QUIRK_IGNORE },
337325 { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN),
326
+ HID_BATTERY_QUIRK_IGNORE },
327
+ { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_SPECTRE_X360_15),
328
+ HID_BATTERY_QUIRK_IGNORE },
329
+ { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_SURFACE_GO_TOUCHSCREEN),
338330 HID_BATTERY_QUIRK_IGNORE },
339331 {}
340332 };
....@@ -683,6 +675,14 @@
683675 break;
684676 }
685677
678
+ if ((usage->hid & 0xf0) == 0xa0) { /* SystemControl */
679
+ switch (usage->hid & 0xf) {
680
+ case 0x9: map_key_clear(KEY_MICMUTE); break;
681
+ default: goto ignore;
682
+ }
683
+ break;
684
+ }
685
+
686686 if ((usage->hid & 0xf0) == 0xb0) { /* SC - Display */
687687 switch (usage->hid & 0xf) {
688688 case 0x05: map_key_clear(KEY_SWITCHVIDEOMODE); break;
....@@ -726,7 +726,15 @@
726726 map_abs_clear(usage->hid & 0xf);
727727 break;
728728
729
- case HID_GD_SLIDER: case HID_GD_DIAL: case HID_GD_WHEEL:
729
+ case HID_GD_WHEEL:
730
+ if (field->flags & HID_MAIN_ITEM_RELATIVE) {
731
+ set_bit(REL_WHEEL, input->relbit);
732
+ map_rel(REL_WHEEL_HI_RES);
733
+ } else {
734
+ map_abs(usage->hid & 0xf);
735
+ }
736
+ break;
737
+ case HID_GD_SLIDER: case HID_GD_DIAL:
730738 if (field->flags & HID_MAIN_ITEM_RELATIVE)
731739 map_rel(usage->hid & 0xf);
732740 else
....@@ -775,6 +783,11 @@
775783 break;
776784
777785 case HID_UP_DIGITIZER:
786
+ if ((field->application & 0xff) == 0x01) /* Digitizer */
787
+ __set_bit(INPUT_PROP_POINTER, input->propbit);
788
+ else if ((field->application & 0xff) == 0x02) /* Pen */
789
+ __set_bit(INPUT_PROP_DIRECT, input->propbit);
790
+
778791 switch (usage->hid & 0xff) {
779792 case 0x00: /* Undefined */
780793 goto ignore;
....@@ -900,7 +913,7 @@
900913 case 0x06a: map_key_clear(KEY_GREEN); break;
901914 case 0x06b: map_key_clear(KEY_BLUE); break;
902915 case 0x06c: map_key_clear(KEY_YELLOW); break;
903
- case 0x06d: map_key_clear(KEY_ZOOM); break;
916
+ case 0x06d: map_key_clear(KEY_ASPECT_RATIO); break;
904917
905918 case 0x06f: map_key_clear(KEY_BRIGHTNESSUP); break;
906919 case 0x070: map_key_clear(KEY_BRIGHTNESSDOWN); break;
....@@ -954,6 +967,10 @@
954967
955968 case 0x0cd: map_key_clear(KEY_PLAYPAUSE); break;
956969 case 0x0cf: map_key_clear(KEY_VOICECOMMAND); break;
970
+
971
+ case 0x0d8: map_key_clear(KEY_DICTATE); break;
972
+ case 0x0d9: map_key_clear(KEY_EMOJI_PICKER); break;
973
+
957974 case 0x0e0: map_abs_clear(ABS_VOLUME); break;
958975 case 0x0e2: map_key_clear(KEY_MUTE); break;
959976 case 0x0e5: map_key_clear(KEY_BASSBOOST); break;
....@@ -1024,9 +1041,13 @@
10241041 case 0x22d: map_key_clear(KEY_ZOOMIN); break;
10251042 case 0x22e: map_key_clear(KEY_ZOOMOUT); break;
10261043 case 0x22f: map_key_clear(KEY_ZOOMRESET); break;
1044
+ case 0x232: map_key_clear(KEY_FULL_SCREEN); break;
10271045 case 0x233: map_key_clear(KEY_SCROLLUP); break;
10281046 case 0x234: map_key_clear(KEY_SCROLLDOWN); break;
1029
- case 0x238: map_rel(REL_HWHEEL); break;
1047
+ case 0x238: /* AC Pan */
1048
+ set_bit(REL_HWHEEL, input->relbit);
1049
+ map_rel(REL_HWHEEL_HI_RES);
1050
+ break;
10301051 case 0x23d: map_key_clear(KEY_EDIT); break;
10311052 case 0x25f: map_key_clear(KEY_CANCEL); break;
10321053 case 0x269: map_key_clear(KEY_INSERT); break;
....@@ -1036,6 +1057,10 @@
10361057 case 0x289: map_key_clear(KEY_REPLY); break;
10371058 case 0x28b: map_key_clear(KEY_FORWARDMAIL); break;
10381059 case 0x28c: map_key_clear(KEY_SEND); break;
1060
+
1061
+ case 0x29d: map_key_clear(KEY_KBD_LAYOUT_NEXT); break;
1062
+
1063
+ case 0x2a2: map_key_clear(KEY_ALL_APPLICATIONS); break;
10391064
10401065 case 0x2c7: map_key_clear(KEY_KBDINPUTASSIST_PREV); break;
10411066 case 0x2c8: map_key_clear(KEY_KBDINPUTASSIST_NEXT); break;
....@@ -1228,6 +1253,38 @@
12281253 usage->code = 0;
12291254 }
12301255
1256
+static void hidinput_handle_scroll(struct hid_usage *usage,
1257
+ struct input_dev *input,
1258
+ __s32 value)
1259
+{
1260
+ int code;
1261
+ int hi_res, lo_res;
1262
+
1263
+ if (value == 0)
1264
+ return;
1265
+
1266
+ if (usage->code == REL_WHEEL_HI_RES)
1267
+ code = REL_WHEEL;
1268
+ else
1269
+ code = REL_HWHEEL;
1270
+
1271
+ /*
1272
+ * Windows reports one wheel click as value 120. Where a high-res
1273
+ * scroll wheel is present, a fraction of 120 is reported instead.
1274
+ * Our REL_WHEEL_HI_RES axis does the same because all HW must
1275
+ * adhere to the 120 expectation.
1276
+ */
1277
+ hi_res = value * 120/usage->resolution_multiplier;
1278
+
1279
+ usage->wheel_accumulated += hi_res;
1280
+ lo_res = usage->wheel_accumulated/120;
1281
+ if (lo_res)
1282
+ usage->wheel_accumulated -= lo_res * 120;
1283
+
1284
+ input_event(input, EV_REL, code, lo_res);
1285
+ input_event(input, EV_REL, usage->code, hi_res);
1286
+}
1287
+
12311288 void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value)
12321289 {
12331290 struct input_dev *input;
....@@ -1295,6 +1352,12 @@
12951352
12961353 if ((usage->type == EV_KEY) && (usage->code == 0)) /* Key 0 is "unassigned", not KEY_UNKNOWN */
12971354 return;
1355
+
1356
+ if ((usage->type == EV_REL) && (usage->code == REL_WHEEL_HI_RES ||
1357
+ usage->code == REL_HWHEEL_HI_RES)) {
1358
+ hidinput_handle_scroll(usage, input, value);
1359
+ return;
1360
+ }
12981361
12991362 if ((usage->type == EV_ABS) && (field->flags & HID_MAIN_ITEM_RELATIVE) &&
13001363 (usage->code == ABS_VOLUME)) {
....@@ -1523,6 +1586,87 @@
15231586 hid_hw_close(hid);
15241587 }
15251588
1589
+static bool __hidinput_change_resolution_multipliers(struct hid_device *hid,
1590
+ struct hid_report *report, bool use_logical_max)
1591
+{
1592
+ struct hid_usage *usage;
1593
+ bool update_needed = false;
1594
+ bool get_report_completed = false;
1595
+ int i, j;
1596
+
1597
+ if (report->maxfield == 0)
1598
+ return false;
1599
+
1600
+ for (i = 0; i < report->maxfield; i++) {
1601
+ __s32 value = use_logical_max ?
1602
+ report->field[i]->logical_maximum :
1603
+ report->field[i]->logical_minimum;
1604
+
1605
+ /* There is no good reason for a Resolution
1606
+ * Multiplier to have a count other than 1.
1607
+ * Ignore that case.
1608
+ */
1609
+ if (report->field[i]->report_count != 1)
1610
+ continue;
1611
+
1612
+ for (j = 0; j < report->field[i]->maxusage; j++) {
1613
+ usage = &report->field[i]->usage[j];
1614
+
1615
+ if (usage->hid != HID_GD_RESOLUTION_MULTIPLIER)
1616
+ continue;
1617
+
1618
+ /*
1619
+ * If we have more than one feature within this
1620
+ * report we need to fill in the bits from the
1621
+ * others before we can overwrite the ones for the
1622
+ * Resolution Multiplier.
1623
+ *
1624
+ * But if we're not allowed to read from the device,
1625
+ * we just bail. Such a device should not exist
1626
+ * anyway.
1627
+ */
1628
+ if (!get_report_completed && report->maxfield > 1) {
1629
+ if (hid->quirks & HID_QUIRK_NO_INIT_REPORTS)
1630
+ return update_needed;
1631
+
1632
+ hid_hw_request(hid, report, HID_REQ_GET_REPORT);
1633
+ hid_hw_wait(hid);
1634
+ get_report_completed = true;
1635
+ }
1636
+
1637
+ report->field[i]->value[j] = value;
1638
+ update_needed = true;
1639
+ }
1640
+ }
1641
+
1642
+ return update_needed;
1643
+}
1644
+
1645
+static void hidinput_change_resolution_multipliers(struct hid_device *hid)
1646
+{
1647
+ struct hid_report_enum *rep_enum;
1648
+ struct hid_report *rep;
1649
+ int ret;
1650
+
1651
+ rep_enum = &hid->report_enum[HID_FEATURE_REPORT];
1652
+ list_for_each_entry(rep, &rep_enum->report_list, list) {
1653
+ bool update_needed = __hidinput_change_resolution_multipliers(hid,
1654
+ rep, true);
1655
+
1656
+ if (update_needed) {
1657
+ ret = __hid_request(hid, rep, HID_REQ_SET_REPORT);
1658
+ if (ret) {
1659
+ __hidinput_change_resolution_multipliers(hid,
1660
+ rep, false);
1661
+ return;
1662
+ }
1663
+ }
1664
+ }
1665
+
1666
+ /* refresh our structs */
1667
+ hid_setup_resolution_multiplier(hid);
1668
+}
1669
+
15261670 static void report_features(struct hid_device *hid)
15271671 {
15281672 struct hid_driver *drv = hid->driver;
....@@ -1558,6 +1702,7 @@
15581702 struct hid_input *hidinput = kzalloc(sizeof(*hidinput), GFP_KERNEL);
15591703 struct input_dev *input_dev = input_allocate_device();
15601704 const char *suffix = NULL;
1705
+ size_t suffix_len, name_len;
15611706
15621707 if (!hidinput || !input_dev)
15631708 goto fail;
....@@ -1601,10 +1746,15 @@
16011746 }
16021747
16031748 if (suffix) {
1604
- hidinput->name = kasprintf(GFP_KERNEL, "%s %s",
1605
- hid->name, suffix);
1606
- if (!hidinput->name)
1607
- goto fail;
1749
+ name_len = strlen(hid->name);
1750
+ suffix_len = strlen(suffix);
1751
+ if ((name_len < suffix_len) ||
1752
+ strcmp(hid->name + name_len - suffix_len, suffix)) {
1753
+ hidinput->name = kasprintf(GFP_KERNEL, "%s %s",
1754
+ hid->name, suffix);
1755
+ if (!hidinput->name)
1756
+ goto fail;
1757
+ }
16081758 }
16091759
16101760 input_set_drvdata(input_dev, hid);
....@@ -1810,6 +1960,8 @@
18101960 }
18111961 }
18121962
1963
+ hidinput_change_resolution_multipliers(hid);
1964
+
18131965 list_for_each_entry_safe(hidinput, next, &hid->inputs, list) {
18141966 if (drv->input_configured &&
18151967 drv->input_configured(hid, hidinput))
....@@ -1868,4 +2020,3 @@
18682020 cancel_work_sync(&hid->led_work);
18692021 }
18702022 EXPORT_SYMBOL_GPL(hidinput_disconnect);
1871
-