Author: gonzo
Date: Sat Apr  1 20:38:12 2017
New Revision: 316371
URL: https://svnweb.freebsd.org/changeset/base/316371

Log:
  [versatilepb] Fix keyboard driver after switching to upstream DTS
  
  FreeBSD's DTS contained only one PL050 node and driver considered it to
  be PS/2 keyboard. In reality PL050 is a PS/2 port that pushes bytes to/from
  the periphers connected to it. New DTS contains two nodes and QEMU emulates
  keyboard connected to port #0 and mouse connected to port #1. Since there
  is no way to say what's connected to port by checking DTS we hardcode
  this knowledge in the driver: it assumes keyboard on port #0 and ignores
  port #1 altogether.
  
  Also QEMU defaults emulated keyboard to scan code set 2 while driver used
  to work with scan code set 1 so when initializing driver make sure keyboard
  is switched to scan code set 1

Modified:
  head/sys/arm/versatile/pl050.c

Modified: head/sys/arm/versatile/pl050.c
==============================================================================
--- head/sys/arm/versatile/pl050.c      Sat Apr  1 20:10:08 2017        
(r316370)
+++ head/sys/arm/versatile/pl050.c      Sat Apr  1 20:38:12 2017        
(r316371)
@@ -106,7 +106,10 @@ __FBSDID("$FreeBSD$");
 #define        KMI_DRIVER_NAME          "kmi"
 #define        KMI_NFKEY        (sizeof(fkey_tab)/sizeof(fkey_tab[0])) /* 
units */
 
+#define        SET_SCANCODE_SET        0xf0
+
 struct kmi_softc {
+       device_t sc_dev;
        keyboard_t sc_kbd;
        keymap_t sc_keymap;
        accentmap_t sc_accmap;
@@ -142,6 +145,8 @@ static int  kmi_ioctl(keyboard_t *, u_lon
 static int     kmi_enable(keyboard_t *);
 static int     kmi_disable(keyboard_t *);
 
+static int     kmi_attached = 0;
+
 /* early keyboard probe, not supported */
 static int
 kmi_configure(int flags)
@@ -480,7 +485,6 @@ kmi_ioctl(keyboard_t *kbd, u_long cmd, c
        }
 }
 
-
 /* clear the internal state of the keyboard */
 static void
 kmi_clear_state(keyboard_t *kbd)
@@ -610,6 +614,17 @@ pl050_kmi_probe(device_t dev)
        if (!ofw_bus_status_okay(dev))
                return (ENXIO);
 
+       /*
+        * PL050 is plain PS2 port that pushes bytes to/from computer
+        * VersatilePB has two such ports and QEMU simulates keyboard
+        * connected to port #0 and mouse connected to port #1. This
+        * information can't be obtained from device tree so we just
+        * hardcode this knowledge here. We attach keyboard driver to
+        * port #0 and ignore port #1
+        */
+       if (kmi_attached)
+               return (ENXIO);
+
        if (ofw_bus_is_compatible(dev, "arm,pl050")) {
                device_set_desc(dev, "PL050 Keyboard/Mouse Interface");
                return (BUS_PROBE_DEFAULT);
@@ -625,7 +640,9 @@ pl050_kmi_attach(device_t dev)
        keyboard_t *kbd;
        int rid;
        int i;
+       uint32_t ack;
 
+       sc->sc_dev = dev;
        kbd = &sc->sc_kbd;
        rid = 0;
 
@@ -654,6 +671,16 @@ pl050_kmi_attach(device_t dev)
 
        /* TODO: clock & divisor */
 
+       pl050_kmi_write_4(sc, KMICR, KMICR_EN);
+
+       pl050_kmi_write_4(sc, KMIDATA, SET_SCANCODE_SET);
+       /* read out ACK */
+       ack = pl050_kmi_read_4(sc, KMIDATA);
+       /* Set Scan Code set 1 (XT) */
+       pl050_kmi_write_4(sc, KMIDATA, 1);
+       /* read out ACK */
+       ack = pl050_kmi_read_4(sc, KMIDATA);
+
        pl050_kmi_write_4(sc, KMICR, KMICR_EN | KMICR_RXINTREN);
 
        kbd_init_struct(kbd, KMI_DRIVER_NAME, KB_OTHER, 
@@ -689,6 +716,7 @@ pl050_kmi_attach(device_t dev)
        if (bootverbose) {
                genkbd_diag(kbd, bootverbose);
        }
+       kmi_attached = 1;
        return (0);
 
 detach:
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to