Skip to content

Commit cf26057

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid
Pull HID updates from Jiri Kosina: - high-resolution scrolling support that gracefully handles differences between MS and Logitech implementations in HW, from Peter Hutterer and Harry Cutts - MSI IRQ support for intel-ish driver, from Song Hongyan - support for new hardware (Cougar 700K, Odys Winbook 13, ASUS FX503VD, ASUS T101HA) from Daniel M. Lambea, Hans de Goede and Aleix Roca Nonell - other small assorted fixups * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid: (22 commits) HID: i2c-hid: Add Odys Winbook 13 to descriptor override HID: lenovo: Add checks to fix of_led_classdev_register HID: intel-ish-hid: add MSI interrupt support HID: debug: Change to use DEFINE_SHOW_ATTRIBUTE macro HID: doc: fix wrong data structure reference for UHID_OUTPUT HID: intel-ish-hid: fixes incorrect error handling HID: asus: Add support for the ASUS T101HA keyboard dock HID: logitech: Use LDJ_DEVICE macro for existing Logitech mice HID: logitech: Enable high-resolution scrolling on Logitech mice HID: logitech: Add function to enable HID++ 1.0 "scrolling acceleration" HID: logitech-hidpp: fix typo, hiddpp to hidpp HID: input: use the Resolution Multiplier for high-resolution scrolling HID: core: process the Resolution Multiplier HID: core: store the collections as a basic tree Input: add `REL_WHEEL_HI_RES` and `REL_HWHEEL_HI_RES` HID: input: support Microsoft wireless radio control hotkey HID: use macros in IS_INPUT_APPLICATION HID: asus: Add support for the ASUS FX503VD laptop HID: asus: Add event handler to catch unmapped Asus Vendor UsagePage codes HID: cougar: Add support for Cougar 700K Gaming Keyboard ...
2 parents 1686cc1 + bd8879f commit cf26057

File tree

17 files changed

+720
-61
lines changed

17 files changed

+720
-61
lines changed

Documentation/hid/uhid.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ them but you should handle them according to your needs.
160160
UHID_OUTPUT:
161161
This is sent if the HID device driver wants to send raw data to the I/O
162162
device on the interrupt channel. You should read the payload and forward it to
163-
the device. The payload is of type "struct uhid_data_req".
163+
the device. The payload is of type "struct uhid_output_req".
164164
This may be received even though you haven't received UHID_OPEN, yet.
165165

166166
UHID_GET_REPORT:

Documentation/input/event-codes.rst

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,26 @@ A few EV_REL codes have special meanings:
190190
* REL_WHEEL, REL_HWHEEL:
191191

192192
- These codes are used for vertical and horizontal scroll wheels,
193-
respectively.
193+
respectively. The value is the number of detents moved on the wheel, the
194+
physical size of which varies by device. For high-resolution wheels
195+
this may be an approximation based on the high-resolution scroll events,
196+
see REL_WHEEL_HI_RES. These event codes are legacy codes and
197+
REL_WHEEL_HI_RES and REL_HWHEEL_HI_RES should be preferred where
198+
available.
199+
200+
* REL_WHEEL_HI_RES, REL_HWHEEL_HI_RES:
201+
202+
- High-resolution scroll wheel data. The accumulated value 120 represents
203+
movement by one detent. For devices that do not provide high-resolution
204+
scrolling, the value is always a multiple of 120. For devices with
205+
high-resolution scrolling, the value may be a fraction of 120.
206+
207+
If a vertical scroll wheel supports high-resolution scrolling, this code
208+
will be emitted in addition to REL_WHEEL or REL_HWHEEL. The REL_WHEEL
209+
and REL_HWHEEL may be an approximation based on the high-resolution
210+
scroll events. There is no guarantee that the high-resolution data
211+
is a multiple of 120 at the time of an emulated REL_WHEEL or REL_HWHEEL
212+
event.
194213

195214
EV_ABS
196215
------

drivers/hid/hid-asus.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad");
7070
#define QUIRK_T100_KEYBOARD BIT(6)
7171
#define QUIRK_T100CHI BIT(7)
7272
#define QUIRK_G752_KEYBOARD BIT(8)
73+
#define QUIRK_T101HA_DOCK BIT(9)
7374

7475
#define I2C_KEYBOARD_QUIRKS (QUIRK_FIX_NOTEBOOK_REPORT | \
7576
QUIRK_NO_INIT_REPORTS | \
@@ -241,6 +242,18 @@ static int asus_report_input(struct asus_drvdata *drvdat, u8 *data, int size)
241242
return 1;
242243
}
243244

245+
static int asus_event(struct hid_device *hdev, struct hid_field *field,
246+
struct hid_usage *usage, __s32 value)
247+
{
248+
if ((usage->hid & HID_USAGE_PAGE) == 0xff310000 &&
249+
(usage->hid & HID_USAGE) != 0x00 && !usage->type) {
250+
hid_warn(hdev, "Unmapped Asus vendor usagepage code 0x%02x\n",
251+
usage->hid & HID_USAGE);
252+
}
253+
254+
return 0;
255+
}
256+
244257
static int asus_raw_event(struct hid_device *hdev,
245258
struct hid_report *report, u8 *data, int size)
246259
{
@@ -510,6 +523,7 @@ static int asus_input_mapping(struct hid_device *hdev,
510523
case 0x20: asus_map_key_clear(KEY_BRIGHTNESSUP); break;
511524
case 0x35: asus_map_key_clear(KEY_DISPLAY_OFF); break;
512525
case 0x6c: asus_map_key_clear(KEY_SLEEP); break;
526+
case 0x7c: asus_map_key_clear(KEY_MICMUTE); break;
513527
case 0x82: asus_map_key_clear(KEY_CAMERA); break;
514528
case 0x88: asus_map_key_clear(KEY_RFKILL); break;
515529
case 0xb5: asus_map_key_clear(KEY_CALC); break;
@@ -528,6 +542,9 @@ static int asus_input_mapping(struct hid_device *hdev,
528542
/* Fn+Space Power4Gear Hybrid */
529543
case 0x5c: asus_map_key_clear(KEY_PROG3); break;
530544

545+
/* Fn+F5 "fan" symbol on FX503VD */
546+
case 0x99: asus_map_key_clear(KEY_PROG4); break;
547+
531548
default:
532549
/* ASUS lazily declares 256 usages, ignore the rest,
533550
* as some make the keyboard appear as a pointer device. */
@@ -683,6 +700,11 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
683700
return ret;
684701
}
685702

703+
/* use hid-multitouch for T101HA touchpad */
704+
if (id->driver_data & QUIRK_T101HA_DOCK &&
705+
hdev->collection->usage == HID_GD_MOUSE)
706+
return -ENODEV;
707+
686708
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
687709
if (ret) {
688710
hid_err(hdev, "Asus hw start failed: %d\n", ret);
@@ -805,12 +827,17 @@ static const struct hid_device_id asus_devices[] = {
805827
USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD2), QUIRK_USE_KBD_BACKLIGHT },
806828
{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
807829
USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD3), QUIRK_G752_KEYBOARD },
830+
{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
831+
USB_DEVICE_ID_ASUSTEK_FX503VD_KEYBOARD),
832+
QUIRK_USE_KBD_BACKLIGHT },
808833
{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
809834
USB_DEVICE_ID_ASUSTEK_T100TA_KEYBOARD),
810835
QUIRK_T100_KEYBOARD | QUIRK_NO_CONSUMER_USAGES },
811836
{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
812837
USB_DEVICE_ID_ASUSTEK_T100TAF_KEYBOARD),
813838
QUIRK_T100_KEYBOARD | QUIRK_NO_CONSUMER_USAGES },
839+
{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
840+
USB_DEVICE_ID_ASUSTEK_T101HA_KEYBOARD), QUIRK_T101HA_DOCK },
814841
{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_ASUS_AK1D) },
815842
{ HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_ASUS_MD_5110) },
816843
{ HID_USB_DEVICE(USB_VENDOR_ID_JESS, USB_DEVICE_ID_ASUS_MD_5112) },
@@ -832,6 +859,7 @@ static struct hid_driver asus_driver = {
832859
#ifdef CONFIG_PM
833860
.reset_resume = asus_reset_resume,
834861
#endif
862+
.event = asus_event,
835863
.raw_event = asus_raw_event
836864
};
837865
module_hid_driver(asus_driver);

drivers/hid/hid-core.c

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ static int open_collection(struct hid_parser *parser, unsigned type)
172172
collection->type = type;
173173
collection->usage = usage;
174174
collection->level = parser->collection_stack_ptr - 1;
175+
collection->parent = parser->active_collection;
176+
parser->active_collection = collection;
175177

176178
if (type == HID_COLLECTION_APPLICATION)
177179
parser->device->maxapplication++;
@@ -190,6 +192,8 @@ static int close_collection(struct hid_parser *parser)
190192
return -EINVAL;
191193
}
192194
parser->collection_stack_ptr--;
195+
if (parser->active_collection)
196+
parser->active_collection = parser->active_collection->parent;
193197
return 0;
194198
}
195199

@@ -290,6 +294,7 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign
290294
field->usage[i].collection_index =
291295
parser->local.collection_index[j];
292296
field->usage[i].usage_index = i;
297+
field->usage[i].resolution_multiplier = 1;
293298
}
294299

295300
field->maxusage = usages;
@@ -943,6 +948,167 @@ struct hid_report *hid_validate_values(struct hid_device *hid,
943948
}
944949
EXPORT_SYMBOL_GPL(hid_validate_values);
945950

951+
static int hid_calculate_multiplier(struct hid_device *hid,
952+
struct hid_field *multiplier)
953+
{
954+
int m;
955+
__s32 v = *multiplier->value;
956+
__s32 lmin = multiplier->logical_minimum;
957+
__s32 lmax = multiplier->logical_maximum;
958+
__s32 pmin = multiplier->physical_minimum;
959+
__s32 pmax = multiplier->physical_maximum;
960+
961+
/*
962+
* "Because OS implementations will generally divide the control's
963+
* reported count by the Effective Resolution Multiplier, designers
964+
* should take care not to establish a potential Effective
965+
* Resolution Multiplier of zero."
966+
* HID Usage Table, v1.12, Section 4.3.1, p31
967+
*/
968+
if (lmax - lmin == 0)
969+
return 1;
970+
/*
971+
* Handling the unit exponent is left as an exercise to whoever
972+
* finds a device where that exponent is not 0.
973+
*/
974+
m = ((v - lmin)/(lmax - lmin) * (pmax - pmin) + pmin);
975+
if (unlikely(multiplier->unit_exponent != 0)) {
976+
hid_warn(hid,
977+
"unsupported Resolution Multiplier unit exponent %d\n",
978+
multiplier->unit_exponent);
979+
}
980+
981+
/* There are no devices with an effective multiplier > 255 */
982+
if (unlikely(m == 0 || m > 255 || m < -255)) {
983+
hid_warn(hid, "unsupported Resolution Multiplier %d\n", m);
984+
m = 1;
985+
}
986+
987+
return m;
988+
}
989+
990+
static void hid_apply_multiplier_to_field(struct hid_device *hid,
991+
struct hid_field *field,
992+
struct hid_collection *multiplier_collection,
993+
int effective_multiplier)
994+
{
995+
struct hid_collection *collection;
996+
struct hid_usage *usage;
997+
int i;
998+
999+
/*
1000+
* If multiplier_collection is NULL, the multiplier applies
1001+
* to all fields in the report.
1002+
* Otherwise, it is the Logical Collection the multiplier applies to
1003+
* but our field may be in a subcollection of that collection.
1004+
*/
1005+
for (i = 0; i < field->maxusage; i++) {
1006+
usage = &field->usage[i];
1007+
1008+
collection = &hid->collection[usage->collection_index];
1009+
while (collection && collection != multiplier_collection)
1010+
collection = collection->parent;
1011+
1012+
if (collection || multiplier_collection == NULL)
1013+
usage->resolution_multiplier = effective_multiplier;
1014+
1015+
}
1016+
}
1017+
1018+
static void hid_apply_multiplier(struct hid_device *hid,
1019+
struct hid_field *multiplier)
1020+
{
1021+
struct hid_report_enum *rep_enum;
1022+
struct hid_report *rep;
1023+
struct hid_field *field;
1024+
struct hid_collection *multiplier_collection;
1025+
int effective_multiplier;
1026+
int i;
1027+
1028+
/*
1029+
* "The Resolution Multiplier control must be contained in the same
1030+
* Logical Collection as the control(s) to which it is to be applied.
1031+
* If no Resolution Multiplier is defined, then the Resolution
1032+
* Multiplier defaults to 1. If more than one control exists in a
1033+
* Logical Collection, the Resolution Multiplier is associated with
1034+
* all controls in the collection. If no Logical Collection is
1035+
* defined, the Resolution Multiplier is associated with all
1036+
* controls in the report."
1037+
* HID Usage Table, v1.12, Section 4.3.1, p30
1038+
*
1039+
* Thus, search from the current collection upwards until we find a
1040+
* logical collection. Then search all fields for that same parent
1041+
* collection. Those are the fields the multiplier applies to.
1042+
*
1043+
* If we have more than one multiplier, it will overwrite the
1044+
* applicable fields later.
1045+
*/
1046+
multiplier_collection = &hid->collection[multiplier->usage->collection_index];
1047+
while (multiplier_collection &&
1048+
multiplier_collection->type != HID_COLLECTION_LOGICAL)
1049+
multiplier_collection = multiplier_collection->parent;
1050+
1051+
effective_multiplier = hid_calculate_multiplier(hid, multiplier);
1052+
1053+
rep_enum = &hid->report_enum[HID_INPUT_REPORT];
1054+
list_for_each_entry(rep, &rep_enum->report_list, list) {
1055+
for (i = 0; i < rep->maxfield; i++) {
1056+
field = rep->field[i];
1057+
hid_apply_multiplier_to_field(hid, field,
1058+
multiplier_collection,
1059+
effective_multiplier);
1060+
}
1061+
}
1062+
}
1063+
1064+
/*
1065+
* hid_setup_resolution_multiplier - set up all resolution multipliers
1066+
*
1067+
* @device: hid device
1068+
*
1069+
* Search for all Resolution Multiplier Feature Reports and apply their
1070+
* value to all matching Input items. This only updates the internal struct
1071+
* fields.
1072+
*
1073+
* The Resolution Multiplier is applied by the hardware. If the multiplier
1074+
* is anything other than 1, the hardware will send pre-multiplied events
1075+
* so that the same physical interaction generates an accumulated
1076+
* accumulated_value = value * * multiplier
1077+
* This may be achieved by sending
1078+
* - "value * multiplier" for each event, or
1079+
* - "value" but "multiplier" times as frequently, or
1080+
* - a combination of the above
1081+
* The only guarantee is that the same physical interaction always generates
1082+
* an accumulated 'value * multiplier'.
1083+
*
1084+
* This function must be called before any event processing and after
1085+
* any SetRequest to the Resolution Multiplier.
1086+
*/
1087+
void hid_setup_resolution_multiplier(struct hid_device *hid)
1088+
{
1089+
struct hid_report_enum *rep_enum;
1090+
struct hid_report *rep;
1091+
struct hid_usage *usage;
1092+
int i, j;
1093+
1094+
rep_enum = &hid->report_enum[HID_FEATURE_REPORT];
1095+
list_for_each_entry(rep, &rep_enum->report_list, list) {
1096+
for (i = 0; i < rep->maxfield; i++) {
1097+
/* Ignore if report count is out of bounds. */
1098+
if (rep->field[i]->report_count < 1)
1099+
continue;
1100+
1101+
for (j = 0; j < rep->field[i]->maxusage; j++) {
1102+
usage = &rep->field[i]->usage[j];
1103+
if (usage->hid == HID_GD_RESOLUTION_MULTIPLIER)
1104+
hid_apply_multiplier(hid,
1105+
rep->field[i]);
1106+
}
1107+
}
1108+
}
1109+
}
1110+
EXPORT_SYMBOL_GPL(hid_setup_resolution_multiplier);
1111+
9461112
/**
9471113
* hid_open_report - open a driver-specific device report
9481114
*
@@ -1039,9 +1205,17 @@ int hid_open_report(struct hid_device *device)
10391205
hid_err(device, "unbalanced delimiter at end of report description\n");
10401206
goto err;
10411207
}
1208+
1209+
/*
1210+
* fetch initial values in case the device's
1211+
* default multiplier isn't the recommended 1
1212+
*/
1213+
hid_setup_resolution_multiplier(device);
1214+
10421215
kfree(parser->collection_stack);
10431216
vfree(parser);
10441217
device->status |= HID_STAT_PARSED;
1218+
10451219
return 0;
10461220
}
10471221
}

