Deleted Added
full compact
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);