1b4dbc599SNathan Whitehorn /*- 2b4dbc599SNathan Whitehorn * Copyright (C) 2008 Nathan Whitehorn 3b4dbc599SNathan Whitehorn * All rights reserved. 4b4dbc599SNathan Whitehorn * 5b4dbc599SNathan Whitehorn * Redistribution and use in source and binary forms, with or without 6b4dbc599SNathan Whitehorn * modification, are permitted provided that the following conditions 7b4dbc599SNathan Whitehorn * are met: 8b4dbc599SNathan Whitehorn * 1. Redistributions of source code must retain the above copyright 9b4dbc599SNathan Whitehorn * notice, this list of conditions and the following disclaimer. 10b4dbc599SNathan Whitehorn * 2. Redistributions in binary form must reproduce the above copyright 11b4dbc599SNathan Whitehorn * notice, this list of conditions and the following disclaimer in the 12b4dbc599SNathan Whitehorn * documentation and/or other materials provided with the distribution. 13b4dbc599SNathan Whitehorn * 14b4dbc599SNathan Whitehorn * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15b4dbc599SNathan Whitehorn * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16b4dbc599SNathan Whitehorn * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17b4dbc599SNathan Whitehorn * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 18b4dbc599SNathan Whitehorn * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19b4dbc599SNathan Whitehorn * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 20b4dbc599SNathan Whitehorn * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 21b4dbc599SNathan Whitehorn * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 22b4dbc599SNathan Whitehorn * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 23b4dbc599SNathan Whitehorn * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24b4dbc599SNathan Whitehorn * 25b4dbc599SNathan Whitehorn * $FreeBSD$ 26b4dbc599SNathan Whitehorn */ 27b4dbc599SNathan Whitehorn 28b4dbc599SNathan Whitehorn #include <sys/cdefs.h> 29b4dbc599SNathan Whitehorn #include <sys/param.h> 30b4dbc599SNathan Whitehorn #include <sys/systm.h> 31b4dbc599SNathan Whitehorn #include <sys/module.h> 32b4dbc599SNathan Whitehorn #include <sys/bus.h> 33b4dbc599SNathan Whitehorn #include <sys/conf.h> 34b4dbc599SNathan Whitehorn #include <sys/kbio.h> 35b4dbc599SNathan Whitehorn #include <sys/condvar.h> 36b4dbc599SNathan Whitehorn #include <sys/callout.h> 37b4dbc599SNathan Whitehorn #include <sys/kernel.h> 38b4dbc599SNathan Whitehorn 39b4dbc599SNathan Whitehorn #include <machine/bus.h> 40b4dbc599SNathan Whitehorn 41b4dbc599SNathan Whitehorn #include "opt_kbd.h" 42b4dbc599SNathan Whitehorn #include <dev/kbd/kbdreg.h> 43b4dbc599SNathan Whitehorn #include <dev/kbd/kbdtables.h> 44b4dbc599SNathan Whitehorn 45b4dbc599SNathan Whitehorn #include <vm/vm.h> 46b4dbc599SNathan Whitehorn #include <vm/pmap.h> 47b4dbc599SNathan Whitehorn 48b4dbc599SNathan Whitehorn #include "adb.h" 49b4dbc599SNathan Whitehorn 50b4dbc599SNathan Whitehorn #define KBD_DRIVER_NAME "akbd" 51b4dbc599SNathan Whitehorn 52b4dbc599SNathan Whitehorn #define AKBD_EMULATE_ATKBD 1 53b4dbc599SNathan Whitehorn 54b4dbc599SNathan Whitehorn static int adb_kbd_probe(device_t dev); 55b4dbc599SNathan Whitehorn static int adb_kbd_attach(device_t dev); 56b4dbc599SNathan Whitehorn static int adb_kbd_detach(device_t dev); 57b4dbc599SNathan Whitehorn static void akbd_repeat(void *xsc); 58b4dbc599SNathan Whitehorn 59b4dbc599SNathan Whitehorn static u_int adb_kbd_receive_packet(device_t dev, u_char status, 60b4dbc599SNathan Whitehorn u_char command, u_char reg, int len, u_char *data); 61b4dbc599SNathan Whitehorn 62b4dbc599SNathan Whitehorn struct adb_kbd_softc { 63b4dbc599SNathan Whitehorn keyboard_t sc_kbd; 64b4dbc599SNathan Whitehorn 65b4dbc599SNathan Whitehorn device_t sc_dev; 66b4dbc599SNathan Whitehorn struct mtx sc_mutex; 67b4dbc599SNathan Whitehorn struct cv sc_cv; 68b4dbc599SNathan Whitehorn 69b4dbc599SNathan Whitehorn int sc_mode; 70b4dbc599SNathan Whitehorn int sc_state; 71b4dbc599SNathan Whitehorn 72b4dbc599SNathan Whitehorn int have_led_control; 73b4dbc599SNathan Whitehorn 74b4dbc599SNathan Whitehorn uint8_t buffer[8]; 754fb52093SNathan Whitehorn #ifdef AKBD_EMULATE_ATKBD 764fb52093SNathan Whitehorn uint8_t at_buffered_char[2]; 774fb52093SNathan Whitehorn #endif 78b4dbc599SNathan Whitehorn volatile int buffers; 79b4dbc599SNathan Whitehorn 80b4dbc599SNathan Whitehorn struct callout sc_repeater; 81b4dbc599SNathan Whitehorn int sc_repeatstart; 82b4dbc599SNathan Whitehorn int sc_repeatcontinue; 83b4dbc599SNathan Whitehorn uint8_t last_press; 84b4dbc599SNathan Whitehorn }; 85b4dbc599SNathan Whitehorn 86b4dbc599SNathan Whitehorn static device_method_t adb_kbd_methods[] = { 87b4dbc599SNathan Whitehorn /* Device interface */ 88b4dbc599SNathan Whitehorn DEVMETHOD(device_probe, adb_kbd_probe), 89b4dbc599SNathan Whitehorn DEVMETHOD(device_attach, adb_kbd_attach), 90b4dbc599SNathan Whitehorn DEVMETHOD(device_detach, adb_kbd_detach), 91b4dbc599SNathan Whitehorn DEVMETHOD(device_shutdown, bus_generic_shutdown), 92b4dbc599SNathan Whitehorn DEVMETHOD(device_suspend, bus_generic_suspend), 93b4dbc599SNathan Whitehorn DEVMETHOD(device_resume, bus_generic_resume), 94b4dbc599SNathan Whitehorn 95b4dbc599SNathan Whitehorn /* ADB interface */ 96b4dbc599SNathan Whitehorn DEVMETHOD(adb_receive_packet, adb_kbd_receive_packet), 97b4dbc599SNathan Whitehorn 98b4dbc599SNathan Whitehorn { 0, 0 } 99b4dbc599SNathan Whitehorn }; 100b4dbc599SNathan Whitehorn 101b4dbc599SNathan Whitehorn static driver_t adb_kbd_driver = { 102b4dbc599SNathan Whitehorn "akbd", 103b4dbc599SNathan Whitehorn adb_kbd_methods, 104b4dbc599SNathan Whitehorn sizeof(struct adb_kbd_softc), 105b4dbc599SNathan Whitehorn }; 106b4dbc599SNathan Whitehorn 107b4dbc599SNathan Whitehorn static devclass_t adb_kbd_devclass; 108b4dbc599SNathan Whitehorn 109b4dbc599SNathan Whitehorn DRIVER_MODULE(akbd, adb, adb_kbd_driver, adb_kbd_devclass, 0, 0); 110b4dbc599SNathan Whitehorn 1114fb52093SNathan Whitehorn #ifdef AKBD_EMULATE_ATKBD 1124fb52093SNathan Whitehorn 1134fb52093SNathan Whitehorn #define SCAN_PRESS 0x000 1144fb52093SNathan Whitehorn #define SCAN_RELEASE 0x080 1154fb52093SNathan Whitehorn #define SCAN_PREFIX_E0 0x100 1164fb52093SNathan Whitehorn #define SCAN_PREFIX_E1 0x200 1174fb52093SNathan Whitehorn #define SCAN_PREFIX_CTL 0x400 1184fb52093SNathan Whitehorn #define SCAN_PREFIX_SHIFT 0x800 1194fb52093SNathan Whitehorn #define SCAN_PREFIX (SCAN_PREFIX_E0 | SCAN_PREFIX_E1 | \ 1204fb52093SNathan Whitehorn SCAN_PREFIX_CTL | SCAN_PREFIX_SHIFT) 1214fb52093SNathan Whitehorn 122b4dbc599SNathan Whitehorn static const uint8_t adb_to_at_scancode_map[128] = { 30, 31, 32, 33, 35, 34, 123b4dbc599SNathan Whitehorn 44, 45, 46, 47, 0, 48, 16, 17, 18, 19, 21, 20, 2, 3, 4, 5, 7, 6, 13, 124b4dbc599SNathan Whitehorn 10, 8, 12, 9, 11, 27, 24, 22, 26, 23, 25, 28, 38, 36, 40, 37, 39, 43, 125b4dbc599SNathan Whitehorn 51, 53, 49, 50, 52, 15, 57, 41, 14, 0, 1, 29, 0, 42, 58, 56, 97, 98, 126b4dbc599SNathan Whitehorn 100, 95, 0, 0, 83, 0, 55, 0, 78, 0, 69, 0, 0, 0, 91, 89, 0, 74, 13, 0, 127b4dbc599SNathan Whitehorn 0, 82, 79, 80, 81, 75, 76, 77, 71, 0, 72, 73, 0, 0, 0, 63, 64, 65, 61, 128b4dbc599SNathan Whitehorn 66, 67, 0, 87, 0, 105, 0, 70, 0, 68, 0, 88, 0, 107, 102, 94, 96, 103, 129b4dbc599SNathan Whitehorn 62, 99, 60, 101, 59, 54, 93, 90, 0, 0 }; 130b4dbc599SNathan Whitehorn 1314fb52093SNathan Whitehorn static int 1324fb52093SNathan Whitehorn keycode2scancode(int keycode, int shift, int up) 1334fb52093SNathan Whitehorn { 1344fb52093SNathan Whitehorn static const int scan[] = { 1354fb52093SNathan Whitehorn /* KP enter, right ctrl, KP divide */ 1364fb52093SNathan Whitehorn 0x1c , 0x1d , 0x35 , 1374fb52093SNathan Whitehorn /* print screen */ 1384fb52093SNathan Whitehorn 0x37 | SCAN_PREFIX_SHIFT, 1394fb52093SNathan Whitehorn /* right alt, home, up, page up, left, right, end */ 1404fb52093SNathan Whitehorn 0x38, 0x47, 0x48, 0x49, 0x4b, 0x4d, 0x4f, 1414fb52093SNathan Whitehorn /* down, page down, insert, delete */ 1424fb52093SNathan Whitehorn 0x50, 0x51, 0x52, 0x53, 1434fb52093SNathan Whitehorn /* pause/break (see also below) */ 1444fb52093SNathan Whitehorn 0x46, 1454fb52093SNathan Whitehorn /* 1464fb52093SNathan Whitehorn * MS: left window, right window, menu 1474fb52093SNathan Whitehorn * also Sun: left meta, right meta, compose 1484fb52093SNathan Whitehorn */ 1494fb52093SNathan Whitehorn 0x5b, 0x5c, 0x5d, 1504fb52093SNathan Whitehorn /* Sun type 6 USB */ 1514fb52093SNathan Whitehorn /* help, stop, again, props, undo, front, copy */ 1524fb52093SNathan Whitehorn 0x68, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 1534fb52093SNathan Whitehorn /* open, paste, find, cut, audiomute, audiolower, audioraise */ 1544fb52093SNathan Whitehorn 0x64, 0x65, 0x66, 0x67, 0x25, 0x1f, 0x1e, 1554fb52093SNathan Whitehorn /* power */ 1564fb52093SNathan Whitehorn 0x20 1574fb52093SNathan Whitehorn }; 1584fb52093SNathan Whitehorn int scancode; 1594fb52093SNathan Whitehorn 1604fb52093SNathan Whitehorn scancode = keycode; 1614fb52093SNathan Whitehorn if ((keycode >= 89) && (keycode < 89 + sizeof(scan) / sizeof(scan[0]))) 1624fb52093SNathan Whitehorn scancode = scan[keycode - 89] | SCAN_PREFIX_E0; 1634fb52093SNathan Whitehorn /* pause/break */ 1644fb52093SNathan Whitehorn if ((keycode == 104) && !(shift & CTLS)) 1654fb52093SNathan Whitehorn scancode = 0x45 | SCAN_PREFIX_E1 | SCAN_PREFIX_CTL; 1664fb52093SNathan Whitehorn if (shift & SHIFTS) 1674fb52093SNathan Whitehorn scancode &= ~SCAN_PREFIX_SHIFT; 1684fb52093SNathan Whitehorn return (scancode | (up ? SCAN_RELEASE : SCAN_PRESS)); 1694fb52093SNathan Whitehorn } 1704fb52093SNathan Whitehorn #endif 1714fb52093SNathan Whitehorn 172b4dbc599SNathan Whitehorn /* keyboard driver declaration */ 173b4dbc599SNathan Whitehorn static int akbd_configure(int flags); 174b4dbc599SNathan Whitehorn static kbd_probe_t akbd_probe; 175b4dbc599SNathan Whitehorn static kbd_init_t akbd_init; 176b4dbc599SNathan Whitehorn static kbd_term_t akbd_term; 177b4dbc599SNathan Whitehorn static kbd_intr_t akbd_interrupt; 178b4dbc599SNathan Whitehorn static kbd_test_if_t akbd_test_if; 179b4dbc599SNathan Whitehorn static kbd_enable_t akbd_enable; 180b4dbc599SNathan Whitehorn static kbd_disable_t akbd_disable; 181b4dbc599SNathan Whitehorn static kbd_read_t akbd_read; 182b4dbc599SNathan Whitehorn static kbd_check_t akbd_check; 183b4dbc599SNathan Whitehorn static kbd_read_char_t akbd_read_char; 184b4dbc599SNathan Whitehorn static kbd_check_char_t akbd_check_char; 185b4dbc599SNathan Whitehorn static kbd_ioctl_t akbd_ioctl; 186b4dbc599SNathan Whitehorn static kbd_lock_t akbd_lock; 187b4dbc599SNathan Whitehorn static kbd_clear_state_t akbd_clear_state; 188b4dbc599SNathan Whitehorn static kbd_get_state_t akbd_get_state; 189b4dbc599SNathan Whitehorn static kbd_set_state_t akbd_set_state; 190b4dbc599SNathan Whitehorn static kbd_poll_mode_t akbd_poll; 191b4dbc599SNathan Whitehorn 192b4dbc599SNathan Whitehorn keyboard_switch_t akbdsw = { 193b4dbc599SNathan Whitehorn akbd_probe, 194b4dbc599SNathan Whitehorn akbd_init, 195b4dbc599SNathan Whitehorn akbd_term, 196b4dbc599SNathan Whitehorn akbd_interrupt, 197b4dbc599SNathan Whitehorn akbd_test_if, 198b4dbc599SNathan Whitehorn akbd_enable, 199b4dbc599SNathan Whitehorn akbd_disable, 200b4dbc599SNathan Whitehorn akbd_read, 201b4dbc599SNathan Whitehorn akbd_check, 202b4dbc599SNathan Whitehorn akbd_read_char, 203b4dbc599SNathan Whitehorn akbd_check_char, 204b4dbc599SNathan Whitehorn akbd_ioctl, 205b4dbc599SNathan Whitehorn akbd_lock, 206b4dbc599SNathan Whitehorn akbd_clear_state, 207b4dbc599SNathan Whitehorn akbd_get_state, 208b4dbc599SNathan Whitehorn akbd_set_state, 209b4dbc599SNathan Whitehorn genkbd_get_fkeystr, 210b4dbc599SNathan Whitehorn akbd_poll, 211b4dbc599SNathan Whitehorn genkbd_diag, 212b4dbc599SNathan Whitehorn }; 213b4dbc599SNathan Whitehorn 214b4dbc599SNathan Whitehorn KEYBOARD_DRIVER(akbd, akbdsw, akbd_configure); 215b4dbc599SNathan Whitehorn 216b4dbc599SNathan Whitehorn static int 217b4dbc599SNathan Whitehorn adb_kbd_probe(device_t dev) 218b4dbc599SNathan Whitehorn { 219b4dbc599SNathan Whitehorn uint8_t type; 220b4dbc599SNathan Whitehorn 221b4dbc599SNathan Whitehorn type = adb_get_device_type(dev); 222b4dbc599SNathan Whitehorn 223b4dbc599SNathan Whitehorn if (type != ADB_DEVICE_KEYBOARD) 224b4dbc599SNathan Whitehorn return (ENXIO); 225b4dbc599SNathan Whitehorn 226b4dbc599SNathan Whitehorn switch(adb_get_device_handler(dev)) { 227b4dbc599SNathan Whitehorn case 1: 228b4dbc599SNathan Whitehorn device_set_desc(dev,"Apple Standard Keyboard"); 229b4dbc599SNathan Whitehorn break; 230b4dbc599SNathan Whitehorn case 2: 231b4dbc599SNathan Whitehorn device_set_desc(dev,"Apple Extended Keyboard"); 232b4dbc599SNathan Whitehorn break; 233b4dbc599SNathan Whitehorn case 4: 234b4dbc599SNathan Whitehorn device_set_desc(dev,"Apple ISO Keyboard"); 235b4dbc599SNathan Whitehorn break; 236b4dbc599SNathan Whitehorn case 5: 237b4dbc599SNathan Whitehorn device_set_desc(dev,"Apple Extended ISO Keyboard"); 238b4dbc599SNathan Whitehorn break; 239b4dbc599SNathan Whitehorn case 8: 240b4dbc599SNathan Whitehorn device_set_desc(dev,"Apple Keyboard II"); 241b4dbc599SNathan Whitehorn break; 242b4dbc599SNathan Whitehorn case 9: 243b4dbc599SNathan Whitehorn device_set_desc(dev,"Apple ISO Keyboard II"); 244b4dbc599SNathan Whitehorn break; 245b4dbc599SNathan Whitehorn case 12: 246b4dbc599SNathan Whitehorn device_set_desc(dev,"PowerBook Keyboard"); 247b4dbc599SNathan Whitehorn break; 248b4dbc599SNathan Whitehorn case 13: 249b4dbc599SNathan Whitehorn device_set_desc(dev,"PowerBook ISO Keyboard"); 250b4dbc599SNathan Whitehorn break; 251b4dbc599SNathan Whitehorn case 24: 252b4dbc599SNathan Whitehorn device_set_desc(dev,"PowerBook Extended Keyboard"); 253b4dbc599SNathan Whitehorn break; 254b4dbc599SNathan Whitehorn case 27: 255b4dbc599SNathan Whitehorn device_set_desc(dev,"Apple Design Keyboard"); 256b4dbc599SNathan Whitehorn break; 257b4dbc599SNathan Whitehorn case 195: 258b4dbc599SNathan Whitehorn device_set_desc(dev,"PowerBook G3 Keyboard"); 259b4dbc599SNathan Whitehorn break; 260b4dbc599SNathan Whitehorn case 196: 261b4dbc599SNathan Whitehorn device_set_desc(dev,"iBook Keyboard"); 262b4dbc599SNathan Whitehorn break; 263b4dbc599SNathan Whitehorn default: 264b4dbc599SNathan Whitehorn device_set_desc(dev,"ADB Keyboard"); 265b4dbc599SNathan Whitehorn break; 266b4dbc599SNathan Whitehorn } 267b4dbc599SNathan Whitehorn 268b4dbc599SNathan Whitehorn return (0); 269b4dbc599SNathan Whitehorn } 270b4dbc599SNathan Whitehorn 271b4dbc599SNathan Whitehorn static int 272b4dbc599SNathan Whitehorn ms_to_ticks(int ms) 273b4dbc599SNathan Whitehorn { 274b4dbc599SNathan Whitehorn if (hz > 1000) 275b4dbc599SNathan Whitehorn return ms*(hz/1000); 276b4dbc599SNathan Whitehorn 277b4dbc599SNathan Whitehorn return ms/(1000/hz); 278b4dbc599SNathan Whitehorn } 279b4dbc599SNathan Whitehorn 280b4dbc599SNathan Whitehorn static int 281b4dbc599SNathan Whitehorn adb_kbd_attach(device_t dev) 282b4dbc599SNathan Whitehorn { 283b4dbc599SNathan Whitehorn struct adb_kbd_softc *sc; 284b4dbc599SNathan Whitehorn keyboard_switch_t *sw; 285b4dbc599SNathan Whitehorn 286b4dbc599SNathan Whitehorn sw = kbd_get_switch(KBD_DRIVER_NAME); 287b4dbc599SNathan Whitehorn if (sw == NULL) { 288b4dbc599SNathan Whitehorn return ENXIO; 289b4dbc599SNathan Whitehorn } 290b4dbc599SNathan Whitehorn 291b4dbc599SNathan Whitehorn sc = device_get_softc(dev); 292b4dbc599SNathan Whitehorn sc->sc_dev = dev; 293b4dbc599SNathan Whitehorn sc->sc_mode = K_RAW; 294b4dbc599SNathan Whitehorn sc->sc_state = 0; 295b4dbc599SNathan Whitehorn sc->have_led_control = 0; 296b4dbc599SNathan Whitehorn sc->buffers = 0; 297b4dbc599SNathan Whitehorn 298b4dbc599SNathan Whitehorn /* Try stepping forward to the extended keyboard protocol */ 299b4dbc599SNathan Whitehorn adb_set_device_handler(dev,3); 300b4dbc599SNathan Whitehorn 301b4dbc599SNathan Whitehorn mtx_init(&sc->sc_mutex,KBD_DRIVER_NAME,MTX_DEF,0); 302b4dbc599SNathan Whitehorn cv_init(&sc->sc_cv,KBD_DRIVER_NAME); 303b4dbc599SNathan Whitehorn callout_init(&sc->sc_repeater, 0); 304b4dbc599SNathan Whitehorn 305b4dbc599SNathan Whitehorn #ifdef AKBD_EMULATE_ATKBD 306b4dbc599SNathan Whitehorn kbd_init_struct(&sc->sc_kbd, KBD_DRIVER_NAME, KB_101, 0, 0, 0, 0); 307b4dbc599SNathan Whitehorn kbd_set_maps(&sc->sc_kbd, &key_map, &accent_map, fkey_tab, 308b4dbc599SNathan Whitehorn sizeof(fkey_tab) / sizeof(fkey_tab[0])); 309b4dbc599SNathan Whitehorn #else 310b4dbc599SNathan Whitehorn #error ADB raw mode not implemented 311b4dbc599SNathan Whitehorn #endif 312b4dbc599SNathan Whitehorn 313b4dbc599SNathan Whitehorn KBD_FOUND_DEVICE(&sc->sc_kbd); 314b4dbc599SNathan Whitehorn KBD_PROBE_DONE(&sc->sc_kbd); 315b4dbc599SNathan Whitehorn KBD_INIT_DONE(&sc->sc_kbd); 316b4dbc599SNathan Whitehorn KBD_CONFIG_DONE(&sc->sc_kbd); 317b4dbc599SNathan Whitehorn 318b4dbc599SNathan Whitehorn (*sw->enable)(&sc->sc_kbd); 319b4dbc599SNathan Whitehorn 320b4dbc599SNathan Whitehorn kbd_register(&sc->sc_kbd); 321b4dbc599SNathan Whitehorn 322b4dbc599SNathan Whitehorn #ifdef KBD_INSTALL_CDEV 323b4dbc599SNathan Whitehorn if (kbd_attach(&sc->sc_kbd)) { 324b4dbc599SNathan Whitehorn adb_kbd_detach(dev); 325b4dbc599SNathan Whitehorn return ENXIO; 326b4dbc599SNathan Whitehorn } 327b4dbc599SNathan Whitehorn #endif 328b4dbc599SNathan Whitehorn 329582434bdSNathan Whitehorn /* Check if we can read out the LED state from 330b4dbc599SNathan Whitehorn this keyboard by reading the key state register */ 331582434bdSNathan Whitehorn if (adb_read_register(dev, 2, NULL) == 2) 332582434bdSNathan Whitehorn sc->have_led_control = 1; 333582434bdSNathan Whitehorn 334582434bdSNathan Whitehorn adb_set_autopoll(dev,1); 335b4dbc599SNathan Whitehorn 336b4dbc599SNathan Whitehorn return (0); 337b4dbc599SNathan Whitehorn } 338b4dbc599SNathan Whitehorn 339b4dbc599SNathan Whitehorn static int 340b4dbc599SNathan Whitehorn adb_kbd_detach(device_t dev) 341b4dbc599SNathan Whitehorn { 342b4dbc599SNathan Whitehorn struct adb_kbd_softc *sc; 343b4dbc599SNathan Whitehorn keyboard_t *kbd; 344b4dbc599SNathan Whitehorn 345b4dbc599SNathan Whitehorn sc = device_get_softc(dev); 346b4dbc599SNathan Whitehorn 347b4dbc599SNathan Whitehorn adb_set_autopoll(dev,0); 348b4dbc599SNathan Whitehorn callout_stop(&sc->sc_repeater); 349b4dbc599SNathan Whitehorn 350b4dbc599SNathan Whitehorn mtx_lock(&sc->sc_mutex); 351b4dbc599SNathan Whitehorn 352b4dbc599SNathan Whitehorn kbd = kbd_get_keyboard(kbd_find_keyboard(KBD_DRIVER_NAME, 353b4dbc599SNathan Whitehorn device_get_unit(dev))); 354b4dbc599SNathan Whitehorn 355b4dbc599SNathan Whitehorn kbdd_disable(kbd); 356b4dbc599SNathan Whitehorn 357b4dbc599SNathan Whitehorn #ifdef KBD_INSTALL_CDEV 358b4dbc599SNathan Whitehorn kbd_detach(kbd); 359b4dbc599SNathan Whitehorn #endif 360b4dbc599SNathan Whitehorn 361b4dbc599SNathan Whitehorn kbdd_term(kbd); 362b4dbc599SNathan Whitehorn 363b4dbc599SNathan Whitehorn mtx_unlock(&sc->sc_mutex); 364b4dbc599SNathan Whitehorn 365b4dbc599SNathan Whitehorn mtx_destroy(&sc->sc_mutex); 366b4dbc599SNathan Whitehorn cv_destroy(&sc->sc_cv); 367b4dbc599SNathan Whitehorn 368b4dbc599SNathan Whitehorn return (0); 369b4dbc599SNathan Whitehorn } 370b4dbc599SNathan Whitehorn 371b4dbc599SNathan Whitehorn static u_int 372b4dbc599SNathan Whitehorn adb_kbd_receive_packet(device_t dev, u_char status, 373b4dbc599SNathan Whitehorn u_char command, u_char reg, int len, u_char *data) 374b4dbc599SNathan Whitehorn { 375b4dbc599SNathan Whitehorn struct adb_kbd_softc *sc; 376b4dbc599SNathan Whitehorn 377b4dbc599SNathan Whitehorn sc = device_get_softc(dev); 378b4dbc599SNathan Whitehorn 379b4dbc599SNathan Whitehorn if (command != ADB_COMMAND_TALK) 380b4dbc599SNathan Whitehorn return 0; 381b4dbc599SNathan Whitehorn 382b4dbc599SNathan Whitehorn if (reg != 0 || len != 2) 383b4dbc599SNathan Whitehorn return (0); 384b4dbc599SNathan Whitehorn 385b4dbc599SNathan Whitehorn mtx_lock(&sc->sc_mutex); 386b4dbc599SNathan Whitehorn if ((data[0] & 0x7f) == 57 && sc->buffers < 7) { 387b4dbc599SNathan Whitehorn /* Fake the down/up cycle for caps lock */ 388b4dbc599SNathan Whitehorn sc->buffer[sc->buffers++] = data[0] & 0x7f; 389b4dbc599SNathan Whitehorn sc->buffer[sc->buffers++] = (data[0] & 0x7f) | (1 << 7); 390b4dbc599SNathan Whitehorn } else { 391b4dbc599SNathan Whitehorn sc->buffer[sc->buffers++] = data[0]; 392b4dbc599SNathan Whitehorn } 393b4dbc599SNathan Whitehorn 394b4dbc599SNathan Whitehorn if (sc->buffer[sc->buffers-1] < 0xff) 395b4dbc599SNathan Whitehorn sc->last_press = sc->buffer[sc->buffers-1]; 396b4dbc599SNathan Whitehorn 397b4dbc599SNathan Whitehorn if ((data[1] & 0x7f) == 57 && sc->buffers < 7) { 398b4dbc599SNathan Whitehorn /* Fake the down/up cycle for caps lock */ 399b4dbc599SNathan Whitehorn sc->buffer[sc->buffers++] = data[1] & 0x7f; 400b4dbc599SNathan Whitehorn sc->buffer[sc->buffers++] = (data[1] & 0x7f) | (1 << 7); 401b4dbc599SNathan Whitehorn } else { 402b4dbc599SNathan Whitehorn sc->buffer[sc->buffers++] = data[1]; 403b4dbc599SNathan Whitehorn } 404b4dbc599SNathan Whitehorn 405b4dbc599SNathan Whitehorn if (sc->buffer[sc->buffers-1] < 0xff) 406b4dbc599SNathan Whitehorn sc->last_press = sc->buffer[sc->buffers-1]; 407b4dbc599SNathan Whitehorn 408b4dbc599SNathan Whitehorn /* Stop any existing key repeating */ 409b4dbc599SNathan Whitehorn callout_stop(&sc->sc_repeater); 410b4dbc599SNathan Whitehorn 411b4dbc599SNathan Whitehorn /* Schedule a repeat callback on keydown */ 412b4dbc599SNathan Whitehorn if (!(sc->last_press & (1 << 7))) { 413b4dbc599SNathan Whitehorn callout_reset(&sc->sc_repeater, 414b4dbc599SNathan Whitehorn ms_to_ticks(sc->sc_kbd.kb_delay1), akbd_repeat, sc); 415b4dbc599SNathan Whitehorn } 416b4dbc599SNathan Whitehorn mtx_unlock(&sc->sc_mutex); 417b4dbc599SNathan Whitehorn 418b4dbc599SNathan Whitehorn cv_broadcast(&sc->sc_cv); 419b4dbc599SNathan Whitehorn 420b4dbc599SNathan Whitehorn if (KBD_IS_ACTIVE(&sc->sc_kbd) && KBD_IS_BUSY(&sc->sc_kbd)) { 421b4dbc599SNathan Whitehorn sc->sc_kbd.kb_callback.kc_func(&sc->sc_kbd, 422b4dbc599SNathan Whitehorn KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg); 423b4dbc599SNathan Whitehorn } 424b4dbc599SNathan Whitehorn 425b4dbc599SNathan Whitehorn return (0); 426b4dbc599SNathan Whitehorn } 427b4dbc599SNathan Whitehorn 428b4dbc599SNathan Whitehorn static void 429b4dbc599SNathan Whitehorn akbd_repeat(void *xsc) { 430b4dbc599SNathan Whitehorn struct adb_kbd_softc *sc = xsc; 431b4dbc599SNathan Whitehorn int notify_kbd = 0; 432b4dbc599SNathan Whitehorn 433b4dbc599SNathan Whitehorn /* Fake an up/down key repeat so long as we have the 434b4dbc599SNathan Whitehorn free buffers */ 435b4dbc599SNathan Whitehorn mtx_lock(&sc->sc_mutex); 436b4dbc599SNathan Whitehorn if (sc->buffers < 7) { 437b4dbc599SNathan Whitehorn sc->buffer[sc->buffers++] = sc->last_press | (1 << 7); 438b4dbc599SNathan Whitehorn sc->buffer[sc->buffers++] = sc->last_press; 439b4dbc599SNathan Whitehorn 440b4dbc599SNathan Whitehorn notify_kbd = 1; 441b4dbc599SNathan Whitehorn } 442b4dbc599SNathan Whitehorn mtx_unlock(&sc->sc_mutex); 443b4dbc599SNathan Whitehorn 444b4dbc599SNathan Whitehorn if (notify_kbd && KBD_IS_ACTIVE(&sc->sc_kbd) 445b4dbc599SNathan Whitehorn && KBD_IS_BUSY(&sc->sc_kbd)) { 446b4dbc599SNathan Whitehorn sc->sc_kbd.kb_callback.kc_func(&sc->sc_kbd, 447b4dbc599SNathan Whitehorn KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg); 448b4dbc599SNathan Whitehorn } 449b4dbc599SNathan Whitehorn 450b4dbc599SNathan Whitehorn /* Reschedule the callout */ 451b4dbc599SNathan Whitehorn callout_reset(&sc->sc_repeater, ms_to_ticks(sc->sc_kbd.kb_delay2), 452b4dbc599SNathan Whitehorn akbd_repeat, sc); 453b4dbc599SNathan Whitehorn } 454b4dbc599SNathan Whitehorn 455b4dbc599SNathan Whitehorn static int 456b4dbc599SNathan Whitehorn akbd_configure(int flags) 457b4dbc599SNathan Whitehorn { 458b4dbc599SNathan Whitehorn return 0; 459b4dbc599SNathan Whitehorn } 460b4dbc599SNathan Whitehorn 461b4dbc599SNathan Whitehorn static int 462b4dbc599SNathan Whitehorn akbd_probe(int unit, void *arg, int flags) 463b4dbc599SNathan Whitehorn { 464b4dbc599SNathan Whitehorn return 0; 465b4dbc599SNathan Whitehorn } 466b4dbc599SNathan Whitehorn 467b4dbc599SNathan Whitehorn static int 468b4dbc599SNathan Whitehorn akbd_init(int unit, keyboard_t **kbdp, void *arg, int flags) 469b4dbc599SNathan Whitehorn { 470b4dbc599SNathan Whitehorn return 0; 471b4dbc599SNathan Whitehorn } 472b4dbc599SNathan Whitehorn 473b4dbc599SNathan Whitehorn static int 474b4dbc599SNathan Whitehorn akbd_term(keyboard_t *kbd) 475b4dbc599SNathan Whitehorn { 476b4dbc599SNathan Whitehorn return 0; 477b4dbc599SNathan Whitehorn } 478b4dbc599SNathan Whitehorn 479b4dbc599SNathan Whitehorn static int 480b4dbc599SNathan Whitehorn akbd_interrupt(keyboard_t *kbd, void *arg) 481b4dbc599SNathan Whitehorn { 482b4dbc599SNathan Whitehorn return 0; 483b4dbc599SNathan Whitehorn } 484b4dbc599SNathan Whitehorn 485b4dbc599SNathan Whitehorn static int 486b4dbc599SNathan Whitehorn akbd_test_if(keyboard_t *kbd) 487b4dbc599SNathan Whitehorn { 488b4dbc599SNathan Whitehorn return 0; 489b4dbc599SNathan Whitehorn } 490b4dbc599SNathan Whitehorn 491b4dbc599SNathan Whitehorn static int 492b4dbc599SNathan Whitehorn akbd_enable(keyboard_t *kbd) 493b4dbc599SNathan Whitehorn { 494b4dbc599SNathan Whitehorn KBD_ACTIVATE(kbd); 495b4dbc599SNathan Whitehorn return (0); 496b4dbc599SNathan Whitehorn } 497b4dbc599SNathan Whitehorn 498b4dbc599SNathan Whitehorn static int 499b4dbc599SNathan Whitehorn akbd_disable(keyboard_t *kbd) 500b4dbc599SNathan Whitehorn { 501b4dbc599SNathan Whitehorn struct adb_kbd_softc *sc; 502b4dbc599SNathan Whitehorn sc = (struct adb_kbd_softc *)(kbd); 503b4dbc599SNathan Whitehorn 504b4dbc599SNathan Whitehorn callout_stop(&sc->sc_repeater); 505b4dbc599SNathan Whitehorn KBD_DEACTIVATE(kbd); 506b4dbc599SNathan Whitehorn return (0); 507b4dbc599SNathan Whitehorn } 508b4dbc599SNathan Whitehorn 509b4dbc599SNathan Whitehorn static int 510b4dbc599SNathan Whitehorn akbd_read(keyboard_t *kbd, int wait) 511b4dbc599SNathan Whitehorn { 512b4dbc599SNathan Whitehorn return (0); 513b4dbc599SNathan Whitehorn } 514b4dbc599SNathan Whitehorn 515b4dbc599SNathan Whitehorn static int 516b4dbc599SNathan Whitehorn akbd_check(keyboard_t *kbd) 517b4dbc599SNathan Whitehorn { 518b4dbc599SNathan Whitehorn struct adb_kbd_softc *sc; 519b4dbc599SNathan Whitehorn 520b4dbc599SNathan Whitehorn if (!KBD_IS_ACTIVE(kbd)) 521b4dbc599SNathan Whitehorn return (FALSE); 522b4dbc599SNathan Whitehorn 523b4dbc599SNathan Whitehorn sc = (struct adb_kbd_softc *)(kbd); 524b4dbc599SNathan Whitehorn 525b4dbc599SNathan Whitehorn mtx_lock(&sc->sc_mutex); 5264fb52093SNathan Whitehorn #ifdef AKBD_EMULATE_ATKBD 5274fb52093SNathan Whitehorn if (sc->at_buffered_char[0]) { 5284fb52093SNathan Whitehorn mtx_unlock(&sc->sc_mutex); 5294fb52093SNathan Whitehorn return (TRUE); 5304fb52093SNathan Whitehorn } 5314fb52093SNathan Whitehorn #endif 5324fb52093SNathan Whitehorn 533b4dbc599SNathan Whitehorn if (sc->buffers > 0) { 534b4dbc599SNathan Whitehorn mtx_unlock(&sc->sc_mutex); 535b4dbc599SNathan Whitehorn return (TRUE); 536b4dbc599SNathan Whitehorn } 537b4dbc599SNathan Whitehorn mtx_unlock(&sc->sc_mutex); 538b4dbc599SNathan Whitehorn 539b4dbc599SNathan Whitehorn return (FALSE); 540b4dbc599SNathan Whitehorn } 541b4dbc599SNathan Whitehorn 542b4dbc599SNathan Whitehorn static u_int 543b4dbc599SNathan Whitehorn akbd_read_char(keyboard_t *kbd, int wait) 544b4dbc599SNathan Whitehorn { 545b4dbc599SNathan Whitehorn struct adb_kbd_softc *sc; 5464fb52093SNathan Whitehorn uint16_t key; 5474fb52093SNathan Whitehorn uint8_t adb_code; 548b4dbc599SNathan Whitehorn int i; 549b4dbc599SNathan Whitehorn 550b4dbc599SNathan Whitehorn sc = (struct adb_kbd_softc *)(kbd); 551b4dbc599SNathan Whitehorn 552b4dbc599SNathan Whitehorn mtx_lock(&sc->sc_mutex); 5534fb52093SNathan Whitehorn 5544fb52093SNathan Whitehorn #if defined(AKBD_EMULATE_ATKBD) 5554fb52093SNathan Whitehorn if (sc->sc_mode == K_RAW && sc->at_buffered_char[0]) { 5564fb52093SNathan Whitehorn key = sc->at_buffered_char[0]; 5574fb52093SNathan Whitehorn if (key & SCAN_PREFIX) { 5584fb52093SNathan Whitehorn sc->at_buffered_char[0] = key & ~SCAN_PREFIX; 5594fb52093SNathan Whitehorn key = (key & SCAN_PREFIX_E0) ? 0xe0 : 0xe1; 5604fb52093SNathan Whitehorn } else { 5614fb52093SNathan Whitehorn sc->at_buffered_char[0] = sc->at_buffered_char[1]; 5624fb52093SNathan Whitehorn sc->at_buffered_char[1] = 0; 5634fb52093SNathan Whitehorn } 5644fb52093SNathan Whitehorn 5654fb52093SNathan Whitehorn mtx_unlock(&sc->sc_mutex); 5664fb52093SNathan Whitehorn 5674fb52093SNathan Whitehorn return (key); 5684fb52093SNathan Whitehorn } 5694fb52093SNathan Whitehorn #endif 5704fb52093SNathan Whitehorn 571b4dbc599SNathan Whitehorn if (!sc->buffers && wait) 572b4dbc599SNathan Whitehorn cv_wait(&sc->sc_cv,&sc->sc_mutex); 573b4dbc599SNathan Whitehorn 574b4dbc599SNathan Whitehorn if (!sc->buffers) { 575b4dbc599SNathan Whitehorn mtx_unlock(&sc->sc_mutex); 576b4dbc599SNathan Whitehorn return (0); 577b4dbc599SNathan Whitehorn } 578b4dbc599SNathan Whitehorn 579b4dbc599SNathan Whitehorn adb_code = sc->buffer[0]; 580b4dbc599SNathan Whitehorn 581b4dbc599SNathan Whitehorn for (i = 1; i < sc->buffers; i++) 582b4dbc599SNathan Whitehorn sc->buffer[i-1] = sc->buffer[i]; 583b4dbc599SNathan Whitehorn 584b4dbc599SNathan Whitehorn sc->buffers--; 585b4dbc599SNathan Whitehorn 586b4dbc599SNathan Whitehorn #ifdef AKBD_EMULATE_ATKBD 5874fb52093SNathan Whitehorn key = adb_to_at_scancode_map[adb_code & 0x7f]; 5884fb52093SNathan Whitehorn if (sc->sc_mode == K_CODE) { 5894fb52093SNathan Whitehorn /* Add the key-release bit */ 5904fb52093SNathan Whitehorn key |= adb_code & 0x80; 5914fb52093SNathan Whitehorn } else if (sc->sc_mode == K_RAW) { 5924fb52093SNathan Whitehorn /* 5934fb52093SNathan Whitehorn * In the raw case, we have to emulate the gross 5944fb52093SNathan Whitehorn * variable-length AT keyboard thing. Since this code 5954fb52093SNathan Whitehorn * is copied from sunkbd, which is the same code 5964fb52093SNathan Whitehorn * as ukbd, it might be nice to have this centralized. 5974fb52093SNathan Whitehorn */ 5984fb52093SNathan Whitehorn 5994fb52093SNathan Whitehorn key = keycode2scancode(key, 6004fb52093SNathan Whitehorn 0, adb_code & 0x80); 6014fb52093SNathan Whitehorn 6024fb52093SNathan Whitehorn if (key & SCAN_PREFIX) { 6034fb52093SNathan Whitehorn if (key & SCAN_PREFIX_CTL) { 6044fb52093SNathan Whitehorn sc->at_buffered_char[0] = 6054fb52093SNathan Whitehorn 0x1d | (key & SCAN_RELEASE); 6064fb52093SNathan Whitehorn sc->at_buffered_char[1] = 6074fb52093SNathan Whitehorn key & ~SCAN_PREFIX; 6084fb52093SNathan Whitehorn } else if (key & SCAN_PREFIX_SHIFT) { 6094fb52093SNathan Whitehorn sc->at_buffered_char[0] = 6104fb52093SNathan Whitehorn 0x2a | (key & SCAN_RELEASE); 6114fb52093SNathan Whitehorn sc->at_buffered_char[1] = 6124fb52093SNathan Whitehorn key & ~SCAN_PREFIX_SHIFT; 6134fb52093SNathan Whitehorn } else { 6144fb52093SNathan Whitehorn sc->at_buffered_char[0] = 6154fb52093SNathan Whitehorn key & ~SCAN_PREFIX; 6164fb52093SNathan Whitehorn sc->at_buffered_char[1] = 0; 6174fb52093SNathan Whitehorn } 6184fb52093SNathan Whitehorn 6194fb52093SNathan Whitehorn key = (key & SCAN_PREFIX_E0) ? 0xe0 : 0xe1; 6204fb52093SNathan Whitehorn } 6214fb52093SNathan Whitehorn } 622b4dbc599SNathan Whitehorn #else 6234fb52093SNathan Whitehorn key = adb_code; 624b4dbc599SNathan Whitehorn #endif 625b4dbc599SNathan Whitehorn 6264fb52093SNathan Whitehorn mtx_unlock(&sc->sc_mutex); 6274fb52093SNathan Whitehorn 6284fb52093SNathan Whitehorn return (key); 629b4dbc599SNathan Whitehorn } 630b4dbc599SNathan Whitehorn 631b4dbc599SNathan Whitehorn static int 632b4dbc599SNathan Whitehorn akbd_check_char(keyboard_t *kbd) 633b4dbc599SNathan Whitehorn { 634b4dbc599SNathan Whitehorn if (!KBD_IS_ACTIVE(kbd)) 635b4dbc599SNathan Whitehorn return (FALSE); 636b4dbc599SNathan Whitehorn 637b4dbc599SNathan Whitehorn return (akbd_check(kbd)); 638b4dbc599SNathan Whitehorn } 639b4dbc599SNathan Whitehorn 640b4dbc599SNathan Whitehorn static int 641b4dbc599SNathan Whitehorn set_typematic(keyboard_t *kbd, int code) 642b4dbc599SNathan Whitehorn { 643b4dbc599SNathan Whitehorn /* These numbers are in microseconds, so convert to ticks */ 644b4dbc599SNathan Whitehorn 645b4dbc599SNathan Whitehorn static int delays[] = { 250, 500, 750, 1000 }; 646b4dbc599SNathan Whitehorn static int rates[] = { 34, 38, 42, 46, 50, 55, 59, 63, 647b4dbc599SNathan Whitehorn 68, 76, 84, 92, 100, 110, 118, 126, 648b4dbc599SNathan Whitehorn 136, 152, 168, 184, 200, 220, 236, 252, 649b4dbc599SNathan Whitehorn 272, 304, 336, 368, 400, 440, 472, 504 }; 650b4dbc599SNathan Whitehorn 651b4dbc599SNathan Whitehorn if (code & ~0x7f) 652b4dbc599SNathan Whitehorn return EINVAL; 653b4dbc599SNathan Whitehorn kbd->kb_delay1 = delays[(code >> 5) & 3]; 654b4dbc599SNathan Whitehorn kbd->kb_delay2 = rates[code & 0x1f]; 655b4dbc599SNathan Whitehorn return 0; 656b4dbc599SNathan Whitehorn } 657b4dbc599SNathan Whitehorn 658b4dbc599SNathan Whitehorn static int akbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t data) 659b4dbc599SNathan Whitehorn { 660b4dbc599SNathan Whitehorn struct adb_kbd_softc *sc; 661b4dbc599SNathan Whitehorn uint16_t r2; 662b4dbc599SNathan Whitehorn int error; 663b4dbc599SNathan Whitehorn 664b4dbc599SNathan Whitehorn sc = (struct adb_kbd_softc *)(kbd); 665b4dbc599SNathan Whitehorn error = 0; 666b4dbc599SNathan Whitehorn 667b4dbc599SNathan Whitehorn switch (cmd) { 668b4dbc599SNathan Whitehorn case KDGKBMODE: 669b4dbc599SNathan Whitehorn *(int *)data = sc->sc_mode; 670b4dbc599SNathan Whitehorn break; 671b4dbc599SNathan Whitehorn case KDSKBMODE: 672b4dbc599SNathan Whitehorn switch (*(int *)data) { 673b4dbc599SNathan Whitehorn case K_XLATE: 674b4dbc599SNathan Whitehorn if (sc->sc_mode != K_XLATE) { 675b4dbc599SNathan Whitehorn /* make lock key state and LED state match */ 676b4dbc599SNathan Whitehorn sc->sc_state &= ~LOCK_MASK; 677b4dbc599SNathan Whitehorn sc->sc_state |= KBD_LED_VAL(kbd); 678b4dbc599SNathan Whitehorn } 679b4dbc599SNathan Whitehorn /* FALLTHROUGH */ 680b4dbc599SNathan Whitehorn case K_RAW: 681b4dbc599SNathan Whitehorn case K_CODE: 682b4dbc599SNathan Whitehorn if (sc->sc_mode != *(int *)data) 683b4dbc599SNathan Whitehorn sc->sc_mode = *(int *)data; 684b4dbc599SNathan Whitehorn break; 685b4dbc599SNathan Whitehorn default: 686b4dbc599SNathan Whitehorn error = EINVAL; 687b4dbc599SNathan Whitehorn break; 688b4dbc599SNathan Whitehorn } 689b4dbc599SNathan Whitehorn 690b4dbc599SNathan Whitehorn break; 691b4dbc599SNathan Whitehorn 692b4dbc599SNathan Whitehorn case KDGETLED: 693b4dbc599SNathan Whitehorn *(int *)data = KBD_LED_VAL(kbd); 694b4dbc599SNathan Whitehorn break; 695b4dbc599SNathan Whitehorn 696b4dbc599SNathan Whitehorn case KDSKBSTATE: 697b4dbc599SNathan Whitehorn if (*(int *)data & ~LOCK_MASK) { 698b4dbc599SNathan Whitehorn error = EINVAL; 699b4dbc599SNathan Whitehorn break; 700b4dbc599SNathan Whitehorn } 701b4dbc599SNathan Whitehorn sc->sc_state &= ~LOCK_MASK; 702b4dbc599SNathan Whitehorn sc->sc_state |= *(int *)data; 703b4dbc599SNathan Whitehorn 704b4dbc599SNathan Whitehorn /* FALLTHROUGH */ 705b4dbc599SNathan Whitehorn 706b4dbc599SNathan Whitehorn case KDSETLED: 707b4dbc599SNathan Whitehorn KBD_LED_VAL(kbd) = *(int *)data; 708b4dbc599SNathan Whitehorn 709b4dbc599SNathan Whitehorn if (!sc->have_led_control) 710b4dbc599SNathan Whitehorn break; 711b4dbc599SNathan Whitehorn 712b4dbc599SNathan Whitehorn r2 = (~0 & 0x04) | 3; 713b4dbc599SNathan Whitehorn 714b4dbc599SNathan Whitehorn if (*(int *)data & NLKED) 715b4dbc599SNathan Whitehorn r2 &= ~1; 716b4dbc599SNathan Whitehorn if (*(int *)data & CLKED) 717b4dbc599SNathan Whitehorn r2 &= ~2; 718b4dbc599SNathan Whitehorn if (*(int *)data & SLKED) 719b4dbc599SNathan Whitehorn r2 &= ~4; 720b4dbc599SNathan Whitehorn 721b4dbc599SNathan Whitehorn adb_send_packet(sc->sc_dev,ADB_COMMAND_LISTEN,2, 722b4dbc599SNathan Whitehorn sizeof(uint16_t),(u_char *)&r2); 723b4dbc599SNathan Whitehorn 724b4dbc599SNathan Whitehorn break; 725b4dbc599SNathan Whitehorn 726b4dbc599SNathan Whitehorn case KDGKBSTATE: 727b4dbc599SNathan Whitehorn *(int *)data = sc->sc_state & LOCK_MASK; 728b4dbc599SNathan Whitehorn break; 729b4dbc599SNathan Whitehorn 730b4dbc599SNathan Whitehorn case KDSETREPEAT: 731b4dbc599SNathan Whitehorn if (!KBD_HAS_DEVICE(kbd)) 732b4dbc599SNathan Whitehorn return 0; 733b4dbc599SNathan Whitehorn if (((int *)data)[1] < 0) 734b4dbc599SNathan Whitehorn return EINVAL; 735b4dbc599SNathan Whitehorn if (((int *)data)[0] < 0) 736b4dbc599SNathan Whitehorn return EINVAL; 737b4dbc599SNathan Whitehorn else if (((int *)data)[0] == 0) /* fastest possible value */ 738b4dbc599SNathan Whitehorn kbd->kb_delay1 = 200; 739b4dbc599SNathan Whitehorn else 740b4dbc599SNathan Whitehorn kbd->kb_delay1 = ((int *)data)[0]; 741b4dbc599SNathan Whitehorn kbd->kb_delay2 = ((int *)data)[1]; 742b4dbc599SNathan Whitehorn 743b4dbc599SNathan Whitehorn break; 744b4dbc599SNathan Whitehorn 745b4dbc599SNathan Whitehorn case KDSETRAD: 746b4dbc599SNathan Whitehorn error = set_typematic(kbd, *(int *)data); 747b4dbc599SNathan Whitehorn break; 748b4dbc599SNathan Whitehorn 749b4dbc599SNathan Whitehorn case PIO_KEYMAP: 750b4dbc599SNathan Whitehorn case PIO_KEYMAPENT: 751b4dbc599SNathan Whitehorn case PIO_DEADKEYMAP: 752b4dbc599SNathan Whitehorn default: 753b4dbc599SNathan Whitehorn return (genkbd_commonioctl(kbd, cmd, data)); 754b4dbc599SNathan Whitehorn } 755b4dbc599SNathan Whitehorn 756b4dbc599SNathan Whitehorn return (error); 757b4dbc599SNathan Whitehorn } 758b4dbc599SNathan Whitehorn 759b4dbc599SNathan Whitehorn static int akbd_lock(keyboard_t *kbd, int lock) 760b4dbc599SNathan Whitehorn { 761b4dbc599SNathan Whitehorn return (0); 762b4dbc599SNathan Whitehorn } 763b4dbc599SNathan Whitehorn 764b4dbc599SNathan Whitehorn static void akbd_clear_state(keyboard_t *kbd) 765b4dbc599SNathan Whitehorn { 7664fb52093SNathan Whitehorn struct adb_kbd_softc *sc; 7674fb52093SNathan Whitehorn 7684fb52093SNathan Whitehorn sc = (struct adb_kbd_softc *)(kbd); 7694fb52093SNathan Whitehorn 7704fb52093SNathan Whitehorn mtx_lock(&sc->sc_mutex); 7714fb52093SNathan Whitehorn 7724fb52093SNathan Whitehorn sc->buffers = 0; 7734fb52093SNathan Whitehorn callout_stop(&sc->sc_repeater); 7744fb52093SNathan Whitehorn 7754fb52093SNathan Whitehorn #if defined(AKBD_EMULATE_ATKBD) 7764fb52093SNathan Whitehorn sc->at_buffered_char[0] = 0; 7774fb52093SNathan Whitehorn sc->at_buffered_char[1] = 0; 7784fb52093SNathan Whitehorn #endif 7794fb52093SNathan Whitehorn mtx_unlock(&sc->sc_mutex); 780b4dbc599SNathan Whitehorn } 781b4dbc599SNathan Whitehorn 782b4dbc599SNathan Whitehorn static int akbd_get_state(keyboard_t *kbd, void *buf, size_t len) 783b4dbc599SNathan Whitehorn { 784b4dbc599SNathan Whitehorn return (0); 785b4dbc599SNathan Whitehorn } 786b4dbc599SNathan Whitehorn 787b4dbc599SNathan Whitehorn static int akbd_set_state(keyboard_t *kbd, void *buf, size_t len) 788b4dbc599SNathan Whitehorn { 789b4dbc599SNathan Whitehorn return (0); 790b4dbc599SNathan Whitehorn } 791b4dbc599SNathan Whitehorn 792b4dbc599SNathan Whitehorn static int akbd_poll(keyboard_t *kbd, int on) 793b4dbc599SNathan Whitehorn { 794b4dbc599SNathan Whitehorn return (0); 795b4dbc599SNathan Whitehorn } 796b4dbc599SNathan Whitehorn 797b4dbc599SNathan Whitehorn static int 798b4dbc599SNathan Whitehorn akbd_modevent(module_t mod, int type, void *data) 799b4dbc599SNathan Whitehorn { 800b4dbc599SNathan Whitehorn switch (type) { 801b4dbc599SNathan Whitehorn case MOD_LOAD: 802b4dbc599SNathan Whitehorn kbd_add_driver(&akbd_kbd_driver); 803b4dbc599SNathan Whitehorn break; 804b4dbc599SNathan Whitehorn 805b4dbc599SNathan Whitehorn case MOD_UNLOAD: 806b4dbc599SNathan Whitehorn kbd_delete_driver(&akbd_kbd_driver); 807b4dbc599SNathan Whitehorn break; 808b4dbc599SNathan Whitehorn 809b4dbc599SNathan Whitehorn default: 810b4dbc599SNathan Whitehorn return (EOPNOTSUPP); 811b4dbc599SNathan Whitehorn } 812b4dbc599SNathan Whitehorn 813b4dbc599SNathan Whitehorn return (0); 814b4dbc599SNathan Whitehorn } 815b4dbc599SNathan Whitehorn 816b4dbc599SNathan Whitehorn DEV_MODULE(akbd, akbd_modevent, NULL); 817b4dbc599SNathan Whitehorn 818