summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 ef4c117ea35..6e9afe26db8 100644
--- a/drivers/macintosh/adbhid.c
+++ b/drivers/macintosh/adbhid.c
@@ -219,11 +219,12 @@ struct adbhid {
int flags;
};
-#define FLAG_FN_KEY_PRESSED 0x00000001
-#define FLAG_POWER_FROM_FN 0x00000002
-#define FLAG_EMU_FWDEL_DOWN 0x00000004
-#define FLAG_CAPSLOCK_TRANSLATE 0x00000008
-#define FLAG_CAPSLOCK_DOWN 0x00000010
+#define FLAG_FN_KEY_PRESSED 0x00000001
+#define FLAG_POWER_FROM_FN 0x00000002
+#define FLAG_EMU_FWDEL_DOWN 0x00000004
+#define FLAG_CAPSLOCK_TRANSLATE 0x00000008
+#define FLAG_CAPSLOCK_DOWN 0x00000010
+#define FLAG_CAPSLOCK_IGNORE_NEXT 0x00000020
static struct adbhid *adbhid[16];
@@ -291,8 +292,15 @@ adbhid_input_keycode(int id, int scancode, int repeat)
if (keycode == ADB_KEY_CAPSLOCK && !up_flag) {
/* Key pressed, turning on the CapsLock LED.
* The next 0xff will be interpreted as a release. */
- ahid->flags |= FLAG_CAPSLOCK_TRANSLATE
+ if (ahid->flags & FLAG_CAPSLOCK_IGNORE_NEXT) {
+ /* Throw away this key event if it happens
+ * just after resume. */
+ ahid->flags &= ~FLAG_CAPSLOCK_IGNORE_NEXT;
+ return;
+ } else {
+ ahid->flags |= FLAG_CAPSLOCK_TRANSLATE
| FLAG_CAPSLOCK_DOWN;
+ }
} else if (scancode == 0xff) {
/* Scancode 0xff usually signifies that the capslock
* key was either pressed or released. */
@@ -681,6 +689,21 @@ static int adbhid_kbd_event(struct input_dev *dev, unsigned int type, unsigned i
return -1;
}
+static void
+adbhid_kbd_capslock_remember(void)
+{
+ struct adbhid *ahid;
+ int i;
+
+ for (i = 1; i < 16; i++) {
+ ahid = adbhid[i];
+
+ if (ahid && ahid->id == ADB_KEYBOARD)
+ if (ahid->flags & FLAG_CAPSLOCK_TRANSLATE)
+ ahid->flags |= FLAG_CAPSLOCK_IGNORE_NEXT;
+ }
+}
+
static int
adb_message_handler(struct notifier_block *this, unsigned long code, void *x)
{
@@ -697,8 +720,17 @@ adb_message_handler(struct notifier_block *this, unsigned long code, void *x)
}
/* Stop pending led requests */
- while(leds_req_pending)
+ while (leds_req_pending)
adb_poll();
+
+ /* After resume, and if the capslock LED is on, the PMU will
+ * send a "capslock down" key event. This confuses the
+ * restore_capslock_events logic. Remember if the capslock
+ * LED was on before suspend so the unwanted key event can
+ * be ignored after resume. */
+ if (restore_capslock_events)
+ adbhid_kbd_capslock_remember();
+
break;
case ADB_MSG_POST_RESET: