]> git.hungrycats.org Git - linux/commitdiff
[PATCH] Input: add atkbd reconnect method
authorDmitry Torokhov <dtor_core@ameritech.net>
Thu, 18 Dec 2003 13:35:03 +0000 (05:35 -0800)
committerDmitry Torokhov <dtor_core@ameritech.net>
Thu, 18 Dec 2003 13:35:03 +0000 (05:35 -0800)
Add reconnect method to atkbd to restore keyboard state after suspend (to
be called from i8042 resume function)

drivers/input/keyboard/atkbd.c

index 78b76789d6da307f6e74d4aaa83be0078618f122..030d75c4ed1765c5f3954f5e0cbf170cd9a69c53 100644 (file)
@@ -700,9 +700,62 @@ static void atkbd_connect(struct serio *serio, struct serio_dev *dev)
        printk(KERN_INFO "input: %s on %s\n", atkbd->name, serio->phys);
 }
 
+/*
+ * atkbd_reconnect() tries to restore keyboard into a sane state and is
+ * most likely called on resume.
+ */
+
+static int atkbd_reconnect(struct serio *serio)
+{
+       struct atkbd *atkbd = serio->private;
+       struct serio_dev *dev = serio->dev;
+       int i;
+
+        if (!dev) {
+                printk(KERN_DEBUG "atkbd: reconnect request, but serio is disconnected, ignoring...\n");
+                return -1;
+        }
+
+       if (atkbd->write) {
+               if (atkbd_probe(atkbd))
+                       return -1;
+
+               atkbd->set = atkbd_set_3(atkbd);
+               atkbd_enable(atkbd);
+       } else {
+               atkbd->set = 2;
+               atkbd->id = 0xab00;
+       }
+
+       /*
+        * Here we probably should check if the keyboard has the same set that
+         * it had before and bail out if it's different. But this will most likely
+         * cause new keyboard device be created... and for the user it will look
+         * like keyboard is lost
+        */
+
+       if (atkbd->translated) {
+               for (i = 0; i < 128; i++) {
+                       atkbd->keycode[i] = atkbd_set2_keycode[atkbd_unxlate_table[i]];
+                       atkbd->keycode[i | 0x80] = atkbd_set2_keycode[atkbd_unxlate_table[i] | 0x80];
+               }
+       } else if (atkbd->set == 2) {
+               memcpy(atkbd->keycode, atkbd_set2_keycode, sizeof(atkbd->keycode));
+       } else {
+               memcpy(atkbd->keycode, atkbd_set3_keycode, sizeof(atkbd->keycode));
+       }
+
+       for (i = 0; i < 512; i++)
+               if (atkbd->keycode[i] && atkbd->keycode[i] < 255)
+                       set_bit(atkbd->keycode[i], atkbd->dev.keybit);
+
+       return 0;
+}
+
 static struct serio_dev atkbd_dev = {
        .interrupt =    atkbd_interrupt,
        .connect =      atkbd_connect,
+       .reconnect =    atkbd_reconnect,
        .disconnect =   atkbd_disconnect,
        .cleanup =      atkbd_cleanup,
 };