tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: pckb[cd] changes for sparc64



Hi,

> I'd like to add support for the keyboard on the Tadpole SPARCle laptops.
> This uses a PC (8042) keyboard controller with two main differences.  The
> first is that the aux port does't probe until after an initial timeout.
> The second is that the keyboard does not do scan code translation, so we
> have to translate the sequences in software.

After some more testing, the pckbport changes needed extra work.  The
extra keys that exist other PC keyboards are now mapped to better locations
and the Sun-specific keys have a wscons mapping (they don't yet work in X).

Updated patch (just the files changed from the previous) attached.

Thanks,

J

PS.  Also tested on shark.

-- 
   NetBSD: simple; works; documented    /        Sailing at Newbiggin
        http://www.netbsd.org/        /   http://www.newbigginsailingclub.org/
Index: sys/dev/pckbport/pckbd.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pckbport/pckbd.c,v
retrieving revision 1.29
diff -u -r1.29 pckbd.c
--- sys/dev/pckbport/pckbd.c    24 Feb 2010 22:38:08 -0000      1.29
+++ sys/dev/pckbport/pckbd.c    1 Oct 2012 09:31:53 -0000
@@ -100,9 +100,12 @@
        pckbport_tag_t t_kbctag;
        pckbport_slot_t t_kbcslot;
 
+       int t_translating;
+
        int t_lastchar;
        int t_extended0;
        int t_extended1;
+       int t_releasing;
 
        struct pckbd_softc *t_sc; /* back pointer */
 };
@@ -167,7 +170,9 @@
 
 void   pckbd_bell(u_int, u_int, u_int, int);
 
-int    pckbd_set_xtscancode(pckbport_tag_t, pckbport_slot_t);
+int    pckbd_scancode_translate(struct pckbd_internal *, int);
+int    pckbd_set_xtscancode(pckbport_tag_t, pckbport_slot_t,
+           struct pckbd_internal *);
 int    pckbd_init(struct pckbd_internal *, pckbport_tag_t, pckbport_slot_t,
                        int);
 void   pckbd_input(void *, int);
@@ -179,9 +184,10 @@
 struct pckbd_internal pckbd_consdata;
 
 int
-pckbd_set_xtscancode(pckbport_tag_t kbctag, pckbport_slot_t kbcslot)
+pckbd_set_xtscancode(pckbport_tag_t kbctag, pckbport_slot_t kbcslot,
+    struct pckbd_internal *id)
 {
-       int res;
+       int xt, res = 0;
        u_char cmd[2];
 
        /*
@@ -192,12 +198,14 @@
         * known to not work on some PS/2 machines.  We try desperately to deal
         * with this by checking the (lack of a) translate bit in the 8042 and
         * attempting to set the keyboard to XT mode.  If this all fails, well,
-        * tough luck.
+        * tough luck.  If the PCKBC_CANT_TRANSLATE pckbc flag was set, we
+        * enable software translation.
         *
         * XXX It would perhaps be a better choice to just use AT scan codes
         * and not bother with this.
         */
-       if (pckbport_xt_translation(kbctag, kbcslot, 1)) {
+       xt = pckbport_xt_translation(kbctag, kbcslot, 1);
+       if (xt == 1) {
                /* The 8042 is translating for us; use AT codes. */
                cmd[0] = KBC_SETTABLE;
                cmd[1] = 2;
@@ -216,6 +224,12 @@
                        pckbport_flush(kbctag, kbcslot);
                        res = 0;
                }
+               if (id != NULL)
+                       id->t_translating = 1;
+       } else if (xt == -1) {
+               /* Software translation required */
+               if (id != NULL)
+                       id->t_translating = 0;
        } else {
                /* Stupid 8042; set keyboard to XT codes. */
                cmd[0] = KBC_SETTABLE;
@@ -223,6 +237,8 @@
                res = pckbport_poll_cmd(kbctag, kbcslot, cmd, 2, 0, 0, 0);
                if (res)
                        aprint_debug("pckbd: error setting scanset 1\n");
+               if (id != NULL)
+                       id->t_translating = 1;
        }
        return res;
 }
