]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blame - drivers/usb/input/hid-input.c
Input: i8042 - add Sony Vaio FSC-115b to MUX blacklist
[mirror_ubuntu-hirsute-kernel.git] / drivers / usb / input / hid-input.c
CommitLineData
1da177e4
LT
1/*
2 * $Id: hid-input.c,v 1.2 2002/04/23 00:59:25 rdamazio Exp $
3 *
4 * Copyright (c) 2000-2001 Vojtech Pavlik
5 *
6 * USB HID to Linux Input mapping
7 */
8
9/*
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 * Should you need to contact me, the author, you can do so either by
25 * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
26 * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
27 */
28
29#include <linux/module.h>
30#include <linux/slab.h>
31#include <linux/kernel.h>
32#include <linux/input.h>
33#include <linux/usb.h>
16a334c0 34#include <linux/usb_input.h>
1da177e4
LT
35
36#undef DEBUG
37
38#include "hid.h"
39
40#define unk KEY_UNKNOWN
41
4c4c9432 42static const unsigned char hid_keyboard[256] = {
1da177e4
LT
43 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
44 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3,
45 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26,
46 27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64,
47 65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106,
48 105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71,
49 72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190,
50 191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113,
51 115,114,unk,unk,unk,121,unk, 89, 93,124, 92, 94, 95,unk,unk,unk,
52 122,123, 90, 91, 85,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
53 unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
54 unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
55 unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
56 unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
57 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
58 150,158,159,128,136,177,178,176,142,152,173,140,unk,unk,unk,unk
59};
60
4c4c9432 61static const struct {
1da177e4
LT
62 __s32 x;
63 __s32 y;
64} hid_hat_to_axis[] = {{ 0, 0}, { 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}};
65
66#define map_abs(c) do { usage->code = c; usage->type = EV_ABS; bit = input->absbit; max = ABS_MAX; } while (0)
67#define map_rel(c) do { usage->code = c; usage->type = EV_REL; bit = input->relbit; max = REL_MAX; } while (0)
68#define map_key(c) do { usage->code = c; usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX; } while (0)
69#define map_led(c) do { usage->code = c; usage->type = EV_LED; bit = input->ledbit; max = LED_MAX; } while (0)
70#define map_ff(c) do { usage->code = c; usage->type = EV_FF; bit = input->ffbit; max = FF_MAX; } while (0)
71
72#define map_abs_clear(c) do { map_abs(c); clear_bit(c, bit); } while (0)
73#define map_key_clear(c) do { map_key(c); clear_bit(c, bit); } while (0)
74#define map_ff_effect(c) do { set_bit(c, input->ffbit); } while (0)
75
76static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field,
77 struct hid_usage *usage)
78{
c5b7c7c3
DT
79 struct input_dev *input = hidinput->input;
80 struct hid_device *device = input->private;
8a409b01
VP
81 int max = 0, code;
82 unsigned long *bit = NULL;
1da177e4
LT
83
84 field->hidinput = hidinput;
85
86#ifdef DEBUG
87 printk(KERN_DEBUG "Mapping: ");
88 resolv_usage(usage->hid);
89 printk(" ---> ");
90#endif
91
92 if (field->flags & HID_MAIN_ITEM_CONSTANT)
93 goto ignore;
94
95 switch (usage->hid & HID_USAGE_PAGE) {
96
97 case HID_UP_UNDEFINED:
98 goto ignore;
99
100 case HID_UP_KEYBOARD:
101
102 set_bit(EV_REP, input->evbit);
103
104 if ((usage->hid & HID_USAGE) < 256) {
105 if (!hid_keyboard[usage->hid & HID_USAGE]) goto ignore;
106 map_key_clear(hid_keyboard[usage->hid & HID_USAGE]);
107 } else
108 map_key(KEY_UNKNOWN);
109
110 break;
111
112 case HID_UP_BUTTON:
113
114 code = ((usage->hid - 1) & 0xf);
115
116 switch (field->application) {
117 case HID_GD_MOUSE:
118 case HID_GD_POINTER: code += 0x110; break;
119 case HID_GD_JOYSTICK: code += 0x120; break;
120 case HID_GD_GAMEPAD: code += 0x130; break;
121 default:
122 switch (field->physical) {
123 case HID_GD_MOUSE:
124 case HID_GD_POINTER: code += 0x110; break;
125 case HID_GD_JOYSTICK: code += 0x120; break;
126 case HID_GD_GAMEPAD: code += 0x130; break;
127 default: code += 0x100;
128 }
129 }
130
131 map_key(code);
132 break;
133
0aebfdac
VP
134
135 case HID_UP_SIMULATION:
136
137 switch (usage->hid & 0xffff) {
138 case 0xba: map_abs(ABS_RUDDER); break;
139 case 0xbb: map_abs(ABS_THROTTLE); break;
ff60dde9 140 default: goto ignore;
0aebfdac
VP
141 }
142 break;
143
1da177e4
LT
144 case HID_UP_GENDESK:
145
146 if ((usage->hid & 0xf0) == 0x80) { /* SystemControl */
147 switch (usage->hid & 0xf) {
148 case 0x1: map_key_clear(KEY_POWER); break;
149 case 0x2: map_key_clear(KEY_SLEEP); break;
150 case 0x3: map_key_clear(KEY_WAKEUP); break;
151 default: goto unknown;
152 }
153 break;
154 }
155
156 if ((usage->hid & 0xf0) == 0x90) { /* D-pad */
157 switch (usage->hid) {
158 case HID_GD_UP: usage->hat_dir = 1; break;
159 case HID_GD_DOWN: usage->hat_dir = 5; break;
160 case HID_GD_RIGHT: usage->hat_dir = 3; break;
161 case HID_GD_LEFT: usage->hat_dir = 7; break;
162 default: goto unknown;
163 }
164 if (field->dpad) {
165 map_abs(field->dpad);
166 goto ignore;
167 }
168 map_abs(ABS_HAT0X);
169 break;
170 }
171
172 switch (usage->hid) {
173
174 /* These usage IDs map directly to the usage codes. */
175 case HID_GD_X: case HID_GD_Y: case HID_GD_Z:
176 case HID_GD_RX: case HID_GD_RY: case HID_GD_RZ:
177 case HID_GD_SLIDER: case HID_GD_DIAL: case HID_GD_WHEEL:
05f091ab 178 if (field->flags & HID_MAIN_ITEM_RELATIVE)
1da177e4
LT
179 map_rel(usage->hid & 0xf);
180 else
181 map_abs(usage->hid & 0xf);
182 break;
183
184 case HID_GD_HATSWITCH:
185 usage->hat_min = field->logical_minimum;
186 usage->hat_max = field->logical_maximum;
187 map_abs(ABS_HAT0X);
188 break;
189
190 case HID_GD_START: map_key_clear(BTN_START); break;
191 case HID_GD_SELECT: map_key_clear(BTN_SELECT); break;
192
193 default: goto unknown;
194 }
195
196 break;
197
198 case HID_UP_LED:
199 if (((usage->hid - 1) & 0xffff) >= LED_MAX)
200 goto ignore;
201 map_led((usage->hid - 1) & 0xffff);
202 break;
203
204 case HID_UP_DIGITIZER:
205
206 switch (usage->hid & 0xff) {
207
208 case 0x30: /* TipPressure */
209 if (!test_bit(BTN_TOUCH, input->keybit)) {
210 device->quirks |= HID_QUIRK_NOTOUCH;
211 set_bit(EV_KEY, input->evbit);
212 set_bit(BTN_TOUCH, input->keybit);
213 }
214
215 map_abs_clear(ABS_PRESSURE);
216 break;
217
218 case 0x32: /* InRange */
219 switch (field->physical & 0xff) {
220 case 0x21: map_key(BTN_TOOL_MOUSE); break;
221 case 0x22: map_key(BTN_TOOL_FINGER); break;
222 default: map_key(BTN_TOOL_PEN); break;
223 }
224 break;
225
226 case 0x3c: /* Invert */
227 map_key_clear(BTN_TOOL_RUBBER);
228 break;
229
230 case 0x33: /* Touch */
231 case 0x42: /* TipSwitch */
232 case 0x43: /* TipSwitch2 */
233 device->quirks &= ~HID_QUIRK_NOTOUCH;
234 map_key_clear(BTN_TOUCH);
235 break;
236
237 case 0x44: /* BarrelSwitch */
238 map_key_clear(BTN_STYLUS);
239 break;
240
241 default: goto unknown;
242 }
243 break;
244
245 case HID_UP_CONSUMER: /* USB HUT v1.1, pages 56-62 */
246
247 switch (usage->hid & HID_USAGE) {
248 case 0x000: goto ignore;
249 case 0x034: map_key_clear(KEY_SLEEP); break;
250 case 0x036: map_key_clear(BTN_MISC); break;
39fd748f 251 case 0x045: map_key_clear(KEY_RADIO); break;
1da177e4 252 case 0x08a: map_key_clear(KEY_WWW); break;
8a409b01 253 case 0x08d: map_key_clear(KEY_PROGRAM); break;
1da177e4 254 case 0x095: map_key_clear(KEY_HELP); break;
8a409b01
VP
255 case 0x09c: map_key_clear(KEY_CHANNELUP); break;
256 case 0x09d: map_key_clear(KEY_CHANNELDOWN); break;
1da177e4
LT
257 case 0x0b0: map_key_clear(KEY_PLAY); break;
258 case 0x0b1: map_key_clear(KEY_PAUSE); break;
259 case 0x0b2: map_key_clear(KEY_RECORD); break;
260 case 0x0b3: map_key_clear(KEY_FASTFORWARD); break;
261 case 0x0b4: map_key_clear(KEY_REWIND); break;
262 case 0x0b5: map_key_clear(KEY_NEXTSONG); break;
263 case 0x0b6: map_key_clear(KEY_PREVIOUSSONG); break;
264 case 0x0b7: map_key_clear(KEY_STOPCD); break;
265 case 0x0b8: map_key_clear(KEY_EJECTCD); break;
266 case 0x0cd: map_key_clear(KEY_PLAYPAUSE); break;
267 case 0x0e0: map_abs_clear(ABS_VOLUME); break;
268 case 0x0e2: map_key_clear(KEY_MUTE); break;
269 case 0x0e5: map_key_clear(KEY_BASSBOOST); break;
270 case 0x0e9: map_key_clear(KEY_VOLUMEUP); break;
271 case 0x0ea: map_key_clear(KEY_VOLUMEDOWN); break;
272 case 0x183: map_key_clear(KEY_CONFIG); break;
273 case 0x18a: map_key_clear(KEY_MAIL); break;
274 case 0x192: map_key_clear(KEY_CALC); break;
275 case 0x194: map_key_clear(KEY_FILE); break;
8a409b01
VP
276 case 0x1a7: map_key_clear(KEY_DOCUMENTS); break;
277 case 0x201: map_key_clear(KEY_NEW); break;
278 case 0x207: map_key_clear(KEY_SAVE); break;
279 case 0x208: map_key_clear(KEY_PRINT); break;
280 case 0x209: map_key_clear(KEY_PROPS); break;
1da177e4
LT
281 case 0x21a: map_key_clear(KEY_UNDO); break;
282 case 0x21b: map_key_clear(KEY_COPY); break;
283 case 0x21c: map_key_clear(KEY_CUT); break;
284 case 0x21d: map_key_clear(KEY_PASTE); break;
285 case 0x221: map_key_clear(KEY_FIND); break;
286 case 0x223: map_key_clear(KEY_HOMEPAGE); break;
287 case 0x224: map_key_clear(KEY_BACK); break;
288 case 0x225: map_key_clear(KEY_FORWARD); break;
289 case 0x226: map_key_clear(KEY_STOP); break;
290 case 0x227: map_key_clear(KEY_REFRESH); break;
291 case 0x22a: map_key_clear(KEY_BOOKMARKS); break;
292 case 0x238: map_rel(REL_HWHEEL); break;
8a409b01
VP
293 case 0x279: map_key_clear(KEY_REDO); break;
294 case 0x289: map_key_clear(KEY_REPLY); break;
295 case 0x28b: map_key_clear(KEY_FORWARDMAIL); break;
296 case 0x28c: map_key_clear(KEY_SEND); break;
297 default: goto ignore;
1da177e4
LT
298 }
299 break;
300
301 case HID_UP_HPVENDOR: /* Reported on a Dutch layout HP5308 */
302
303 set_bit(EV_REP, input->evbit);
304 switch (usage->hid & HID_USAGE) {
305 case 0x021: map_key_clear(KEY_PRINT); break;
306 case 0x070: map_key_clear(KEY_HP); break;
307 case 0x071: map_key_clear(KEY_CAMERA); break;
308 case 0x072: map_key_clear(KEY_SOUND); break;
309 case 0x073: map_key_clear(KEY_QUESTION); break;
310 case 0x080: map_key_clear(KEY_EMAIL); break;
311 case 0x081: map_key_clear(KEY_CHAT); break;
312 case 0x082: map_key_clear(KEY_SEARCH); break;
313 case 0x083: map_key_clear(KEY_CONNECT); break;
314 case 0x084: map_key_clear(KEY_FINANCE); break;
315 case 0x085: map_key_clear(KEY_SPORT); break;
316 case 0x086: map_key_clear(KEY_SHOP); break;
317 default: goto ignore;
318 }
319 break;
320
321 case HID_UP_MSVENDOR:
1da177e4 322 goto ignore;
05f091ab 323
e875ce37
SP
324 case HID_UP_CUSTOM: /* Reported on Logitech and Powerbook USB keyboards */
325
326 set_bit(EV_REP, input->evbit);
327 switch(usage->hid & HID_USAGE) {
328 case 0x003: map_key_clear(KEY_FN); break;
329 default: goto ignore;
330 }
331 break;
332
333 case HID_UP_LOGIVENDOR: /* Reported on Logitech Ultra X Media Remote */
39fd748f
MG
334
335 set_bit(EV_REP, input->evbit);
336 switch(usage->hid & HID_USAGE) {
337 case 0x004: map_key_clear(KEY_AGAIN); break;
338 case 0x00d: map_key_clear(KEY_HOME); break;
339 case 0x024: map_key_clear(KEY_SHUFFLE); break;
340 case 0x025: map_key_clear(KEY_TV); break;
341 case 0x026: map_key_clear(KEY_MENU); break;
342 case 0x031: map_key_clear(KEY_AUDIO); break;
343 case 0x032: map_key_clear(KEY_SUBTITLE); break;
344 case 0x033: map_key_clear(KEY_LAST); break;
345 case 0x047: map_key_clear(KEY_MP3); break;
346 case 0x048: map_key_clear(KEY_DVD); break;
347 case 0x049: map_key_clear(KEY_MEDIA); break;
348 case 0x04a: map_key_clear(KEY_VIDEO); break;
349 case 0x04b: map_key_clear(KEY_ANGLE); break;
350 case 0x04c: map_key_clear(KEY_LANGUAGE); break;
351 case 0x04d: map_key_clear(KEY_SUBTITLE); break;
352 case 0x051: map_key_clear(KEY_RED); break;
353 case 0x052: map_key_clear(KEY_CLOSE); break;
354 default: goto ignore;
355 }
356 break;
357
1da177e4
LT
358 case HID_UP_PID:
359
360 set_bit(EV_FF, input->evbit);
361 switch(usage->hid & HID_USAGE) {
362 case 0x26: map_ff_effect(FF_CONSTANT); goto ignore;
363 case 0x27: map_ff_effect(FF_RAMP); goto ignore;
364 case 0x28: map_ff_effect(FF_CUSTOM); goto ignore;
365 case 0x30: map_ff_effect(FF_SQUARE); map_ff_effect(FF_PERIODIC); goto ignore;
366 case 0x31: map_ff_effect(FF_SINE); map_ff_effect(FF_PERIODIC); goto ignore;
367 case 0x32: map_ff_effect(FF_TRIANGLE); map_ff_effect(FF_PERIODIC); goto ignore;
368 case 0x33: map_ff_effect(FF_SAW_UP); map_ff_effect(FF_PERIODIC); goto ignore;
369 case 0x34: map_ff_effect(FF_SAW_DOWN); map_ff_effect(FF_PERIODIC); goto ignore;
370 case 0x40: map_ff_effect(FF_SPRING); goto ignore;
371 case 0x41: map_ff_effect(FF_DAMPER); goto ignore;
372 case 0x42: map_ff_effect(FF_INERTIA); goto ignore;
373 case 0x43: map_ff_effect(FF_FRICTION); goto ignore;
374 case 0x7e: map_ff(FF_GAIN); break;
375 case 0x83: input->ff_effects_max = field->value[0]; goto ignore;
376 case 0x98: map_ff(FF_AUTOCENTER); break;
377 case 0xa4: map_key_clear(BTN_DEAD); break;
378 default: goto ignore;
379 }
380 break;
381
382 default:
383 unknown:
384 if (field->report_size == 1) {
385 if (field->report->type == HID_OUTPUT_REPORT) {
386 map_led(LED_MISC);
387 break;
388 }
389 map_key(BTN_MISC);
390 break;
391 }
392 if (field->flags & HID_MAIN_ITEM_RELATIVE) {
393 map_rel(REL_MISC);
394 break;
395 }
396 map_abs(ABS_MISC);
397 break;
398 }
399
400 set_bit(usage->type, input->evbit);
401
402 while (usage->code <= max && test_and_set_bit(usage->code, bit))
403 usage->code = find_next_zero_bit(bit, max + 1, usage->code);
404
405 if (usage->code > max)
406 goto ignore;
407
c58de6d9
VP
408 if (((device->quirks & (HID_QUIRK_2WHEEL_POWERMOUSE)) && (usage->hid == 0x00010032)))
409 map_rel(REL_HWHEEL);
410
1da177e4 411 if ((device->quirks & (HID_QUIRK_2WHEEL_MOUSE_HACK_7 | HID_QUIRK_2WHEEL_MOUSE_HACK_5)) &&
05f091ab 412 (usage->type == EV_REL) && (usage->code == REL_WHEEL))
1da177e4
LT
413 set_bit(REL_HWHEEL, bit);
414
415 if (((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_5) && (usage->hid == 0x00090005))
416 || ((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007)))
417 goto ignore;
418
419 if (usage->type == EV_ABS) {
420
421 int a = field->logical_minimum;
422 int b = field->logical_maximum;
423
424 if ((device->quirks & HID_QUIRK_BADPAD) && (usage->code == ABS_X || usage->code == ABS_Y)) {
425 a = field->logical_minimum = 0;
426 b = field->logical_maximum = 255;
427 }
05f091ab 428
1da177e4
LT
429 if (field->application == HID_GD_GAMEPAD || field->application == HID_GD_JOYSTICK)
430 input_set_abs_params(input, usage->code, a, b, (b - a) >> 8, (b - a) >> 4);
431 else input_set_abs_params(input, usage->code, a, b, 0, 0);
05f091ab 432
1da177e4
LT
433 }
434
435 if (usage->hat_min < usage->hat_max || usage->hat_dir) {
436 int i;
437 for (i = usage->code; i < usage->code + 2 && i <= max; i++) {
438 input_set_abs_params(input, i, -1, 1, 0, 0);
439 set_bit(i, input->absbit);
440 }
441 if (usage->hat_dir && !field->dpad)
442 field->dpad = usage->code;
443 }
444
445#ifdef DEBUG
446 resolv_event(usage->type, usage->code);
447 printk("\n");
448#endif
449 return;
450
451ignore:
452#ifdef DEBUG
453 printk("IGNORED\n");
454#endif
455 return;
456}
457
458void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, struct pt_regs *regs)
459{
a9b2e917 460 struct input_dev *input;
1da177e4
LT
461 int *quirks = &hid->quirks;
462
a9b2e917 463 if (!field->hidinput)
1da177e4 464 return;
c5b7c7c3
DT
465
466 input = field->hidinput->input;
1da177e4
LT
467
468 input_regs(input, regs);
469
470 if (!usage->type)
471 return;
472
473 if (((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_5) && (usage->hid == 0x00090005))
474 || ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007))) {
475 if (value) hid->quirks |= HID_QUIRK_2WHEEL_MOUSE_HACK_ON;
476 else hid->quirks &= ~HID_QUIRK_2WHEEL_MOUSE_HACK_ON;
477 return;
478 }
479
480 if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_ON) && (usage->code == REL_WHEEL)) {
481 input_event(input, usage->type, REL_HWHEEL, value);
482 return;
483 }
484
05f091ab 485 if (usage->hat_min < usage->hat_max || usage->hat_dir) {
1da177e4
LT
486 int hat_dir = usage->hat_dir;
487 if (!hat_dir)
488 hat_dir = (value - usage->hat_min) * 8 / (usage->hat_max - usage->hat_min + 1) + 1;
489 if (hat_dir < 0 || hat_dir > 8) hat_dir = 0;
490 input_event(input, usage->type, usage->code , hid_hat_to_axis[hat_dir].x);
491 input_event(input, usage->type, usage->code + 1, hid_hat_to_axis[hat_dir].y);
492 return;
493 }
494
495 if (usage->hid == (HID_UP_DIGITIZER | 0x003c)) { /* Invert */
496 *quirks = value ? (*quirks | HID_QUIRK_INVERT) : (*quirks & ~HID_QUIRK_INVERT);
497 return;
498 }
499
500 if (usage->hid == (HID_UP_DIGITIZER | 0x0032)) { /* InRange */
501 if (value) {
502 input_event(input, usage->type, (*quirks & HID_QUIRK_INVERT) ? BTN_TOOL_RUBBER : usage->code, 1);
503 return;
504 }
505 input_event(input, usage->type, usage->code, 0);
506 input_event(input, usage->type, BTN_TOOL_RUBBER, 0);
507 return;
508 }
509
510 if (usage->hid == (HID_UP_DIGITIZER | 0x0030) && (*quirks & HID_QUIRK_NOTOUCH)) { /* Pressure */
511 int a = field->logical_minimum;
512 int b = field->logical_maximum;
513 input_event(input, EV_KEY, BTN_TOUCH, value > a + ((b - a) >> 3));
514 }
515
516 if (usage->hid == (HID_UP_PID | 0x83UL)) { /* Simultaneous Effects Max */
517 input->ff_effects_max = value;
518 dbg("Maximum Effects - %d",input->ff_effects_max);
519 return;
520 }
521
522 if (usage->hid == (HID_UP_PID | 0x7fUL)) {
523 dbg("PID Pool Report\n");
524 return;
525 }
526
527 if((usage->type == EV_KEY) && (usage->code == 0)) /* Key 0 is "unassigned", not KEY_UNKNOWN */
528 return;
529
530 input_event(input, usage->type, usage->code, value);
531
532 if ((field->flags & HID_MAIN_ITEM_RELATIVE) && (usage->type == EV_KEY))
533 input_event(input, usage->type, usage->code, 0);
534}
535
536void hidinput_report_event(struct hid_device *hid, struct hid_report *report)
537{
1da177e4
LT
538 struct hid_input *hidinput;
539
c5b7c7c3
DT
540 list_for_each_entry(hidinput, &hid->inputs, list)
541 input_sync(hidinput->input);
1da177e4
LT
542}
543
544static int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field)
545{
546 struct hid_report *report;
547 int i, j;
548
549 list_for_each_entry(report, &hid->report_enum[HID_OUTPUT_REPORT].report_list, list) {
550 for (i = 0; i < report->maxfield; i++) {
551 *field = report->field[i];
552 for (j = 0; j < (*field)->maxusage; j++)
553 if ((*field)->usage[j].type == type && (*field)->usage[j].code == code)
554 return j;
555 }
556 }
557 return -1;
558}
559
560static int hidinput_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
561{
562 struct hid_device *hid = dev->private;
563 struct hid_field *field;
564 int offset;
565
566 if (type == EV_FF)
567 return hid_ff_event(hid, dev, type, code, value);
568
569 if (type != EV_LED)
570 return -1;
571
572 if ((offset = hidinput_find_field(hid, type, code, &field)) == -1) {
573 warn("event field not found");
574 return -1;
575 }
576
577 hid_set_field(field, offset, value);
578 hid_submit_report(hid, field->report, USB_DIR_OUT);
579
580 return 0;
581}
582
583static int hidinput_open(struct input_dev *dev)
584{
585 struct hid_device *hid = dev->private;
586 return hid_open(hid);
587}
588
589static void hidinput_close(struct input_dev *dev)
590{
591 struct hid_device *hid = dev->private;
592 hid_close(hid);
593}
594
595/*
596 * Register the input device; print a message.
597 * Configure the input layer interface
598 * Read all reports and initialize the absolute field values.
599 */
600
601int hidinput_connect(struct hid_device *hid)
602{
603 struct usb_device *dev = hid->dev;
604 struct hid_report *report;
605 struct hid_input *hidinput = NULL;
c5b7c7c3 606 struct input_dev *input_dev;
1da177e4
LT
607 int i, j, k;
608
609 INIT_LIST_HEAD(&hid->inputs);
610
611 for (i = 0; i < hid->maxcollection; i++)
612 if (hid->collection[i].type == HID_COLLECTION_APPLICATION ||
613 hid->collection[i].type == HID_COLLECTION_PHYSICAL)
05f091ab 614 if (IS_INPUT_APPLICATION(hid->collection[i].usage))
1da177e4
LT
615 break;
616
617 if (i == hid->maxcollection)
618 return -1;
619
620 for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++)
621 list_for_each_entry(report, &hid->report_enum[k].report_list, list) {
622
623 if (!report->maxfield)
624 continue;
625
626 if (!hidinput) {
c5b7c7c3
DT
627 hidinput = kzalloc(sizeof(*hidinput), GFP_KERNEL);
628 input_dev = input_allocate_device();
629 if (!hidinput || !input_dev) {
630 kfree(hidinput);
631 input_free_device(input_dev);
1da177e4
LT
632 err("Out of memory during hid input probe");
633 return -1;
634 }
1da177e4 635
c5b7c7c3
DT
636 input_dev->private = hid;
637 input_dev->event = hidinput_input_event;
638 input_dev->open = hidinput_open;
639 input_dev->close = hidinput_close;
1da177e4 640
c5b7c7c3
DT
641 input_dev->name = hid->name;
642 input_dev->phys = hid->phys;
643 input_dev->uniq = hid->uniq;
644 usb_to_input_id(dev, &input_dev->id);
645 input_dev->cdev.dev = &hid->intf->dev;
1da177e4 646
c5b7c7c3
DT
647 hidinput->input = input_dev;
648 list_add_tail(&hidinput->list, &hid->inputs);
1da177e4
LT
649 }
650
651 for (i = 0; i < report->maxfield; i++)
652 for (j = 0; j < report->field[i]->maxusage; j++)
653 hidinput_configure_usage(hidinput, report->field[i],
654 report->field[i]->usage + j);
05f091ab 655
1da177e4
LT
656 if (hid->quirks & HID_QUIRK_MULTI_INPUT) {
657 /* This will leave hidinput NULL, so that it
658 * allocates another one if we have more inputs on
659 * the same interface. Some devices (e.g. Happ's
660 * UGCI) cram a lot of unrelated inputs into the
661 * same interface. */
662 hidinput->report = report;
c5b7c7c3 663 input_register_device(hidinput->input);
1da177e4
LT
664 hidinput = NULL;
665 }
666 }
667
668 /* This only gets called when we are a single-input (most of the
669 * time). IOW, not a HID_QUIRK_MULTI_INPUT. The hid_ff_init() is
670 * only useful in this case, and not for multi-input quirks. */
671 if (hidinput) {
672 hid_ff_init(hid);
c5b7c7c3 673 input_register_device(hidinput->input);
1da177e4
LT
674 }
675
676 return 0;
677}
678
679void hidinput_disconnect(struct hid_device *hid)
680{
c5b7c7c3 681 struct hid_input *hidinput, *next;
1da177e4 682
c5b7c7c3 683 list_for_each_entry_safe(hidinput, next, &hid->inputs, list) {
1da177e4 684 list_del(&hidinput->list);
c5b7c7c3 685 input_unregister_device(hidinput->input);
1da177e4
LT
686 kfree(hidinput);
687 }
688}