Date: Fri, 30 May 2014 06:45:50 +0000 (UTC) From: Ruslan Bukin <br@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r266872 - in head/sys: arm/samsung/exynos boot/fdt/dts/arm Message-ID: <201405300645.s4U6joQG082233@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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.ua@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>; }; };
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201405300645.s4U6joQG082233>