@@ -331,7 +347,7 @@
         */
        pckbport_flush(pa->pa_tag, pa->pa_slot);
 
-       if (pckbd_set_xtscancode(pa->pa_tag, pa->pa_slot))
+       if (pckbd_set_xtscancode(pa->pa_tag, pa->pa_slot, NULL))
                return 0;
 
        return 2;
@@ -421,7 +437,7 @@
                }
 
                res = pckbd_set_xtscancode(sc->id->t_kbctag,
-                                          sc->id->t_kbcslot);
+                                          sc->id->t_kbcslot, sc->id);
                if (res)
                        return res;
 
@@ -446,21 +462,395 @@
        return 0;
 }
 
+const u_int8_t pckbd_xtbl[] = {
+/* 0x00 */
+       0,
+       0x43,           /* F9 */
+       0x89,           /* SunStop */
+       0x3f,           /* F5 */
+       0x3d,           /* F3 */
+       0x3b,           /* F1 */
+       0x3c,           /* F2 */
+       0x58,           /* F12 */
+       0,
+       0x44,           /* F10 */
+       0x42,           /* F8 */
+       0x40,           /* F6 */
+       0x3e,           /* F4 */
+       0x0f,           /* Tab */
+       0x29,           /* ` ~ */
+       0,
+/* 0x10 */
+       0,
+       0x38,           /* Left Alt */
+       0x2a,           /* Left Shift */
+       0,
+       0x1d,           /* Left Ctrl */
+       0x10,           /* q */
+       0x02,           /* 1 ! */
+       0,
+       0,
+       0,
+       0x2c,           /* z */
+       0x1f,           /* s */
+       0x1e,           /* a */
+       0x11,           /* w */
+       0x03,           /* 2 @ */
+       0,
+/* 0x20 */     
+       0,
+       0x2e,           /* c */
+       0x2d,           /* x */
+       0x20,           /* d */
+       0x12,           /* e */
+       0x05,           /* 4 $ */
+       0x04,           /* 3 # */
+       0,
+       0,
+       0x39,           /* Space */
+       0x2f,           /* v */
+       0x21,           /* f */
+       0x14,           /* t */
+       0x13,           /* r */
+       0x06,           /* 5 % */
+       0,
+/* 0x30 */
+       0,
+       0x31,           /* n */
+       0x30,           /* b */
+       0x23,           /* h */
+       0x22,           /* g */
+       0x15,           /* y */
+       0x07,           /* 6 ^ */
+       0,
+       0,
+       0,
+       0x32,           /* m */
+       0x24,           /* j */
+       0x16,           /* u */
+       0x08,           /* 7 & */
+       0x09,           /* 8 * */
+       0,
+/* 0x40 */
+       0,
+       0x33,           /* , < */
+       0x25,           /* k */
+       0x17,           /* i */
+       0x18,           /* o */
+       0x0b,           /* 0 ) */
+       0x0a,           /* 9 ( */
+       0,
+       0,
+       0x34,           /* . > */
+       0x35,           /* / ? */
+       0x26,           /* l */
+       0x27,           /* ; : */
+       0x19,           /* p */
+       0x0c,           /* - _ */
+       0,
+/* 0x50 */
+       0,
+       0,
+       0x28,           /* ' " */
+       0,
+       0x1a,           /* [ { */
+       0x0d,           /* = + */
+       0,
+       0,
+       0x3a,           /* Caps Lock */
+       0x36,           /* Right Shift */
+       0x1c,           /* Return */
+       0x1b,           /* ] } */
+       0,
+       0x2b,           /* \ | */
+       0,
+       0,
+/* 0x60 */
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0x0e,           /* Back Space */
+       0,
+       0,
+       0x4f,           /* KP 1 */
+       0,
+       0x4b,           /* KP 4 */
+       0x47,           /* KP 7 */
+       0,
+       0,
+       0,
+/* 0x70 */
+       0x52,           /* KP 0 */
+       0x53,           /* KP . */
+       0x50,           /* KP 2 */
+       0x4c,           /* KP 5 */
+       0x4d,           /* KP 6 */
+       0x48,           /* KP 8 */
+       0x01,           /* Escape */
+       0x45,           /* Num Lock */
+       0x57,           /* F11 */
+       0x4e,           /* KP + */
+       0x51,           /* KP 3 */
+       0x4a,           /* KP - */
+       0x37,           /* KP * */
+       0x49,           /* KP 9 */
+       0x46,           /* Scroll Lock */
+       0,
+/* 0x80 */
+       0,
+       0,
+       0,
+       0x41,           /* F7 (produced as an actual 8 bit code) */
+       0,              /* Alt-Print Screen */
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+/* 0x90 */
+       0xdb,           /* Left Meta */
+       0x88,           /* SunHelp */
+       0x8a,           /* SunAgain */
+       0x8c,           /* SunUndo */
+       0x8e,           /* SunCopy */
+       0x90,           /* SunPaste */
+       0x92,           /* SunCut */
+       0x8b,           /* SunProps */
+       0x8d,           /* SunFront */
+       0x8f,           /* SunOpen */
+       0x91            /* SunFind */
+};
+
+const u_int8_t pckbd_xtbl_ext[] = {
+/* 0x00 */
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+/* 0x10 */
+       0,
+       0x38,           /* Right Alt */
+       0,              /* E0 12, to be ignored */
+       0,
+       0x1d,           /* Right Ctrl */
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+/* 0x20 */
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0xdd,           /* Compose */
+/* 0x30 */
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+/* 0x40 */
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0xb5,           /* KP / */
+       0,
+       0,
+       0,
+       0,
+       0,
+/* 0x50 */
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0x1c,           /* KP Return */
+       0,
+       0,
+       0,
+       0,
+       0,
+/* 0x60 */
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0x4f,           /* End */
+       0,
+       0x4b,           /* Left */
+       0x47,           /* Home */
+       0,
+       0,
+       0,
+/* 0x70 */
+       0x52,           /* Insert */
+       0x53,           /* Delete */
+       0x50,           /* Down */
+       0,
+       0x4d,           /* Right */
+       0x48,           /* Up */
+       0,
+       0,
+       0,
+       0,
+       0x51,           /* Page Down */
+       0,
+       0x37,           /* Print Screen */
+       0x49,           /* Page Up */
+       0x46,           /* Ctrl-Break */
+       0
+};
+
+/*
+ * Translate scan codes from set 2 to set 1
+ */
+int
+pckbd_scancode_translate(struct pckbd_internal *id, int datain)
+{
+       if (id->t_translating != 0)
+               return datain;
+
+       if (datain == KBR_BREAK) {
+               id->t_releasing = 0x80; /* next keycode is a release */
+               return 0;       /* consume scancode */
+       }
+
+       /*
+        * Handle extended sequences
+        */
+       if (datain == KBR_EXTENDED0 || datain == KBR_EXTENDED1)
+               return datain;
+
+       /*
+        * Convert BREAK sequence (14 77 -> 1D 45)
+        */
+       if (id->t_extended1 == 2 && datain == 0x14)
+               return 0x1d | id->t_releasing;
+       else if (id->t_extended1 == 1 && datain == 0x77)
+               return 0x45 | id->t_releasing;
+
+       if (id->t_extended0 != 0) {
+               if (datain >= sizeof pckbd_xtbl_ext)
+                       datain = 0;
+               else
+                       datain = pckbd_xtbl_ext[datain];
+       } else {
+               if (datain >= sizeof pckbd_xtbl)
+                       datain = 0;
+               else
+                       datain = pckbd_xtbl[datain];
+       }
+
+       /* 
+        * If we are mapping in the range 128-254, then make this
+        * an extended keycode, as table 1 codes are limited to
+        * the range 0-127 (the top bit is used for key up/break).
+        */
+       if (datain > 0x7f) {
+               datain &= 0x7f;
+               id->t_extended0 = 0x80;
+       }
+               
+       if (datain == 0) {
+               /*
+                * We don't know how to translate this scan code, but
+                * we can't silently eat it either (because there might
+                * have been an extended byte transmitted already).
+                * Hopefully this value will be harmless to the upper
+                * layers.
+                */
+               return 0xff;
+       }
+       return datain | id->t_releasing;
+}
+
 static int
 pckbd_decode(struct pckbd_internal *id, int datain, u_int *type, int *dataout)
 {
        int key;
+       int releasing;
 
        if (datain == KBR_EXTENDED0) {
-               id->t_extended0 = 1;
+               id->t_extended0 = 0x80;
                return 0;
        } else if (datain == KBR_EXTENDED1) {
                id->t_extended1 = 2;
                return 0;
        }
 
-       if (id->t_extended0 == 1) {
-               switch (datain & 0x7f) {
+       releasing = datain & 0x80;
+       datain &= 0x7f;
+
+       if (id->t_extended0 == 0x80) {
+               switch (datain) {
                case 0x2a:
                case 0x36:
                        id->t_extended0 = 0;
@@ -470,8 +860,8 @@
                }
        }
 
-       /* map extended keys to (unused) codes 128-254 */
-       key = (datain & 0x7f) | (id->t_extended0 ? 0x80 : 0);
+       /* map extended keys to (unused) codes 128-254 */
+       key = datain | id->t_extended0;
        id->t_extended0 = 0;
 
        /*
@@ -489,7 +879,14 @@
                id->t_extended1 = 0;
        }
 
-       if (datain & 0x80) {
+       if (id->t_translating != 0) {
+               id->t_releasing = releasing;
+       } else {
+               /* id->t_releasing computed in pckbd_scancode_translate() */
+       }
+
+       if (id->t_releasing) {
+               id->t_releasing = 0;
                id->t_lastchar = 0;
                *type = WSCONS_EVENT_KEY_UP;
        } else {
@@ -515,7 +912,7 @@
        t->t_kbctag = kbctag;
        t->t_kbcslot = kbcslot;
 
-       return pckbd_set_xtscancode(kbctag, kbcslot);
+       return pckbd_set_xtscancode(kbctag, kbcslot, t);
 }
 
 static int
@@ -574,6 +971,10 @@
        int key;
        u_int type;
 
+       data = pckbd_scancode_translate(sc->id, data);
+       if (data == 0)
+               return;
+
 #ifdef WSDISPLAY_COMPAT_RAWKBD
        if (sc->rawkbd) {
                u_char d = data;
@@ -692,7 +1093,14 @@
 
        for (;;) {
                val = pckbport_poll_data(t->t_kbctag, t->t_kbcslot);
-               if ((val != -1) && pckbd_decode(t, val, type, data))
+               if (val == -1)
+                       continue;
+
+               val = pckbd_scancode_translate(t, val);
+               if (val == 0)
+                       continue;
+
+               if (pckbd_decode(t, val, type, data))
                        return;
        }
 }
Index: sys/dev/pckbport/wskbdmap_mfii.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pckbport/wskbdmap_mfii.c,v
retrieving revision 1.22
diff -u -r1.22 wskbdmap_mfii.c
--- sys/dev/pckbport/wskbdmap_mfii.c    22 Jul 2011 23:22:38 -0000      1.22
+++ sys/dev/pckbport/wskbdmap_mfii.c    1 Oct 2012 09:31:53 -0000
@@ -128,6 +128,17 @@
     KC(87),                    KS_f11,
     KC(88),                    KS_f12,
     KC(127),                   KS_Pause, /* Break */
+    KC(136),                   KS_Help,
+    KC(137),                   KS_Stop,
+    KC(138),                   KS_Again,
+    KC(139),                   KS_Props,
+    KC(140),                   KS_Undo,
+    KC(141),                   KS_Front,
+    KC(142),                   KS_Copy,
+    KC(143),                   KS_Open,
+    KC(144),                   KS_Paste,
+    KC(145),                   KS_Find,
+    KC(146),                   KS_Cut,
     KC(156),                   KS_KP_Enter,
     KC(157),                   KS_Control_R,
     KC(160),                   KS_Cmd_VolumeToggle,


Home | Main Index | Thread Index | Old Index