diff options
Diffstat (limited to 'drivers/input/input.c')
-rw-r--r-- | drivers/input/input.c | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/drivers/input/input.c b/drivers/input/input.c index 4486402fbf5d..26393a606e6f 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -299,6 +299,87 @@ void input_close_device(struct input_handle *handle) | |||
299 | } | 299 | } |
300 | EXPORT_SYMBOL(input_close_device); | 300 | EXPORT_SYMBOL(input_close_device); |
301 | 301 | ||
302 | static int input_fetch_keycode(struct input_dev *dev, int scancode) | ||
303 | { | ||
304 | switch (dev->keycodesize) { | ||
305 | case 1: | ||
306 | return ((u8 *)dev->keycode)[scancode]; | ||
307 | |||
308 | case 2: | ||
309 | return ((u16 *)dev->keycode)[scancode]; | ||
310 | |||
311 | default: | ||
312 | return ((u32 *)dev->keycode)[scancode]; | ||
313 | } | ||
314 | } | ||
315 | |||
316 | static int input_default_getkeycode(struct input_dev *dev, | ||
317 | int scancode, int *keycode) | ||
318 | { | ||
319 | if (!dev->keycodesize) | ||
320 | return -EINVAL; | ||
321 | |||
322 | if (scancode < 0 || scancode >= dev->keycodemax) | ||
323 | return -EINVAL; | ||
324 | |||
325 | *keycode = input_fetch_keycode(dev, scancode); | ||
326 | |||
327 | return 0; | ||
328 | } | ||
329 | |||
330 | static int input_default_setkeycode(struct input_dev *dev, | ||
331 | int scancode, int keycode) | ||
332 | { | ||
333 | int old_keycode; | ||
334 | int i; | ||
335 | |||
336 | if (scancode < 0 || scancode >= dev->keycodemax) | ||
337 | return -EINVAL; | ||
338 | |||
339 | if (keycode < 0 || keycode > KEY_MAX) | ||
340 | return -EINVAL; | ||
341 | |||
342 | if (!dev->keycodesize) | ||
343 | return -EINVAL; | ||
344 | |||
345 | if (dev->keycodesize < sizeof(keycode) && (keycode >> (dev->keycodesize * 8))) | ||
346 | return -EINVAL; | ||
347 | |||
348 | switch (dev->keycodesize) { | ||
349 | case 1: { | ||
350 | u8 *k = (u8 *)dev->keycode; | ||
351 | old_keycode = k[scancode]; | ||
352 | k[scancode] = keycode; | ||
353 | break; | ||
354 | } | ||
355 | case 2: { | ||
356 | u16 *k = (u16 *)dev->keycode; | ||
357 | old_keycode = k[scancode]; | ||
358 | k[scancode] = keycode; | ||
359 | break; | ||
360 | } | ||
361 | default: { | ||
362 | u32 *k = (u32 *)dev->keycode; | ||
363 | old_keycode = k[scancode]; | ||
364 | k[scancode] = keycode; | ||
365 | break; | ||
366 | } | ||
367 | } | ||
368 | |||
369 | clear_bit(old_keycode, dev->keybit); | ||
370 | set_bit(keycode, dev->keybit); | ||
371 | |||
372 | for (i = 0; i < dev->keycodemax; i++) { | ||
373 | if (input_fetch_keycode(dev, i) == old_keycode) { | ||
374 | set_bit(old_keycode, dev->keybit); | ||
375 | break; /* Setting the bit twice is useless, so break */ | ||
376 | } | ||
377 | } | ||
378 | |||
379 | return 0; | ||
380 | } | ||
381 | |||
382 | |||
302 | static void input_link_handle(struct input_handle *handle) | 383 | static void input_link_handle(struct input_handle *handle) |
303 | { | 384 | { |
304 | list_add_tail(&handle->d_node, &handle->dev->h_list); | 385 | list_add_tail(&handle->d_node, &handle->dev->h_list); |
@@ -978,6 +1059,12 @@ int input_register_device(struct input_dev *dev) | |||
978 | dev->rep[REP_PERIOD] = 33; | 1059 | dev->rep[REP_PERIOD] = 33; |
979 | } | 1060 | } |
980 | 1061 | ||
1062 | if (!dev->getkeycode) | ||
1063 | dev->getkeycode = input_default_getkeycode; | ||
1064 | |||
1065 | if (!dev->setkeycode) | ||
1066 | dev->setkeycode = input_default_setkeycode; | ||
1067 | |||
981 | list_add_tail(&dev->node, &input_dev_list); | 1068 | list_add_tail(&dev->node, &input_dev_list); |
982 | 1069 | ||
983 | snprintf(dev->cdev.class_id, sizeof(dev->cdev.class_id), | 1070 | snprintf(dev->cdev.class_id, sizeof(dev->cdev.class_id), |