| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * HID support for Linux |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 8 | 9 | */ |
|---|
| 9 | 10 | |
|---|
| 10 | 11 | /* |
|---|
| 11 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 12 | | - * under the terms of the GNU General Public License as published by the Free |
|---|
| 13 | | - * Software Foundation; either version 2 of the License, or (at your option) |
|---|
| 14 | | - * any later version. |
|---|
| 15 | 12 | */ |
|---|
| 16 | 13 | |
|---|
| 17 | 14 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
|---|
| .. | .. |
|---|
| 125 | 122 | { |
|---|
| 126 | 123 | struct hid_collection *collection; |
|---|
| 127 | 124 | unsigned usage; |
|---|
| 125 | + int collection_index; |
|---|
| 128 | 126 | |
|---|
| 129 | 127 | usage = parser->local.usage[0]; |
|---|
| 130 | 128 | |
|---|
| .. | .. |
|---|
| 167 | 165 | parser->collection_stack[parser->collection_stack_ptr++] = |
|---|
| 168 | 166 | parser->device->maxcollection; |
|---|
| 169 | 167 | |
|---|
| 170 | | - collection = parser->device->collection + |
|---|
| 171 | | - parser->device->maxcollection++; |
|---|
| 168 | + collection_index = parser->device->maxcollection++; |
|---|
| 169 | + collection = parser->device->collection + collection_index; |
|---|
| 172 | 170 | collection->type = type; |
|---|
| 173 | 171 | collection->usage = usage; |
|---|
| 174 | 172 | collection->level = parser->collection_stack_ptr - 1; |
|---|
| 173 | + collection->parent_idx = (collection->level == 0) ? -1 : |
|---|
| 174 | + parser->collection_stack[collection->level - 1]; |
|---|
| 175 | 175 | |
|---|
| 176 | 176 | if (type == HID_COLLECTION_APPLICATION) |
|---|
| 177 | 177 | parser->device->maxapplication++; |
|---|
| .. | .. |
|---|
| 317 | 317 | field->usage[i].collection_index = |
|---|
| 318 | 318 | parser->local.collection_index[j]; |
|---|
| 319 | 319 | field->usage[i].usage_index = i; |
|---|
| 320 | + field->usage[i].resolution_multiplier = 1; |
|---|
| 320 | 321 | } |
|---|
| 321 | 322 | |
|---|
| 322 | 323 | field->maxusage = usages; |
|---|
| .. | .. |
|---|
| 433 | 434 | |
|---|
| 434 | 435 | case HID_GLOBAL_ITEM_TAG_REPORT_SIZE: |
|---|
| 435 | 436 | parser->global.report_size = item_udata(item); |
|---|
| 436 | | - if (parser->global.report_size > 128) { |
|---|
| 437 | + if (parser->global.report_size > 256) { |
|---|
| 437 | 438 | hid_err(parser->device, "invalid report_size %d\n", |
|---|
| 438 | 439 | parser->global.report_size); |
|---|
| 439 | 440 | return -1; |
|---|
| .. | .. |
|---|
| 813 | 814 | |
|---|
| 814 | 815 | if ((parser->global.usage_page << 16) >= HID_UP_MSVENDOR) |
|---|
| 815 | 816 | parser->scan_flags |= HID_SCAN_FLAG_VENDOR_SPECIFIC; |
|---|
| 817 | + |
|---|
| 818 | + if ((parser->global.usage_page << 16) == HID_UP_GOOGLEVENDOR) |
|---|
| 819 | + for (i = 0; i < parser->local.usage_index; i++) |
|---|
| 820 | + if (parser->local.usage[i] == |
|---|
| 821 | + (HID_UP_GOOGLEVENDOR | 0x0001)) |
|---|
| 822 | + parser->device->group = |
|---|
| 823 | + HID_GROUP_VIVALDI; |
|---|
| 816 | 824 | } |
|---|
| 817 | 825 | |
|---|
| 818 | 826 | static int hid_scan_main(struct hid_parser *parser, struct hid_item *item) |
|---|
| .. | .. |
|---|
| 919 | 927 | /** |
|---|
| 920 | 928 | * hid_parse_report - parse device report |
|---|
| 921 | 929 | * |
|---|
| 922 | | - * @device: hid device |
|---|
| 930 | + * @hid: hid device |
|---|
| 923 | 931 | * @start: report start |
|---|
| 924 | 932 | * @size: report size |
|---|
| 925 | 933 | * |
|---|
| .. | .. |
|---|
| 944 | 952 | /** |
|---|
| 945 | 953 | * hid_validate_values - validate existing device report's value indexes |
|---|
| 946 | 954 | * |
|---|
| 947 | | - * @device: hid device |
|---|
| 955 | + * @hid: hid device |
|---|
| 948 | 956 | * @type: which report type to examine |
|---|
| 949 | 957 | * @id: which report ID to examine (0 for first) |
|---|
| 950 | 958 | * @field_index: which report field to examine |
|---|
| .. | .. |
|---|
| 1003 | 1011 | return report; |
|---|
| 1004 | 1012 | } |
|---|
| 1005 | 1013 | EXPORT_SYMBOL_GPL(hid_validate_values); |
|---|
| 1014 | + |
|---|
| 1015 | +static int hid_calculate_multiplier(struct hid_device *hid, |
|---|
| 1016 | + struct hid_field *multiplier) |
|---|
| 1017 | +{ |
|---|
| 1018 | + int m; |
|---|
| 1019 | + __s32 v = *multiplier->value; |
|---|
| 1020 | + __s32 lmin = multiplier->logical_minimum; |
|---|
| 1021 | + __s32 lmax = multiplier->logical_maximum; |
|---|
| 1022 | + __s32 pmin = multiplier->physical_minimum; |
|---|
| 1023 | + __s32 pmax = multiplier->physical_maximum; |
|---|
| 1024 | + |
|---|
| 1025 | + /* |
|---|
| 1026 | + * "Because OS implementations will generally divide the control's |
|---|
| 1027 | + * reported count by the Effective Resolution Multiplier, designers |
|---|
| 1028 | + * should take care not to establish a potential Effective |
|---|
| 1029 | + * Resolution Multiplier of zero." |
|---|
| 1030 | + * HID Usage Table, v1.12, Section 4.3.1, p31 |
|---|
| 1031 | + */ |
|---|
| 1032 | + if (lmax - lmin == 0) |
|---|
| 1033 | + return 1; |
|---|
| 1034 | + /* |
|---|
| 1035 | + * Handling the unit exponent is left as an exercise to whoever |
|---|
| 1036 | + * finds a device where that exponent is not 0. |
|---|
| 1037 | + */ |
|---|
| 1038 | + m = ((v - lmin)/(lmax - lmin) * (pmax - pmin) + pmin); |
|---|
| 1039 | + if (unlikely(multiplier->unit_exponent != 0)) { |
|---|
| 1040 | + hid_warn(hid, |
|---|
| 1041 | + "unsupported Resolution Multiplier unit exponent %d\n", |
|---|
| 1042 | + multiplier->unit_exponent); |
|---|
| 1043 | + } |
|---|
| 1044 | + |
|---|
| 1045 | + /* There are no devices with an effective multiplier > 255 */ |
|---|
| 1046 | + if (unlikely(m == 0 || m > 255 || m < -255)) { |
|---|
| 1047 | + hid_warn(hid, "unsupported Resolution Multiplier %d\n", m); |
|---|
| 1048 | + m = 1; |
|---|
| 1049 | + } |
|---|
| 1050 | + |
|---|
| 1051 | + return m; |
|---|
| 1052 | +} |
|---|
| 1053 | + |
|---|
| 1054 | +static void hid_apply_multiplier_to_field(struct hid_device *hid, |
|---|
| 1055 | + struct hid_field *field, |
|---|
| 1056 | + struct hid_collection *multiplier_collection, |
|---|
| 1057 | + int effective_multiplier) |
|---|
| 1058 | +{ |
|---|
| 1059 | + struct hid_collection *collection; |
|---|
| 1060 | + struct hid_usage *usage; |
|---|
| 1061 | + int i; |
|---|
| 1062 | + |
|---|
| 1063 | + /* |
|---|
| 1064 | + * If multiplier_collection is NULL, the multiplier applies |
|---|
| 1065 | + * to all fields in the report. |
|---|
| 1066 | + * Otherwise, it is the Logical Collection the multiplier applies to |
|---|
| 1067 | + * but our field may be in a subcollection of that collection. |
|---|
| 1068 | + */ |
|---|
| 1069 | + for (i = 0; i < field->maxusage; i++) { |
|---|
| 1070 | + usage = &field->usage[i]; |
|---|
| 1071 | + |
|---|
| 1072 | + collection = &hid->collection[usage->collection_index]; |
|---|
| 1073 | + while (collection->parent_idx != -1 && |
|---|
| 1074 | + collection != multiplier_collection) |
|---|
| 1075 | + collection = &hid->collection[collection->parent_idx]; |
|---|
| 1076 | + |
|---|
| 1077 | + if (collection->parent_idx != -1 || |
|---|
| 1078 | + multiplier_collection == NULL) |
|---|
| 1079 | + usage->resolution_multiplier = effective_multiplier; |
|---|
| 1080 | + |
|---|
| 1081 | + } |
|---|
| 1082 | +} |
|---|
| 1083 | + |
|---|
| 1084 | +static void hid_apply_multiplier(struct hid_device *hid, |
|---|
| 1085 | + struct hid_field *multiplier) |
|---|
| 1086 | +{ |
|---|
| 1087 | + struct hid_report_enum *rep_enum; |
|---|
| 1088 | + struct hid_report *rep; |
|---|
| 1089 | + struct hid_field *field; |
|---|
| 1090 | + struct hid_collection *multiplier_collection; |
|---|
| 1091 | + int effective_multiplier; |
|---|
| 1092 | + int i; |
|---|
| 1093 | + |
|---|
| 1094 | + /* |
|---|
| 1095 | + * "The Resolution Multiplier control must be contained in the same |
|---|
| 1096 | + * Logical Collection as the control(s) to which it is to be applied. |
|---|
| 1097 | + * If no Resolution Multiplier is defined, then the Resolution |
|---|
| 1098 | + * Multiplier defaults to 1. If more than one control exists in a |
|---|
| 1099 | + * Logical Collection, the Resolution Multiplier is associated with |
|---|
| 1100 | + * all controls in the collection. If no Logical Collection is |
|---|
| 1101 | + * defined, the Resolution Multiplier is associated with all |
|---|
| 1102 | + * controls in the report." |
|---|
| 1103 | + * HID Usage Table, v1.12, Section 4.3.1, p30 |
|---|
| 1104 | + * |
|---|
| 1105 | + * Thus, search from the current collection upwards until we find a |
|---|
| 1106 | + * logical collection. Then search all fields for that same parent |
|---|
| 1107 | + * collection. Those are the fields the multiplier applies to. |
|---|
| 1108 | + * |
|---|
| 1109 | + * If we have more than one multiplier, it will overwrite the |
|---|
| 1110 | + * applicable fields later. |
|---|
| 1111 | + */ |
|---|
| 1112 | + multiplier_collection = &hid->collection[multiplier->usage->collection_index]; |
|---|
| 1113 | + while (multiplier_collection->parent_idx != -1 && |
|---|
| 1114 | + multiplier_collection->type != HID_COLLECTION_LOGICAL) |
|---|
| 1115 | + multiplier_collection = &hid->collection[multiplier_collection->parent_idx]; |
|---|
| 1116 | + |
|---|
| 1117 | + effective_multiplier = hid_calculate_multiplier(hid, multiplier); |
|---|
| 1118 | + |
|---|
| 1119 | + rep_enum = &hid->report_enum[HID_INPUT_REPORT]; |
|---|
| 1120 | + list_for_each_entry(rep, &rep_enum->report_list, list) { |
|---|
| 1121 | + for (i = 0; i < rep->maxfield; i++) { |
|---|
| 1122 | + field = rep->field[i]; |
|---|
| 1123 | + hid_apply_multiplier_to_field(hid, field, |
|---|
| 1124 | + multiplier_collection, |
|---|
| 1125 | + effective_multiplier); |
|---|
| 1126 | + } |
|---|
| 1127 | + } |
|---|
| 1128 | +} |
|---|
| 1129 | + |
|---|
| 1130 | +/* |
|---|
| 1131 | + * hid_setup_resolution_multiplier - set up all resolution multipliers |
|---|
| 1132 | + * |
|---|
| 1133 | + * @device: hid device |
|---|
| 1134 | + * |
|---|
| 1135 | + * Search for all Resolution Multiplier Feature Reports and apply their |
|---|
| 1136 | + * value to all matching Input items. This only updates the internal struct |
|---|
| 1137 | + * fields. |
|---|
| 1138 | + * |
|---|
| 1139 | + * The Resolution Multiplier is applied by the hardware. If the multiplier |
|---|
| 1140 | + * is anything other than 1, the hardware will send pre-multiplied events |
|---|
| 1141 | + * so that the same physical interaction generates an accumulated |
|---|
| 1142 | + * accumulated_value = value * * multiplier |
|---|
| 1143 | + * This may be achieved by sending |
|---|
| 1144 | + * - "value * multiplier" for each event, or |
|---|
| 1145 | + * - "value" but "multiplier" times as frequently, or |
|---|
| 1146 | + * - a combination of the above |
|---|
| 1147 | + * The only guarantee is that the same physical interaction always generates |
|---|
| 1148 | + * an accumulated 'value * multiplier'. |
|---|
| 1149 | + * |
|---|
| 1150 | + * This function must be called before any event processing and after |
|---|
| 1151 | + * any SetRequest to the Resolution Multiplier. |
|---|
| 1152 | + */ |
|---|
| 1153 | +void hid_setup_resolution_multiplier(struct hid_device *hid) |
|---|
| 1154 | +{ |
|---|
| 1155 | + struct hid_report_enum *rep_enum; |
|---|
| 1156 | + struct hid_report *rep; |
|---|
| 1157 | + struct hid_usage *usage; |
|---|
| 1158 | + int i, j; |
|---|
| 1159 | + |
|---|
| 1160 | + rep_enum = &hid->report_enum[HID_FEATURE_REPORT]; |
|---|
| 1161 | + list_for_each_entry(rep, &rep_enum->report_list, list) { |
|---|
| 1162 | + for (i = 0; i < rep->maxfield; i++) { |
|---|
| 1163 | + /* Ignore if report count is out of bounds. */ |
|---|
| 1164 | + if (rep->field[i]->report_count < 1) |
|---|
| 1165 | + continue; |
|---|
| 1166 | + |
|---|
| 1167 | + for (j = 0; j < rep->field[i]->maxusage; j++) { |
|---|
| 1168 | + usage = &rep->field[i]->usage[j]; |
|---|
| 1169 | + if (usage->hid == HID_GD_RESOLUTION_MULTIPLIER) |
|---|
| 1170 | + hid_apply_multiplier(hid, |
|---|
| 1171 | + rep->field[i]); |
|---|
| 1172 | + } |
|---|
| 1173 | + } |
|---|
| 1174 | + } |
|---|
| 1175 | +} |
|---|
| 1176 | +EXPORT_SYMBOL_GPL(hid_setup_resolution_multiplier); |
|---|
| 1006 | 1177 | |
|---|
| 1007 | 1178 | /** |
|---|
| 1008 | 1179 | * hid_open_report - open a driver-specific device report |
|---|
| .. | .. |
|---|
| 1102 | 1273 | hid_err(device, "unbalanced delimiter at end of report description\n"); |
|---|
| 1103 | 1274 | goto err; |
|---|
| 1104 | 1275 | } |
|---|
| 1276 | + |
|---|
| 1277 | + /* |
|---|
| 1278 | + * fetch initial values in case the device's |
|---|
| 1279 | + * default multiplier isn't the recommended 1 |
|---|
| 1280 | + */ |
|---|
| 1281 | + hid_setup_resolution_multiplier(device); |
|---|
| 1282 | + |
|---|
| 1105 | 1283 | kfree(parser->collection_stack); |
|---|
| 1106 | 1284 | vfree(parser); |
|---|
| 1107 | 1285 | device->status |= HID_STAT_PARSED; |
|---|
| 1286 | + |
|---|
| 1108 | 1287 | return 0; |
|---|
| 1109 | 1288 | } |
|---|
| 1110 | 1289 | } |
|---|
| .. | .. |
|---|
| 1130 | 1309 | { |
|---|
| 1131 | 1310 | if (!value || !n) |
|---|
| 1132 | 1311 | return 0; |
|---|
| 1312 | + |
|---|
| 1313 | + if (n > 32) |
|---|
| 1314 | + n = 32; |
|---|
| 1133 | 1315 | |
|---|
| 1134 | 1316 | switch (n) { |
|---|
| 1135 | 1317 | case 8: return ((__s8)value); |
|---|
| .. | .. |
|---|
| 1194 | 1376 | unsigned offset, unsigned n) |
|---|
| 1195 | 1377 | { |
|---|
| 1196 | 1378 | if (n > 32) { |
|---|
| 1197 | | - hid_warn(hid, "hid_field_extract() called with n (%d) > 32! (%s)\n", |
|---|
| 1198 | | - n, current->comm); |
|---|
| 1379 | + hid_warn_once(hid, "%s() called with n (%d) > 32! (%s)\n", |
|---|
| 1380 | + __func__, n, current->comm); |
|---|
| 1199 | 1381 | n = 32; |
|---|
| 1200 | 1382 | } |
|---|
| 1201 | 1383 | |
|---|
| .. | .. |
|---|
| 1275 | 1457 | * hid_match_report - check if driver's raw_event should be called |
|---|
| 1276 | 1458 | * |
|---|
| 1277 | 1459 | * @hid: hid device |
|---|
| 1278 | | - * @report_type: type to match against |
|---|
| 1460 | + * @report: hid report to match against |
|---|
| 1279 | 1461 | * |
|---|
| 1280 | 1462 | * compare hid->driver->report_table->report_type to report->type |
|---|
| 1281 | 1463 | */ |
|---|
| .. | .. |
|---|
| 1527 | 1709 | * Implement a generic .request() callback, using .raw_request() |
|---|
| 1528 | 1710 | * DO NOT USE in hid drivers directly, but through hid_hw_request instead. |
|---|
| 1529 | 1711 | */ |
|---|
| 1530 | | -void __hid_request(struct hid_device *hid, struct hid_report *report, |
|---|
| 1712 | +int __hid_request(struct hid_device *hid, struct hid_report *report, |
|---|
| 1531 | 1713 | int reqtype) |
|---|
| 1532 | 1714 | { |
|---|
| 1533 | 1715 | char *buf; |
|---|
| .. | .. |
|---|
| 1536 | 1718 | |
|---|
| 1537 | 1719 | buf = hid_alloc_report_buf(report, GFP_KERNEL); |
|---|
| 1538 | 1720 | if (!buf) |
|---|
| 1539 | | - return; |
|---|
| 1721 | + return -ENOMEM; |
|---|
| 1540 | 1722 | |
|---|
| 1541 | 1723 | len = hid_report_len(report); |
|---|
| 1542 | 1724 | |
|---|
| .. | .. |
|---|
| 1553 | 1735 | if (reqtype == HID_REQ_GET_REPORT) |
|---|
| 1554 | 1736 | hid_input_report(hid, report->type, buf, ret, 0); |
|---|
| 1555 | 1737 | |
|---|
| 1738 | + ret = 0; |
|---|
| 1739 | + |
|---|
| 1556 | 1740 | out: |
|---|
| 1557 | 1741 | kfree(buf); |
|---|
| 1742 | + return ret; |
|---|
| 1558 | 1743 | } |
|---|
| 1559 | 1744 | EXPORT_SYMBOL_GPL(__hid_request); |
|---|
| 1560 | 1745 | |
|---|
| .. | .. |
|---|
| 1951 | 2136 | |
|---|
| 1952 | 2137 | /** |
|---|
| 1953 | 2138 | * store_new_id - add a new HID device ID to this driver and re-probe devices |
|---|
| 1954 | | - * @driver: target device driver |
|---|
| 2139 | + * @drv: target device driver |
|---|
| 1955 | 2140 | * @buf: buffer for scanning device ID data |
|---|
| 1956 | 2141 | * @count: input size |
|---|
| 1957 | 2142 | * |
|---|
| .. | .. |
|---|
| 2443 | 2628 | hid_quirks_exit(HID_BUS_ANY); |
|---|
| 2444 | 2629 | } |
|---|
| 2445 | 2630 | |
|---|
| 2446 | | -#ifdef CONFIG_ROCKCHIP_THUNDER_BOOT |
|---|
| 2447 | | -rootfs_initcall(hid_init); |
|---|
| 2448 | | -#else |
|---|
| 2449 | 2631 | module_init(hid_init); |
|---|
| 2450 | | -#endif |
|---|
| 2451 | 2632 | module_exit(hid_exit); |
|---|
| 2452 | 2633 | |
|---|
| 2453 | 2634 | MODULE_AUTHOR("Andreas Gal"); |
|---|