aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/macintosh/adbhid.c46
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
228static struct adbhid *adbhid[16]; 229static 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
692static void
693adbhid_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
684static int 707static int
685adb_message_handler(struct notifier_block *this, unsigned long code, void *x) 708adb_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: