diff options
Diffstat (limited to 'drivers/hid/hid-input.c')
-rw-r--r-- | drivers/hid/hid-input.c | 101 |
1 files changed, 96 insertions, 5 deletions
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index a19b65ed3119..7f817897b178 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
@@ -240,11 +240,94 @@ static inline void hidinput_pb_setup(struct input_dev *input) | |||
240 | } | 240 | } |
241 | #endif | 241 | #endif |
242 | 242 | ||
243 | static inline int match_scancode(int code, int scancode) | ||
244 | { | ||
245 | if (scancode == 0) | ||
246 | return 1; | ||
247 | return ((code & (HID_USAGE_PAGE | HID_USAGE)) == scancode); | ||
248 | } | ||
249 | |||
250 | static inline int match_keycode(int code, int keycode) | ||
251 | { | ||
252 | if (keycode == 0) | ||
253 | return 1; | ||
254 | return (code == keycode); | ||
255 | } | ||
256 | |||
257 | static struct hid_usage *hidinput_find_key(struct hid_device *hid, | ||
258 | int scancode, int keycode) | ||
259 | { | ||
260 | int i, j, k; | ||
261 | struct hid_report *report; | ||
262 | struct hid_usage *usage; | ||
263 | |||
264 | for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) { | ||
265 | list_for_each_entry(report, &hid->report_enum[k].report_list, list) { | ||
266 | for (i = 0; i < report->maxfield; i++) { | ||
267 | for ( j = 0; j < report->field[i]->maxusage; j++) { | ||
268 | usage = report->field[i]->usage + j; | ||
269 | if (usage->type == EV_KEY && | ||
270 | match_scancode(usage->hid, scancode) && | ||
271 | match_keycode(usage->code, keycode)) | ||
272 | return usage; | ||
273 | } | ||
274 | } | ||
275 | } | ||
276 | } | ||
277 | return NULL; | ||
278 | } | ||
279 | |||
280 | static int hidinput_getkeycode(struct input_dev *dev, int scancode, | ||
281 | int *keycode) | ||
282 | { | ||
283 | struct hid_device *hid = dev->private; | ||
284 | struct hid_usage *usage; | ||
285 | |||
286 | usage = hidinput_find_key(hid, scancode, 0); | ||
287 | if (usage) { | ||
288 | *keycode = usage->code; | ||
289 | return 0; | ||
290 | } | ||
291 | return -EINVAL; | ||
292 | } | ||
293 | |||
294 | static int hidinput_setkeycode(struct input_dev *dev, int scancode, | ||
295 | int keycode) | ||
296 | { | ||
297 | struct hid_device *hid = dev->private; | ||
298 | struct hid_usage *usage; | ||
299 | int old_keycode; | ||
300 | |||
301 | if (keycode < 0 || keycode > KEY_MAX) | ||
302 | return -EINVAL; | ||
303 | |||
304 | usage = hidinput_find_key(hid, scancode, 0); | ||
305 | if (usage) { | ||
306 | old_keycode = usage->code; | ||
307 | usage->code = keycode; | ||
308 | |||
309 | clear_bit(old_keycode, dev->keybit); | ||
310 | set_bit(usage->code, dev->keybit); | ||
311 | #ifdef CONFIG_HID_DEBUG | ||
312 | printk (KERN_DEBUG "Assigned keycode %d to HID usage code %x\n", keycode, scancode); | ||
313 | #endif | ||
314 | /* Set the keybit for the old keycode if the old keycode is used | ||
315 | * by another key */ | ||
316 | if (hidinput_find_key (hid, 0, old_keycode)) | ||
317 | set_bit(old_keycode, dev->keybit); | ||
318 | |||
319 | return 0; | ||
320 | } | ||
321 | |||
322 | return -EINVAL; | ||
323 | } | ||
324 | |||
325 | |||
243 | static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field, | 326 | static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field, |
244 | struct hid_usage *usage) | 327 | struct hid_usage *usage) |
245 | { | 328 | { |
246 | struct input_dev *input = hidinput->input; | 329 | struct input_dev *input = hidinput->input; |
247 | struct hid_device *device = input->private; | 330 | struct hid_device *device = input_get_drvdata(input); |
248 | int max = 0, code; | 331 | int max = 0, code; |
249 | unsigned long *bit = NULL; | 332 | unsigned long *bit = NULL; |
250 | 333 | ||
@@ -553,6 +636,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
553 | case 0x1015: map_key_clear(KEY_RECORD); break; | 636 | case 0x1015: map_key_clear(KEY_RECORD); break; |
554 | case 0x1016: map_key_clear(KEY_PLAYER); break; | 637 | case 0x1016: map_key_clear(KEY_PLAYER); break; |
555 | case 0x1017: map_key_clear(KEY_EJECTCD); break; | 638 | case 0x1017: map_key_clear(KEY_EJECTCD); break; |
639 | case 0x1018: map_key_clear(KEY_MEDIA); break; | ||
556 | case 0x1019: map_key_clear(KEY_PROG1); break; | 640 | case 0x1019: map_key_clear(KEY_PROG1); break; |
557 | case 0x101a: map_key_clear(KEY_PROG2); break; | 641 | case 0x101a: map_key_clear(KEY_PROG2); break; |
558 | case 0x101b: map_key_clear(KEY_PROG3); break; | 642 | case 0x101b: map_key_clear(KEY_PROG3); break; |
@@ -560,9 +644,12 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
560 | case 0x1020: map_key_clear(KEY_ZOOMOUT); break; | 644 | case 0x1020: map_key_clear(KEY_ZOOMOUT); break; |
561 | case 0x1021: map_key_clear(KEY_ZOOMRESET); break; | 645 | case 0x1021: map_key_clear(KEY_ZOOMRESET); break; |
562 | case 0x1023: map_key_clear(KEY_CLOSE); break; | 646 | case 0x1023: map_key_clear(KEY_CLOSE); break; |
647 | case 0x1027: map_key_clear(KEY_MENU); break; | ||
563 | /* this one is marked as 'Rotate' */ | 648 | /* this one is marked as 'Rotate' */ |
564 | case 0x1028: map_key_clear(KEY_ANGLE); break; | 649 | case 0x1028: map_key_clear(KEY_ANGLE); break; |
565 | case 0x1029: map_key_clear(KEY_SHUFFLE); break; | 650 | case 0x1029: map_key_clear(KEY_SHUFFLE); break; |
651 | case 0x102a: map_key_clear(KEY_BACK); break; | ||
652 | case 0x102b: map_key_clear(KEY_CYCLEWINDOWS); break; | ||
566 | case 0x1041: map_key_clear(KEY_BATTERY); break; | 653 | case 0x1041: map_key_clear(KEY_BATTERY); break; |
567 | case 0x1042: map_key_clear(KEY_WORDPROCESSOR); break; | 654 | case 0x1042: map_key_clear(KEY_WORDPROCESSOR); break; |
568 | case 0x1043: map_key_clear(KEY_SPREADSHEET); break; | 655 | case 0x1043: map_key_clear(KEY_SPREADSHEET); break; |
@@ -855,13 +942,15 @@ EXPORT_SYMBOL_GPL(hidinput_find_field); | |||
855 | 942 | ||
856 | static int hidinput_open(struct input_dev *dev) | 943 | static int hidinput_open(struct input_dev *dev) |
857 | { | 944 | { |
858 | struct hid_device *hid = dev->private; | 945 | struct hid_device *hid = input_get_drvdata(dev); |
946 | |||
859 | return hid->hid_open(hid); | 947 | return hid->hid_open(hid); |
860 | } | 948 | } |
861 | 949 | ||
862 | static void hidinput_close(struct input_dev *dev) | 950 | static void hidinput_close(struct input_dev *dev) |
863 | { | 951 | { |
864 | struct hid_device *hid = dev->private; | 952 | struct hid_device *hid = input_get_drvdata(dev); |
953 | |||
865 | hid->hid_close(hid); | 954 | hid->hid_close(hid); |
866 | } | 955 | } |
867 | 956 | ||
@@ -909,10 +998,12 @@ int hidinput_connect(struct hid_device *hid) | |||
909 | return -1; | 998 | return -1; |
910 | } | 999 | } |
911 | 1000 | ||
912 | input_dev->private = hid; | 1001 | input_set_drvdata(input_dev, hid); |
913 | input_dev->event = hid->hidinput_input_event; | 1002 | input_dev->event = hid->hidinput_input_event; |
914 | input_dev->open = hidinput_open; | 1003 | input_dev->open = hidinput_open; |
915 | input_dev->close = hidinput_close; | 1004 | input_dev->close = hidinput_close; |
1005 | input_dev->setkeycode = hidinput_setkeycode; | ||
1006 | input_dev->getkeycode = hidinput_getkeycode; | ||
916 | 1007 | ||
917 | input_dev->name = hid->name; | 1008 | input_dev->name = hid->name; |
918 | input_dev->phys = hid->phys; | 1009 | input_dev->phys = hid->phys; |
@@ -921,7 +1012,7 @@ int hidinput_connect(struct hid_device *hid) | |||
921 | input_dev->id.vendor = hid->vendor; | 1012 | input_dev->id.vendor = hid->vendor; |
922 | input_dev->id.product = hid->product; | 1013 | input_dev->id.product = hid->product; |
923 | input_dev->id.version = hid->version; | 1014 | input_dev->id.version = hid->version; |
924 | input_dev->cdev.dev = hid->dev; | 1015 | input_dev->dev.parent = hid->dev; |
925 | hidinput->input = input_dev; | 1016 | hidinput->input = input_dev; |
926 | list_add_tail(&hidinput->list, &hid->inputs); | 1017 | list_add_tail(&hidinput->list, &hid->inputs); |
927 | } | 1018 | } |