drivers/hid/hid-cougar.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,8 @@ module_param_cb(g6_is_space, &cougar_g6_is_space_ops, &g6_is_space, 0644);
326326
static struct hid_device_id cougar_id_table[] = {
327327
{ HID_USB_DEVICE(USB_VENDOR_ID_SOLID_YEAR,
328328
USB_DEVICE_ID_COUGAR_500K_GAMING_KEYBOARD) },
329+
{ HID_USB_DEVICE(USB_VENDOR_ID_SOLID_YEAR,
330+
USB_DEVICE_ID_COUGAR_700K_GAMING_KEYBOARD) },
329331
{}
330332
};
331333
MODULE_DEVICE_TABLE(hid, cougar_id_table);

drivers/hid/hid-debug.c

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,11 +1072,6 @@ static int hid_debug_rdesc_show(struct seq_file *f, void *p)
10721072
return 0;
10731073
}
10741074

1075-
static int hid_debug_rdesc_open(struct inode *inode, struct file *file)
1076-
{
1077-
return single_open(file, hid_debug_rdesc_show, inode->i_private);
1078-
}
1079-
10801075
static int hid_debug_events_open(struct inode *inode, struct file *file)
10811076
{
10821077
int err = 0;
@@ -1211,12 +1206,7 @@ static int hid_debug_events_release(struct inode *inode, struct file *file)
12111206
return 0;
12121207
}
12131208

1214-
static const struct file_operations hid_debug_rdesc_fops = {
1215-
.open = hid_debug_rdesc_open,
1216-
.read = seq_read,
1217-
.llseek = seq_lseek,
1218-
.release = single_release,
1219-
};
1209+
DEFINE_SHOW_ATTRIBUTE(hid_debug_rdesc);
12201210

12211211
static const struct file_operations hid_debug_events_fops = {
12221212
.owner = THIS_MODULE,

drivers/hid/hid-ids.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,12 +187,14 @@
187187
#define USB_DEVICE_ID_ASUSTEK_T100TA_KEYBOARD 0x17e0
188188
#define USB_DEVICE_ID_ASUSTEK_T100TAF_KEYBOARD 0x1807
189189
#define USB_DEVICE_ID_ASUSTEK_T100CHI_KEYBOARD 0x8502
190+
#define USB_DEVICE_ID_ASUSTEK_T101HA_KEYBOARD 0x183d
190191
#define USB_DEVICE_ID_ASUSTEK_T304_KEYBOARD 0x184a
191192
#define USB_DEVICE_ID_ASUSTEK_I2C_KEYBOARD 0x8585
192193
#define USB_DEVICE_ID_ASUSTEK_I2C_TOUCHPAD 0x0101
193194
#define USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD1 0x1854
194195
#define USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD2 0x1837
195196
#define USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD3 0x1822
197+
#define USB_DEVICE_ID_ASUSTEK_FX503VD_KEYBOARD 0x1869
196198

197199
#define USB_VENDOR_ID_ATEN 0x0557
198200
#define USB_DEVICE_ID_ATEN_UC100KM 0x2004
@@ -1025,6 +1027,7 @@
10251027

10261028
#define USB_VENDOR_ID_SOLID_YEAR 0x060b
10271029
#define USB_DEVICE_ID_COUGAR_500K_GAMING_KEYBOARD 0x500a
1030+
#define USB_DEVICE_ID_COUGAR_700K_GAMING_KEYBOARD 0x700a
10281031

10291032
#define USB_VENDOR_ID_SOUNDGRAPH 0x15c2
10301033
#define USB_DEVICE_ID_SOUNDGRAPH_IMON_FIRST 0x0034

0 commit comments

Comments
 (0)