1 /*- 2 * Copyright (C) 2008 Nathan Whitehorn 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 ``AS IS'' AND ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 18 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 20 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 21 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 22 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 23 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * 25 * $FreeBSD$ 26 */ 27 28 #include <sys/cdefs.h> 29 #include <sys/param.h> 30 #include <sys/systm.h> 31 #include <sys/module.h> 32 #include <sys/bus.h> 33 #include <sys/conf.h> 34 #include <sys/kbio.h> 35 #include <sys/condvar.h> 36 #include <sys/callout.h> 37 #include <sys/kernel.h> 38 39 #include <machine/bus.h> 40 41 #include "opt_kbd.h" 42 #include <dev/kbd/kbdreg.h> 43 #include <dev/kbd/kbdtables.h> 44 45 #include <vm/vm.h> 46 #include <vm/pmap.h> 47 48 #include "adb.h" 49 50 #define KBD_DRIVER_NAME "akbd" 51 52 #define AKBD_EMULATE_ATKBD 1 53 54 static int adb_kbd_probe(device_t dev); 55 static int adb_kbd_attach(device_t dev); 56 static int adb_kbd_detach(device_t dev); 57 static void akbd_repeat(void *xsc); 58 59 static u_int adb_kbd_receive_packet(device_t dev, u_char status, 60 u_char command, u_char reg, int len, u_char *data); 61 62 struct adb_kbd_softc { 63 keyboard_t sc_kbd; 64 65 device_t sc_dev; 66 struct mtx sc_mutex; 67 struct cv sc_cv; 68 69 int sc_mode; 70 int sc_state; 71 72 int have_led_control; 73 74 uint8_t buffer[8]; 75 volatile int buffers; 76 77 struct callout sc_repeater; 78 int sc_repeatstart; 79 int sc_repeatcontinue; 80 uint8_t last_press; 81 }; 82 83 static device_method_t adb_kbd_methods[] = { 84 /* Device interface */ 85 DEVMETHOD(device_probe, adb_kbd_probe), 86 DEVMETHOD(device_attach, adb_kbd_attach), 87 DEVMETHOD(device_detach, adb_kbd_detach), 88 DEVMETHOD(device_shutdown, bus_generic_shutdown), 89 DEVMETHOD(device_suspend, bus_generic_suspend), 90 DEVMETHOD(device_resume, bus_generic_resume), 91 92 /* ADB interface */ 93 DEVMETHOD(adb_receive_packet, adb_kbd_receive_packet), 94 95 { 0, 0 } 96 }; 97 98 static driver_t adb_kbd_driver = { 99 "akbd", 100 adb_kbd_methods, 101 sizeof(struct adb_kbd_softc), 102 }; 103 104 static devclass_t adb_kbd_devclass; 105 106 DRIVER_MODULE(akbd, adb, adb_kbd_driver, adb_kbd_devclass, 0, 0); 107 108 static const uint8_t adb_to_at_scancode_map[128] = { 30, 31, 32, 33, 35, 34, 109 44, 45, 46, 47, 0, 48, 16, 17, 18, 19, 21, 20, 2, 3, 4, 5, 7, 6, 13, 110 10, 8, 12, 9, 11, 27, 24, 22, 26, 23, 25, 28, 38, 36, 40, 37, 39, 43, 111 51, 53, 49, 50, 52, 15, 57, 41, 14, 0, 1, 29, 0, 42, 58, 56, 97, 98, 112 100, 95, 0, 0, 83, 0, 55, 0, 78, 0, 69, 0, 0, 0, 91, 89, 0, 74, 13, 0, 113 0, 82, 79, 80, 81, 75, 76, 77, 71, 0, 72, 73, 0, 0, 0, 63, 64, 65, 61, 114 66, 67, 0, 87, 0, 105, 0, 70, 0, 68, 0, 88, 0, 107, 102, 94, 96, 103, 115 62, 99, 60, 101, 59, 54, 93, 90, 0, 0 }; 116 117 /* keyboard driver declaration */ 118 static int akbd_configure(int flags); 119 static kbd_probe_t akbd_probe; 120 static kbd_init_t akbd_init; 121 static kbd_term_t akbd_term; 122 static kbd_intr_t akbd_interrupt; 123 static kbd_test_if_t akbd_test_if; 124 static kbd_enable_t akbd_enable; 125 static kbd_disable_t akbd_disable; 126 static kbd_read_t akbd_read; 127 static kbd_check_t akbd_check; 128 static kbd_read_char_t akbd_read_char; 129 static kbd_check_char_t akbd_check_char; 130 static kbd_ioctl_t akbd_ioctl; 131 static kbd_lock_t akbd_lock; 132 static kbd_clear_state_t akbd_clear_state; 133 static kbd_get_state_t akbd_get_state; 134 static kbd_set_state_t akbd_set_state; 135 static kbd_poll_mode_t akbd_poll; 136 137 keyboard_switch_t akbdsw = { 138 akbd_probe, 139 akbd_init, 140 akbd_term, 141 akbd_interrupt, 142 akbd_test_if, 143 akbd_enable, 144 akbd_disable, 145 akbd_read, 146 akbd_check, 147 akbd_read_char, 148 akbd_check_char, 149 akbd_ioctl, 150 akbd_lock, 151 akbd_clear_state, 152 akbd_get_state, 153 akbd_set_state, 154 genkbd_get_fkeystr, 155 akbd_poll, 156 genkbd_diag, 157 }; 158 159 KEYBOARD_DRIVER(akbd, akbdsw, akbd_configure); 160 161 static int 162 adb_kbd_probe(device_t dev) 163 { 164 uint8_t type; 165 166 type = adb_get_device_type(dev); 167 168 if (type != ADB_DEVICE_KEYBOARD) 169 return (ENXIO); 170 171 switch(adb_get_device_handler(dev)) { 172 case 1: 173 device_set_desc(dev,"Apple Standard Keyboard"); 174 break; 175 case 2: 176 device_set_desc(dev,"Apple Extended Keyboard"); 177 break; 178 case 4: 179 device_set_desc(dev,"Apple ISO Keyboard"); 180 break; 181 case 5: 182 device_set_desc(dev,"Apple Extended ISO Keyboard"); 183 break; 184 case 8: 185 device_set_desc(dev,"Apple Keyboard II"); 186 break; 187 case 9: 188 device_set_desc(dev,"Apple ISO Keyboard II"); 189 break; 190 case 12: 191 device_set_desc(dev,"PowerBook Keyboard"); 192 break; 193 case 13: 194 device_set_desc(dev,"PowerBook ISO Keyboard"); 195 break; 196 case 24: 197 device_set_desc(dev,"PowerBook Extended Keyboard"); 198 break; 199 case 27: 200 device_set_desc(dev,"Apple Design Keyboard"); 201 break; 202 case 195: 203 device_set_desc(dev,"PowerBook G3 Keyboard"); 204 break; 205 case 196: 206 device_set_desc(dev,"iBook Keyboard"); 207 break; 208 default: 209 device_set_desc(dev,"ADB Keyboard"); 210 break; 211 } 212 213 return (0); 214 } 215 216 static int 217 ms_to_ticks(int ms) 218 { 219 if (hz > 1000) 220 return ms*(hz/1000); 221 222 return ms/(1000/hz); 223 } 224 225 static int 226 adb_kbd_attach(device_t dev) 227 { 228 struct adb_kbd_softc *sc; 229 keyboard_switch_t *sw; 230 231 sw = kbd_get_switch(KBD_DRIVER_NAME); 232 if (sw == NULL) { 233 return ENXIO; 234 } 235 236 sc = device_get_softc(dev); 237 sc->sc_dev = dev; 238 sc->sc_mode = K_RAW; 239 sc->sc_state = 0; 240 sc->have_led_control = 0; 241 sc->buffers = 0; 242 243 /* Try stepping forward to the extended keyboard protocol */ 244 adb_set_device_handler(dev,3); 245 246 mtx_init(&sc->sc_mutex,KBD_DRIVER_NAME,MTX_DEF,0); 247 cv_init(&sc->sc_cv,KBD_DRIVER_NAME); 248 callout_init(&sc->sc_repeater, 0); 249 250 #ifdef AKBD_EMULATE_ATKBD 251 kbd_init_struct(&sc->sc_kbd, KBD_DRIVER_NAME, KB_101, 0, 0, 0, 0); 252 kbd_set_maps(&sc->sc_kbd, &key_map, &accent_map, fkey_tab, 253 sizeof(fkey_tab) / sizeof(fkey_tab[0])); 254 #else 255 #error ADB raw mode not implemented 256 #endif 257 258 KBD_FOUND_DEVICE(&sc->sc_kbd); 259 KBD_PROBE_DONE(&sc->sc_kbd); 260 KBD_INIT_DONE(&sc->sc_kbd); 261 KBD_CONFIG_DONE(&sc->sc_kbd); 262 263 (*sw->enable)(&sc->sc_kbd); 264 265 kbd_register(&sc->sc_kbd); 266 267 #ifdef KBD_INSTALL_CDEV 268 if (kbd_attach(&sc->sc_kbd)) { 269 adb_kbd_detach(dev); 270 return ENXIO; 271 } 272 #endif 273 274 adb_set_autopoll(dev,1); 275 276 /* Check (asynchronously) if we can read out the LED state from 277 this keyboard by reading the key state register */ 278 adb_send_packet(dev,ADB_COMMAND_TALK,2,0,NULL); 279 280 return (0); 281 } 282 283 static int 284 adb_kbd_detach(device_t dev) 285 { 286 struct adb_kbd_softc *sc; 287 keyboard_t *kbd; 288 289 sc = device_get_softc(dev); 290 291 adb_set_autopoll(dev,0); 292 callout_stop(&sc->sc_repeater); 293 294 mtx_lock(&sc->sc_mutex); 295 296 kbd = kbd_get_keyboard(kbd_find_keyboard(KBD_DRIVER_NAME, 297 device_get_unit(dev))); 298 299 kbdd_disable(kbd); 300 301 #ifdef KBD_INSTALL_CDEV 302 kbd_detach(kbd); 303 #endif 304 305 kbdd_term(kbd); 306 307 mtx_unlock(&sc->sc_mutex); 308 309 mtx_destroy(&sc->sc_mutex); 310 cv_destroy(&sc->sc_cv); 311 312 return (0); 313 } 314 315 static u_int 316 adb_kbd_receive_packet(device_t dev, u_char status, 317 u_char command, u_char reg, int len, u_char *data) 318 { 319 struct adb_kbd_softc *sc; 320 321 sc = device_get_softc(dev); 322 323 if (command != ADB_COMMAND_TALK) 324 return 0; 325 326 if (reg == 2 && len == 2) { 327 sc->have_led_control = 1; 328 return 0; 329 } 330 331 if (reg != 0 || len != 2) 332 return (0); 333 334 mtx_lock(&sc->sc_mutex); 335 if ((data[0] & 0x7f) == 57 && sc->buffers < 7) { 336 /* Fake the down/up cycle for caps lock */ 337 sc->buffer[sc->buffers++] = data[0] & 0x7f; 338 sc->buffer[sc->buffers++] = (data[0] & 0x7f) | (1 << 7); 339 } else { 340 sc->buffer[sc->buffers++] = data[0]; 341 } 342 343 if (sc->buffer[sc->buffers-1] < 0xff) 344 sc->last_press = sc->buffer[sc->buffers-1]; 345 346 if ((data[1] & 0x7f) == 57 && sc->buffers < 7) { 347 /* Fake the down/up cycle for caps lock */ 348 sc->buffer[sc->buffers++] = data[1] & 0x7f; 349 sc->buffer[sc->buffers++] = (data[1] & 0x7f) | (1 << 7); 350 } else { 351 sc->buffer[sc->buffers++] = data[1]; 352 } 353 354 if (sc->buffer[sc->buffers-1] < 0xff) 355 sc->last_press = sc->buffer[sc->buffers-1]; 356 357 /* Stop any existing key repeating */ 358 callout_stop(&sc->sc_repeater); 359 360 /* Schedule a repeat callback on keydown */ 361 if (!(sc->last_press & (1 << 7))) { 362 callout_reset(&sc->sc_repeater, 363 ms_to_ticks(sc->sc_kbd.kb_delay1), akbd_repeat, sc); 364 } 365 mtx_unlock(&sc->sc_mutex); 366 367 cv_broadcast(&sc->sc_cv); 368 369 if (KBD_IS_ACTIVE(&sc->sc_kbd) && KBD_IS_BUSY(&sc->sc_kbd)) { 370 sc->sc_kbd.kb_callback.kc_func(&sc->sc_kbd, 371 KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg); 372 } 373 374 return (0); 375 } 376 377 static void 378 akbd_repeat(void *xsc) { 379 struct adb_kbd_softc *sc = xsc; 380 int notify_kbd = 0; 381 382 /* Fake an up/down key repeat so long as we have the 383 free buffers */ 384 mtx_lock(&sc->sc_mutex); 385 if (sc->buffers < 7) { 386 sc->buffer[sc->buffers++] = sc->last_press | (1 << 7); 387 sc->buffer[sc->buffers++] = sc->last_press; 388 389 notify_kbd = 1; 390 } 391 mtx_unlock(&sc->sc_mutex); 392 393 if (notify_kbd && KBD_IS_ACTIVE(&sc->sc_kbd) 394 && KBD_IS_BUSY(&sc->sc_kbd)) { 395 sc->sc_kbd.kb_callback.kc_func(&sc->sc_kbd, 396 KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg); 397 } 398 399 /* Reschedule the callout */ 400 callout_reset(&sc->sc_repeater, ms_to_ticks(sc->sc_kbd.kb_delay2), 401 akbd_repeat, sc); 402 } 403 404 static int 405 akbd_configure(int flags) 406 { 407 return 0; 408 } 409 410 static int 411 akbd_probe(int unit, void *arg, int flags) 412 { 413 return 0; 414 } 415 416 static int 417 akbd_init(int unit, keyboard_t **kbdp, void *arg, int flags) 418 { 419 return 0; 420 } 421 422 static int 423 akbd_term(keyboard_t *kbd) 424 { 425 return 0; 426 } 427 428 static int 429 akbd_interrupt(keyboard_t *kbd, void *arg) 430 { 431 return 0; 432 } 433 434 static int 435 akbd_test_if(keyboard_t *kbd) 436 { 437 return 0; 438 } 439 440 static int 441 akbd_enable(keyboard_t *kbd) 442 { 443 KBD_ACTIVATE(kbd); 444 return (0); 445 } 446 447 static int 448 akbd_disable(keyboard_t *kbd) 449 { 450 struct adb_kbd_softc *sc; 451 sc = (struct adb_kbd_softc *)(kbd); 452 453 callout_stop(&sc->sc_repeater); 454 KBD_DEACTIVATE(kbd); 455 return (0); 456 } 457 458 static int 459 akbd_read(keyboard_t *kbd, int wait) 460 { 461 return (0); 462 } 463 464 static int 465 akbd_check(keyboard_t *kbd) 466 { 467 struct adb_kbd_softc *sc; 468 469 if (!KBD_IS_ACTIVE(kbd)) 470 return (FALSE); 471 472 sc = (struct adb_kbd_softc *)(kbd); 473 474 mtx_lock(&sc->sc_mutex); 475 if (sc->buffers > 0) { 476 mtx_unlock(&sc->sc_mutex); 477 return (TRUE); 478 } 479 mtx_unlock(&sc->sc_mutex); 480 481 return (FALSE); 482 } 483 484 static u_int 485 akbd_read_char(keyboard_t *kbd, int wait) 486 { 487 struct adb_kbd_softc *sc; 488 uint8_t adb_code, final_scancode; 489 int i; 490 491 sc = (struct adb_kbd_softc *)(kbd); 492 493 mtx_lock(&sc->sc_mutex); 494 if (!sc->buffers && wait) 495 cv_wait(&sc->sc_cv,&sc->sc_mutex); 496 497 if (!sc->buffers) { 498 mtx_unlock(&sc->sc_mutex); 499 return (0); 500 } 501 502 adb_code = sc->buffer[0]; 503 504 for (i = 1; i < sc->buffers; i++) 505 sc->buffer[i-1] = sc->buffer[i]; 506 507 sc->buffers--; 508 mtx_unlock(&sc->sc_mutex); 509 510 #ifdef AKBD_EMULATE_ATKBD 511 final_scancode = adb_to_at_scancode_map[adb_code & 0x7f]; 512 final_scancode |= adb_code & 0x80; 513 #else 514 final_scancode = adb_code; 515 #endif 516 517 return (final_scancode); 518 } 519 520 static int 521 akbd_check_char(keyboard_t *kbd) 522 { 523 if (!KBD_IS_ACTIVE(kbd)) 524 return (FALSE); 525 526 return (akbd_check(kbd)); 527 } 528 529 static int 530 set_typematic(keyboard_t *kbd, int code) 531 { 532 /* These numbers are in microseconds, so convert to ticks */ 533 534 static int delays[] = { 250, 500, 750, 1000 }; 535 static int rates[] = { 34, 38, 42, 46, 50, 55, 59, 63, 536 68, 76, 84, 92, 100, 110, 118, 126, 537 136, 152, 168, 184, 200, 220, 236, 252, 538 272, 304, 336, 368, 400, 440, 472, 504 }; 539 540 if (code & ~0x7f) 541 return EINVAL; 542 kbd->kb_delay1 = delays[(code >> 5) & 3]; 543 kbd->kb_delay2 = rates[code & 0x1f]; 544 return 0; 545 } 546 547 static int akbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t data) 548 { 549 struct adb_kbd_softc *sc; 550 uint16_t r2; 551 int error; 552 553 sc = (struct adb_kbd_softc *)(kbd); 554 error = 0; 555 556 switch (cmd) { 557 case KDGKBMODE: 558 *(int *)data = sc->sc_mode; 559 break; 560 case KDSKBMODE: 561 switch (*(int *)data) { 562 case K_XLATE: 563 if (sc->sc_mode != K_XLATE) { 564 /* make lock key state and LED state match */ 565 sc->sc_state &= ~LOCK_MASK; 566 sc->sc_state |= KBD_LED_VAL(kbd); 567 } 568 /* FALLTHROUGH */ 569 case K_RAW: 570 case K_CODE: 571 if (sc->sc_mode != *(int *)data) 572 sc->sc_mode = *(int *)data; 573 break; 574 default: 575 error = EINVAL; 576 break; 577 } 578 579 break; 580 581 case KDGETLED: 582 *(int *)data = KBD_LED_VAL(kbd); 583 break; 584 585 case KDSKBSTATE: 586 if (*(int *)data & ~LOCK_MASK) { 587 error = EINVAL; 588 break; 589 } 590 sc->sc_state &= ~LOCK_MASK; 591 sc->sc_state |= *(int *)data; 592 593 /* FALLTHROUGH */ 594 595 case KDSETLED: 596 KBD_LED_VAL(kbd) = *(int *)data; 597 598 if (!sc->have_led_control) 599 break; 600 601 r2 = (~0 & 0x04) | 3; 602 603 if (*(int *)data & NLKED) 604 r2 &= ~1; 605 if (*(int *)data & CLKED) 606 r2 &= ~2; 607 if (*(int *)data & SLKED) 608 r2 &= ~4; 609 610 adb_send_packet(sc->sc_dev,ADB_COMMAND_LISTEN,2, 611 sizeof(uint16_t),(u_char *)&r2); 612 613 break; 614 615 case KDGKBSTATE: 616 *(int *)data = sc->sc_state & LOCK_MASK; 617 break; 618 619 case KDSETREPEAT: 620 if (!KBD_HAS_DEVICE(kbd)) 621 return 0; 622 if (((int *)data)[1] < 0) 623 return EINVAL; 624 if (((int *)data)[0] < 0) 625 return EINVAL; 626 else if (((int *)data)[0] == 0) /* fastest possible value */ 627 kbd->kb_delay1 = 200; 628 else 629 kbd->kb_delay1 = ((int *)data)[0]; 630 kbd->kb_delay2 = ((int *)data)[1]; 631 632 break; 633 634 case KDSETRAD: 635 error = set_typematic(kbd, *(int *)data); 636 break; 637 638 case PIO_KEYMAP: 639 case PIO_KEYMAPENT: 640 case PIO_DEADKEYMAP: 641 default: 642 return (genkbd_commonioctl(kbd, cmd, data)); 643 } 644 645 return (error); 646 } 647 648 static int akbd_lock(keyboard_t *kbd, int lock) 649 { 650 return (0); 651 } 652 653 static void akbd_clear_state(keyboard_t *kbd) 654 { 655 } 656 657 static int akbd_get_state(keyboard_t *kbd, void *buf, size_t len) 658 { 659 return (0); 660 } 661 662 static int akbd_set_state(keyboard_t *kbd, void *buf, size_t len) 663 { 664 return (0); 665 } 666 667 static int akbd_poll(keyboard_t *kbd, int on) 668 { 669 return (0); 670 } 671 672 static int 673 akbd_modevent(module_t mod, int type, void *data) 674 { 675 switch (type) { 676 case MOD_LOAD: 677 kbd_add_driver(&akbd_kbd_driver); 678 break; 679 680 case MOD_UNLOAD: 681 kbd_delete_driver(&akbd_kbd_driver); 682 break; 683 684 default: 685 return (EOPNOTSUPP); 686 } 687 688 return (0); 689 } 690 691 DEV_MODULE(akbd, akbd_modevent, NULL); 692 693