aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hid/hid-input-quirks.c77
-rw-r--r--drivers/hid/hid-input.c16
-rw-r--r--include/linux/hid.h56
3 files changed, 103 insertions, 46 deletions
diff --git a/drivers/hid/hid-input-quirks.c b/drivers/hid/hid-input-quirks.c
index 16feea014494..8ec64b74d38d 100644
--- a/drivers/hid/hid-input-quirks.c
+++ b/drivers/hid/hid-input-quirks.c
@@ -16,16 +16,14 @@
16#include <linux/input.h> 16#include <linux/input.h>
17#include <linux/hid.h> 17#include <linux/hid.h>
18 18
19#define map_abs(c) do { usage->code = c; usage->type = EV_ABS; *bit = input->absbit; *max = ABS_MAX; } while (0) 19#define map_rel(c) hid_map_usage(hidinput, usage, bit, max, EV_REL, (c))
20#define map_rel(c) do { usage->code = c; usage->type = EV_REL; *bit = input->relbit; *max = REL_MAX; } while (0) 20#define map_key(c) hid_map_usage(hidinput, usage, bit, max, EV_KEY, (c))
21#define map_key(c) do { usage->code = c; usage->type = EV_KEY; *bit = input->keybit; *max = KEY_MAX; } while (0)
22#define map_led(c) do { usage->code = c; usage->type = EV_LED; *bit = input->ledbit; *max = LED_MAX; } while (0)
23 21
24#define map_abs_clear(c) do { map_abs(c); clear_bit(c, *bit); } while (0) 22#define map_key_clear(c) hid_map_usage_clear(hidinput, usage, bit, \
25#define map_key_clear(c) do { map_key(c); clear_bit(c, *bit); } while (0) 23 max, EV_KEY, (c))
26 24
27static int quirk_belkin_wkbd(struct hid_usage *usage, struct input_dev *input, 25static int quirk_belkin_wkbd(struct hid_usage *usage,
28 unsigned long **bit, int *max) 26 struct hid_input *hidinput, unsigned long **bit, int *max)
29{ 27{
30 if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) 28 if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)
31 return 0; 29 return 0;
@@ -40,8 +38,8 @@ static int quirk_belkin_wkbd(struct hid_usage *usage, struct input_dev *input,
40 return 1; 38 return 1;
41} 39}
42 40
43static int quirk_cherry_cymotion(struct hid_usage *usage, struct input_dev *input, 41static int quirk_cherry_cymotion(struct hid_usage *usage,
44 unsigned long **bit, int *max) 42 struct hid_input *hidinput, unsigned long **bit, int *max)
45{ 43{
46 if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) 44 if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)
47 return 0; 45 return 0;
@@ -56,13 +54,13 @@ static int quirk_cherry_cymotion(struct hid_usage *usage, struct input_dev *inpu
56 return 1; 54 return 1;
57} 55}
58 56
59static int quirk_logitech_ultrax_remote(struct hid_usage *usage, struct input_dev *input, 57static int quirk_logitech_ultrax_remote(struct hid_usage *usage,
60 unsigned long **bit, int *max) 58 struct hid_input *hidinput, unsigned long **bit, int *max)
61{ 59{
62 if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR) 60 if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR)
63 return 0; 61 return 0;
64 62
65 set_bit(EV_REP, input->evbit); 63 set_bit(EV_REP, hidinput->input->evbit);
66 switch(usage->hid & HID_USAGE) { 64 switch(usage->hid & HID_USAGE) {
67 /* Reported on Logitech Ultra X Media Remote */ 65 /* Reported on Logitech Ultra X Media Remote */
68 case 0x004: map_key_clear(KEY_AGAIN); break; 66 case 0x004: map_key_clear(KEY_AGAIN); break;
@@ -89,13 +87,13 @@ static int quirk_logitech_ultrax_remote(struct hid_usage *usage, struct input_de
89 return 1; 87 return 1;
90} 88}
91 89
92static int quirk_gyration_remote(struct hid_usage *usage, struct input_dev *input, 90static int quirk_gyration_remote(struct hid_usage *usage,
93 unsigned long **bit, int *max) 91 struct hid_input *hidinput, unsigned long **bit, int *max)
94{ 92{
95 if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR) 93 if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR)
96 return 0; 94 return 0;
97 95
98 set_bit(EV_REP, input->evbit); 96 set_bit(EV_REP, hidinput->input->evbit);
99 switch(usage->hid & HID_USAGE) { 97 switch(usage->hid & HID_USAGE) {
100 /* Reported on Gyration MCE Remote */ 98 /* Reported on Gyration MCE Remote */
101 case 0x00d: map_key_clear(KEY_HOME); break; 99 case 0x00d: map_key_clear(KEY_HOME); break;
@@ -112,13 +110,13 @@ static int quirk_gyration_remote(struct hid_usage *usage, struct input_dev *inpu
112 return 1; 110 return 1;
113} 111}
114 112
115static int quirk_chicony_tactical_pad(struct hid_usage *usage, struct input_dev *input, 113static int quirk_chicony_tactical_pad(struct hid_usage *usage,
116 unsigned long **bit, int *max) 114 struct hid_input *hidinput, unsigned long **bit, int *max)
117{ 115{
118 if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR) 116 if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR)
119 return 0; 117 return 0;
120 118
121 set_bit(EV_REP, input->evbit); 119 set_bit(EV_REP, hidinput->input->evbit);
122 switch (usage->hid & HID_USAGE) { 120 switch (usage->hid & HID_USAGE) {
123 case 0xff01: map_key_clear(BTN_1); break; 121 case 0xff01: map_key_clear(BTN_1); break;
124 case 0xff02: map_key_clear(BTN_2); break; 122 case 0xff02: map_key_clear(BTN_2); break;
@@ -137,9 +135,11 @@ static int quirk_chicony_tactical_pad(struct hid_usage *usage, struct input_dev
137 return 1; 135 return 1;
138} 136}
139 137
140static int quirk_microsoft_ergonomy_kb(struct hid_usage *usage, struct input_dev *input, 138static int quirk_microsoft_ergonomy_kb(struct hid_usage *usage,
141 unsigned long **bit, int *max) 139 struct hid_input *hidinput, unsigned long **bit, int *max)
142{ 140{
141 struct input_dev *input = hidinput->input;
142
143 if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR) 143 if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR)
144 return 0; 144 return 0;
145 145
@@ -160,13 +160,13 @@ static int quirk_microsoft_ergonomy_kb(struct hid_usage *usage, struct input_dev
160 return 1; 160 return 1;
161} 161}
162 162
163static int quirk_microsoft_presenter_8k(struct hid_usage *usage, struct input_dev *input, 163static int quirk_microsoft_presenter_8k(struct hid_usage *usage,
164 unsigned long **bit, int *max) 164 struct hid_input *hidinput, unsigned long **bit, int *max)
165{ 165{
166 if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR) 166 if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR)
167 return 0; 167 return 0;
168 168
169 set_bit(EV_REP, input->evbit); 169 set_bit(EV_REP, hidinput->input->evbit);
170 switch(usage->hid & HID_USAGE) { 170 switch(usage->hid & HID_USAGE) {
171 case 0xfd08: map_key_clear(KEY_FORWARD); break; 171 case 0xfd08: map_key_clear(KEY_FORWARD); break;
172 case 0xfd09: map_key_clear(KEY_BACK); break; 172 case 0xfd09: map_key_clear(KEY_BACK); break;
@@ -179,8 +179,8 @@ static int quirk_microsoft_presenter_8k(struct hid_usage *usage, struct input_de
179 return 1; 179 return 1;
180} 180}
181 181
182static int quirk_petalynx_remote(struct hid_usage *usage, struct input_dev *input, 182static int quirk_petalynx_remote(struct hid_usage *usage,
183 unsigned long **bit, int *max) 183 struct hid_input *hidinput, unsigned long **bit, int *max)
184{ 184{
185 if (((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR) && 185 if (((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR) &&
186 ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)) 186 ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER))
@@ -207,8 +207,8 @@ static int quirk_petalynx_remote(struct hid_usage *usage, struct input_dev *inpu
207 return 1; 207 return 1;
208} 208}
209 209
210static int quirk_logitech_wireless(struct hid_usage *usage, struct input_dev *input, 210static int quirk_logitech_wireless(struct hid_usage *usage,
211 unsigned long **bit, int *max) 211 struct hid_input *hidinput, unsigned long **bit, int *max)
212{ 212{
213 if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) 213 if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)
214 return 0; 214 return 0;
@@ -259,8 +259,8 @@ static int quirk_logitech_wireless(struct hid_usage *usage, struct input_dev *in
259 return 1; 259 return 1;
260} 260}
261 261
262static int quirk_cherry_genius_29e(struct hid_usage *usage, struct input_dev *input, 262static int quirk_cherry_genius_29e(struct hid_usage *usage,
263 unsigned long **bit, int *max) 263 struct hid_input *hidinput, unsigned long **bit, int *max)
264{ 264{
265 if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) 265 if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)
266 return 0; 266 return 0;
@@ -277,7 +277,7 @@ static int quirk_cherry_genius_29e(struct hid_usage *usage, struct input_dev *in
277 return 1; 277 return 1;
278} 278}
279 279
280static int quirk_btc_8193(struct hid_usage *usage, struct input_dev *input, 280static int quirk_btc_8193(struct hid_usage *usage, struct hid_input *hidinput,
281 unsigned long **bit, int *max) 281 unsigned long **bit, int *max)
282{ 282{
283 if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) 283 if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)
@@ -299,8 +299,8 @@ static int quirk_btc_8193(struct hid_usage *usage, struct input_dev *input,
299 return 1; 299 return 1;
300} 300}
301 301
302static int quirk_sunplus_wdesktop(struct hid_usage *usage, struct input_dev *input, 302static int quirk_sunplus_wdesktop(struct hid_usage *usage,
303 unsigned long **bit, int *max) 303 struct hid_input *hidinput, unsigned long **bit, int *max)
304{ 304{
305 if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) 305 if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)
306 return 0; 306 return 0;
@@ -353,7 +353,8 @@ static int quirk_sunplus_wdesktop(struct hid_usage *usage, struct input_dev *inp
353static const struct hid_input_blacklist { 353static const struct hid_input_blacklist {
354 __u16 idVendor; 354 __u16 idVendor;
355 __u16 idProduct; 355 __u16 idProduct;
356 int (*quirk)(struct hid_usage *, struct input_dev *, unsigned long **, int *); 356 int (*quirk)(struct hid_usage *, struct hid_input *, unsigned long **,
357 int *);
357} hid_input_blacklist[] = { 358} hid_input_blacklist[] = {
358 { VENDOR_ID_BELKIN, DEVICE_ID_BELKIN_WIRELESS_KEYBOARD, quirk_belkin_wkbd }, 359 { VENDOR_ID_BELKIN, DEVICE_ID_BELKIN_WIRELESS_KEYBOARD, quirk_belkin_wkbd },
359 360
@@ -385,16 +386,16 @@ static const struct hid_input_blacklist {
385}; 386};
386 387
387int hidinput_mapping_quirks(struct hid_usage *usage, 388int hidinput_mapping_quirks(struct hid_usage *usage,
388 struct input_dev *input, 389 struct hid_input *hi, unsigned long **bit, int *max)
389 unsigned long **bit, int *max)
390{ 390{
391 struct hid_device *device = input_get_drvdata(input); 391 struct hid_device *device = input_get_drvdata(hi->input);
392 int i = 0; 392 int i = 0;
393 393
394 while (hid_input_blacklist[i].quirk) { 394 while (hid_input_blacklist[i].quirk) {
395 if (hid_input_blacklist[i].idVendor == device->vendor && 395 if (hid_input_blacklist[i].idVendor == device->vendor &&
396 hid_input_blacklist[i].idProduct == device->product) 396 hid_input_blacklist[i].idProduct == device->product)
397 return hid_input_blacklist[i].quirk(usage, input, bit, max); 397 return hid_input_blacklist[i].quirk(usage, hi, bit,
398 max);
398 i++; 399 i++;
399 } 400 }
400 return 0; 401 return 0;
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 9fa7239ab310..be2c7a8ad254 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -76,13 +76,15 @@ static const struct {
76 __s32 y; 76 __s32 y;
77} hid_hat_to_axis[] = {{ 0, 0}, { 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}}; 77} hid_hat_to_axis[] = {{ 0, 0}, { 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}};
78 78
79#define map_abs(c) do { usage->code = c; usage->type = EV_ABS; bit = input->absbit; max = ABS_MAX; } while (0) 79#define map_abs(c) hid_map_usage(hidinput, usage, &bit, &max, EV_ABS, (c))
80#define map_rel(c) do { usage->code = c; usage->type = EV_REL; bit = input->relbit; max = REL_MAX; } while (0) 80#define map_rel(c) hid_map_usage(hidinput, usage, &bit, &max, EV_REL, (c))
81#define map_key(c) do { usage->code = c; usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX; } while (0) 81#define map_key(c) hid_map_usage(hidinput, usage, &bit, &max, EV_KEY, (c))
82#define map_led(c) do { usage->code = c; usage->type = EV_LED; bit = input->ledbit; max = LED_MAX; } while (0) 82#define map_led(c) hid_map_usage(hidinput, usage, &bit, &max, EV_LED, (c))
83 83
84#define map_abs_clear(c) do { map_abs(c); clear_bit(c, bit); } while (0) 84#define map_abs_clear(c) hid_map_usage_clear(hidinput, usage, &bit, \
85#define map_key_clear(c) do { map_key(c); clear_bit(c, bit); } while (0) 85 &max, EV_ABS, (c))
86#define map_key_clear(c) hid_map_usage_clear(hidinput, usage, &bit, \
87 &max, EV_KEY, (c))
86 88
87#ifdef CONFIG_USB_HIDINPUT_POWERBOOK 89#ifdef CONFIG_USB_HIDINPUT_POWERBOOK
88 90
@@ -386,7 +388,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
386 } 388 }
387 389
388 /* handle input mappings for quirky devices */ 390 /* handle input mappings for quirky devices */
389 ret = hidinput_mapping_quirks(usage, input, &bit, &max); 391 ret = hidinput_mapping_quirks(usage, hidinput, &bit, &max);
390 if (ret) 392 if (ret)
391 goto mapped; 393 goto mapped;
392 394
diff --git a/include/linux/hid.h b/include/linux/hid.h
index ac2584fe65c5..986c0e7ea66a 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -655,7 +655,8 @@ extern void hidinput_disconnect(struct hid_device *);
655int hid_set_field(struct hid_field *, unsigned, __s32); 655int hid_set_field(struct hid_field *, unsigned, __s32);
656int hid_input_report(struct hid_device *, int type, u8 *, int, int); 656int hid_input_report(struct hid_device *, int type, u8 *, int, int);
657int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field); 657int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field);
658int hidinput_mapping_quirks(struct hid_usage *, struct input_dev *, unsigned long **, int *); 658int hidinput_mapping_quirks(struct hid_usage *, struct hid_input *,
659 unsigned long **, int *);
659int hidinput_event_quirks(struct hid_device *, struct hid_field *, struct hid_usage *, __s32); 660int hidinput_event_quirks(struct hid_device *, struct hid_field *, struct hid_usage *, __s32);
660int hidinput_apple_event(struct hid_device *, struct input_dev *, struct hid_usage *, __s32); 661int hidinput_apple_event(struct hid_device *, struct input_dev *, struct hid_usage *, __s32);
661void hid_output_report(struct hid_report *report, __u8 *data); 662void hid_output_report(struct hid_report *report, __u8 *data);
@@ -663,6 +664,59 @@ struct hid_device *hid_allocate_device(void);
663int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size); 664int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size);
664 665
665/** 666/**
667 * hid_map_usage - map usage input bits
668 *
669 * @hidinput: hidinput which we are interested in
670 * @usage: usage to fill in
671 * @bit: pointer to input->{}bit (out parameter)
672 * @max: maximal valid usage->code to consider later (out parameter)
673 * @type: input event type (EV_KEY, EV_REL, ...)
674 * @c: code which corresponds to this usage and type
675 */
676static inline void hid_map_usage(struct hid_input *hidinput,
677 struct hid_usage *usage, unsigned long **bit, int *max,
678 __u8 type, __u16 c)
679{
680 struct input_dev *input = hidinput->input;
681
682 usage->type = type;
683 usage->code = c;
684
685 switch (type) {
686 case EV_ABS:
687 *bit = input->absbit;
688 *max = ABS_MAX;
689 break;
690 case EV_REL:
691 *bit = input->relbit;
692 *max = REL_MAX;
693 break;
694 case EV_KEY:
695 *bit = input->keybit;
696 *max = KEY_MAX;
697 break;
698 case EV_LED:
699 *bit = input->ledbit;
700 *max = LED_MAX;
701 break;
702 }
703}
704
705/**
706 * hid_map_usage_clear - map usage input bits and clear the input bit
707 *
708 * The same as hid_map_usage, except the @c bit is also cleared in supported
709 * bits (@bit).
710 */
711static inline void hid_map_usage_clear(struct hid_input *hidinput,
712 struct hid_usage *usage, unsigned long **bit, int *max,
713 __u8 type, __u16 c)
714{
715 hid_map_usage(hidinput, usage, bit, max, type, c);
716 clear_bit(c, *bit);
717}
718
719/**
666 * hid_parse - parse HW reports 720 * hid_parse - parse HW reports
667 * 721 *
668 * @hdev: hid device 722 * @hdev: hid device