chrome_kb.c revision 266352
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 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27/* 28 * Samsung Chromebook Keyboard 29 */ 30 31#include <sys/cdefs.h> 32__FBSDID("$FreeBSD: stable/10/sys/arm/samsung/exynos/chrome_kb.c 266352 2014-05-17 20:52:10Z ian $"); 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> 41#include <sys/proc.h> 42#include <sys/sched.h> 43#include <sys/kdb.h> 44#include <sys/timeet.h> 45#include <sys/timetc.h> 46#include <sys/mutex.h> 47#include <sys/gpio.h> 48 49#include <dev/fdt/fdt_common.h> 50#include <dev/ofw/openfirm.h> 51#include <dev/ofw/ofw_bus.h> 52#include <dev/ofw/ofw_bus_subr.h> 53 54#include <sys/ioccom.h> 55#include <sys/filio.h> 56#include <sys/tty.h> 57#include <sys/kbio.h> 58 59#include <machine/bus.h> 60#include <machine/fdt.h> 61#include <machine/cpu.h> 62#include <machine/intr.h> 63 64#include "gpio_if.h" 65 66#include <arm/samsung/exynos/chrome_ec.h> 67#include <arm/samsung/exynos/chrome_kb.h> 68 69#include <arm/samsung/exynos/exynos5_combiner.h> 70#include <arm/samsung/exynos/exynos5_pad.h> 71 72#define CKB_LOCK() mtx_lock(&Giant) 73#define CKB_UNLOCK() mtx_unlock(&Giant) 74 75#ifdef INVARIANTS 76/* 77 * Assert that the lock is held in all contexts 78 * where the code can be executed. 79 */ 80#define CKB_LOCK_ASSERT() mtx_assert(&Giant, MA_OWNED) 81/* 82 * Assert that the lock is held in the contexts 83 * where it really has to be so. 84 */ 85#define CKB_CTX_LOCK_ASSERT() \ 86 do { \ 87 if (!kdb_active && panicstr == NULL) \ 88 mtx_assert(&Giant, MA_OWNED); \ 89 } while (0) 90#else 91#define CKB_LOCK_ASSERT() (void)0 92#define CKB_CTX_LOCK_ASSERT() (void)0 93#endif 94 95/* 96 * Define a stub keyboard driver in case one hasn't been 97 * compiled into the kernel 98 */ 99#include <sys/kbio.h> 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; 119 void* sc_intr_hl; 120 121 int sc_mode; /* input mode (K_XLATE,K_RAW,K_CODE) */ 122 int sc_state; /* shift/lock key state */ 123 int sc_accents; /* accent key index (> 0) */ 124 int sc_flags; /* flags */ 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; 133 device_t dev; 134 struct thread *sc_poll_thread; 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); 143static void ckb_clear_state(keyboard_t *); 144static int ckb_ioctl(keyboard_t *, u_long, caddr_t); 145static int ckb_enable(keyboard_t *); 146static int ckb_disable(keyboard_t *); 147 148static void 149ckb_repeat(void *arg) 150{ 151 struct ckb_softc *sc; 152 153 sc = arg; 154 155 if (KBD_IS_ACTIVE(&sc->sc_kbd) && KBD_IS_BUSY(&sc->sc_kbd)) { 156 if (sc->sc_repeat_key != -1) { 157 sc->sc_repeating = 1; 158 sc->sc_kbd.kb_callback.kc_func(&sc->sc_kbd, 159 KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg); 160 } 161 } 162} 163 164/* detect a keyboard, not used */ 165static int 166ckb__probe(int unit, void *arg, int flags) 167{ 168 169 return (ENXIO); 170} 171 172/* reset and initialize the device, not used */ 173static int 174ckb_init(int unit, keyboard_t **kbdp, void *arg, int flags) 175{ 176 177 return (ENXIO); 178} 179 180/* test the interface to the device, not used */ 181static int 182ckb_test_if(keyboard_t *kbd) 183{ 184 185 return (0); 186} 187 188/* finish using this keyboard, not used */ 189static int 190ckb_term(keyboard_t *kbd) 191{ 192 193 return (ENXIO); 194} 195 196/* keyboard interrupt routine, not used */ 197static int 198ckb_intr(keyboard_t *kbd, void *arg) 199{ 200 201 return (0); 202} 203 204/* lock the access to the keyboard, not used */ 205static int 206ckb_lock(keyboard_t *kbd, int lock) 207{ 208 209 return (1); 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 218 sc = kbd->kb_data; 219 220 CKB_CTX_LOCK_ASSERT(); 221 222 sc->sc_flags &= ~(CKB_FLAG_COMPOSE | CKB_FLAG_POLLING); 223 sc->sc_state &= LOCK_MASK; /* preserve locking key state */ 224 sc->sc_accents = 0; 225} 226 227/* save the internal state, not used */ 228static int 229ckb_get_state(keyboard_t *kbd, void *buf, size_t len) 230{ 231 232 return (len == 0) ? 1 : -1; 233} 234 235/* set the internal state, not used */ 236static int 237ckb_set_state(keyboard_t *kbd, void *buf, size_t len) 238{ 239 240 return (EINVAL); 241} 242 243 244/* check if data is waiting */ 245static int 246ckb_check(keyboard_t *kbd) 247{ 248 struct ckb_softc *sc; 249 int i; 250 251 sc = kbd->kb_data; 252 253 CKB_CTX_LOCK_ASSERT(); 254 255 if (!KBD_IS_ACTIVE(kbd)) 256 return (0); 257 258 if (sc->sc_flags & CKB_FLAG_POLLING) { 259 return (1); 260 }; 261 262 for (i = 0; i < sc->cols; i++) 263 if (sc->scan_local[i] != sc->scan[i]) { 264 return (1); 265 }; 266 267 if (sc->sc_repeating) 268 return (1); 269 270 return (0); 271} 272 273/* check if char is waiting */ 274static int 275ckb_check_char_locked(keyboard_t *kbd) 276{ 277 CKB_CTX_LOCK_ASSERT(); 278 279 if (!KBD_IS_ACTIVE(kbd)) 280 return (0); 281 282 return (ckb_check(kbd)); 283} 284 285static int 286ckb_check_char(keyboard_t *kbd) 287{ 288 int result; 289 290 CKB_LOCK(); 291 result = ckb_check_char_locked(kbd); 292 CKB_UNLOCK(); 293 294 return (result); 295} 296 297/* read one byte from the keyboard if it's allowed */ 298/* Currently unused. */ 299static int 300ckb_read(keyboard_t *kbd, int wait) 301{ 302 CKB_CTX_LOCK_ASSERT(); 303 304 if (!KBD_IS_ACTIVE(kbd)) 305 return (-1); 306 307 printf("Implement ME: %s\n", __func__); 308 return (0); 309} 310 311int scantokey(int i, int j); 312 313int 314scantokey(int i, int j) 315{ 316 int k; 317 318 for (k = 0; k < KEYMAP_LEN; k++) 319 if ((keymap[k].col == i) && (keymap[k].row == j)) 320 return (keymap[k].key); 321 322 return (0); 323} 324 325/* read char from the keyboard */ 326static uint32_t 327ckb_read_char_locked(keyboard_t *kbd, int wait) 328{ 329 struct ckb_softc *sc; 330 int i,j; 331 uint16_t key; 332 int oldbit; 333 int newbit; 334 335 sc = kbd->kb_data; 336 337 CKB_CTX_LOCK_ASSERT(); 338 339 if (!KBD_IS_ACTIVE(kbd)) 340 return (NOKEY); 341 342 if (sc->sc_repeating) { 343 sc->sc_repeating = 0; 344 callout_reset(&sc->sc_repeat_callout, hz / 10, 345 ckb_repeat, sc); 346 return (sc->sc_repeat_key); 347 }; 348 349 if (sc->sc_flags & CKB_FLAG_POLLING) { 350 /* TODO */ 351 }; 352 353 for (i = 0; i < sc->cols; i++) { 354 for (j = 0; j < sc->rows; j++) { 355 oldbit = (sc->scan_local[i] & (1 << j)); 356 newbit = (sc->scan[i] & (1 << j)); 357 358 if (oldbit == newbit) 359 continue; 360 361 key = scantokey(i,j); 362 if (key == 0) { 363 continue; 364 }; 365 366 if (newbit > 0) { 367 /* key pressed */ 368 sc->scan_local[i] |= (1 << j); 369 370 /* setup repeating */ 371 sc->sc_repeat_key = key; 372 callout_reset(&sc->sc_repeat_callout, 373 hz / 2, ckb_repeat, sc); 374 375 } else { 376 /* key released */ 377 sc->scan_local[i] &= ~(1 << j); 378 379 /* release flag */ 380 key |= 0x80; 381 382 /* unsetup repeating */ 383 sc->sc_repeat_key = -1; 384 callout_stop(&sc->sc_repeat_callout); 385 } 386 387 return (key); 388 } 389 } 390 391 return (NOKEY); 392} 393 394/* Currently wait is always false. */ 395static uint32_t 396ckb_read_char(keyboard_t *kbd, int wait) 397{ 398 uint32_t keycode; 399 400 CKB_LOCK(); 401 keycode = ckb_read_char_locked(kbd, wait); 402 CKB_UNLOCK(); 403 404 return (keycode); 405} 406 407 408/* some useful control functions */ 409static int 410ckb_ioctl_locked(keyboard_t *kbd, u_long cmd, caddr_t arg) 411{ 412 struct ckb_softc *sc; 413 int i; 414 415 sc = kbd->kb_data; 416 417 CKB_LOCK_ASSERT(); 418 419 switch (cmd) { 420 case KDGKBMODE: /* get keyboard mode */ 421 *(int *)arg = sc->sc_mode; 422 break; 423 424 case KDSKBMODE: /* set keyboard mode */ 425 switch (*(int *)arg) { 426 case K_XLATE: 427 if (sc->sc_mode != K_XLATE) { 428 /* make lock key state and LED state match */ 429 sc->sc_state &= ~LOCK_MASK; 430 sc->sc_state |= KBD_LED_VAL(kbd); 431 } 432 /* FALLTHROUGH */ 433 case K_RAW: 434 case K_CODE: 435 if (sc->sc_mode != *(int *)arg) { 436 if ((sc->sc_flags & CKB_FLAG_POLLING) == 0) 437 ckb_clear_state(kbd); 438 sc->sc_mode = *(int *)arg; 439 } 440 break; 441 default: 442 return (EINVAL); 443 } 444 break; 445 446 case KDGETLED: /* get keyboard LED */ 447 *(int *)arg = KBD_LED_VAL(kbd); 448 break; 449 450 case KDSETLED: /* set keyboard LED */ 451 /* NOTE: lock key state in "sc_state" won't be changed */ 452 if (*(int *)arg & ~LOCK_MASK) 453 return (EINVAL); 454 455 i = *(int *)arg; 456 457 /* replace CAPS LED with ALTGR LED for ALTGR keyboards */ 458 if (sc->sc_mode == K_XLATE && 459 kbd->kb_keymap->n_keys > ALTGR_OFFSET) { 460 if (i & ALKED) 461 i |= CLKED; 462 else 463 i &= ~CLKED; 464 } 465 if (KBD_HAS_DEVICE(kbd)) { 466 /* Configure LED */ 467 } 468 469 KBD_LED_VAL(kbd) = *(int *)arg; 470 break; 471 case KDGKBSTATE: /* get lock key state */ 472 *(int *)arg = sc->sc_state & LOCK_MASK; 473 break; 474 475 case KDSKBSTATE: /* set lock key state */ 476 if (*(int *)arg & ~LOCK_MASK) { 477 return (EINVAL); 478 } 479 sc->sc_state &= ~LOCK_MASK; 480 sc->sc_state |= *(int *)arg; 481 482 /* set LEDs and quit */ 483 return (ckb_ioctl(kbd, KDSETLED, arg)); 484 485 case KDSETREPEAT: /* set keyboard repeat rate (new 486 * interface) */ 487 488 if (!KBD_HAS_DEVICE(kbd)) { 489 return (0); 490 } 491 if (((int *)arg)[1] < 0) { 492 return (EINVAL); 493 } 494 if (((int *)arg)[0] < 0) { 495 return (EINVAL); 496 } 497 if (((int *)arg)[0] < 200) /* fastest possible value */ 498 kbd->kb_delay1 = 200; 499 else 500 kbd->kb_delay1 = ((int *)arg)[0]; 501 kbd->kb_delay2 = ((int *)arg)[1]; 502 return (0); 503 504 case KDSETRAD: /* set keyboard repeat rate (old 505 * interface) */ 506 return (ckb_set_typematic(kbd, *(int *)arg)); 507 508 case PIO_KEYMAP: /* set keyboard translation table */ 509 case OPIO_KEYMAP: /* set keyboard translation table 510 * (compat) */ 511 case PIO_KEYMAPENT: /* set keyboard translation table 512 * entry */ 513 case PIO_DEADKEYMAP: /* set accent key translation table */ 514 sc->sc_accents = 0; 515 /* FALLTHROUGH */ 516 default: 517 return (genkbd_commonioctl(kbd, cmd, arg)); 518 } 519 520 return (0); 521} 522 523static int 524ckb_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg) 525{ 526 int result; 527 528 /* 529 * XXX KDGKBSTATE, KDSKBSTATE and KDSETLED can be called from any 530 * context where printf(9) can be called, which among other things 531 * includes interrupt filters and threads with any kinds of locks 532 * already held. For this reason it would be dangerous to acquire 533 * the Giant here unconditionally. On the other hand we have to 534 * have it to handle the ioctl. 535 * So we make our best effort to auto-detect whether we can grab 536 * the Giant or not. Blame syscons(4) for this. 537 */ 538 switch (cmd) { 539 case KDGKBSTATE: 540 case KDSKBSTATE: 541 case KDSETLED: 542 if (!mtx_owned(&Giant) && !SCHEDULER_STOPPED()) 543 return (EDEADLK); /* best I could come up with */ 544 /* FALLTHROUGH */ 545 default: 546 CKB_LOCK(); 547 result = ckb_ioctl_locked(kbd, cmd, arg); 548 CKB_UNLOCK(); 549 return (result); 550 } 551} 552 553 554/* 555 * Enable the access to the device; until this function is called, 556 * the client cannot read from the keyboard. 557 */ 558static int 559ckb_enable(keyboard_t *kbd) 560{ 561 562 CKB_LOCK(); 563 KBD_ACTIVATE(kbd); 564 CKB_UNLOCK(); 565 566 return (0); 567} 568 569/* disallow the access to the device */ 570static int 571ckb_disable(keyboard_t *kbd) 572{ 573 574 CKB_LOCK(); 575 KBD_DEACTIVATE(kbd); 576 CKB_UNLOCK(); 577 578 return (0); 579} 580 581/* local functions */ 582 583static int 584ckb_set_typematic(keyboard_t *kbd, int code) 585{ 586 static const int delays[] = {250, 500, 750, 1000}; 587 static const int rates[] = {34, 38, 42, 46, 50, 55, 59, 63, 588 68, 76, 84, 92, 100, 110, 118, 126, 589 136, 152, 168, 184, 200, 220, 236, 252, 590 272, 304, 336, 368, 400, 440, 472, 504}; 591 592 if (code & ~0x7f) { 593 return (EINVAL); 594 } 595 kbd->kb_delay1 = delays[(code >> 5) & 3]; 596 kbd->kb_delay2 = rates[code & 0x1f]; 597 return (0); 598} 599 600static int 601ckb_poll(keyboard_t *kbd, int on) 602{ 603 struct ckb_softc *sc; 604 605 sc = kbd->kb_data; 606 607 CKB_LOCK(); 608 if (on) { 609 sc->sc_flags |= CKB_FLAG_POLLING; 610 sc->sc_poll_thread = curthread; 611 } else { 612 sc->sc_flags &= ~CKB_FLAG_POLLING; 613 } 614 CKB_UNLOCK(); 615 616 return (0); 617} 618 619/* local functions */ 620 621static int dummy_kbd_configure(int flags); 622 623keyboard_switch_t ckbdsw = { 624 .probe = &ckb__probe, 625 .init = &ckb_init, 626 .term = &ckb_term, 627 .intr = &ckb_intr, 628 .test_if = &ckb_test_if, 629 .enable = &ckb_enable, 630 .disable = &ckb_disable, 631 .read = &ckb_read, 632 .check = &ckb_check, 633 .read_char = &ckb_read_char, 634 .check_char = &ckb_check_char, 635 .ioctl = &ckb_ioctl, 636 .lock = &ckb_lock, 637 .clear_state = &ckb_clear_state, 638 .get_state = &ckb_get_state, 639 .set_state = &ckb_set_state, 640 .get_fkeystr = &genkbd_get_fkeystr, 641 .poll = &ckb_poll, 642 .diag = &genkbd_diag, 643}; 644 645static int 646dummy_kbd_configure(int flags) 647{ 648 649 return (0); 650} 651 652KEYBOARD_DRIVER(ckbd, ckbdsw, dummy_kbd_configure); 653 654static int 655parse_dts(struct ckb_softc *sc) 656{ 657 phandle_t node; 658 pcell_t dts_value; 659 int len; 660 661 if ((node = ofw_bus_get_node(sc->dev)) == -1) 662 return (ENXIO); 663 664 if ((len = OF_getproplen(node, "keypad,num-rows")) <= 0) 665 return (ENXIO); 666 OF_getprop(node, "keypad,num-rows", &dts_value, len); 667 sc->rows = fdt32_to_cpu(dts_value); 668 669 if ((len = OF_getproplen(node, "keypad,num-columns")) <= 0) 670 return (ENXIO); 671 OF_getprop(node, "keypad,num-columns", &dts_value, len); 672 sc->cols = fdt32_to_cpu(dts_value); 673 674 if ((sc->rows == 0) || (sc->cols == 0)) 675 return (ENXIO); 676 677 return (0); 678} 679 680void 681ckb_ec_intr(void *arg) 682{ 683 struct ckb_softc *sc; 684 685 sc = arg; 686 687 if (sc->sc_flags & CKB_FLAG_POLLING) 688 return; 689 690 ec_command(EC_CMD_MKBP_STATE, sc->scan, sc->cols, 691 sc->scan, sc->cols); 692 693 (sc->sc_kbd.kb_callback.kc_func) (&sc->sc_kbd, KBDIO_KEYINPUT, 694 sc->sc_kbd.kb_callback.kc_arg); 695}; 696 697static int 698chrome_kb_attach(device_t dev) 699{ 700 struct ckb_softc *sc; 701 keyboard_t *kbd; 702 int error; 703 int rid; 704 int i; 705 706 sc = device_get_softc(dev); 707 708 sc->dev = dev; 709 710 if ((error = parse_dts(sc)) != 0) 711 return error; 712 713#if 0 714 device_printf(sc->dev, "Keyboard matrix [%dx%d]\n", 715 sc->cols, sc->rows); 716#endif 717 718 /* TODO: take interrupt from DTS */ 719 pad_setup_intr(KB_GPIO_INT, ckb_ec_intr, sc); 720 721 kbd = &sc->sc_kbd; 722 rid = 0; 723 724 sc->scan_local = malloc(sc->cols, M_DEVBUF, M_NOWAIT); 725 sc->scan = malloc(sc->cols, M_DEVBUF, M_NOWAIT); 726 727 for (i = 0; i < sc->cols; i++) { 728 sc->scan_local[i] = 0; 729 sc->scan[i] = 0; 730 }; 731 732 kbd_init_struct(kbd, KBD_DRIVER_NAME, KB_OTHER, 733 device_get_unit(dev), 0, 0, 0); 734 kbd->kb_data = (void *)sc; 735 736 sc->sc_keymap = key_map; 737 sc->sc_accmap = accent_map; 738 for (i = 0; i < CKB_NFKEY; i++) { 739 sc->sc_fkeymap[i] = fkey_tab[i]; 740 } 741 742 kbd_set_maps(kbd, &sc->sc_keymap, &sc->sc_accmap, 743 sc->sc_fkeymap, CKB_NFKEY); 744 745 KBD_FOUND_DEVICE(kbd); 746 ckb_clear_state(kbd); 747 KBD_PROBE_DONE(kbd); 748 749 callout_init(&sc->sc_repeat_callout, 0); 750 751 KBD_INIT_DONE(kbd); 752 753 if (kbd_register(kbd) < 0) { 754 return (ENXIO); 755 }; 756 KBD_CONFIG_DONE(kbd); 757 758 return (0); 759} 760 761static int 762chrome_kb_probe(device_t dev) 763{ 764 765 if (!ofw_bus_status_okay(dev)) 766 return (ENXIO); 767 768 if (ofw_bus_is_compatible(dev, "google,cros-ec-keyb")) { 769 device_set_desc(dev, "Chrome EC Keyboard"); 770 return (BUS_PROBE_DEFAULT); 771 } 772 773 return (ENXIO); 774} 775 776static device_method_t chrome_kb_methods[] = { 777 DEVMETHOD(device_probe, chrome_kb_probe), 778 DEVMETHOD(device_attach, chrome_kb_attach), 779 { 0, 0 } 780}; 781 782static driver_t chrome_kb_driver = { 783 "chrome_kb", 784 chrome_kb_methods, 785 sizeof(struct ckb_softc), 786}; 787 788static devclass_t chrome_kb_devclass; 789 790DRIVER_MODULE(chrome_kb, simplebus, chrome_kb_driver, 791 chrome_kb_devclass, 0, 0); 792