diff options
-rw-r--r-- | drivers/hid/Kconfig | 9 | ||||
-rw-r--r-- | drivers/hid/hid-core.c | 3 | ||||
-rw-r--r-- | drivers/hid/hid-ids.h | 3 | ||||
-rw-r--r-- | drivers/hid/hid-kye.c | 399 | ||||
-rw-r--r-- | drivers/hid/usbhid/hid-quirks.c | 2 |
5 files changed, 396 insertions, 20 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 9398cfce80b6..838fa6a3a287 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig | |||
@@ -200,11 +200,14 @@ config HID_KEYTOUCH | |||
200 | - Keytouch IEC 60945 | 200 | - Keytouch IEC 60945 |
201 | 201 | ||
202 | config HID_KYE | 202 | config HID_KYE |
203 | tristate "Kye/Genius Ergo Mouse" if EXPERT | 203 | tristate "KYE/Genius devices" |
204 | depends on USB_HID | 204 | depends on USB_HID |
205 | default !EXPERT | ||
206 | ---help--- | 205 | ---help--- |
207 | Support for Kye/Genius Ergo Mouse. | 206 | Support for KYE/Genius devices not fully compliant with HID standard: |
207 | - Ergo Mouse | ||
208 | - EasyPen i405X tablet | ||
209 | - MousePen i608X tablet | ||
210 | - EasyPen M610X tablet | ||
208 | 211 | ||
209 | config HID_UCLOGIC | 212 | config HID_UCLOGIC |
210 | tristate "UC-Logic" | 213 | tristate "UC-Logic" |
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 58d8f50649eb..ed96333af745 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -1436,6 +1436,9 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1436 | { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) }, | 1436 | { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) }, |
1437 | { HID_USB_DEVICE(USB_VENDOR_ID_KEYTOUCH, USB_DEVICE_ID_KEYTOUCH_IEC) }, | 1437 | { HID_USB_DEVICE(USB_VENDOR_ID_KEYTOUCH, USB_DEVICE_ID_KEYTOUCH_IEC) }, |
1438 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) }, | 1438 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) }, |
1439 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_I405X) }, | ||
1440 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X) }, | ||
1441 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X) }, | ||
1439 | { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, | 1442 | { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, |
1440 | { HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) }, | 1443 | { HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) }, |
1441 | { HID_USB_DEVICE(USB_VENDOR_ID_LG, USB_DEVICE_ID_LG_MULTITOUCH) }, | 1444 | { HID_USB_DEVICE(USB_VENDOR_ID_LG, USB_DEVICE_ID_LG_MULTITOUCH) }, |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 30d1f7ba2723..6e119a3a755e 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
@@ -407,6 +407,9 @@ | |||
407 | #define USB_VENDOR_ID_KYE 0x0458 | 407 | #define USB_VENDOR_ID_KYE 0x0458 |
408 | #define USB_DEVICE_ID_KYE_ERGO_525V 0x0087 | 408 | #define USB_DEVICE_ID_KYE_ERGO_525V 0x0087 |
409 | #define USB_DEVICE_ID_KYE_GPEN_560 0x5003 | 409 | #define USB_DEVICE_ID_KYE_GPEN_560 0x5003 |
410 | #define USB_DEVICE_ID_KYE_EASYPEN_I405X 0x5010 | ||
411 | #define USB_DEVICE_ID_KYE_MOUSEPEN_I608X 0x5011 | ||
412 | #define USB_DEVICE_ID_KYE_EASYPEN_M610X 0x5013 | ||
410 | 413 | ||
411 | #define USB_VENDOR_ID_LABTEC 0x1020 | 414 | #define USB_VENDOR_ID_LABTEC 0x1020 |
412 | #define USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD 0x0006 | 415 | #define USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD 0x0006 |
diff --git a/drivers/hid/hid-kye.c b/drivers/hid/hid-kye.c index f2ba9efc3a53..b4f0d8216fd0 100644 --- a/drivers/hid/hid-kye.c +++ b/drivers/hid/hid-kye.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (c) 2009 Jiri Kosina | 4 | * Copyright (c) 2009 Jiri Kosina |
5 | * Copyright (c) 2009 Tomas Hanak | 5 | * Copyright (c) 2009 Tomas Hanak |
6 | * Copyright (c) 2012 Nikolai Kondrashov | ||
6 | */ | 7 | */ |
7 | 8 | ||
8 | /* | 9 | /* |
@@ -15,36 +16,399 @@ | |||
15 | #include <linux/device.h> | 16 | #include <linux/device.h> |
16 | #include <linux/hid.h> | 17 | #include <linux/hid.h> |
17 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/usb.h> | ||
20 | #include "usbhid/usbhid.h" | ||
18 | 21 | ||
19 | #include "hid-ids.h" | 22 | #include "hid-ids.h" |
20 | 23 | ||
21 | /* the fixups that need to be done: | 24 | /* |
22 | * - change led usage page to button for extra buttons | 25 | * See EasyPen i405X description, device and HID report descriptors at |
23 | * - report size 8 count 1 must be size 1 count 8 for button bitfield | 26 | * http://sf.net/apps/mediawiki/digimend/?title=KYE_EasyPen_i405X |
24 | * - change the button usage range to 4-7 for the extra buttons | ||
25 | */ | 27 | */ |
28 | |||
29 | /* Original EasyPen i405X report descriptor size */ | ||
30 | #define EASYPEN_I405X_RDESC_ORIG_SIZE 476 | ||
31 | |||
32 | /* Fixed EasyPen i405X report descriptor */ | ||
33 | static __u8 easypen_i405x_rdesc_fixed[] = { | ||
34 | 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ | ||
35 | 0x09, 0x01, /* Usage (01h), */ | ||
36 | 0xA1, 0x01, /* Collection (Application), */ | ||
37 | 0x85, 0x05, /* Report ID (5), */ | ||
38 | 0x09, 0x01, /* Usage (01h), */ | ||
39 | 0x15, 0x80, /* Logical Minimum (-128), */ | ||
40 | 0x25, 0x7F, /* Logical Maximum (127), */ | ||
41 | 0x75, 0x08, /* Report Size (8), */ | ||
42 | 0x95, 0x07, /* Report Count (7), */ | ||
43 | 0xB1, 0x02, /* Feature (Variable), */ | ||
44 | 0xC0, /* End Collection, */ | ||
45 | 0x05, 0x0D, /* Usage Page (Digitizer), */ | ||
46 | 0x09, 0x02, /* Usage (Pen), */ | ||
47 | 0xA1, 0x01, /* Collection (Application), */ | ||
48 | 0x85, 0x10, /* Report ID (16), */ | ||
49 | 0x09, 0x20, /* Usage (Stylus), */ | ||
50 | 0xA0, /* Collection (Physical), */ | ||
51 | 0x14, /* Logical Minimum (0), */ | ||
52 | 0x25, 0x01, /* Logical Maximum (1), */ | ||
53 | 0x75, 0x01, /* Report Size (1), */ | ||
54 | 0x09, 0x42, /* Usage (Tip Switch), */ | ||
55 | 0x09, 0x44, /* Usage (Barrel Switch), */ | ||
56 | 0x09, 0x46, /* Usage (Tablet Pick), */ | ||
57 | 0x95, 0x03, /* Report Count (3), */ | ||
58 | 0x81, 0x02, /* Input (Variable), */ | ||
59 | 0x95, 0x04, /* Report Count (4), */ | ||
60 | 0x81, 0x03, /* Input (Constant, Variable), */ | ||
61 | 0x09, 0x32, /* Usage (In Range), */ | ||
62 | 0x95, 0x01, /* Report Count (1), */ | ||
63 | 0x81, 0x02, /* Input (Variable), */ | ||
64 | 0x75, 0x10, /* Report Size (16), */ | ||
65 | 0x95, 0x01, /* Report Count (1), */ | ||
66 | 0xA4, /* Push, */ | ||
67 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
68 | 0x55, 0xFD, /* Unit Exponent (-3), */ | ||
69 | 0x65, 0x13, /* Unit (Inch), */ | ||
70 | 0x34, /* Physical Minimum (0), */ | ||
71 | 0x09, 0x30, /* Usage (X), */ | ||
72 | 0x46, 0x7C, 0x15, /* Physical Maximum (5500), */ | ||
73 | 0x26, 0x00, 0x37, /* Logical Maximum (14080), */ | ||
74 | 0x81, 0x02, /* Input (Variable), */ | ||
75 | 0x09, 0x31, /* Usage (Y), */ | ||
76 | 0x46, 0xA0, 0x0F, /* Physical Maximum (4000), */ | ||
77 | 0x26, 0x00, 0x28, /* Logical Maximum (10240), */ | ||
78 | 0x81, 0x02, /* Input (Variable), */ | ||
79 | 0xB4, /* Pop, */ | ||
80 | 0x09, 0x30, /* Usage (Tip Pressure), */ | ||
81 | 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ | ||
82 | 0x81, 0x02, /* Input (Variable), */ | ||
83 | 0xC0, /* End Collection, */ | ||
84 | 0xC0 /* End Collection */ | ||
85 | }; | ||
86 | |||
87 | /* | ||
88 | * See MousePen i608X description, device and HID report descriptors at | ||
89 | * http://sf.net/apps/mediawiki/digimend/?title=KYE_MousePen_i608X | ||
90 | */ | ||
91 | |||
92 | /* Original MousePen i608X report descriptor size */ | ||
93 | #define MOUSEPEN_I608X_RDESC_ORIG_SIZE 476 | ||
94 | |||
95 | /* Fixed MousePen i608X report descriptor */ | ||
96 | static __u8 mousepen_i608x_rdesc_fixed[] = { | ||
97 | 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ | ||
98 | 0x09, 0x01, /* Usage (01h), */ | ||
99 | 0xA1, 0x01, /* Collection (Application), */ | ||
100 | 0x85, 0x05, /* Report ID (5), */ | ||
101 | 0x09, 0x01, /* Usage (01h), */ | ||
102 | 0x15, 0x80, /* Logical Minimum (-128), */ | ||
103 | 0x25, 0x7F, /* Logical Maximum (127), */ | ||
104 | 0x75, 0x08, /* Report Size (8), */ | ||
105 | 0x95, 0x07, /* Report Count (7), */ | ||
106 | 0xB1, 0x02, /* Feature (Variable), */ | ||
107 | 0xC0, /* End Collection, */ | ||
108 | 0x05, 0x0D, /* Usage Page (Digitizer), */ | ||
109 | 0x09, 0x02, /* Usage (Pen), */ | ||
110 | 0xA1, 0x01, /* Collection (Application), */ | ||
111 | 0x85, 0x10, /* Report ID (16), */ | ||
112 | 0x09, 0x20, /* Usage (Stylus), */ | ||
113 | 0xA0, /* Collection (Physical), */ | ||
114 | 0x14, /* Logical Minimum (0), */ | ||
115 | 0x25, 0x01, /* Logical Maximum (1), */ | ||
116 | 0x75, 0x01, /* Report Size (1), */ | ||
117 | 0x09, 0x42, /* Usage (Tip Switch), */ | ||
118 | 0x09, 0x44, /* Usage (Barrel Switch), */ | ||
119 | 0x09, 0x46, /* Usage (Tablet Pick), */ | ||
120 | 0x95, 0x03, /* Report Count (3), */ | ||
121 | 0x81, 0x02, /* Input (Variable), */ | ||
122 | 0x95, 0x04, /* Report Count (4), */ | ||
123 | 0x81, 0x03, /* Input (Constant, Variable), */ | ||
124 | 0x09, 0x32, /* Usage (In Range), */ | ||
125 | 0x95, 0x01, /* Report Count (1), */ | ||
126 | 0x81, 0x02, /* Input (Variable), */ | ||
127 | 0x75, 0x10, /* Report Size (16), */ | ||
128 | 0x95, 0x01, /* Report Count (1), */ | ||
129 | 0xA4, /* Push, */ | ||
130 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
131 | 0x55, 0xFD, /* Unit Exponent (-3), */ | ||
132 | 0x65, 0x13, /* Unit (Inch), */ | ||
133 | 0x34, /* Physical Minimum (0), */ | ||
134 | 0x09, 0x30, /* Usage (X), */ | ||
135 | 0x46, 0x40, 0x1F, /* Physical Maximum (8000), */ | ||
136 | 0x26, 0x00, 0x50, /* Logical Maximum (20480), */ | ||
137 | 0x81, 0x02, /* Input (Variable), */ | ||
138 | 0x09, 0x31, /* Usage (Y), */ | ||
139 | 0x46, 0x70, 0x17, /* Physical Maximum (6000), */ | ||
140 | 0x26, 0x00, 0x3C, /* Logical Maximum (15360), */ | ||
141 | 0x81, 0x02, /* Input (Variable), */ | ||
142 | 0xB4, /* Pop, */ | ||
143 | 0x09, 0x30, /* Usage (Tip Pressure), */ | ||
144 | 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ | ||
145 | 0x81, 0x02, /* Input (Variable), */ | ||
146 | 0xC0, /* End Collection, */ | ||
147 | 0xC0, /* End Collection, */ | ||
148 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
149 | 0x09, 0x02, /* Usage (Mouse), */ | ||
150 | 0xA1, 0x01, /* Collection (Application), */ | ||
151 | 0x85, 0x11, /* Report ID (17), */ | ||
152 | 0x09, 0x01, /* Usage (Pointer), */ | ||
153 | 0xA0, /* Collection (Physical), */ | ||
154 | 0x14, /* Logical Minimum (0), */ | ||
155 | 0xA4, /* Push, */ | ||
156 | 0x05, 0x09, /* Usage Page (Button), */ | ||
157 | 0x75, 0x01, /* Report Size (1), */ | ||
158 | 0x19, 0x01, /* Usage Minimum (01h), */ | ||
159 | 0x29, 0x03, /* Usage Maximum (03h), */ | ||
160 | 0x25, 0x01, /* Logical Maximum (1), */ | ||
161 | 0x95, 0x03, /* Report Count (3), */ | ||
162 | 0x81, 0x02, /* Input (Variable), */ | ||
163 | 0x95, 0x05, /* Report Count (5), */ | ||
164 | 0x81, 0x01, /* Input (Constant), */ | ||
165 | 0xB4, /* Pop, */ | ||
166 | 0x95, 0x01, /* Report Count (1), */ | ||
167 | 0xA4, /* Push, */ | ||
168 | 0x55, 0xFD, /* Unit Exponent (-3), */ | ||
169 | 0x65, 0x13, /* Unit (Inch), */ | ||
170 | 0x34, /* Physical Minimum (0), */ | ||
171 | 0x75, 0x10, /* Report Size (16), */ | ||
172 | 0x09, 0x30, /* Usage (X), */ | ||
173 | 0x46, 0x40, 0x1F, /* Physical Maximum (8000), */ | ||
174 | 0x26, 0x00, 0x50, /* Logical Maximum (20480), */ | ||
175 | 0x81, 0x02, /* Input (Variable), */ | ||
176 | 0x09, 0x31, /* Usage (Y), */ | ||
177 | 0x46, 0x70, 0x17, /* Physical Maximum (6000), */ | ||
178 | 0x26, 0x00, 0x3C, /* Logical Maximum (15360), */ | ||
179 | 0x81, 0x02, /* Input (Variable), */ | ||
180 | 0xB4, /* Pop, */ | ||
181 | 0x75, 0x08, /* Report Size (8), */ | ||
182 | 0x09, 0x38, /* Usage (Wheel), */ | ||
183 | 0x15, 0xFF, /* Logical Minimum (-1), */ | ||
184 | 0x25, 0x01, /* Logical Maximum (1), */ | ||
185 | 0x81, 0x06, /* Input (Variable, Relative), */ | ||
186 | 0x81, 0x01, /* Input (Constant), */ | ||
187 | 0xC0, /* End Collection, */ | ||
188 | 0xC0 /* End Collection */ | ||
189 | }; | ||
190 | |||
191 | /* | ||
192 | * See EasyPen M610X description, device and HID report descriptors at | ||
193 | * http://sf.net/apps/mediawiki/digimend/?title=KYE_EasyPen_M610X | ||
194 | */ | ||
195 | |||
196 | /* Original EasyPen M610X report descriptor size */ | ||
197 | #define EASYPEN_M610X_RDESC_ORIG_SIZE 476 | ||
198 | |||
199 | /* Fixed EasyPen M610X report descriptor */ | ||
200 | static __u8 easypen_m610x_rdesc_fixed[] = { | ||
201 | 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ | ||
202 | 0x09, 0x01, /* Usage (01h), */ | ||
203 | 0xA1, 0x01, /* Collection (Application), */ | ||
204 | 0x85, 0x05, /* Report ID (5), */ | ||
205 | 0x09, 0x01, /* Usage (01h), */ | ||
206 | 0x15, 0x80, /* Logical Minimum (-128), */ | ||
207 | 0x25, 0x7F, /* Logical Maximum (127), */ | ||
208 | 0x75, 0x08, /* Report Size (8), */ | ||
209 | 0x95, 0x07, /* Report Count (7), */ | ||
210 | 0xB1, 0x02, /* Feature (Variable), */ | ||
211 | 0xC0, /* End Collection, */ | ||
212 | 0x05, 0x0D, /* Usage Page (Digitizer), */ | ||
213 | 0x09, 0x02, /* Usage (Pen), */ | ||
214 | 0xA1, 0x01, /* Collection (Application), */ | ||
215 | 0x85, 0x10, /* Report ID (16), */ | ||
216 | 0x09, 0x20, /* Usage (Stylus), */ | ||
217 | 0xA0, /* Collection (Physical), */ | ||
218 | 0x14, /* Logical Minimum (0), */ | ||
219 | 0x25, 0x01, /* Logical Maximum (1), */ | ||
220 | 0x75, 0x01, /* Report Size (1), */ | ||
221 | 0x09, 0x42, /* Usage (Tip Switch), */ | ||
222 | 0x09, 0x44, /* Usage (Barrel Switch), */ | ||
223 | 0x09, 0x46, /* Usage (Tablet Pick), */ | ||
224 | 0x95, 0x03, /* Report Count (3), */ | ||
225 | 0x81, 0x02, /* Input (Variable), */ | ||
226 | 0x95, 0x04, /* Report Count (4), */ | ||
227 | 0x81, 0x03, /* Input (Constant, Variable), */ | ||
228 | 0x09, 0x32, /* Usage (In Range), */ | ||
229 | 0x95, 0x01, /* Report Count (1), */ | ||
230 | 0x81, 0x02, /* Input (Variable), */ | ||
231 | 0x75, 0x10, /* Report Size (16), */ | ||
232 | 0x95, 0x01, /* Report Count (1), */ | ||
233 | 0xA4, /* Push, */ | ||
234 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
235 | 0x55, 0xFD, /* Unit Exponent (-3), */ | ||
236 | 0x65, 0x13, /* Unit (Inch), */ | ||
237 | 0x34, /* Physical Minimum (0), */ | ||
238 | 0x09, 0x30, /* Usage (X), */ | ||
239 | 0x46, 0x10, 0x27, /* Physical Maximum (10000), */ | ||
240 | 0x27, 0x00, 0xA0, 0x00, 0x00, /* Logical Maximum (40960), */ | ||
241 | 0x81, 0x02, /* Input (Variable), */ | ||
242 | 0x09, 0x31, /* Usage (Y), */ | ||
243 | 0x46, 0x6A, 0x18, /* Physical Maximum (6250), */ | ||
244 | 0x26, 0x00, 0x64, /* Logical Maximum (25600), */ | ||
245 | 0x81, 0x02, /* Input (Variable), */ | ||
246 | 0xB4, /* Pop, */ | ||
247 | 0x09, 0x30, /* Usage (Tip Pressure), */ | ||
248 | 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ | ||
249 | 0x81, 0x02, /* Input (Variable), */ | ||
250 | 0xC0, /* End Collection, */ | ||
251 | 0xC0, /* End Collection, */ | ||
252 | 0x05, 0x0C, /* Usage Page (Consumer), */ | ||
253 | 0x09, 0x01, /* Usage (Consumer Control), */ | ||
254 | 0xA1, 0x01, /* Collection (Application), */ | ||
255 | 0x85, 0x12, /* Report ID (18), */ | ||
256 | 0x14, /* Logical Minimum (0), */ | ||
257 | 0x25, 0x01, /* Logical Maximum (1), */ | ||
258 | 0x75, 0x01, /* Report Size (1), */ | ||
259 | 0x95, 0x04, /* Report Count (4), */ | ||
260 | 0x0A, 0x1A, 0x02, /* Usage (AC Undo), */ | ||
261 | 0x0A, 0x79, 0x02, /* Usage (AC Redo Or Repeat), */ | ||
262 | 0x0A, 0x2D, 0x02, /* Usage (AC Zoom In), */ | ||
263 | 0x0A, 0x2E, 0x02, /* Usage (AC Zoom Out), */ | ||
264 | 0x81, 0x02, /* Input (Variable), */ | ||
265 | 0x95, 0x01, /* Report Count (1), */ | ||
266 | 0x75, 0x14, /* Report Size (20), */ | ||
267 | 0x81, 0x03, /* Input (Constant, Variable), */ | ||
268 | 0x75, 0x20, /* Report Size (32), */ | ||
269 | 0x81, 0x03, /* Input (Constant, Variable), */ | ||
270 | 0xC0 /* End Collection */ | ||
271 | }; | ||
272 | |||
26 | static __u8 *kye_report_fixup(struct hid_device *hdev, __u8 *rdesc, | 273 | static __u8 *kye_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
27 | unsigned int *rsize) | 274 | unsigned int *rsize) |
28 | { | 275 | { |
29 | if (*rsize >= 74 && | 276 | switch (hdev->product) { |
30 | rdesc[61] == 0x05 && rdesc[62] == 0x08 && | 277 | case USB_DEVICE_ID_KYE_ERGO_525V: |
31 | rdesc[63] == 0x19 && rdesc[64] == 0x08 && | 278 | /* the fixups that need to be done: |
32 | rdesc[65] == 0x29 && rdesc[66] == 0x0f && | 279 | * - change led usage page to button for extra buttons |
33 | rdesc[71] == 0x75 && rdesc[72] == 0x08 && | 280 | * - report size 8 count 1 must be size 1 count 8 for button |
34 | rdesc[73] == 0x95 && rdesc[74] == 0x01) { | 281 | * bitfield |
35 | hid_info(hdev, | 282 | * - change the button usage range to 4-7 for the extra |
36 | "fixing up Kye/Genius Ergo Mouse report descriptor\n"); | 283 | * buttons |
37 | rdesc[62] = 0x09; | 284 | */ |
38 | rdesc[64] = 0x04; | 285 | if (*rsize >= 74 && |
39 | rdesc[66] = 0x07; | 286 | rdesc[61] == 0x05 && rdesc[62] == 0x08 && |
40 | rdesc[72] = 0x01; | 287 | rdesc[63] == 0x19 && rdesc[64] == 0x08 && |
41 | rdesc[74] = 0x08; | 288 | rdesc[65] == 0x29 && rdesc[66] == 0x0f && |
289 | rdesc[71] == 0x75 && rdesc[72] == 0x08 && | ||
290 | rdesc[73] == 0x95 && rdesc[74] == 0x01) { | ||
291 | hid_info(hdev, | ||
292 | "fixing up Kye/Genius Ergo Mouse " | ||
293 | "report descriptor\n"); | ||
294 | rdesc[62] = 0x09; | ||
295 | rdesc[64] = 0x04; | ||
296 | rdesc[66] = 0x07; | ||
297 | rdesc[72] = 0x01; | ||
298 | rdesc[74] = 0x08; | ||
299 | } | ||
300 | break; | ||
301 | case USB_DEVICE_ID_KYE_EASYPEN_I405X: | ||
302 | if (*rsize == EASYPEN_I405X_RDESC_ORIG_SIZE) { | ||
303 | rdesc = easypen_i405x_rdesc_fixed; | ||
304 | *rsize = sizeof(easypen_i405x_rdesc_fixed); | ||
305 | } | ||
306 | break; | ||
307 | case USB_DEVICE_ID_KYE_MOUSEPEN_I608X: | ||
308 | if (*rsize == MOUSEPEN_I608X_RDESC_ORIG_SIZE) { | ||
309 | rdesc = mousepen_i608x_rdesc_fixed; | ||
310 | *rsize = sizeof(mousepen_i608x_rdesc_fixed); | ||
311 | } | ||
312 | break; | ||
313 | case USB_DEVICE_ID_KYE_EASYPEN_M610X: | ||
314 | if (*rsize == EASYPEN_M610X_RDESC_ORIG_SIZE) { | ||
315 | rdesc = easypen_m610x_rdesc_fixed; | ||
316 | *rsize = sizeof(easypen_m610x_rdesc_fixed); | ||
317 | } | ||
318 | break; | ||
42 | } | 319 | } |
43 | return rdesc; | 320 | return rdesc; |
44 | } | 321 | } |
45 | 322 | ||
323 | /** | ||
324 | * Enable fully-functional tablet mode by setting a special feature report. | ||
325 | * | ||
326 | * @hdev: HID device | ||
327 | * | ||
328 | * The specific report ID and data were discovered by sniffing the | ||
329 | * Windows driver traffic. | ||
330 | */ | ||
331 | static int kye_tablet_enable(struct hid_device *hdev) | ||
332 | { | ||
333 | struct list_head *list; | ||
334 | struct list_head *head; | ||
335 | struct hid_report *report; | ||
336 | __s32 *value; | ||
337 | |||
338 | list = &hdev->report_enum[HID_FEATURE_REPORT].report_list; | ||
339 | list_for_each(head, list) { | ||
340 | report = list_entry(head, struct hid_report, list); | ||
341 | if (report->id == 5) | ||
342 | break; | ||
343 | } | ||
344 | |||
345 | if (head == list) { | ||
346 | hid_err(hdev, "tablet-enabling feature report not found\n"); | ||
347 | return -ENODEV; | ||
348 | } | ||
349 | |||
350 | if (report->maxfield < 1 || report->field[0]->report_count < 7) { | ||
351 | hid_err(hdev, "invalid tablet-enabling feature report\n"); | ||
352 | return -ENODEV; | ||
353 | } | ||
354 | |||
355 | value = report->field[0]->value; | ||
356 | |||
357 | value[0] = 0x12; | ||
358 | value[1] = 0x10; | ||
359 | value[2] = 0x11; | ||
360 | value[3] = 0x12; | ||
361 | value[4] = 0x00; | ||
362 | value[5] = 0x00; | ||
363 | value[6] = 0x00; | ||
364 | usbhid_submit_report(hdev, report, USB_DIR_OUT); | ||
365 | |||
366 | return 0; | ||
367 | } | ||
368 | |||
369 | static int kye_probe(struct hid_device *hdev, const struct hid_device_id *id) | ||
370 | { | ||
371 | int ret; | ||
372 | |||
373 | ret = hid_parse(hdev); | ||
374 | if (ret) { | ||
375 | hid_err(hdev, "parse failed\n"); | ||
376 | goto err; | ||
377 | } | ||
378 | |||
379 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); | ||
380 | if (ret) { | ||
381 | hid_err(hdev, "hw start failed\n"); | ||
382 | goto err; | ||
383 | } | ||
384 | |||
385 | switch (id->product) { | ||
386 | case USB_DEVICE_ID_KYE_EASYPEN_I405X: | ||
387 | case USB_DEVICE_ID_KYE_MOUSEPEN_I608X: | ||
388 | case USB_DEVICE_ID_KYE_EASYPEN_M610X: | ||
389 | ret = kye_tablet_enable(hdev); | ||
390 | if (ret) { | ||
391 | hid_err(hdev, "tablet enabling failed\n"); | ||
392 | goto enabling_err; | ||
393 | } | ||
394 | break; | ||
395 | } | ||
396 | |||
397 | return 0; | ||
398 | enabling_err: | ||
399 | hid_hw_stop(hdev); | ||
400 | err: | ||
401 | return ret; | ||
402 | } | ||
403 | |||
46 | static const struct hid_device_id kye_devices[] = { | 404 | static const struct hid_device_id kye_devices[] = { |
47 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) }, | 405 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) }, |
406 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, | ||
407 | USB_DEVICE_ID_KYE_EASYPEN_I405X) }, | ||
408 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, | ||
409 | USB_DEVICE_ID_KYE_MOUSEPEN_I608X) }, | ||
410 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, | ||
411 | USB_DEVICE_ID_KYE_EASYPEN_M610X) }, | ||
48 | { } | 412 | { } |
49 | }; | 413 | }; |
50 | MODULE_DEVICE_TABLE(hid, kye_devices); | 414 | MODULE_DEVICE_TABLE(hid, kye_devices); |
@@ -52,6 +416,7 @@ MODULE_DEVICE_TABLE(hid, kye_devices); | |||
52 | static struct hid_driver kye_driver = { | 416 | static struct hid_driver kye_driver = { |
53 | .name = "kye", | 417 | .name = "kye", |
54 | .id_table = kye_devices, | 418 | .id_table = kye_devices, |
419 | .probe = kye_probe, | ||
55 | .report_fixup = kye_report_fixup, | 420 | .report_fixup = kye_report_fixup, |
56 | }; | 421 | }; |
57 | 422 | ||
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index ae7d28321dc3..3cfea61e9792 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c | |||
@@ -95,6 +95,8 @@ static const struct hid_blacklist { | |||
95 | { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_MULTI_TOUCH, HID_QUIRK_MULTI_INPUT }, | 95 | { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_MULTI_TOUCH, HID_QUIRK_MULTI_INPUT }, |
96 | { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS, HID_QUIRK_MULTI_INPUT }, | 96 | { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS, HID_QUIRK_MULTI_INPUT }, |
97 | { USB_VENDOR_ID_SIGMA_MICRO, USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD, HID_QUIRK_NO_INIT_REPORTS }, | 97 | { USB_VENDOR_ID_SIGMA_MICRO, USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD, HID_QUIRK_NO_INIT_REPORTS }, |
98 | { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X, HID_QUIRK_MULTI_INPUT }, | ||
99 | { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X, HID_QUIRK_MULTI_INPUT }, | ||
98 | { 0, 0 } | 100 | { 0, 0 } |
99 | }; | 101 | }; |
100 | 102 | ||