chrome_kb.c (266787) | chrome_kb.c (266872) |
---|---|
1/*- 2 * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 15 unchanged lines hidden (view full) --- 24 * SUCH DAMAGE. 25 */ 26 27/* 28 * Samsung Chromebook Keyboard 29 */ 30 31#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 15 unchanged lines hidden (view full) --- 24 * SUCH DAMAGE. 25 */ 26 27/* 28 * Samsung Chromebook Keyboard 29 */ 30 31#include <sys/cdefs.h> |
32__FBSDID("$FreeBSD: head/sys/arm/samsung/exynos/chrome_kb.c 266787 2014-05-28 06:15:45Z br $"); | 32__FBSDID("$FreeBSD: head/sys/arm/samsung/exynos/chrome_kb.c 266872 2014-05-30 06:45:50Z br $"); |
33 34#include <sys/param.h> 35#include <sys/systm.h> 36#include <sys/bus.h> 37#include <sys/kernel.h> 38#include <sys/module.h> 39#include <sys/malloc.h> 40#include <sys/rman.h> --- 59 unchanged lines hidden (view full) --- 100#include <dev/kbd/kbdreg.h> 101#include <dev/kbd/kbdtables.h> 102 103#define CKB_NFKEY 12 104#define CKB_FLAG_COMPOSE 0x1 105#define CKB_FLAG_POLLING 0x2 106#define KBD_DRIVER_NAME "ckbd" 107 | 33 34#include <sys/param.h> 35#include <sys/systm.h> 36#include <sys/bus.h> 37#include <sys/kernel.h> 38#include <sys/module.h> 39#include <sys/malloc.h> 40#include <sys/rman.h> --- 59 unchanged lines hidden (view full) --- 100#include <dev/kbd/kbdreg.h> 101#include <dev/kbd/kbdtables.h> 102 103#define CKB_NFKEY 12 104#define CKB_FLAG_COMPOSE 0x1 105#define CKB_FLAG_POLLING 0x2 106#define KBD_DRIVER_NAME "ckbd" 107 |
108/* TODO: take interrupt from DTS */ 109#define KB_GPIO_INT 146 110 | |
111struct ckb_softc { 112 keyboard_t sc_kbd; 113 keymap_t sc_keymap; 114 accentmap_t sc_accmap; 115 fkeytab_t sc_fkeymap[CKB_NFKEY]; 116 117 struct resource* sc_mem_res; 118 struct resource* sc_irq_res; --- 6 unchanged lines hidden (view full) --- 125 126 struct callout sc_repeat_callout; 127 int sc_repeat_key; 128 int sc_repeating; 129 130 int flag; 131 int rows; 132 int cols; | 108struct ckb_softc { 109 keyboard_t sc_kbd; 110 keymap_t sc_keymap; 111 accentmap_t sc_accmap; 112 fkeytab_t sc_fkeymap[CKB_NFKEY]; 113 114 struct resource* sc_mem_res; 115 struct resource* sc_irq_res; --- 6 unchanged lines hidden (view full) --- 122 123 struct callout sc_repeat_callout; 124 int sc_repeat_key; 125 int sc_repeating; 126 127 int flag; 128 int rows; 129 int cols; |
130 int gpio; |
|
133 device_t dev; 134 device_t gpio_dev; 135 struct thread *sc_poll_thread; | 131 device_t dev; 132 device_t gpio_dev; 133 struct thread *sc_poll_thread; |
134 uint16_t *keymap; |
|
136 137 uint8_t *scan_local; 138 uint8_t *scan; 139}; 140 141/* prototypes */ 142static int ckb_set_typematic(keyboard_t *, int); 143static uint32_t ckb_read_char(keyboard_t *, int); --- 50 unchanged lines hidden (view full) --- 194 return (ENXIO); 195} 196 197/* keyboard interrupt routine, not used */ 198static int 199ckb_intr(keyboard_t *kbd, void *arg) 200{ 201 | 135 136 uint8_t *scan_local; 137 uint8_t *scan; 138}; 139 140/* prototypes */ 141static int ckb_set_typematic(keyboard_t *, int); 142static uint32_t ckb_read_char(keyboard_t *, int); --- 50 unchanged lines hidden (view full) --- 193 return (ENXIO); 194} 195 196/* keyboard interrupt routine, not used */ 197static int 198ckb_intr(keyboard_t *kbd, void *arg) 199{ 200 |
202 return (0); | 201 return (0); |
203} 204 205/* lock the access to the keyboard, not used */ 206static int 207ckb_lock(keyboard_t *kbd, int lock) 208{ 209 | 202} 203 204/* lock the access to the keyboard, not used */ 205static int 206ckb_lock(keyboard_t *kbd, int lock) 207{ 208 |
210 return (1); | 209 return (1); |
211} 212 213/* clear the internal state of the keyboard */ 214static void 215ckb_clear_state(keyboard_t *kbd) 216{ 217 struct ckb_softc *sc; 218 --- 85 unchanged lines hidden (view full) --- 304 305 if (!KBD_IS_ACTIVE(kbd)) 306 return (-1); 307 308 printf("Implement ME: %s\n", __func__); 309 return (0); 310} 311 | 210} 211 212/* clear the internal state of the keyboard */ 213static void 214ckb_clear_state(keyboard_t *kbd) 215{ 216 struct ckb_softc *sc; 217 --- 85 unchanged lines hidden (view full) --- 303 304 if (!KBD_IS_ACTIVE(kbd)) 305 return (-1); 306 307 printf("Implement ME: %s\n", __func__); 308 return (0); 309} 310 |
312int scantokey(int i, int j); 313 314int 315scantokey(int i, int j) | 311static uint16_t 312keymap_read(struct ckb_softc *sc, int col, int row) |
316{ | 313{ |
317 int k; | |
318 | 314 |
319 for (k = 0; k < KEYMAP_LEN; k++) 320 if ((keymap[k].col == i) && (keymap[k].row == j)) 321 return (keymap[k].key); | 315 KASSERT(sc->keymap != NULL, "keymap_read: no keymap"); 316 if (col >= 0 && col < sc->cols && 317 row >= 0 && row < sc->rows) { 318 return sc->keymap[row * sc->cols + col]; 319 } |
322 323 return (0); 324} 325 | 320 321 return (0); 322} 323 |
324static int 325keymap_write(struct ckb_softc *sc, int col, int row, uint16_t key) 326{ 327 328 KASSERT(sc->keymap != NULL, "keymap_write: no keymap"); 329 if (col >= 0 && col < sc->cols && 330 row >= 0 && row < sc->rows) { 331 sc->keymap[row * sc->cols + col] = key; 332 return (0); 333 } 334 335 return (-1); 336} 337 |
|
326/* read char from the keyboard */ 327static uint32_t 328ckb_read_char_locked(keyboard_t *kbd, int wait) 329{ 330 struct ckb_softc *sc; 331 int i,j; 332 uint16_t key; 333 int oldbit; --- 11 unchanged lines hidden (view full) --- 345 sc->sc_repeating = 0; 346 callout_reset(&sc->sc_repeat_callout, hz / 10, 347 ckb_repeat, sc); 348 return (sc->sc_repeat_key); 349 }; 350 351 if (sc->sc_flags & CKB_FLAG_POLLING) { 352 for (;;) { | 338/* read char from the keyboard */ 339static uint32_t 340ckb_read_char_locked(keyboard_t *kbd, int wait) 341{ 342 struct ckb_softc *sc; 343 int i,j; 344 uint16_t key; 345 int oldbit; --- 11 unchanged lines hidden (view full) --- 357 sc->sc_repeating = 0; 358 callout_reset(&sc->sc_repeat_callout, hz / 10, 359 ckb_repeat, sc); 360 return (sc->sc_repeat_key); 361 }; 362 363 if (sc->sc_flags & CKB_FLAG_POLLING) { 364 for (;;) { |
353 GPIO_PIN_GET(sc->gpio_dev, KB_GPIO_INT, &status); | 365 GPIO_PIN_GET(sc->gpio_dev, sc->gpio, &status); |
354 if (status == 0) { | 366 if (status == 0) { |
355 if (ec_command(EC_CMD_MKBP_STATE, sc->scan, sc->cols, | 367 if (ec_command(EC_CMD_MKBP_STATE, sc->scan, 368 sc->cols, |
356 sc->scan, sc->cols)) { 357 return (NOKEY); 358 } 359 break; 360 } 361 if (!wait) { 362 return (NOKEY); 363 } --- 4 unchanged lines hidden (view full) --- 368 for (i = 0; i < sc->cols; i++) { 369 for (j = 0; j < sc->rows; j++) { 370 oldbit = (sc->scan_local[i] & (1 << j)); 371 newbit = (sc->scan[i] & (1 << j)); 372 373 if (oldbit == newbit) 374 continue; 375 | 369 sc->scan, sc->cols)) { 370 return (NOKEY); 371 } 372 break; 373 } 374 if (!wait) { 375 return (NOKEY); 376 } --- 4 unchanged lines hidden (view full) --- 381 for (i = 0; i < sc->cols; i++) { 382 for (j = 0; j < sc->rows; j++) { 383 oldbit = (sc->scan_local[i] & (1 << j)); 384 newbit = (sc->scan[i] & (1 << j)); 385 386 if (oldbit == newbit) 387 continue; 388 |
376 key = scantokey(i,j); | 389 key = keymap_read(sc, i, j); |
377 if (key == 0) { 378 continue; 379 }; 380 381 if (newbit > 0) { 382 /* key pressed */ 383 sc->scan_local[i] |= (1 << j); 384 --- 276 unchanged lines hidden (view full) --- 661dummy_kbd_configure(int flags) 662{ 663 664 return (0); 665} 666 667KEYBOARD_DRIVER(ckbd, ckbdsw, dummy_kbd_configure); 668 | 390 if (key == 0) { 391 continue; 392 }; 393 394 if (newbit > 0) { 395 /* key pressed */ 396 sc->scan_local[i] |= (1 << j); 397 --- 276 unchanged lines hidden (view full) --- 674dummy_kbd_configure(int flags) 675{ 676 677 return (0); 678} 679 680KEYBOARD_DRIVER(ckbd, ckbdsw, dummy_kbd_configure); 681 |
682/* 683 * Parses 'keymap' into sc->keymap. 684 * Requires sc->cols and sc->rows to be set. 685 */ |
|
669static int | 686static int |
687parse_keymap(struct ckb_softc *sc, pcell_t *keymap, size_t len) 688{ 689 int i; 690 691 sc->keymap = malloc(sc->cols * sc->rows * sizeof(sc->keymap[0]), 692 M_DEVBUF, M_NOWAIT | M_ZERO); 693 if (sc->keymap == NULL) { 694 return (ENOMEM); 695 } 696 697 for (i = 0; i < len; i++) { 698 /* 699 * Return value is ignored, we just write whatever fits into 700 * specified number of rows and columns and silently ignore 701 * everything else. 702 * Keymap entries follow this format: 0xRRCCKKKK 703 * RR - row number, CC - column number, KKKK - key code 704 */ 705 keymap_write(sc, (keymap[i] >> 16) & 0xff, 706 (keymap[i] >> 24) & 0xff, 707 keymap[i] & 0xffff); 708 } 709 710 return (0); 711} 712 713/* Allocates a new array for keymap and returns it in 'keymap'. */ 714static int 715read_keymap(phandle_t node, const char *prop, pcell_t **keymap, size_t *len) 716{ 717 718 if ((*len = OF_getproplen(node, prop)) <= 0) { 719 return (ENXIO); 720 } 721 if ((*keymap = malloc(*len, M_DEVBUF, M_NOWAIT)) == NULL) { 722 return (ENOMEM); 723 } 724 if (OF_getencprop(node, prop, *keymap, *len) != *len) { 725 return (ENXIO); 726 } 727 return (0); 728} 729 730static int |
|
670parse_dts(struct ckb_softc *sc) 671{ 672 phandle_t node; 673 pcell_t dts_value; | 731parse_dts(struct ckb_softc *sc) 732{ 733 phandle_t node; 734 pcell_t dts_value; |
674 int len; | 735 pcell_t *keymap; 736 int len, ret; 737 const char *keymap_prop = NULL; |
675 676 if ((node = ofw_bus_get_node(sc->dev)) == -1) 677 return (ENXIO); 678 | 738 739 if ((node = ofw_bus_get_node(sc->dev)) == -1) 740 return (ENXIO); 741 |
679 if ((len = OF_getproplen(node, "keypad,num-rows")) <= 0) | 742 if ((len = OF_getproplen(node, "google,key-rows")) <= 0) |
680 return (ENXIO); | 743 return (ENXIO); |
681 OF_getprop(node, "keypad,num-rows", &dts_value, len); | 744 OF_getprop(node, "google,key-rows", &dts_value, len); |
682 sc->rows = fdt32_to_cpu(dts_value); 683 | 745 sc->rows = fdt32_to_cpu(dts_value); 746 |
684 if ((len = OF_getproplen(node, "keypad,num-columns")) <= 0) | 747 if ((len = OF_getproplen(node, "google,key-columns")) <= 0) |
685 return (ENXIO); | 748 return (ENXIO); |
686 OF_getprop(node, "keypad,num-columns", &dts_value, len); | 749 OF_getprop(node, "google,key-columns", &dts_value, len); |
687 sc->cols = fdt32_to_cpu(dts_value); 688 | 750 sc->cols = fdt32_to_cpu(dts_value); 751 |
689 if ((sc->rows == 0) || (sc->cols == 0)) | 752 if ((len = OF_getproplen(node, "freebsd,intr-gpio")) <= 0) |
690 return (ENXIO); | 753 return (ENXIO); |
754 OF_getprop(node, "freebsd,intr-gpio", &dts_value, len); 755 sc->gpio = fdt32_to_cpu(dts_value); |
|
691 | 756 |
757 if (OF_hasprop(node, "freebsd,keymap")) { 758 keymap_prop = "freebsd,keymap"; 759 device_printf(sc->dev, "using FreeBSD-specific keymap from FDT\n"); 760 } else if (OF_hasprop(node, "linux,keymap")) { 761 keymap_prop = "linux,keymap"; 762 device_printf(sc->dev, "using Linux keymap from FDT\n"); 763 } else { 764 device_printf(sc->dev, "using built-in keymap\n"); 765 } 766 767 if (keymap_prop != NULL) { 768 if ((ret = read_keymap(node, keymap_prop, &keymap, &len))) { 769 device_printf(sc->dev, 770 "failed to read keymap from FDT: %d\n", ret); 771 return (ret); 772 } 773 ret = parse_keymap(sc, keymap, len); 774 free(keymap, M_DEVBUF); 775 if (ret) { 776 return (ret); 777 } 778 } else { 779 if ((ret = parse_keymap(sc, default_keymap, KEYMAP_LEN))) { 780 return (ret); 781 } 782 } 783 784 if ((sc->rows == 0) || (sc->cols == 0) || (sc->gpio == 0)) 785 return (ENXIO); 786 |
|
692 return (0); 693} 694 695void 696ckb_ec_intr(void *arg) 697{ 698 struct ckb_softc *sc; 699 --- 16 unchanged lines hidden (view full) --- 716 keyboard_t *kbd; 717 int error; 718 int rid; 719 int i; 720 721 sc = device_get_softc(dev); 722 723 sc->dev = dev; | 787 return (0); 788} 789 790void 791ckb_ec_intr(void *arg) 792{ 793 struct ckb_softc *sc; 794 --- 16 unchanged lines hidden (view full) --- 811 keyboard_t *kbd; 812 int error; 813 int rid; 814 int i; 815 816 sc = device_get_softc(dev); 817 818 sc->dev = dev; |
819 sc->keymap = NULL; |
|
724 725 if ((error = parse_dts(sc)) != 0) 726 return error; 727 728 sc->gpio_dev = devclass_get_device(devclass_find("gpio"), 0); 729 if (sc->gpio_dev == NULL) { 730 device_printf(sc->dev, "Can't find gpio device.\n"); 731 return (ENXIO); 732 } 733 734#if 0 735 device_printf(sc->dev, "Keyboard matrix [%dx%d]\n", 736 sc->cols, sc->rows); 737#endif 738 | 820 821 if ((error = parse_dts(sc)) != 0) 822 return error; 823 824 sc->gpio_dev = devclass_get_device(devclass_find("gpio"), 0); 825 if (sc->gpio_dev == NULL) { 826 device_printf(sc->dev, "Can't find gpio device.\n"); 827 return (ENXIO); 828 } 829 830#if 0 831 device_printf(sc->dev, "Keyboard matrix [%dx%d]\n", 832 sc->cols, sc->rows); 833#endif 834 |
739 /* TODO: take interrupt from DTS */ 740 pad_setup_intr(KB_GPIO_INT, ckb_ec_intr, sc); | 835 pad_setup_intr(sc->gpio, ckb_ec_intr, sc); |
741 742 kbd = &sc->sc_kbd; 743 rid = 0; 744 745 sc->scan_local = malloc(sc->cols, M_DEVBUF, M_NOWAIT); 746 sc->scan = malloc(sc->cols, M_DEVBUF, M_NOWAIT); 747 748 for (i = 0; i < sc->cols; i++) { --- 32 unchanged lines hidden (view full) --- 781 782static int 783chrome_kb_probe(device_t dev) 784{ 785 786 if (!ofw_bus_status_okay(dev)) 787 return (ENXIO); 788 | 836 837 kbd = &sc->sc_kbd; 838 rid = 0; 839 840 sc->scan_local = malloc(sc->cols, M_DEVBUF, M_NOWAIT); 841 sc->scan = malloc(sc->cols, M_DEVBUF, M_NOWAIT); 842 843 for (i = 0; i < sc->cols; i++) { --- 32 unchanged lines hidden (view full) --- 876 877static int 878chrome_kb_probe(device_t dev) 879{ 880 881 if (!ofw_bus_status_okay(dev)) 882 return (ENXIO); 883 |
789 if (ofw_bus_is_compatible(dev, "google,cros-ec-keyb")) { | 884 if (ofw_bus_is_compatible(dev, "google,cros-ec-keyb") || 885 ofw_bus_is_compatible(dev, "google,mkbp-keyb")) { |
790 device_set_desc(dev, "Chrome EC Keyboard"); 791 return (BUS_PROBE_DEFAULT); 792 } 793 794 return (ENXIO); 795} 796 | 886 device_set_desc(dev, "Chrome EC Keyboard"); 887 return (BUS_PROBE_DEFAULT); 888 } 889 890 return (ENXIO); 891} 892 |
893static int 894chrome_kb_detach(device_t dev) 895{ 896 struct ckb_softc *sc; 897 898 sc = device_get_softc(dev); 899 900 if (sc->keymap != NULL) { 901 free(sc->keymap, M_DEVBUF); 902 } 903 904 return 0; 905} 906 |
|
797static device_method_t chrome_kb_methods[] = { 798 DEVMETHOD(device_probe, chrome_kb_probe), 799 DEVMETHOD(device_attach, chrome_kb_attach), | 907static device_method_t chrome_kb_methods[] = { 908 DEVMETHOD(device_probe, chrome_kb_probe), 909 DEVMETHOD(device_attach, chrome_kb_attach), |
910 DEVMETHOD(device_detach, chrome_kb_detach), |
|
800 { 0, 0 } 801}; 802 803static driver_t chrome_kb_driver = { 804 "chrome_kb", 805 chrome_kb_methods, 806 sizeof(struct ckb_softc), 807}; 808 809static devclass_t chrome_kb_devclass; 810 811DRIVER_MODULE(chrome_kb, simplebus, chrome_kb_driver, 812 chrome_kb_devclass, 0, 0); | 911 { 0, 0 } 912}; 913 914static driver_t chrome_kb_driver = { 915 "chrome_kb", 916 chrome_kb_methods, 917 sizeof(struct ckb_softc), 918}; 919 920static devclass_t chrome_kb_devclass; 921 922DRIVER_MODULE(chrome_kb, simplebus, chrome_kb_driver, 923 chrome_kb_devclass, 0, 0); |