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>
This commit is contained in:
parent
1a31ec5e51
commit
17f65b3a8d
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=266872
@ -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, int wait)
|
||||
|
||||
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, int wait)
|
||||
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 }
|
||||
};
|
||||
|
||||
|
@ -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 */
|
||||
pcell_t default_keymap[KEYMAP_LEN] = {
|
||||
0x0001007d, /* lmeta */
|
||||
0x0002003b, /* F1 */
|
||||
0x00030030, /* B */
|
||||
0x00040044, /* F10 */
|
||||
0x00060031, /* N */
|
||||
0x0008000d, /* = */
|
||||
0x000a0064, /* 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 */
|
||||
0x01010001, /* escape */
|
||||
0x0102003e, /* F4 */
|
||||
0x01030022, /* G */
|
||||
0x01040041, /* F7 */
|
||||
0x01060023, /* H */
|
||||
0x01080028, /* ' */
|
||||
0x01090043, /* F9 */
|
||||
0x010b000e, /* 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 */
|
||||
0x0200001d, /* lctrl */
|
||||
0x0201000f, /* tab */
|
||||
0x0202003d, /* F3 */
|
||||
0x02030014, /* t */
|
||||
0x02040040, /* F6 */
|
||||
0x0205001b, /* ] */
|
||||
0x02060015, /* y */
|
||||
0x02070056, /* 102nd */
|
||||
0x0208001a, /* [ */
|
||||
0x02090042, /* 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 }, /* \ */
|
||||
0x03010029, /* grave */
|
||||
0x0302003c, /* F2 */
|
||||
0x03030006, /* 5 */
|
||||
0x0304003f, /* F5 */
|
||||
0x03060007, /* 6 */
|
||||
0x0308000c, /* - */
|
||||
0x030b002b, /* \ */
|
||||
|
||||
{ 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 */
|
||||
0x04000061, /* rctrl */
|
||||
0x0401001e, /* a */
|
||||
0x04020020, /* d */
|
||||
0x04030021, /* f */
|
||||
0x0404001f, /* s */
|
||||
0x04050025, /* k */
|
||||
0x04060024, /* j */
|
||||
0x04080027, /* ; */
|
||||
0x04090026, /* l */
|
||||
0x040a002b, /* \ */
|
||||
0x040b001c, /* 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 */
|
||||
0x0501002c, /* z */
|
||||
0x0502002e, /* c */
|
||||
0x0503002f, /* v */
|
||||
0x0504002d, /* x */
|
||||
0x05050033, /* , */
|
||||
0x05060032, /* m */
|
||||
0x0507002a, /* lsh */
|
||||
0x05080035, /* / */
|
||||
0x05090034, /* . */
|
||||
0x050B0039, /* 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 */
|
||||
0x06010002, /* 1 */
|
||||
0x06020004, /* 3 */
|
||||
0x06030005, /* 4 */
|
||||
0x06040003, /* 2 */
|
||||
0x06050009, /* 8 */
|
||||
0x06060008, /* 7 */
|
||||
0x0608000b, /* 0 */
|
||||
0x0609000a, /* 9 */
|
||||
0x060a0038, /* lalt */
|
||||
0x060b0064, /* down */
|
||||
0x060c0062, /* 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 */
|
||||
0x07010010, /* q */
|
||||
0x07020012, /* e */
|
||||
0x07030013, /* r */
|
||||
0x07040011, /* w */
|
||||
0x07050017, /* i */
|
||||
0x07060016, /* u */
|
||||
0x07070036, /* rsh */
|
||||
0x07080019, /* p */
|
||||
0x07090018, /* o */
|
||||
0x070b005F, /* up */
|
||||
0x070c0061, /* left */
|
||||
};
|
||||
|
@ -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>;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -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>;
|
||||
};
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user