aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/macintosh
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/macintosh')
-rw-r--r--drivers/macintosh/adbhid.c61
1 files changed, 51 insertions, 10 deletions
diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c
index 59ea520a5d7a..5396c67ba0a4 100644
--- a/drivers/macintosh/adbhid.c
+++ b/drivers/macintosh/adbhid.c
@@ -219,11 +219,13 @@ 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
228#define FLAG_POWER_KEY_PRESSED 0x00000040
227 229
228static struct adbhid *adbhid[16]; 230static struct adbhid *adbhid[16];
229 231
@@ -291,11 +293,20 @@ adbhid_input_keycode(int id, int scancode, int repeat)
291 if (keycode == ADB_KEY_CAPSLOCK && !up_flag) { 293 if (keycode == ADB_KEY_CAPSLOCK && !up_flag) {
292 /* Key pressed, turning on the CapsLock LED. 294 /* Key pressed, turning on the CapsLock LED.
293 * The next 0xff will be interpreted as a release. */ 295 * The next 0xff will be interpreted as a release. */
294 ahid->flags |= FLAG_CAPSLOCK_TRANSLATE 296 if (ahid->flags & FLAG_CAPSLOCK_IGNORE_NEXT) {
297 /* Throw away this key event if it happens
298 * just after resume. */
299 ahid->flags &= ~FLAG_CAPSLOCK_IGNORE_NEXT;
300 return;
301 } else {
302 ahid->flags |= FLAG_CAPSLOCK_TRANSLATE
295 | FLAG_CAPSLOCK_DOWN; 303 | FLAG_CAPSLOCK_DOWN;
296 } else if (scancode == 0xff) { 304 }
305 } else if (scancode == 0xff &&
306 !(ahid->flags & FLAG_POWER_KEY_PRESSED)) {
297 /* Scancode 0xff usually signifies that the capslock 307 /* Scancode 0xff usually signifies that the capslock
298 * key was either pressed or released. */ 308 * key was either pressed or released, or that the
309 * power button was released. */
299 if (ahid->flags & FLAG_CAPSLOCK_TRANSLATE) { 310 if (ahid->flags & FLAG_CAPSLOCK_TRANSLATE) {
300 keycode = ADB_KEY_CAPSLOCK; 311 keycode = ADB_KEY_CAPSLOCK;
301 if (ahid->flags & FLAG_CAPSLOCK_DOWN) { 312 if (ahid->flags & FLAG_CAPSLOCK_DOWN) {
@@ -309,7 +320,7 @@ adbhid_input_keycode(int id, int scancode, int repeat)
309 } 320 }
310 } else { 321 } else {
311 printk(KERN_INFO "Spurious caps lock event " 322 printk(KERN_INFO "Spurious caps lock event "
312 "(scancode 0xff)."); 323 "(scancode 0xff).\n");
313 } 324 }
314 } 325 }
315 } 326 }
@@ -336,6 +347,12 @@ adbhid_input_keycode(int id, int scancode, int repeat)
336 } 347 }
337 break; 348 break;
338 case ADB_KEY_POWER: 349 case ADB_KEY_POWER:
350 /* Keep track of the power key state */
351 if (up_flag)
352 ahid->flags &= ~FLAG_POWER_KEY_PRESSED;
353 else
354 ahid->flags |= FLAG_POWER_KEY_PRESSED;
355
339 /* Fn + Command will produce a bogus "power" keycode */ 356 /* Fn + Command will produce a bogus "power" keycode */
340 if (ahid->flags & FLAG_FN_KEY_PRESSED) { 357 if (ahid->flags & FLAG_FN_KEY_PRESSED) {
341 keycode = ADB_KEY_CMD; 358 keycode = ADB_KEY_CMD;
@@ -681,6 +698,21 @@ static int adbhid_kbd_event(struct input_dev *dev, unsigned int type, unsigned i
681 return -1; 698 return -1;
682} 699}
683 700
701static void
702adbhid_kbd_capslock_remember(void)
703{
704 struct adbhid *ahid;
705 int i;
706
707 for (i = 1; i < 16; i++) {
708 ahid = adbhid[i];
709
710 if (ahid && ahid->id == ADB_KEYBOARD)
711 if (ahid->flags & FLAG_CAPSLOCK_TRANSLATE)
712 ahid->flags |= FLAG_CAPSLOCK_IGNORE_NEXT;
713 }
714}
715
684static int 716static int
685adb_message_handler(struct notifier_block *this, unsigned long code, void *x) 717adb_message_handler(struct notifier_block *this, unsigned long code, void *x)
686{ 718{
@@ -697,8 +729,17 @@ adb_message_handler(struct notifier_block *this, unsigned long code, void *x)
697 } 729 }
698 730
699 /* Stop pending led requests */ 731 /* Stop pending led requests */
700 while(leds_req_pending) 732 while (leds_req_pending)
701 adb_poll(); 733 adb_poll();
734
735 /* After resume, and if the capslock LED is on, the PMU will
736 * send a "capslock down" key event. This confuses the
737 * restore_capslock_events logic. Remember if the capslock
738 * LED was on before suspend so the unwanted key event can
739 * be ignored after resume. */
740 if (restore_capslock_events)
741 adbhid_kbd_capslock_remember();
742
702 break; 743 break;
703 744
704 case ADB_MSG_POST_RESET: 745 case ADB_MSG_POST_RESET: