Skip site navigation (1)Skip section navigation (2)
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>