29 30#include "opt_compat.h" 31#include "opt_kbd.h" 32#include "opt_sunkbd.h" 33 34#if (defined(SUNKBD_EMULATE_ATKBD) && defined(SUNKBD_DFLT_KEYMAP)) || \ 35 !defined(SUNKBD_EMULATE_ATKBD) 36#define KBD_DFLT_KEYMAP 37#endif 38 39#include <sys/param.h> 40#include <sys/systm.h> 41#include <sys/bus.h> 42#include <sys/interrupt.h> 43#include <sys/kbio.h> 44#include <sys/kernel.h> 45#include <sys/limits.h> 46 47#include <machine/bus.h> 48 49#include <dev/kbd/kbdreg.h> 50#include <dev/kbd/kbdtables.h> 51 52#include <dev/uart/uart.h> 53#include <dev/uart/uart_bus.h> 54#include <dev/uart/uart_cpu.h> 55 56#include <dev/uart/uart_kbd_sun.h> 57#if !defined(SUNKBD_EMULATE_ATKBD) 58#include <dev/uart/uart_kbd_sun_tables.h> 59#endif 60 61#if defined(SUNKBD_EMULATE_ATKBD) && defined(SUNKBD_DFLT_KEYMAP) 62#include "sunkbdmap.h" 63#endif 64#include "uart_if.h" 65 66#define SUNKBD_DRIVER_NAME "sunkbd" 67 68#define TODO printf("%s: unimplemented", __func__) 69 70struct sunkbd_softc { 71 keyboard_t sc_kbd; 72 struct uart_softc *sc_uart; 73 struct uart_devinfo *sc_sysdev; 74 75 struct callout sc_repeat_callout; 76 int sc_repeat_key; 77 78 int sc_accents; 79 int sc_composed_char; 80 int sc_flags; 81#define KPCOMPOSE (1 << 0) 82 int sc_mode; 83 int sc_polling; 84 int sc_repeating; 85 int sc_state; 86 87#if defined(SUNKBD_EMULATE_ATKBD) 88 int sc_buffered_char[2]; 89#endif 90}; 91 92static int sunkbd_configure(int flags); 93static int sunkbd_probe_keyboard(struct uart_devinfo *di); 94 95static int sunkbd_probe(int unit, void *arg, int flags); 96static int sunkbd_init(int unit, keyboard_t **kbdp, void *arg, int flags); 97static int sunkbd_term(keyboard_t *kbd); 98static int sunkbd_intr(keyboard_t *kbd, void *arg); 99static int sunkbd_test_if(keyboard_t *kbd); 100static int sunkbd_enable(keyboard_t *kbd); 101static int sunkbd_disable(keyboard_t *kbd); 102static int sunkbd_read(keyboard_t *kbd, int wait); 103static int sunkbd_check(keyboard_t *kbd); 104static u_int sunkbd_read_char(keyboard_t *kbd, int wait); 105static int sunkbd_check_char(keyboard_t *kbd); 106static int sunkbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t data); 107static int sunkbd_lock(keyboard_t *kbd, int lock); 108static void sunkbd_clear_state(keyboard_t *kbd); 109static int sunkbd_get_state(keyboard_t *kbd, void *buf, size_t len); 110static int sunkbd_set_state(keyboard_t *kbd, void *buf, size_t len); 111static int sunkbd_poll_mode(keyboard_t *kbd, int on); 112static void sunkbd_diag(keyboard_t *kbd, int level); 113 114static void sunkbd_repeat(void *v); 115#if defined(SUNKBD_EMULATE_ATKBD) 116static int keycode2scancode(int keycode, int shift, int up); 117#endif 118 119static keyboard_switch_t sunkbdsw = { 120 sunkbd_probe, 121 sunkbd_init, 122 sunkbd_term, 123 sunkbd_intr, 124 sunkbd_test_if, 125 sunkbd_enable, 126 sunkbd_disable, 127 sunkbd_read, 128 sunkbd_check, 129 sunkbd_read_char, 130 sunkbd_check_char, 131 sunkbd_ioctl, 132 sunkbd_lock, 133 sunkbd_clear_state, 134 sunkbd_get_state, 135 sunkbd_set_state, 136 genkbd_get_fkeystr, 137 sunkbd_poll_mode, 138 sunkbd_diag 139}; 140 141KEYBOARD_DRIVER(sunkbd, sunkbdsw, sunkbd_configure); 142 143static struct sunkbd_softc sunkbd_softc; 144static struct uart_devinfo uart_keyboard; 145 146#if defined(SUNKBD_EMULATE_ATKBD) 147 148#define SCAN_PRESS 0x000 149#define SCAN_RELEASE 0x080 150#define SCAN_PREFIX_E0 0x100 151#define SCAN_PREFIX_E1 0x200 152#define SCAN_PREFIX_CTL 0x400 153#define SCAN_PREFIX_SHIFT 0x800 154#define SCAN_PREFIX (SCAN_PREFIX_E0 | SCAN_PREFIX_E1 | \ 155 SCAN_PREFIX_CTL | SCAN_PREFIX_SHIFT) 156 157#define NOTR 0x0 /* no translation */ 158 159static const uint8_t sunkbd_trtab[] = { 160 NOTR, 0x6d, 0x78, 0x6e, 0x79, 0x3b, 0x3c, 0x44, /* 0x00 - 0x07 */ 161 0x3d, 0x57, 0x3e, 0x58, 0x3f, 0x5d, 0x40, NOTR, /* 0x08 - 0x0f */ 162 0x41, 0x42, 0x43, 0x38, 0x5f, 0x68, 0x5c, 0x46, /* 0x10 - 0x17 */ 163 0x61, 0x6e, 0x70, 0x64, 0x62, 0x01, 0x02, 0x03, /* 0x18 - 0x1f */ 164 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, /* 0x20 - 0x27 */ 165 0x0c, 0x0d, 0x29, 0x0e, 0x66, 0x77, 0x5b, 0x37, /* 0x28 - 0x2f */ 166 0x7a, 0x71, 0x53, 0x72, 0x5e, 0x0f, 0x10, 0x11, /* 0x30 - 0x37 */ 167 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, /* 0x38 - 0x3f */ 168 0x1a, 0x1b, 0x67, 0x6b, 0x47, 0x48, 0x49, 0x4a, /* 0x40 - 0x47 */ 169 0x73, 0x74, 0x63, NOTR, 0x1d, 0x1e, 0x1f, 0x20, /* 0x48 - 0x4f */ 170 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, /* 0x50 - 0x57 */ 171 0x2b, 0x1c, 0x59, 0x4b, 0x4c, 0x4d, 0x52, 0x75, /* 0x58 - 0x5f */ 172 0x60, 0x76, 0x45, 0x2a, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x60 - 0x67 */ 173 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, NOTR, /* 0x68 - 0x6f */ 174 0x4f, 0x50, 0x51, NOTR, NOTR, NOTR, 0x6c, 0x3a, /* 0x70 - 0x77 */ 175 0x69, 0x39, 0x6a, 0x65, 0x56, 0x4e, NOTR, NOTR /* 0x78 - 0x7f */ 176}; 177 178#endif 179 180static int 181sunkbd_probe_keyboard(struct uart_devinfo *di) 182{ 183 int c, id, ltries, tries; 184 185 for (tries = 5; tries != 0; tries--) { 186 uart_putc(di, SKBD_CMD_RESET); 187 for (ltries = 1000; ltries != 0; ltries--) { 188 if (uart_poll(di) == SKBD_RSP_RESET) 189 break; 190 DELAY(1000); 191 } 192 if (ltries == 0) 193 continue; 194 id = -1; 195 for (ltries = 1000; ltries != 0; ltries--) { 196 switch (c = uart_poll(di)) { 197 case -1: 198 break; 199 case SKBD_RSP_IDLE: 200 return (id); 201 default: 202 id = c; 203 } 204 DELAY(1000); 205 } 206 } 207 return (-1); 208} 209 210static int sunkbd_attach(struct uart_softc *sc); 211static void sunkbd_uart_intr(void *arg); 212 213static int 214sunkbd_configure(int flags) 215{ 216 struct sunkbd_softc *sc; 217 218 /* 219 * We are only prepared to be used for the high-level console 220 * when the keyboard is both configured and attached. 221 */ 222 if (!(flags & KB_CONF_PROBE_ONLY)) { 223 if (KBD_IS_INITIALIZED(&sunkbd_softc.sc_kbd)) 224 goto found; 225 else 226 return (0); 227 } 228 229 if (uart_cpu_getdev(UART_DEV_KEYBOARD, &uart_keyboard)) 230 return (0); 231 if (uart_probe(&uart_keyboard)) 232 return (0); 233 uart_init(&uart_keyboard); 234 235 uart_keyboard.type = UART_DEV_KEYBOARD; 236 uart_keyboard.attach = sunkbd_attach; 237 uart_add_sysdev(&uart_keyboard); 238 239 if (sunkbd_probe_keyboard(&uart_keyboard) != KB_SUN4) 240 return (0); 241 242 sc = &sunkbd_softc; 243 callout_init(&sc->sc_repeat_callout, 0); 244 sunkbd_clear_state(&sc->sc_kbd); 245 246#if defined(SUNKBD_EMULATE_ATKBD) 247 kbd_init_struct(&sc->sc_kbd, SUNKBD_DRIVER_NAME, KB_101, 0, 0, 0, 0); 248 kbd_set_maps(&sc->sc_kbd, &key_map, &accent_map, fkey_tab, 249 sizeof(fkey_tab) / sizeof(fkey_tab[0])); 250#else 251 kbd_init_struct(&sc->sc_kbd, SUNKBD_DRIVER_NAME, KB_OTHER, 0, 0, 0, 0); 252 kbd_set_maps(&sc->sc_kbd, &keymap_sun_us_unix_kbd, 253 &accentmap_sun_us_unix_kbd, fkey_tab, 254 sizeof(fkey_tab) / sizeof(fkey_tab[0])); 255#endif 256 sc->sc_mode = K_XLATE; 257 kbd_register(&sc->sc_kbd); 258 259 sc->sc_sysdev = &uart_keyboard; 260 261 found: 262 /* Return number of found keyboards. */ 263 return (1); 264} 265 266static int 267sunkbd_attach(struct uart_softc *sc) 268{ 269 270 /* 271 * Don't attach if we didn't probe the keyboard. Note that 272 * the UART is still marked as a system device in that case. 273 */ 274 if (sunkbd_softc.sc_sysdev == NULL) { 275 device_printf(sc->sc_dev, "keyboard not present\n"); 276 return (0); 277 } 278 279 if (sc->sc_sysdev != NULL) { 280 sunkbd_softc.sc_uart = sc; 281 282#ifdef KBD_INSTALL_CDEV 283 kbd_attach(&sunkbd_softc.sc_kbd); 284#endif 285 sunkbd_enable(&sunkbd_softc.sc_kbd); 286 287 swi_add(&tty_intr_event, uart_driver_name, sunkbd_uart_intr, 288 &sunkbd_softc, SWI_TTY, INTR_TYPE_TTY, &sc->sc_softih); 289 290 sc->sc_opened = 1; 291 KBD_INIT_DONE(&sunkbd_softc.sc_kbd); 292 } 293 294 return (0); 295} 296 297static void 298sunkbd_uart_intr(void *arg) 299{ 300 struct sunkbd_softc *sc = arg; 301 int pend; 302 303 if (sc->sc_uart->sc_leaving) 304 return; 305 306 pend = atomic_readandclear_32(&sc->sc_uart->sc_ttypend); 307 if (!(pend & SER_INT_MASK)) 308 return; 309 310 if (pend & SER_INT_RXREADY) { 311 if (KBD_IS_ACTIVE(&sc->sc_kbd) && KBD_IS_BUSY(&sc->sc_kbd)) { 312 sc->sc_kbd.kb_callback.kc_func(&sc->sc_kbd, 313 KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg); 314 } 315 } 316} 317 318static int 319sunkbd_probe(int unit, void *arg, int flags) 320{ 321 322 TODO; 323 return (0); 324} 325 326static int 327sunkbd_init(int unit, keyboard_t **kbdp, void *arg, int flags) 328{ 329 330 TODO; 331 return (0); 332} 333 334static int 335sunkbd_term(keyboard_t *kbd) 336{ 337 338 TODO; 339 return (0); 340} 341 342static int 343sunkbd_intr(keyboard_t *kbd, void *arg) 344{ 345 346 TODO; 347 return (0); 348} 349 350static int 351sunkbd_test_if(keyboard_t *kbd) 352{ 353 354 TODO; 355 return (0); 356} 357 358static int 359sunkbd_enable(keyboard_t *kbd) 360{ 361 362 KBD_ACTIVATE(kbd); 363 return (0); 364} 365 366static int 367sunkbd_disable(keyboard_t *kbd) 368{ 369 370 KBD_DEACTIVATE(kbd); 371 return (0); 372} 373 374static int 375sunkbd_read(keyboard_t *kbd, int wait) 376{ 377 378 TODO; 379 return (0); 380} 381 382static int 383sunkbd_check(keyboard_t *kbd) 384{ 385 struct sunkbd_softc *sc; 386 387 if (!KBD_IS_ACTIVE(kbd)) 388 return (FALSE); 389 390 sc = (struct sunkbd_softc *)kbd; 391 392#if defined(SUNKBD_EMULATE_ATKBD) 393 if (sc->sc_buffered_char[0]) 394 return (TRUE); 395#endif 396 397 if (sc->sc_repeating) 398 return (TRUE); 399 400 if (sc->sc_uart != NULL && !uart_rx_empty(sc->sc_uart)) 401 return (TRUE); 402 403 if (sc->sc_polling != 0 && sc->sc_sysdev != NULL && 404 uart_rxready(sc->sc_sysdev)) 405 return (TRUE); 406 407 return (FALSE); 408} 409 410static u_int 411sunkbd_read_char(keyboard_t *kbd, int wait) 412{ 413 struct sunkbd_softc *sc; 414 int key, release, repeated, suncode; 415 416 sc = (struct sunkbd_softc *)kbd; 417 418#if defined(SUNKBD_EMULATE_ATKBD) 419 if (sc->sc_mode == K_RAW && sc->sc_buffered_char[0]) { 420 key = sc->sc_buffered_char[0]; 421 if (key & SCAN_PREFIX) { 422 sc->sc_buffered_char[0] = key & ~SCAN_PREFIX; 423 return ((key & SCAN_PREFIX_E0) ? 0xe0 : 0xe1); 424 } else { 425 sc->sc_buffered_char[0] = sc->sc_buffered_char[1]; 426 sc->sc_buffered_char[1] = 0; 427 return (key); 428 } 429 } 430#endif 431 432 repeated = 0; 433 if (sc->sc_repeating) { 434 repeated = 1; 435 sc->sc_repeating = 0; 436 callout_reset(&sc->sc_repeat_callout, hz / 10, 437 sunkbd_repeat, sc); 438 suncode = sc->sc_repeat_key; 439 goto process_code; 440 } 441 442 for (;;) { 443 next_code: 444 if (!(sc->sc_flags & KPCOMPOSE) && (sc->sc_composed_char > 0)) { 445 key = sc->sc_composed_char; 446 sc->sc_composed_char = 0; 447 if (key > UCHAR_MAX) 448 return (ERRKEY); 449 return (key); 450 } 451 452 if (sc->sc_uart != NULL && !uart_rx_empty(sc->sc_uart)) { 453 suncode = uart_rx_get(sc->sc_uart); 454 } else if (sc->sc_polling != 0 && sc->sc_sysdev != NULL) { 455 if (wait) 456 suncode = uart_getc(sc->sc_sysdev); 457 else if ((suncode = uart_poll(sc->sc_sysdev)) == -1) 458 return (NOKEY); 459 } else { 460 return (NOKEY); 461 } 462 463 switch (suncode) { 464 case SKBD_RSP_IDLE: 465 break; 466 default: 467 process_code: 468 ++kbd->kb_count; 469 key = SKBD_KEY_CHAR(suncode); 470 release = suncode & SKBD_KEY_RELEASE; 471 if (!repeated) { 472 if (release == 0) { 473 callout_reset(&sc->sc_repeat_callout, 474 hz / 2, sunkbd_repeat, sc); 475 sc->sc_repeat_key = suncode; 476 } else if (sc->sc_repeat_key == key) { 477 callout_stop(&sc->sc_repeat_callout); 478 sc->sc_repeat_key = -1; 479 } 480 } 481 482#if defined(SUNKBD_EMULATE_ATKBD) 483 key = sunkbd_trtab[key]; 484 if (key == NOTR) 485 return (NOKEY); 486 487 if (!repeated) { 488 switch (key) { 489 case 0x1d: /* ctrl */ 490 if (release != 0) 491 sc->sc_flags &= ~CTLS; 492 else 493 sc->sc_flags |= CTLS; 494 break; 495 case 0x2a: /* left shift */ 496 case 0x36: /* right shift */ 497 if (release != 0) 498 sc->sc_flags &= ~SHIFTS; 499 else 500 sc->sc_flags |= SHIFTS; 501 break; 502 case 0x38: /* alt */ 503 case 0x5d: /* altgr */ 504 if (release != 0) 505 sc->sc_flags &= ~ALTS; 506 else 507 sc->sc_flags |= ALTS; 508 break; 509 } 510 } 511 if (sc->sc_mode == K_RAW) { 512 key = keycode2scancode(key, sc->sc_flags, 513 release); 514 if (key & SCAN_PREFIX) { 515 if (key & SCAN_PREFIX_CTL) { 516 sc->sc_buffered_char[0] = 517 0x1d | (key & SCAN_RELEASE); 518 sc->sc_buffered_char[1] = 519 key & ~SCAN_PREFIX; 520 } else if (key & SCAN_PREFIX_SHIFT) { 521 sc->sc_buffered_char[0] = 522 0x2a | (key & SCAN_RELEASE); 523 sc->sc_buffered_char[1] = 524 key & ~SCAN_PREFIX_SHIFT; 525 } else { 526 sc->sc_buffered_char[0] = 527 key & ~SCAN_PREFIX; 528 sc->sc_buffered_char[1] = 0; 529 } 530 return ((key & SCAN_PREFIX_E0) ? 531 0xe0 : 0xe1); 532 } 533 return (key); 534 } 535 switch (key) { 536 case 0x5c: /* print screen */ 537 if (sc->sc_flags & ALTS) 538 key = 0x54; /* sysrq */ 539 break; 540 case 0x68: /* pause/break */ 541 if (sc->sc_flags & CTLS) 542 key = 0x6c; /* break */ 543 break; 544 } 545 546 if (sc->sc_mode == K_CODE) 547 return (key | release); 548#else 549 if (sc->sc_mode == K_RAW || sc->sc_mode == K_CODE) 550 return (suncode); 551#endif 552 553#if defined(SUNKBD_EMULATE_ATKBD) 554 if (key == 0x38) { /* left alt (KP compose key) */ 555#else 556 if (key == 0x13) { /* left alt (KP compose key) */ 557#endif 558 if (release != 0) { 559 if (sc->sc_flags & KPCOMPOSE) { 560 sc->sc_flags &= ~KPCOMPOSE; 561 if (sc->sc_composed_char > 562 UCHAR_MAX) 563 sc->sc_composed_char = 564 0; 565 } 566 } else { 567 if (!(sc->sc_flags & KPCOMPOSE)) { 568 sc->sc_flags |= KPCOMPOSE; 569 sc->sc_composed_char = 0; 570 } 571 } 572 } 573 if (sc->sc_flags & KPCOMPOSE) { 574 switch (suncode) { 575 case 0x44: /* KP 7 */ 576 case 0x45: /* KP 8 */ 577 case 0x46: /* KP 9 */ 578 sc->sc_composed_char *= 10; 579 sc->sc_composed_char += suncode - 0x3d; 580 if (sc->sc_composed_char > UCHAR_MAX) 581 return (ERRKEY); 582 goto next_code; 583 case 0x5b: /* KP 4 */ 584 case 0x5c: /* KP 5 */ 585 case 0x5d: /* KP 6 */ 586 sc->sc_composed_char *= 10; 587 sc->sc_composed_char += suncode - 0x58; 588 if (sc->sc_composed_char > UCHAR_MAX) 589 return (ERRKEY); 590 goto next_code; 591 case 0x70: /* KP 1 */ 592 case 0x71: /* KP 2 */ 593 case 0x72: /* KP 3 */ 594 sc->sc_composed_char *= 10; 595 sc->sc_composed_char += suncode - 0x6f; 596 if (sc->sc_composed_char > UCHAR_MAX) 597 return (ERRKEY); 598 goto next_code; 599 case 0x5e: /* KP 0 */ 600 sc->sc_composed_char *= 10; 601 if (sc->sc_composed_char > UCHAR_MAX) 602 return (ERRKEY); 603 goto next_code; 604 605 case 0x44 | SKBD_KEY_RELEASE: /* KP 7 */ 606 case 0x45 | SKBD_KEY_RELEASE: /* KP 8 */ 607 case 0x46 | SKBD_KEY_RELEASE: /* KP 9 */ 608 case 0x5b | SKBD_KEY_RELEASE: /* KP 4 */ 609 case 0x5c | SKBD_KEY_RELEASE: /* KP 5 */ 610 case 0x5d | SKBD_KEY_RELEASE: /* KP 6 */ 611 case 0x70 | SKBD_KEY_RELEASE: /* KP 1 */ 612 case 0x71 | SKBD_KEY_RELEASE: /* KP 2 */ 613 case 0x72 | SKBD_KEY_RELEASE: /* KP 3 */ 614 case 0x5e | SKBD_KEY_RELEASE: /* KP 0 */ 615 goto next_code; 616 default: 617 if (sc->sc_composed_char > 0) { 618 sc->sc_flags &= ~KPCOMPOSE; 619 sc->sc_composed_char = 0; 620 return (ERRKEY); 621 } 622 } 623 } 624 625 key = genkbd_keyaction(kbd, key, release, 626 &sc->sc_state, &sc->sc_accents); 627 if (key != NOKEY || repeated) 628 return (key); 629 } 630 } 631 return (0); 632} 633 634static int 635sunkbd_check_char(keyboard_t *kbd) 636{ 637 struct sunkbd_softc *sc; 638 639 if (!KBD_IS_ACTIVE(kbd)) 640 return (FALSE); 641 642 sc = (struct sunkbd_softc *)kbd; 643 if (!(sc->sc_flags & KPCOMPOSE) && (sc->sc_composed_char > 0)) 644 return (TRUE); 645 646 return (sunkbd_check(kbd)); 647} 648 649static int 650sunkbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t data) 651{ 652 struct sunkbd_softc *sc; 653 int c, error; 654#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) 655 int ival; 656#endif 657 658 sc = (struct sunkbd_softc *)kbd; 659 error = 0; 660 switch (cmd) { 661 case KDGKBMODE: 662 *(int *)data = sc->sc_mode; 663 break; 664#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) 665 case _IO('K', 7): 666 ival = IOCPARM_IVAL(data); 667 data = (caddr_t)&ival; 668 /* FALLTHROUGH */ 669#endif 670 case KDSKBMODE: 671 switch (*(int *)data) { 672 case K_XLATE: 673 if (sc->sc_mode != K_XLATE) { 674 /* make lock key state and LED state match */ 675 sc->sc_state &= ~LOCK_MASK; 676 sc->sc_state |= KBD_LED_VAL(kbd); 677 } 678 /* FALLTHROUGH */ 679 case K_RAW: 680 case K_CODE: 681 if (sc->sc_mode != *(int *)data) { 682 sunkbd_clear_state(kbd); 683 sc->sc_mode = *(int *)data; 684 } 685 break; 686 default: 687 error = EINVAL; 688 break; 689 } 690 break; 691 case KDGETLED: 692 *(int *)data = KBD_LED_VAL(kbd); 693 break; 694#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) 695 case _IO('K', 66): 696 ival = IOCPARM_IVAL(data); 697 data = (caddr_t)&ival; 698 /* FALLTHROUGH */ 699#endif 700 case KDSETLED: 701 if (*(int *)data & ~LOCK_MASK) { 702 error = EINVAL; 703 break; 704 } 705 if (sc->sc_sysdev == NULL) 706 break; 707 c = 0; 708 if (*(int *)data & CLKED) 709 c |= SKBD_LED_CAPSLOCK; 710 if (*(int *)data & NLKED) 711 c |= SKBD_LED_NUMLOCK; 712 if (*(int *)data & SLKED) 713 c |= SKBD_LED_SCROLLLOCK; 714 uart_lock(sc->sc_sysdev->hwmtx);
|
717 uart_unlock(sc->sc_sysdev->hwmtx); 718 KBD_LED_VAL(kbd) = *(int *)data; 719 break; 720 case KDGKBSTATE: 721 *(int *)data = sc->sc_state & LOCK_MASK; 722 break; 723#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) 724 case _IO('K', 20): 725 ival = IOCPARM_IVAL(data); 726 data = (caddr_t)&ival; 727 /* FALLTHROUGH */ 728#endif 729 case KDSKBSTATE: 730 if (*(int *)data & ~LOCK_MASK) { 731 error = EINVAL; 732 break; 733 } 734 sc->sc_state &= ~LOCK_MASK; 735 sc->sc_state |= *(int *)data; 736 /* set LEDs and quit */ 737 return (sunkbd_ioctl(kbd, KDSETLED, data)); 738 case KDSETREPEAT: 739 case KDSETRAD: 740 break; 741 case PIO_KEYMAP: 742 case PIO_KEYMAPENT: 743 case PIO_DEADKEYMAP: 744 default: 745 return (genkbd_commonioctl(kbd, cmd, data)); 746 } 747 return (error); 748} 749 750static int 751sunkbd_lock(keyboard_t *kbd, int lock) 752{ 753 754 TODO; 755 return (0); 756} 757 758static void 759sunkbd_clear_state(keyboard_t *kbd) 760{ 761 struct sunkbd_softc *sc; 762 763 sc = (struct sunkbd_softc *)kbd; 764 sc->sc_repeat_key = -1; 765 sc->sc_accents = 0; 766 sc->sc_composed_char = 0; 767 sc->sc_flags = 0; 768 sc->sc_polling = 0; 769 sc->sc_repeating = 0; 770 sc->sc_state &= LOCK_MASK; /* Preserve locking key state. */ 771 772#if defined(SUNKBD_EMULATE_ATKBD) 773 sc->sc_buffered_char[0] = 0; 774 sc->sc_buffered_char[1] = 0; 775#endif 776} 777 778static int 779sunkbd_get_state(keyboard_t *kbd, void *buf, size_t len) 780{ 781 782 TODO; 783 return (0); 784} 785 786static int 787sunkbd_set_state(keyboard_t *kbd, void *buf, size_t len) 788{ 789 790 TODO; 791 return (0); 792} 793 794static int 795sunkbd_poll_mode(keyboard_t *kbd, int on) 796{ 797 struct sunkbd_softc *sc; 798 799 sc = (struct sunkbd_softc *)kbd; 800 if (on) 801 sc->sc_polling++; 802 else 803 sc->sc_polling--; 804 return (0); 805} 806 807static void 808sunkbd_diag(keyboard_t *kbd, int level) 809{ 810 811 TODO; 812} 813 814static void 815sunkbd_repeat(void *v) 816{ 817 struct sunkbd_softc *sc = v; 818 819 if (KBD_IS_ACTIVE(&sc->sc_kbd) && KBD_IS_BUSY(&sc->sc_kbd)) { 820 if (sc->sc_repeat_key != -1) { 821 sc->sc_repeating = 1; 822 sc->sc_kbd.kb_callback.kc_func(&sc->sc_kbd, 823 KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg); 824 } 825 } 826} 827 828#if defined(SUNKBD_EMULATE_ATKBD) 829static int 830keycode2scancode(int keycode, int shift, int up) 831{ 832 static const int scan[] = { 833 /* KP enter, right ctrl, KP divide */ 834 0x1c , 0x1d , 0x35 , 835 /* print screen */ 836 0x37 | SCAN_PREFIX_SHIFT, 837 /* right alt, home, up, page up, left, right, end */ 838 0x38, 0x47, 0x48, 0x49, 0x4b, 0x4d, 0x4f, 839 /* down, page down, insert, delete */ 840 0x50, 0x51, 0x52, 0x53, 841 /* pause/break (see also below) */ 842 0x46, 843 /* 844 * MS: left window, right window, menu 845 * also Sun: left meta, right meta, compose 846 */ 847 0x5b, 0x5c, 0x5d, 848 /* Sun type 6 USB */ 849 /* help, stop, again, props, undo, front, copy */ 850 0x68, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 851 /* open, paste, find, cut, audiomute, audiolower, audioraise */ 852 0x64, 0x65, 0x66, 0x67, 0x25, 0x1f, 0x1e, 853 /* power */ 854 0x20 855 }; 856 int scancode; 857 858 scancode = keycode; 859 if ((keycode >= 89) && (keycode < 89 + sizeof(scan) / sizeof(scan[0]))) 860 scancode = scan[keycode - 89] | SCAN_PREFIX_E0; 861 /* pause/break */ 862 if ((keycode == 104) && !(shift & CTLS)) 863 scancode = 0x45 | SCAN_PREFIX_E1 | SCAN_PREFIX_CTL; 864 if (shift & SHIFTS) 865 scancode &= ~SCAN_PREFIX_SHIFT; 866 return (scancode | (up ? SCAN_RELEASE : SCAN_PRESS)); 867} 868#endif
|