diff options
Diffstat (limited to 'drivers/input/misc/ati_remote2.c')
-rw-r--r-- | drivers/input/misc/ati_remote2.c | 98 |
1 files changed, 69 insertions, 29 deletions
diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c index 23257652b8e8..1de58e8a1b71 100644 --- a/drivers/input/misc/ati_remote2.c +++ b/drivers/input/misc/ati_remote2.c | |||
@@ -483,51 +483,88 @@ static void ati_remote2_complete_key(struct urb *urb) | |||
483 | } | 483 | } |
484 | 484 | ||
485 | static int ati_remote2_getkeycode(struct input_dev *idev, | 485 | static int ati_remote2_getkeycode(struct input_dev *idev, |
486 | unsigned int scancode, unsigned int *keycode) | 486 | struct input_keymap_entry *ke) |
487 | { | 487 | { |
488 | struct ati_remote2 *ar2 = input_get_drvdata(idev); | 488 | struct ati_remote2 *ar2 = input_get_drvdata(idev); |
489 | unsigned int mode; | 489 | unsigned int mode; |
490 | int index; | 490 | int offset; |
491 | 491 | unsigned int index; | |
492 | mode = scancode >> 8; | 492 | unsigned int scancode; |
493 | if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask)) | 493 | |
494 | return -EINVAL; | 494 | if (ke->flags & INPUT_KEYMAP_BY_INDEX) { |
495 | index = ke->index; | ||
496 | if (index >= ATI_REMOTE2_MODES * | ||
497 | ARRAY_SIZE(ati_remote2_key_table)) | ||
498 | return -EINVAL; | ||
499 | |||
500 | mode = ke->index / ARRAY_SIZE(ati_remote2_key_table); | ||
501 | offset = ke->index % ARRAY_SIZE(ati_remote2_key_table); | ||
502 | scancode = (mode << 8) + ati_remote2_key_table[offset].hw_code; | ||
503 | } else { | ||
504 | if (input_scancode_to_scalar(ke, &scancode)) | ||
505 | return -EINVAL; | ||
506 | |||
507 | mode = scancode >> 8; | ||
508 | if (mode > ATI_REMOTE2_PC) | ||
509 | return -EINVAL; | ||
510 | |||
511 | offset = ati_remote2_lookup(scancode & 0xff); | ||
512 | if (offset < 0) | ||
513 | return -EINVAL; | ||
514 | |||
515 | index = mode * ARRAY_SIZE(ati_remote2_key_table) + offset; | ||
516 | } | ||
495 | 517 | ||
496 | index = ati_remote2_lookup(scancode & 0xFF); | 518 | ke->keycode = ar2->keycode[mode][offset]; |
497 | if (index < 0) | 519 | ke->len = sizeof(scancode); |
498 | return -EINVAL; | 520 | memcpy(&ke->scancode, &scancode, sizeof(scancode)); |
521 | ke->index = index; | ||
499 | 522 | ||
500 | *keycode = ar2->keycode[mode][index]; | ||
501 | return 0; | 523 | return 0; |
502 | } | 524 | } |
503 | 525 | ||
504 | static int ati_remote2_setkeycode(struct input_dev *idev, | 526 | static int ati_remote2_setkeycode(struct input_dev *idev, |
505 | unsigned int scancode, unsigned int keycode) | 527 | const struct input_keymap_entry *ke, |
528 | unsigned int *old_keycode) | ||
506 | { | 529 | { |
507 | struct ati_remote2 *ar2 = input_get_drvdata(idev); | 530 | struct ati_remote2 *ar2 = input_get_drvdata(idev); |
508 | unsigned int mode, old_keycode; | 531 | unsigned int mode; |
509 | int index; | 532 | int offset; |
510 | 533 | unsigned int index; | |
511 | mode = scancode >> 8; | 534 | unsigned int scancode; |
512 | if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask)) | 535 | |
513 | return -EINVAL; | 536 | if (ke->flags & INPUT_KEYMAP_BY_INDEX) { |
514 | 537 | if (ke->index >= ATI_REMOTE2_MODES * | |
515 | index = ati_remote2_lookup(scancode & 0xFF); | 538 | ARRAY_SIZE(ati_remote2_key_table)) |
516 | if (index < 0) | 539 | return -EINVAL; |
517 | return -EINVAL; | 540 | |
541 | mode = ke->index / ARRAY_SIZE(ati_remote2_key_table); | ||
542 | offset = ke->index % ARRAY_SIZE(ati_remote2_key_table); | ||
543 | } else { | ||
544 | if (input_scancode_to_scalar(ke, &scancode)) | ||
545 | return -EINVAL; | ||
546 | |||
547 | mode = scancode >> 8; | ||
548 | if (mode > ATI_REMOTE2_PC) | ||
549 | return -EINVAL; | ||
550 | |||
551 | offset = ati_remote2_lookup(scancode & 0xff); | ||
552 | if (offset < 0) | ||
553 | return -EINVAL; | ||
554 | } | ||
518 | 555 | ||
519 | old_keycode = ar2->keycode[mode][index]; | 556 | *old_keycode = ar2->keycode[mode][offset]; |
520 | ar2->keycode[mode][index] = keycode; | 557 | ar2->keycode[mode][offset] = ke->keycode; |
521 | __set_bit(keycode, idev->keybit); | 558 | __set_bit(ke->keycode, idev->keybit); |
522 | 559 | ||
523 | for (mode = 0; mode < ATI_REMOTE2_MODES; mode++) { | 560 | for (mode = 0; mode < ATI_REMOTE2_MODES; mode++) { |
524 | for (index = 0; index < ARRAY_SIZE(ati_remote2_key_table); index++) { | 561 | for (index = 0; index < ARRAY_SIZE(ati_remote2_key_table); index++) { |
525 | if (ar2->keycode[mode][index] == old_keycode) | 562 | if (ar2->keycode[mode][index] == *old_keycode) |
526 | return 0; | 563 | return 0; |
527 | } | 564 | } |
528 | } | 565 | } |
529 | 566 | ||
530 | __clear_bit(old_keycode, idev->keybit); | 567 | __clear_bit(*old_keycode, idev->keybit); |
531 | 568 | ||
532 | return 0; | 569 | return 0; |
533 | } | 570 | } |
@@ -700,14 +737,17 @@ static ssize_t ati_remote2_store_channel_mask(struct device *dev, | |||
700 | 737 | ||
701 | mutex_lock(&ati_remote2_mutex); | 738 | mutex_lock(&ati_remote2_mutex); |
702 | 739 | ||
703 | if (mask != ar2->channel_mask && !ati_remote2_setup(ar2, mask)) | 740 | if (mask != ar2->channel_mask) { |
704 | ar2->channel_mask = mask; | 741 | r = ati_remote2_setup(ar2, mask); |
742 | if (!r) | ||
743 | ar2->channel_mask = mask; | ||
744 | } | ||
705 | 745 | ||
706 | mutex_unlock(&ati_remote2_mutex); | 746 | mutex_unlock(&ati_remote2_mutex); |
707 | 747 | ||
708 | usb_autopm_put_interface(ar2->intf[0]); | 748 | usb_autopm_put_interface(ar2->intf[0]); |
709 | 749 | ||
710 | return count; | 750 | return r ? r : count; |
711 | } | 751 | } |
712 | 752 | ||
713 | static ssize_t ati_remote2_show_mode_mask(struct device *dev, | 753 | static ssize_t ati_remote2_show_mode_mask(struct device *dev, |