diff options
-rw-r--r-- | drivers/hid/hid-input.c | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index a87b059f866f..7f817897b178 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
@@ -240,6 +240,89 @@ 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 | { |
@@ -919,6 +1002,8 @@ int hidinput_connect(struct hid_device *hid) | |||
919 | input_dev->event = hid->hidinput_input_event; | 1002 | input_dev->event = hid->hidinput_input_event; |
920 | input_dev->open = hidinput_open; | 1003 | input_dev->open = hidinput_open; |
921 | input_dev->close = hidinput_close; | 1004 | input_dev->close = hidinput_close; |
1005 | input_dev->setkeycode = hidinput_setkeycode; | ||
1006 | input_dev->getkeycode = hidinput_getkeycode; | ||
922 | 1007 | ||
923 | input_dev->name = hid->name; | 1008 | input_dev->name = hid->name; |
924 | input_dev->phys = hid->phys; | 1009 | input_dev->phys = hid->phys; |