hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
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 };
....@@ -726,7 +718,15 @@
726718 map_abs_clear(usage->hid & 0xf);
727719 break;
728720
729
- case HID_GD_SLIDER: case HID_GD_DIAL: case HID_GD_WHEEL:
721
+ case HID_GD_WHEEL:
722
+ if (field->flags & HID_MAIN_ITEM_RELATIVE) {
723
+ set_bit(REL_WHEEL, input->relbit);
724
+ map_rel(REL_WHEEL_HI_RES);
725
+ } else {
726
+ map_abs(usage->hid & 0xf);
727
+ }
728
+ break;
729
+ case HID_GD_SLIDER: case HID_GD_DIAL:
730730 if (field->flags & HID_MAIN_ITEM_RELATIVE)
731731 map_rel(usage->hid & 0xf);
732732 else
....@@ -775,6 +775,11 @@
775775 break;
776776
777777 case HID_UP_DIGITIZER:
778
+ if ((field->application & 0xff) == 0x01) /* Digitizer */
779
+ __set_bit(INPUT_PROP_POINTER, input->propbit);
780
+ else if ((field->application & 0xff) == 0x02) /* Pen */
781
+ __set_bit(INPUT_PROP_DIRECT, input->propbit);
782
+
778783 switch (usage->hid & 0xff) {
779784 case 0x00: /* Undefined */
780785 goto ignore;
....@@ -900,7 +905,7 @@
900905 case 0x06a: map_key_clear(KEY_GREEN); break;
901906 case 0x06b: map_key_clear(KEY_BLUE); break;
902907 case 0x06c: map_key_clear(KEY_YELLOW); break;
903
- case 0x06d: map_key_clear(KEY_ZOOM); break;
908
+ case 0x06d: map_key_clear(KEY_ASPECT_RATIO); break;
904909
905910 case 0x06f: map_key_clear(KEY_BRIGHTNESSUP); break;
906911 case 0x070: map_key_clear(KEY_BRIGHTNESSDOWN); break;
....@@ -954,6 +959,10 @@
954959
955960 case 0x0cd: map_key_clear(KEY_PLAYPAUSE); break;
956961 case 0x0cf: map_key_clear(KEY_VOICECOMMAND); break;
962
+
963
+ case 0x0d8: map_key_clear(KEY_DICTATE); break;
964
+ case 0x0d9: map_key_clear(KEY_EMOJI_PICKER); break;
965
+
957966 case 0x0e0: map_abs_clear(ABS_VOLUME); break;
958967 case 0x0e2: map_key_clear(KEY_MUTE); break;
959968 case 0x0e5: map_key_clear(KEY_BASSBOOST); break;
....@@ -1024,9 +1033,13 @@
10241033 case 0x22d: map_key_clear(KEY_ZOOMIN); break;
10251034 case 0x22e: map_key_clear(KEY_ZOOMOUT); break;
10261035 case 0x22f: map_key_clear(KEY_ZOOMRESET); break;
1036
+ case 0x232: map_key_clear(KEY_FULL_SCREEN); break;
10271037 case 0x233: map_key_clear(KEY_SCROLLUP); break;
10281038 case 0x234: map_key_clear(KEY_SCROLLDOWN); break;
1029
- case 0x238: map_rel(REL_HWHEEL); break;
1039
+ case 0x238: /* AC Pan */
1040
+ set_bit(REL_HWHEEL, input->relbit);
1041
+ map_rel(REL_HWHEEL_HI_RES);
1042
+ break;
10301043 case 0x23d: map_key_clear(KEY_EDIT); break;
10311044 case 0x25f: map_key_clear(KEY_CANCEL); break;
10321045 case 0x269: map_key_clear(KEY_INSERT); break;
....@@ -1036,6 +1049,10 @@
10361049 case 0x289: map_key_clear(KEY_REPLY); break;
10371050 case 0x28b: map_key_clear(KEY_FORWARDMAIL); break;
10381051 case 0x28c: map_key_clear(KEY_SEND); break;
1052
+
1053
+ case 0x29d: map_key_clear(KEY_KBD_LAYOUT_NEXT); break;
1054
+
1055
+ case 0x2a2: map_key_clear(KEY_ALL_APPLICATIONS); break;
10391056
10401057 case 0x2c7: map_key_clear(KEY_KBDINPUTASSIST_PREV); break;
10411058 case 0x2c8: map_key_clear(KEY_KBDINPUTASSIST_NEXT); break;
....@@ -1228,6 +1245,38 @@
12281245 usage->code = 0;
12291246 }
12301247
1248
+static void hidinput_handle_scroll(struct hid_usage *usage,
1249
+ struct input_dev *input,
1250
+ __s32 value)
1251
+{
1252
+ int code;
1253
+ int hi_res, lo_res;
1254
+
1255
+ if (value == 0)
1256
+ return;
1257
+
1258
+ if (usage->code == REL_WHEEL_HI_RES)
1259
+ code = REL_WHEEL;
1260
+ else
1261
+ code = REL_HWHEEL;
1262
+
1263
+ /*
1264
+ * Windows reports one wheel click as value 120. Where a high-res
1265
+ * scroll wheel is present, a fraction of 120 is reported instead.
1266
+ * Our REL_WHEEL_HI_RES axis does the same because all HW must
1267
+ * adhere to the 120 expectation.
1268
+ */
1269
+ hi_res = value * 120/usage->resolution_multiplier;
1270
+
1271
+ usage->wheel_accumulated += hi_res;
1272
+ lo_res = usage->wheel_accumulated/120;
1273
+ if (lo_res)
1274
+ usage->wheel_accumulated -= lo_res * 120;
1275
+
1276
+ input_event(input, EV_REL, code, lo_res);
1277
+ input_event(input, EV_REL, usage->code, hi_res);
1278
+}
1279
+
12311280 void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value)
12321281 {
12331282 struct input_dev *input;
....@@ -1295,6 +1344,12 @@
12951344
12961345 if ((usage->type == EV_KEY) && (usage->code == 0)) /* Key 0 is "unassigned", not KEY_UNKNOWN */
12971346 return;
1347
+
1348
+ if ((usage->type == EV_REL) && (usage->code == REL_WHEEL_HI_RES ||
1349
+ usage->code == REL_HWHEEL_HI_RES)) {
1350
+ hidinput_handle_scroll(usage, input, value);
1351
+ return;
1352
+ }
12981353
12991354 if ((usage->type == EV_ABS) && (field->flags & HID_MAIN_ITEM_RELATIVE) &&
13001355 (usage->code == ABS_VOLUME)) {
....@@ -1523,6 +1578,87 @@
15231578 hid_hw_close(hid);
15241579 }
15251580
1581
+static bool __hidinput_change_resolution_multipliers(struct hid_device *hid,
1582
+ struct hid_report *report, bool use_logical_max)
1583
+{
1584
+ struct hid_usage *usage;
1585
+ bool update_needed = false;
1586
+ bool get_report_completed = false;
1587
+ int i, j;
1588
+
1589
+ if (report->maxfield == 0)
1590
+ return false;
1591
+
1592
+ for (i = 0; i < report->maxfield; i++) {
1593
+ __s32 value = use_logical_max ?
1594
+ report->field[i]->logical_maximum :
1595
+ report->field[i]->logical_minimum;
1596
+
1597
+ /* There is no good reason for a Resolution
1598
+ * Multiplier to have a count other than 1.
1599
+ * Ignore that case.
1600
+ */
1601
+ if (report->field[i]->report_count != 1)
1602
+ continue;
1603
+
1604
+ for (j = 0; j < report->field[i]->maxusage; j++) {
1605
+ usage = &report->field[i]->usage[j];
1606
+
1607
+ if (usage->hid != HID_GD_RESOLUTION_MULTIPLIER)
1608
+ continue;
1609
+
1610
+ /*
1611
+ * If we have more than one feature within this
1612
+ * report we need to fill in the bits from the
1613
+ * others before we can overwrite the ones for the
1614
+ * Resolution Multiplier.
1615
+ *
1616
+ * But if we're not allowed to read from the device,
1617
+ * we just bail. Such a device should not exist
1618
+ * anyway.
1619
+ */
1620
+ if (!get_report_completed && report->maxfield > 1) {
1621
+ if (hid->quirks & HID_QUIRK_NO_INIT_REPORTS)
1622
+ return update_needed;
1623
+
1624
+ hid_hw_request(hid, report, HID_REQ_GET_REPORT);
1625
+ hid_hw_wait(hid);
1626
+ get_report_completed = true;
1627
+ }
1628
+
1629
+ report->field[i]->value[j] = value;
1630
+ update_needed = true;
1631
+ }
1632
+ }
1633
+
1634
+ return update_needed;
1635
+}
1636
+
1637
+static void hidinput_change_resolution_multipliers(struct hid_device *hid)
1638
+{
1639
+ struct hid_report_enum *rep_enum;
1640
+ struct hid_report *rep;
1641
+ int ret;
1642
+
1643
+ rep_enum = &hid->report_enum[HID_FEATURE_REPORT];
1644
+ list_for_each_entry(rep, &rep_enum->report_list, list) {
1645
+ bool update_needed = __hidinput_change_resolution_multipliers(hid,
1646
+ rep, true);
1647
+
1648
+ if (update_needed) {
1649
+ ret = __hid_request(hid, rep, HID_REQ_SET_REPORT);
1650
+ if (ret) {
1651
+ __hidinput_change_resolution_multipliers(hid,
1652
+ rep, false);
1653
+ return;
1654
+ }
1655
+ }
1656
+ }
1657
+
1658
+ /* refresh our structs */
1659
+ hid_setup_resolution_multiplier(hid);
1660
+}
1661
+
15261662 static void report_features(struct hid_device *hid)
15271663 {
15281664 struct hid_driver *drv = hid->driver;
....@@ -1558,6 +1694,7 @@
15581694 struct hid_input *hidinput = kzalloc(sizeof(*hidinput), GFP_KERNEL);
15591695 struct input_dev *input_dev = input_allocate_device();
15601696 const char *suffix = NULL;
1697
+ size_t suffix_len, name_len;
15611698
15621699 if (!hidinput || !input_dev)
15631700 goto fail;
....@@ -1601,10 +1738,15 @@
16011738 }
16021739
16031740 if (suffix) {
1604
- hidinput->name = kasprintf(GFP_KERNEL, "%s %s",
1605
- hid->name, suffix);
1606
- if (!hidinput->name)
1607
- goto fail;
1741
+ name_len = strlen(hid->name);
1742
+ suffix_len = strlen(suffix);
1743
+ if ((name_len < suffix_len) ||
1744
+ strcmp(hid->name + name_len - suffix_len, suffix)) {
1745
+ hidinput->name = kasprintf(GFP_KERNEL, "%s %s",
1746
+ hid->name, suffix);
1747
+ if (!hidinput->name)
1748
+ goto fail;
1749
+ }
16081750 }
16091751
16101752 input_set_drvdata(input_dev, hid);
....@@ -1810,6 +1952,8 @@
18101952 }
18111953 }
18121954
1955
+ hidinput_change_resolution_multipliers(hid);
1956
+
18131957 list_for_each_entry_safe(hidinput, next, &hid->inputs, list) {
18141958 if (drv->input_configured &&
18151959 drv->input_configured(hid, hidinput))
....@@ -1868,4 +2012,3 @@
18682012 cancel_work_sync(&hid->led_work);
18692013 }
18702014 EXPORT_SYMBOL_GPL(hidinput_disconnect);
1871
-