Author: br
Date: Fri May 30 06:45:50 2014
New Revision: 266872
URL: http://svnweb.freebsd.org/changeset/base/266872

Log:
  o Make keyboard-related properties to be compatible with vendor standard
  o Allow setting keymap in FDT, use hardcoded one by default
  o Represent fallback keymap as a list rather than directly usable M*N array
  
  Submitted by: Maxim Ignatenko <gelraen...@gmail.com>

Modified:
  head/sys/arm/samsung/exynos/chrome_kb.c
  head/sys/arm/samsung/exynos/chrome_kb.h
  head/sys/boot/fdt/dts/arm/exynos5250-chromebook-snow.dts
  head/sys/boot/fdt/dts/arm/exynos5250-chromebook-spring.dts

Modified: head/sys/arm/samsung/exynos/chrome_kb.c
==============================================================================
--- head/sys/arm/samsung/exynos/chrome_kb.c     Fri May 30 06:37:06 2014        
(r266871)
+++ head/sys/arm/samsung/exynos/chrome_kb.c     Fri May 30 06:45:50 2014        
(r266872)
@@ -105,9 +105,6 @@ __FBSDID("$FreeBSD$");
 #define        CKB_FLAG_POLLING        0x2
 #define        KBD_DRIVER_NAME         "ckbd"
 
-/* TODO: take interrupt from DTS */
-#define        KB_GPIO_INT             146
-
 struct ckb_softc {
        keyboard_t sc_kbd;
        keymap_t sc_keymap;
@@ -130,9 +127,11 @@ struct ckb_softc {
        int                     flag;
        int                     rows;
        int                     cols;
+       int                     gpio;
        device_t                dev;
        device_t                gpio_dev;
        struct thread           *sc_poll_thread;
+       uint16_t                *keymap;
 
        uint8_t                 *scan_local;
        uint8_t                 *scan;
@@ -199,7 +198,7 @@ static int
 ckb_intr(keyboard_t *kbd, void *arg)
 {
 
-        return (0);
+       return (0);
 }
 
 /* lock the access to the keyboard, not used */
@@ -207,7 +206,7 @@ static int
 ckb_lock(keyboard_t *kbd, int lock)
 {
 
-        return (1);
+       return (1);
 }
 
 /* clear the internal state of the keyboard */
@@ -309,20 +308,33 @@ ckb_read(keyboard_t *kbd, int wait)
        return (0);
 }
 
-int scantokey(int i, int j);
-
-int
-scantokey(int i, int j)
+static uint16_t
+keymap_read(struct ckb_softc *sc, int col, int row)
 {
-       int k;
 
-       for (k = 0; k < KEYMAP_LEN; k++)
-               if ((keymap[k].col == i) && (keymap[k].row == j))
-                       return (keymap[k].key);
+       KASSERT(sc->keymap != NULL, "keymap_read: no keymap");
+       if (col >= 0 && col < sc->cols &&
+           row >= 0 && row < sc->rows) {
+               return sc->keymap[row * sc->cols + col];
+       }
 
        return (0);
 }
 
+static int
+keymap_write(struct ckb_softc *sc, int col, int row, uint16_t key)
+{
+
+       KASSERT(sc->keymap != NULL, "keymap_write: no keymap");
+       if (col >= 0 && col < sc->cols &&
+           row >= 0 && row < sc->rows) {
+               sc->keymap[row * sc->cols + col] = key;
+               return (0);
+       }
+
+       return (-1);
+}
+
 /* read char from the keyboard */
 static uint32_t
 ckb_read_char_locked(keyboard_t *kbd, int wait)
@@ -350,9 +362,10 @@ ckb_read_char_locked(keyboard_t *kbd, in
 
        if (sc->sc_flags & CKB_FLAG_POLLING) {
                for (;;) {
-                       GPIO_PIN_GET(sc->gpio_dev, KB_GPIO_INT, &status);
+                       GPIO_PIN_GET(sc->gpio_dev, sc->gpio, &status);
                        if (status == 0) {
-                               if (ec_command(EC_CMD_MKBP_STATE, sc->scan, 
sc->cols,
+                               if (ec_command(EC_CMD_MKBP_STATE, sc->scan,
+                                       sc->cols,
                                    sc->scan, sc->cols)) {
                                        return (NOKEY);
                                }
@@ -373,7 +386,7 @@ ckb_read_char_locked(keyboard_t *kbd, in
                        if (oldbit == newbit)
                                continue;
 
-                       key = scantokey(i,j);
+                       key = keymap_read(sc, i, j);
                        if (key == 0) {
                                continue;
                        };
@@ -666,27 +679,109 @@ dummy_kbd_configure(int flags)
 
 KEYBOARD_DRIVER(ckbd, ckbdsw, dummy_kbd_configure);
 
+/* 
+ * Parses 'keymap' into sc->keymap.
+ * Requires sc->cols and sc->rows to be set.
+ */
+static int
+parse_keymap(struct ckb_softc *sc, pcell_t *keymap, size_t len)
+{
+       int i;
+
+       sc->keymap = malloc(sc->cols * sc->rows * sizeof(sc->keymap[0]),
+           M_DEVBUF, M_NOWAIT | M_ZERO);
+       if (sc->keymap == NULL) {
+               return (ENOMEM);
+       }
+
+       for (i = 0; i < len; i++) {
+               /* 
+                * Return value is ignored, we just write whatever fits into
+                * specified number of rows and columns and silently ignore
+                * everything else.
+                * Keymap entries follow this format: 0xRRCCKKKK
+                * RR - row number, CC - column number, KKKK - key code
+                */
+               keymap_write(sc, (keymap[i] >> 16) & 0xff,
+                   (keymap[i] >> 24) & 0xff,
+                   keymap[i] & 0xffff);
+       }
+
+       return (0);
+}
+
+/* Allocates a new array for keymap and returns it in 'keymap'. */
+static int
+read_keymap(phandle_t node, const char *prop, pcell_t **keymap, size_t *len)
+{
+
+       if ((*len = OF_getproplen(node, prop)) <= 0) {
+               return (ENXIO);
+       }
+       if ((*keymap = malloc(*len, M_DEVBUF, M_NOWAIT)) == NULL) {
+               return (ENOMEM);
+       }
+       if (OF_getencprop(node, prop, *keymap, *len) != *len) {
+               return (ENXIO);
+       }
+       return (0);
+}
+
 static int
 parse_dts(struct ckb_softc *sc)
 {
        phandle_t node;
        pcell_t dts_value;
-       int len;
+       pcell_t *keymap;
+       int len, ret;
+       const char *keymap_prop = NULL;
 
        if ((node = ofw_bus_get_node(sc->dev)) == -1)
                return (ENXIO);
 
-       if ((len = OF_getproplen(node, "keypad,num-rows")) <= 0)
+       if ((len = OF_getproplen(node, "google,key-rows")) <= 0)
                return (ENXIO);
-       OF_getprop(node, "keypad,num-rows", &dts_value, len);
+       OF_getprop(node, "google,key-rows", &dts_value, len);
        sc->rows = fdt32_to_cpu(dts_value);
 
-       if ((len = OF_getproplen(node, "keypad,num-columns")) <= 0)
+       if ((len = OF_getproplen(node, "google,key-columns")) <= 0)
                return (ENXIO);
-       OF_getprop(node, "keypad,num-columns", &dts_value, len);
+       OF_getprop(node, "google,key-columns", &dts_value, len);
        sc->cols = fdt32_to_cpu(dts_value);
 
-       if ((sc->rows == 0) || (sc->cols == 0))
+       if ((len = OF_getproplen(node, "freebsd,intr-gpio")) <= 0)
+               return (ENXIO);
+       OF_getprop(node, "freebsd,intr-gpio", &dts_value, len);
+       sc->gpio = fdt32_to_cpu(dts_value);
+
+       if (OF_hasprop(node, "freebsd,keymap")) {
+               keymap_prop = "freebsd,keymap";
+               device_printf(sc->dev, "using FreeBSD-specific keymap from 
FDT\n");
+       } else if (OF_hasprop(node, "linux,keymap")) {
+               keymap_prop = "linux,keymap";
+               device_printf(sc->dev, "using Linux keymap from FDT\n");
+       } else {
+               device_printf(sc->dev, "using built-in keymap\n");
+       }
+
+       if (keymap_prop != NULL) {
+               if ((ret = read_keymap(node, keymap_prop, &keymap, &len))) {
+                       device_printf(sc->dev,
+                            "failed to read keymap from FDT: %d\n", ret);
+                       return (ret);
+               }
+               ret = parse_keymap(sc, keymap, len);
+               free(keymap, M_DEVBUF);
+               if (ret) {
+                       return (ret);
+               }
+       } else {
+               if ((ret = parse_keymap(sc, default_keymap, KEYMAP_LEN))) {
+                       return (ret);
+               }
+       }
+
+       if ((sc->rows == 0) || (sc->cols == 0) || (sc->gpio == 0))
                return (ENXIO);
 
        return (0);
@@ -721,6 +816,7 @@ chrome_kb_attach(device_t dev)
        sc = device_get_softc(dev);
 
        sc->dev = dev;
+       sc->keymap = NULL;
 
        if ((error = parse_dts(sc)) != 0)
                return error;
@@ -736,8 +832,7 @@ chrome_kb_attach(device_t dev)
            sc->cols, sc->rows);
 #endif
 
-       /* TODO: take interrupt from DTS */
-       pad_setup_intr(KB_GPIO_INT, ckb_ec_intr, sc);
+       pad_setup_intr(sc->gpio, ckb_ec_intr, sc);
 
        kbd = &sc->sc_kbd;
        rid = 0;
@@ -786,7 +881,8 @@ chrome_kb_probe(device_t dev)
        if (!ofw_bus_status_okay(dev))
                return (ENXIO);
 
-       if (ofw_bus_is_compatible(dev, "google,cros-ec-keyb")) {
+       if (ofw_bus_is_compatible(dev, "google,cros-ec-keyb") ||
+           ofw_bus_is_compatible(dev, "google,mkbp-keyb")) {
                device_set_desc(dev, "Chrome EC Keyboard");
                return (BUS_PROBE_DEFAULT);
        }
@@ -794,9 +890,24 @@ chrome_kb_probe(device_t dev)
        return (ENXIO);
 }
 
+static int
+chrome_kb_detach(device_t dev)
+{
+       struct ckb_softc *sc;
+
+       sc = device_get_softc(dev);
+
+       if (sc->keymap != NULL) {
+               free(sc->keymap, M_DEVBUF);
+       }
+
+       return 0;
+}
+
 static device_method_t chrome_kb_methods[] = {
        DEVMETHOD(device_probe,         chrome_kb_probe),
        DEVMETHOD(device_attach,        chrome_kb_attach),
+       DEVMETHOD(device_detach,        chrome_kb_detach),
        { 0, 0 }
 };
 

Modified: head/sys/arm/samsung/exynos/chrome_kb.h
==============================================================================
--- head/sys/arm/samsung/exynos/chrome_kb.h     Fri May 30 06:37:06 2014        
(r266871)
+++ head/sys/arm/samsung/exynos/chrome_kb.h     Fri May 30 06:45:50 2014        
(r266872)
@@ -26,97 +26,93 @@
  * $FreeBSD$
  */
 
-void ckb_ec_intr(void *);
+#include <dev/ofw/openfirm.h>
 
-struct key {
-       uint8_t row;
-       uint8_t col;
-       uint8_t key;
-};
+void ckb_ec_intr(void *);
 
 #define        KEYMAP_LEN      75
 
-struct key keymap[KEYMAP_LEN] = {
-       { 0x00, 0x01, 0x7d }, /* lmeta */
-       { 0x00, 0x02, 0x3b }, /* F1 */
-       { 0x00, 0x03, 0x30 }, /* B */
-       { 0x00, 0x04, 0x44 }, /* F10 */
-       { 0x00, 0x06, 0x31 }, /* N */
-       { 0x00, 0x08, 0x0d }, /* = */
-       { 0x00, 0x0a, 0x64 }, /* ralt */
-
-       { 0x01, 0x01, 0x01 }, /* escape */
-       { 0x01, 0x02, 0x3e }, /* F4 */
-       { 0x01, 0x03, 0x22 }, /* G */
-       { 0x01, 0x04, 0x41 }, /* F7 */
-       { 0x01, 0x06, 0x23 }, /* H */
-       { 0x01, 0x08, 0x28 }, /* ' */
-       { 0x01, 0x09, 0x43 }, /* F9 */
-       { 0x01, 0x0b, 0x0e }, /* backspace */
-
-       { 0x02, 0x00, 0x1d }, /* lctrl */
-       { 0x02, 0x01, 0x0f }, /* tab */
-       { 0x02, 0x02, 0x3d }, /* F3 */
-       { 0x02, 0x03, 0x14 }, /* t */
-       { 0x02, 0x04, 0x40 }, /* F6 */
-       { 0x02, 0x05, 0x1b }, /* ] */
-       { 0x02, 0x06, 0x15 }, /* y */
-       { 0x02, 0x07, 0x56 }, /* 102nd */
-       { 0x02, 0x08, 0x1a }, /* [ */
-       { 0x02, 0x09, 0x42 }, /* F8 */
-
-       { 0x03, 0x01, 0x29 }, /* grave */
-       { 0x03, 0x02, 0x3c }, /* F2 */
-       { 0x03, 0x03, 0x06 }, /* 5 */
-       { 0x03, 0x04, 0x3f }, /* F5 */
-       { 0x03, 0x06, 0x07 }, /* 6 */
-       { 0x03, 0x08, 0x0c }, /* - */
-       { 0x03, 0x0b, 0x2b }, /* \ */
-
-       { 0x04, 0x00, 0x61 }, /* rctrl */
-       { 0x04, 0x01, 0x1e }, /* a */
-       { 0x04, 0x02, 0x20 }, /* d */
-       { 0x04, 0x03, 0x21 }, /* f */
-       { 0x04, 0x04, 0x1f }, /* s */
-       { 0x04, 0x05, 0x25 }, /* k */
-       { 0x04, 0x06, 0x24 }, /* j */
-       { 0x04, 0x08, 0x27 }, /* ; */
-       { 0x04, 0x09, 0x26 }, /* l */
-       { 0x04, 0x0a, 0x2b }, /* \ */
-       { 0x04, 0x0b, 0x1c }, /* enter */
-
-       { 0x05, 0x01, 0x2c }, /* z */
-       { 0x05, 0x02, 0x2e }, /* c */
-       { 0x05, 0x03, 0x2f }, /* v */
-       { 0x05, 0x04, 0x2d }, /* x */
-       { 0x05, 0x05, 0x33 }, /* , */
-       { 0x05, 0x06, 0x32 }, /* m */
-       { 0x05, 0x07, 0x2a }, /* lsh */
-       { 0x05, 0x08, 0x35 }, /* / */
-       { 0x05, 0x09, 0x34 }, /* . */
-       { 0x05, 0x0B, 0x39 }, /* space */
-
-       { 0x06, 0x01, 0x02 }, /* 1 */
-       { 0x06, 0x02, 0x04 }, /* 3 */
-       { 0x06, 0x03, 0x05 }, /* 4 */
-       { 0x06, 0x04, 0x03 }, /* 2 */
-       { 0x06, 0x05, 0x09 }, /* 8 */
-       { 0x06, 0x06, 0x08 }, /* 7 */
-       { 0x06, 0x08, 0x0b }, /* 0 */
-       { 0x06, 0x09, 0x0a }, /* 9 */
-       { 0x06, 0x0a, 0x38 }, /* lalt */
-       { 0x06, 0x0b, 0x64 }, /* down */
-       { 0x06, 0x0c, 0x62 }, /* right */
-
-       { 0x07, 0x01, 0x10 }, /* q */
-       { 0x07, 0x02, 0x12 }, /* e */
-       { 0x07, 0x03, 0x13 }, /* r */
-       { 0x07, 0x04, 0x11 }, /* w */
-       { 0x07, 0x05, 0x17 }, /* i */
-       { 0x07, 0x06, 0x16 }, /* u */
-       { 0x07, 0x07, 0x36 }, /* rsh */
-       { 0x07, 0x08, 0x19 }, /* p */
-       { 0x07, 0x09, 0x18 }, /* o */
-       { 0x07, 0x0b, 0x5F }, /* up */
-       { 0x07, 0x0c, 0x61 }, /* left */
+pcell_t default_keymap[KEYMAP_LEN] = {
+       0x0001007d, /* lmeta */
+       0x0002003b, /* F1 */
+       0x00030030, /* B */
+       0x00040044, /* F10 */
+       0x00060031, /* N */
+       0x0008000d, /* = */
+       0x000a0064, /* ralt */
+
+       0x01010001, /* escape */
+       0x0102003e, /* F4 */
+       0x01030022, /* G */
+       0x01040041, /* F7 */
+       0x01060023, /* H */
+       0x01080028, /* ' */
+       0x01090043, /* F9 */
+       0x010b000e, /* backspace */
+
+       0x0200001d, /* lctrl */
+       0x0201000f, /* tab */
+       0x0202003d, /* F3 */
+       0x02030014, /* t */
+       0x02040040, /* F6 */
+       0x0205001b, /* ] */
+       0x02060015, /* y */
+       0x02070056, /* 102nd */
+       0x0208001a, /* [ */
+       0x02090042, /* F8 */
+
+       0x03010029, /* grave */
+       0x0302003c, /* F2 */
+       0x03030006, /* 5 */
+       0x0304003f, /* F5 */
+       0x03060007, /* 6 */
+       0x0308000c, /* - */
+       0x030b002b, /* \ */
+
+       0x04000061, /* rctrl */
+       0x0401001e, /* a */
+       0x04020020, /* d */
+       0x04030021, /* f */
+       0x0404001f, /* s */
+       0x04050025, /* k */
+       0x04060024, /* j */
+       0x04080027, /* ; */
+       0x04090026, /* l */
+       0x040a002b, /* \ */
+       0x040b001c, /* enter */
+
+       0x0501002c, /* z */
+       0x0502002e, /* c */
+       0x0503002f, /* v */
+       0x0504002d, /* x */
+       0x05050033, /* , */
+       0x05060032, /* m */
+       0x0507002a, /* lsh */
+       0x05080035, /* / */
+       0x05090034, /* . */
+       0x050B0039, /* space */
+
+       0x06010002, /* 1 */
+       0x06020004, /* 3 */
+       0x06030005, /* 4 */
+       0x06040003, /* 2 */
+       0x06050009, /* 8 */
+       0x06060008, /* 7 */
+       0x0608000b, /* 0 */
+       0x0609000a, /* 9 */
+       0x060a0038, /* lalt */
+       0x060b0064, /* down */
+       0x060c0062, /* right */
+
+       0x07010010, /* q */
+       0x07020012, /* e */
+       0x07030013, /* r */
+       0x07040011, /* w */
+       0x07050017, /* i */
+       0x07060016, /* u */
+       0x07070036, /* rsh */
+       0x07080019, /* p */
+       0x07090018, /* o */
+       0x070b005F, /* up */
+       0x070c0061, /* left */
 };

Modified: head/sys/boot/fdt/dts/arm/exynos5250-chromebook-snow.dts
==============================================================================
--- head/sys/boot/fdt/dts/arm/exynos5250-chromebook-snow.dts    Fri May 30 
06:37:06 2014        (r266871)
+++ head/sys/boot/fdt/dts/arm/exynos5250-chromebook-snow.dts    Fri May 30 
06:45:50 2014        (r266872)
@@ -59,9 +59,10 @@
                };
 
                keyboard-controller {
-                       compatible = "google,cros-ec-keyb";
-                       keypad,num-rows = <8>;
-                       keypad,num-columns = <13>;
+                       compatible = "google,mkbp-keyb";
+                       google,key-rows = <8>;
+                       google,key-columns = <13>;
+                       freebsd,intr-gpio = <146>;
                };
        };
 

Modified: head/sys/boot/fdt/dts/arm/exynos5250-chromebook-spring.dts
==============================================================================
--- head/sys/boot/fdt/dts/arm/exynos5250-chromebook-spring.dts  Fri May 30 
06:37:06 2014        (r266871)
+++ head/sys/boot/fdt/dts/arm/exynos5250-chromebook-spring.dts  Fri May 30 
06:45:50 2014        (r266872)
@@ -59,9 +59,10 @@
                };
 
                keyboard-controller {
-                       compatible = "google,cros-ec-keyb";
-                       keypad,num-rows = <8>;
-                       keypad,num-columns = <13>;
+                       compatible = "google,mkbp-keyb";
+                       google,key-rows = <8>;
+                       google,key-columns = <13>;
+                       freebsd,intr-gpio = <146>;
                };
        };
 
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to