diff options
Diffstat (limited to 'drivers/macintosh/adbhid.c')
-rw-r--r-- | drivers/macintosh/adbhid.c | 46 |
1 files changed, 39 insertions, 7 deletions
diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c index ef4c117ea35f..6e9afe26db89 100644 --- a/drivers/macintosh/adbhid.c +++ b/drivers/macintosh/adbhid.c | |||
@@ -219,11 +219,12 @@ struct adbhid { | |||
219 | int flags; | 219 | int flags; |
220 | }; | 220 | }; |
221 | 221 | ||
222 | #define FLAG_FN_KEY_PRESSED 0x00000001 | 222 | #define FLAG_FN_KEY_PRESSED 0x00000001 |
223 | #define FLAG_POWER_FROM_FN 0x00000002 | 223 | #define FLAG_POWER_FROM_FN 0x00000002 |
224 | #define FLAG_EMU_FWDEL_DOWN 0x00000004 | 224 | #define FLAG_EMU_FWDEL_DOWN 0x00000004 |
225 | #define FLAG_CAPSLOCK_TRANSLATE 0x00000008 | 225 | #define FLAG_CAPSLOCK_TRANSLATE 0x00000008 |
226 | #define FLAG_CAPSLOCK_DOWN 0x00000010 | 226 | #define FLAG_CAPSLOCK_DOWN 0x00000010 |
227 | #define FLAG_CAPSLOCK_IGNORE_NEXT 0x00000020 | ||
227 | 228 | ||
228 | static struct adbhid *adbhid[16]; | 229 | static struct adbhid *adbhid[16]; |
229 | 230 | ||
@@ -291,8 +292,15 @@ adbhid_input_keycode(int id, int scancode, int repeat) | |||
291 | if (keycode == ADB_KEY_CAPSLOCK && !up_flag) { | 292 | if (keycode == ADB_KEY_CAPSLOCK && !up_flag) { |
292 | /* Key pressed, turning on the CapsLock LED. | 293 | /* Key pressed, turning on the CapsLock LED. |
293 | * The next 0xff will be interpreted as a release. */ | 294 | * The next 0xff will be interpreted as a release. */ |
294 | ahid->flags |= FLAG_CAPSLOCK_TRANSLATE | 295 | if (ahid->flags & FLAG_CAPSLOCK_IGNORE_NEXT) { |
296 | /* Throw away this key event if it happens | ||
297 | * just after resume. */ | ||
298 | ahid->flags &= ~FLAG_CAPSLOCK_IGNORE_NEXT; | ||
299 | return; | ||
300 | } else { | ||
301 | ahid->flags |= FLAG_CAPSLOCK_TRANSLATE | ||
295 | | FLAG_CAPSLOCK_DOWN; | 302 | | FLAG_CAPSLOCK_DOWN; |
303 | } | ||
296 | } else if (scancode == 0xff) { | 304 | } else if (scancode == 0xff) { |
297 | /* Scancode 0xff usually signifies that the capslock | 305 | /* Scancode 0xff usually signifies that the capslock |
298 | * key was either pressed or released. */ | 306 | * key was either pressed or released. */ |
@@ -681,6 +689,21 @@ static int adbhid_kbd_event(struct input_dev *dev, unsigned int type, unsigned i | |||
681 | return -1; | 689 | return -1; |
682 | } | 690 | } |
683 | 691 | ||
692 | static void | ||
693 | adbhid_kbd_capslock_remember(void) | ||
694 | { | ||
695 | struct adbhid *ahid; | ||
696 | int i; | ||
697 | |||
698 | for (i = 1; i < 16; i++) { | ||
699 | ahid = adbhid[i]; | ||
700 | |||
701 | if (ahid && ahid->id == ADB_KEYBOARD) | ||
702 | if (ahid->flags & FLAG_CAPSLOCK_TRANSLATE) | ||
703 | ahid->flags |= FLAG_CAPSLOCK_IGNORE_NEXT; | ||
704 | } | ||
705 | } | ||
706 | |||
684 | static int | 707 | static int |
685 | adb_message_handler(struct notifier_block *this, unsigned long code, void *x) | 708 | adb_message_handler(struct notifier_block *this, unsigned long code, void *x) |
686 | { | 709 | { |
@@ -697,8 +720,17 @@ adb_message_handler(struct notifier_block *this, unsigned long code, void *x) | |||
697 | } | 720 | } |
698 | 721 | ||
699 | /* Stop pending led requests */ | 722 | /* Stop pending led requests */ |
700 | while(leds_req_pending) | 723 | while (leds_req_pending) |
701 | adb_poll(); | 724 | adb_poll(); |
725 | |||
726 | /* After resume, and if the capslock LED is on, the PMU will | ||
727 | * send a "capslock down" key event. This confuses the | ||
728 | * restore_capslock_events logic. Remember if the capslock | ||
729 | * LED was on before suspend so the unwanted key event can | ||
730 | * be ignored after resume. */ | ||
731 | if (restore_capslock_events) | ||
732 | adbhid_kbd_capslock_remember(); | ||
733 | |||
702 | break; | 734 | break; |
703 | 735 | ||
704 | case ADB_MSG_POST_RESET: | 736 | case ADB_MSG_POST_RESET: |