Commit | Line | Data |
---|---|---|
64b386ea | 1 | /* |
0bb7a37f | 2 | * HID driver for ELECOM devices. |
64b386ea | 3 | * Copyright (c) 2010 Richard Nauber <Richard.Nauber@gmail.com> |
0bb7a37f DEP |
4 | * Copyright (c) 2016 Yuxuan Shui <yshuiv7@gmail.com> |
5 | * Copyright (c) 2017 Diego Elio Pettenò <flameeyes@flameeyes.eu> | |
a0933a45 | 6 | * Copyright (c) 2017 Alex Manoussakis <amanou@gnu.org> |
64b386ea RN |
7 | */ |
8 | ||
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; either version 2 of the License, or (at your option) | |
13 | * any later version. | |
14 | */ | |
15 | ||
16 | #include <linux/device.h> | |
17 | #include <linux/hid.h> | |
18 | #include <linux/module.h> | |
19 | ||
20 | #include "hid-ids.h" | |
21 | ||
73e4008d NK |
22 | static __u8 *elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
23 | unsigned int *rsize) | |
64b386ea | 24 | { |
0bb7a37f DEP |
25 | switch (hdev->product) { |
26 | case USB_DEVICE_ID_ELECOM_BM084: | |
27 | /* The BM084 Bluetooth mouse includes a non-existing horizontal | |
28 | * wheel in the HID descriptor. */ | |
29 | if (*rsize >= 48 && rdesc[46] == 0x05 && rdesc[47] == 0x0c) { | |
30 | hid_info(hdev, "Fixing up Elecom BM084 report descriptor\n"); | |
31 | rdesc[47] = 0x00; | |
32 | } | |
33 | break; | |
34 | case USB_DEVICE_ID_ELECOM_DEFT_WIRED: | |
35 | case USB_DEVICE_ID_ELECOM_DEFT_WIRELESS: | |
a0933a45 AM |
36 | case USB_DEVICE_ID_ELECOM_HUGE_WIRED: |
37 | case USB_DEVICE_ID_ELECOM_HUGE_WIRELESS: | |
38 | /* The DEFT/HUGE trackball has eight buttons, but its descriptor | |
39 | * only reports five, disabling the three Fn buttons on the top | |
40 | * of the mouse. | |
0bb7a37f DEP |
41 | * |
42 | * Apply the following diff to the descriptor: | |
43 | * | |
44 | * Collection (Physical), Collection (Physical), | |
45 | * Report ID (1), Report ID (1), | |
46 | * Report Count (5), -> Report Count (8), | |
47 | * Report Size (1), Report Size (1), | |
48 | * Usage Page (Button), Usage Page (Button), | |
49 | * Usage Minimum (01h), Usage Minimum (01h), | |
50 | * Usage Maximum (05h), -> Usage Maximum (08h), | |
51 | * Logical Minimum (0), Logical Minimum (0), | |
52 | * Logical Maximum (1), Logical Maximum (1), | |
53 | * Input (Variable), Input (Variable), | |
54 | * Report Count (1), -> Report Count (0), | |
55 | * Report Size (3), Report Size (3), | |
56 | * Input (Constant), Input (Constant), | |
57 | * Report Size (16), Report Size (16), | |
58 | * Report Count (2), Report Count (2), | |
59 | * Usage Page (Desktop), Usage Page (Desktop), | |
60 | * Usage (X), Usage (X), | |
61 | * Usage (Y), Usage (Y), | |
62 | * Logical Minimum (-32768), Logical Minimum (-32768), | |
63 | * Logical Maximum (32767), Logical Maximum (32767), | |
64 | * Input (Variable, Relative), Input (Variable, Relative), | |
65 | * End Collection, End Collection, | |
66 | */ | |
67 | if (*rsize == 213 && rdesc[13] == 5 && rdesc[21] == 5) { | |
a0933a45 | 68 | hid_info(hdev, "Fixing up Elecom DEFT/HUGE Fn buttons\n"); |
0bb7a37f DEP |
69 | rdesc[13] = 8; /* Button/Variable Report Count */ |
70 | rdesc[21] = 8; /* Button/Variable Usage Maximum */ | |
71 | rdesc[29] = 0; /* Button/Constant Report Count */ | |
72 | } | |
73 | break; | |
64b386ea | 74 | } |
636a89d4 | 75 | return rdesc; |
64b386ea RN |
76 | } |
77 | ||
78 | static const struct hid_device_id elecom_devices[] = { | |
0bb7a37f DEP |
79 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, |
80 | { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_DEFT_WIRED) }, | |
81 | { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_DEFT_WIRELESS) }, | |
a0933a45 AM |
82 | { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_HUGE_WIRED) }, |
83 | { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_HUGE_WIRELESS) }, | |
64b386ea RN |
84 | { } |
85 | }; | |
86 | MODULE_DEVICE_TABLE(hid, elecom_devices); | |
87 | ||
88 | static struct hid_driver elecom_driver = { | |
89 | .name = "elecom", | |
90 | .id_table = elecom_devices, | |
91 | .report_fixup = elecom_report_fixup | |
92 | }; | |
f425458e | 93 | module_hid_driver(elecom_driver); |
64b386ea | 94 | |
64b386ea | 95 | MODULE_LICENSE("GPL"); |