1 1.28 nat /* $NetBSD: akbd.c,v 1.28 2025/01/12 05:56:59 nat Exp $ */ 2 1.1 ender 3 1.1 ender /* 4 1.1 ender * Copyright (C) 1998 Colin Wood 5 1.1 ender * All rights reserved. 6 1.1 ender * 7 1.1 ender * Redistribution and use in source and binary forms, with or without 8 1.1 ender * modification, are permitted provided that the following conditions 9 1.1 ender * are met: 10 1.1 ender * 1. Redistributions of source code must retain the above copyright 11 1.1 ender * notice, this list of conditions and the following disclaimer. 12 1.1 ender * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 ender * notice, this list of conditions and the following disclaimer in the 14 1.1 ender * documentation and/or other materials provided with the distribution. 15 1.1 ender * 3. All advertising materials mentioning features or use of this software 16 1.1 ender * must display the following acknowledgement: 17 1.1 ender * This product includes software developed by Colin Wood. 18 1.1 ender * 4. The name of the author may not be used to endorse or promote products 19 1.1 ender * derived from this software without specific prior written permission. 20 1.1 ender * 21 1.1 ender * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 1.1 ender * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 1.1 ender * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 1.1 ender * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 1.1 ender * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 1.1 ender * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 1.1 ender * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 1.1 ender * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 1.1 ender * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 1.1 ender * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 1.1 ender */ 32 1.16 lukem 33 1.16 lukem #include <sys/cdefs.h> 34 1.28 nat __KERNEL_RCSID(0, "$NetBSD: akbd.c,v 1.28 2025/01/12 05:56:59 nat Exp $"); 35 1.1 ender 36 1.5 scottr #include "opt_adb.h" 37 1.5 scottr 38 1.1 ender #include <sys/param.h> 39 1.1 ender #include <sys/device.h> 40 1.1 ender #include <sys/fcntl.h> 41 1.1 ender #include <sys/poll.h> 42 1.1 ender #include <sys/select.h> 43 1.1 ender #include <sys/proc.h> 44 1.1 ender #include <sys/signalvar.h> 45 1.1 ender #include <sys/systm.h> 46 1.12 thorpej #include <sys/kernel.h> 47 1.1 ender 48 1.5 scottr #include "aed.h" 49 1.5 scottr #include "wskbd.h" 50 1.5 scottr 51 1.5 scottr #include <dev/wscons/wsconsio.h> 52 1.5 scottr #include <dev/wscons/wskbdvar.h> 53 1.5 scottr #include <dev/wscons/wsksymdef.h> 54 1.5 scottr #include <dev/wscons/wsksymvar.h> 55 1.5 scottr 56 1.1 ender #include <machine/autoconf.h> 57 1.5 scottr #include <machine/cpu.h> 58 1.5 scottr #define KEYBOARD_ARRAY 59 1.5 scottr #include <machine/keyboard.h> 60 1.5 scottr #include <machine/viareg.h> 61 1.1 ender 62 1.1 ender #include <mac68k/mac68k/macrom.h> 63 1.1 ender #include <mac68k/dev/adbvar.h> 64 1.1 ender #include <mac68k/dev/aedvar.h> 65 1.6 ender #include <mac68k/dev/akbdmap.h> 66 1.5 scottr #include <mac68k/dev/akbdvar.h> 67 1.5 scottr #include <mac68k/dev/amsvar.h> 68 1.1 ender 69 1.1 ender /* 70 1.1 ender * Function declarations. 71 1.1 ender */ 72 1.23 chs static int akbdmatch(device_t, cfdata_t, void *); 73 1.23 chs static void akbdattach(device_t, device_t, void *); 74 1.17 chs static void kbd_processevent(adb_event_t *, struct akbd_softc *); 75 1.1 ender #ifdef notyet 76 1.17 chs static u_char getleds(int); 77 1.17 chs static int setleds(struct akbd_softc *, u_char); 78 1.17 chs static void blinkleds(struct akbd_softc *); 79 1.1 ender #endif 80 1.1 ender 81 1.1 ender /* 82 1.1 ender * Local variables. 83 1.1 ender */ 84 1.1 ender 85 1.1 ender /* Driver definition. */ 86 1.23 chs CFATTACH_DECL_NEW(akbd, sizeof(struct akbd_softc), 87 1.15 thorpej akbdmatch, akbdattach, NULL, NULL); 88 1.5 scottr 89 1.5 scottr extern struct cfdriver akbd_cd; 90 1.5 scottr 91 1.17 chs int kbd_intr(adb_event_t *, struct akbd_softc *); 92 1.17 chs int akbd_enable(void *, int); 93 1.17 chs void akbd_set_leds(void *, int); 94 1.19 christos int akbd_ioctl(void *, u_long, void *, int, struct lwp *); 95 1.5 scottr 96 1.5 scottr struct wskbd_accessops akbd_accessops = { 97 1.5 scottr akbd_enable, 98 1.5 scottr akbd_set_leds, 99 1.5 scottr akbd_ioctl, 100 1.5 scottr }; 101 1.5 scottr 102 1.17 chs void akbd_cngetc(void *, u_int *, int *); 103 1.17 chs void akbd_cnpollc(void *, int); 104 1.17 chs int akbd_cnattach(void); 105 1.5 scottr 106 1.5 scottr struct wskbd_consops akbd_consops = { 107 1.5 scottr akbd_cngetc, 108 1.5 scottr akbd_cnpollc, 109 1.5 scottr }; 110 1.5 scottr 111 1.5 scottr struct wskbd_mapdata akbd_keymapdata = { 112 1.5 scottr akbd_keydesctab, 113 1.5 scottr KB_US, 114 1.1 ender }; 115 1.1 ender 116 1.17 chs static int akbd_is_console(void); 117 1.1 ender 118 1.1 ender static int 119 1.23 chs akbdmatch(device_t parent, cfdata_t cf, void *aux) 120 1.1 ender { 121 1.1 ender struct adb_attach_args *aa_args = (struct adb_attach_args *)aux; 122 1.1 ender 123 1.1 ender if (aa_args->origaddr == ADBADDR_KBD) 124 1.1 ender return 1; 125 1.1 ender else 126 1.1 ender return 0; 127 1.1 ender } 128 1.1 ender 129 1.1 ender static void 130 1.23 chs akbdattach(device_t parent, device_t self, void *aux) 131 1.1 ender { 132 1.1 ender ADBSetInfoBlock adbinfo; 133 1.23 chs struct akbd_softc *sc = device_private(self); 134 1.1 ender struct adb_attach_args *aa_args = (struct adb_attach_args *)aux; 135 1.24 martin int error __unused, kbd_done; 136 1.1 ender short cmd; 137 1.1 ender u_char buffer[9]; 138 1.5 scottr #if NWSKBD > 0 139 1.5 scottr struct wskbddev_attach_args a; 140 1.17 chs static int akbd_console_initted; 141 1.8 scottr int wskbd_eligible; 142 1.8 scottr 143 1.8 scottr wskbd_eligible = 1; 144 1.5 scottr #endif 145 1.1 ender 146 1.1 ender sc->origaddr = aa_args->origaddr; 147 1.1 ender sc->adbaddr = aa_args->adbaddr; 148 1.1 ender sc->handler_id = aa_args->handler_id; 149 1.1 ender 150 1.1 ender sc->sc_leds = (u_int8_t)0x00; /* initially off */ 151 1.1 ender 152 1.1 ender adbinfo.siServiceRtPtr = (Ptr)adb_kbd_asmcomplete; 153 1.19 christos adbinfo.siDataAreaAddr = (void *)sc; 154 1.1 ender 155 1.1 ender switch (sc->handler_id) { 156 1.1 ender case ADB_STDKBD: 157 1.1 ender printf("standard keyboard\n"); 158 1.1 ender break; 159 1.1 ender case ADB_ISOKBD: 160 1.1 ender printf("standard keyboard (ISO layout)\n"); 161 1.1 ender break; 162 1.1 ender case ADB_EXTKBD: 163 1.7 scottr cmd = ADBTALK(sc->adbaddr, 1); 164 1.10 scottr kbd_done = 165 1.10 scottr (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd) == 0); 166 1.1 ender 167 1.1 ender /* Ignore Logitech MouseMan/Trackman pseudo keyboard */ 168 1.1 ender if (kbd_done && buffer[1] == 0x9a && buffer[2] == 0x20) { 169 1.1 ender printf("Mouseman (non-EMP) pseudo keyboard\n"); 170 1.1 ender adbinfo.siServiceRtPtr = (Ptr)0; 171 1.1 ender adbinfo.siDataAreaAddr = (Ptr)0; 172 1.8 scottr #if NWSKBD > 0 173 1.8 scottr wskbd_eligible = 0; 174 1.8 scottr #endif /* NWSKBD > 0 */ 175 1.1 ender } else if (kbd_done && buffer[1] == 0x9a && buffer[2] == 0x21) { 176 1.1 ender printf("Trackman (non-EMP) pseudo keyboard\n"); 177 1.1 ender adbinfo.siServiceRtPtr = (Ptr)0; 178 1.1 ender adbinfo.siDataAreaAddr = (Ptr)0; 179 1.8 scottr #if NWSKBD > 0 180 1.8 scottr wskbd_eligible = 0; 181 1.8 scottr #endif /* NWSKBD > 0 */ 182 1.1 ender } else { 183 1.1 ender printf("extended keyboard\n"); 184 1.1 ender #ifdef notyet 185 1.1 ender blinkleds(sc); 186 1.1 ender #endif 187 1.1 ender } 188 1.1 ender break; 189 1.1 ender case ADB_EXTISOKBD: 190 1.1 ender printf("extended keyboard (ISO layout)\n"); 191 1.1 ender #ifdef notyet 192 1.1 ender blinkleds(sc); 193 1.1 ender #endif 194 1.1 ender break; 195 1.1 ender case ADB_KBDII: 196 1.1 ender printf("keyboard II\n"); 197 1.1 ender break; 198 1.1 ender case ADB_ISOKBDII: 199 1.1 ender printf("keyboard II (ISO layout)\n"); 200 1.1 ender break; 201 1.1 ender case ADB_PBKBD: 202 1.1 ender printf("PowerBook keyboard\n"); 203 1.1 ender break; 204 1.1 ender case ADB_PBISOKBD: 205 1.1 ender printf("PowerBook keyboard (ISO layout)\n"); 206 1.1 ender break; 207 1.1 ender case ADB_ADJKPD: 208 1.1 ender printf("adjustable keypad\n"); 209 1.8 scottr #if NWSKBD > 0 210 1.8 scottr wskbd_eligible = 0; 211 1.8 scottr #endif /* NWSKBD > 0 */ 212 1.1 ender break; 213 1.1 ender case ADB_ADJKBD: 214 1.1 ender printf("adjustable keyboard\n"); 215 1.1 ender break; 216 1.1 ender case ADB_ADJISOKBD: 217 1.1 ender printf("adjustable keyboard (ISO layout)\n"); 218 1.1 ender break; 219 1.1 ender case ADB_ADJJAPKBD: 220 1.1 ender printf("adjustable keyboard (Japanese layout)\n"); 221 1.1 ender break; 222 1.1 ender case ADB_PBEXTISOKBD: 223 1.1 ender printf("PowerBook extended keyboard (ISO layout)\n"); 224 1.1 ender break; 225 1.1 ender case ADB_PBEXTJAPKBD: 226 1.1 ender printf("PowerBook extended keyboard (Japanese layout)\n"); 227 1.1 ender break; 228 1.5 scottr case ADB_JPKBDII: 229 1.5 scottr printf("keyboard II (Japanese layout)\n"); 230 1.5 scottr break; 231 1.1 ender case ADB_PBEXTKBD: 232 1.1 ender printf("PowerBook extended keyboard\n"); 233 1.1 ender break; 234 1.1 ender case ADB_DESIGNKBD: 235 1.1 ender printf("extended keyboard\n"); 236 1.1 ender #ifdef notyet 237 1.1 ender blinkleds(sc); 238 1.1 ender #endif 239 1.1 ender break; 240 1.5 scottr case ADB_PBJPKBD: 241 1.5 scottr printf("PowerBook keyboard (Japanese layout)\n"); 242 1.5 scottr break; 243 1.1 ender default: 244 1.1 ender printf("mapped device (%d)\n", sc->handler_id); 245 1.8 scottr #if NWSKBD > 0 246 1.8 scottr wskbd_eligible = 0; 247 1.8 scottr #endif /* NWSKBD > 0 */ 248 1.1 ender break; 249 1.1 ender } 250 1.1 ender error = SetADBInfo(&adbinfo, sc->adbaddr); 251 1.1 ender #ifdef ADB_DEBUG 252 1.1 ender if (adb_debug) 253 1.5 scottr printf("akbd: returned %d from SetADBInfo\n", error); 254 1.1 ender #endif 255 1.1 ender 256 1.5 scottr #if NWSKBD > 0 257 1.11 scottr if (akbd_is_console() && wskbd_eligible) 258 1.11 scottr a.console = (++akbd_console_initted == 1); 259 1.11 scottr else 260 1.11 scottr a.console = 0; 261 1.5 scottr a.keymap = &akbd_keymapdata; 262 1.5 scottr a.accessops = &akbd_accessops; 263 1.5 scottr a.accesscookie = sc; 264 1.5 scottr 265 1.26 thorpej sc->sc_wskbddev = config_found(self, &a, wskbddevprint, CFARGS_NONE); 266 1.5 scottr #endif 267 1.1 ender } 268 1.1 ender 269 1.1 ender 270 1.1 ender /* 271 1.1 ender * Handle putting the keyboard data received from the ADB into 272 1.1 ender * an ADB event record. 273 1.1 ender */ 274 1.1 ender void 275 1.21 hauke kbd_adbcomplete(uint8_t *buffer, void *data_area, int adb_command) 276 1.1 ender { 277 1.1 ender adb_event_t event; 278 1.5 scottr struct akbd_softc *ksc; 279 1.1 ender int adbaddr; 280 1.1 ender #ifdef ADB_DEBUG 281 1.1 ender int i; 282 1.1 ender 283 1.1 ender if (adb_debug) 284 1.1 ender printf("adb: transaction completion\n"); 285 1.1 ender #endif 286 1.1 ender 287 1.7 scottr adbaddr = ADB_CMDADDR(adb_command); 288 1.5 scottr ksc = (struct akbd_softc *)data_area; 289 1.1 ender 290 1.1 ender event.addr = adbaddr; 291 1.1 ender event.hand_id = ksc->handler_id; 292 1.1 ender event.def_addr = ksc->origaddr; 293 1.21 hauke event.byte_count = buffer[0]; 294 1.21 hauke memcpy(event.bytes, buffer + 1, event.byte_count); 295 1.1 ender 296 1.1 ender #ifdef ADB_DEBUG 297 1.1 ender if (adb_debug) { 298 1.5 scottr printf("akbd: from %d at %d (org %d) %d:", event.addr, 299 1.1 ender event.hand_id, event.def_addr, buffer[0]); 300 1.1 ender for (i = 1; i <= buffer[0]; i++) 301 1.1 ender printf(" %x", buffer[i]); 302 1.1 ender printf("\n"); 303 1.1 ender } 304 1.1 ender #endif 305 1.1 ender 306 1.1 ender microtime(&event.timestamp); 307 1.1 ender 308 1.1 ender kbd_processevent(&event, ksc); 309 1.1 ender } 310 1.1 ender 311 1.1 ender /* 312 1.1 ender * Given a keyboard ADB event, record the keycodes and call the key 313 1.1 ender * repeat handler, optionally passing the event through the mouse 314 1.1 ender * button emulation handler first. 315 1.1 ender */ 316 1.1 ender static void 317 1.17 chs kbd_processevent(adb_event_t *event, struct akbd_softc *ksc) 318 1.1 ender { 319 1.1 ender adb_event_t new_event; 320 1.1 ender 321 1.1 ender new_event = *event; 322 1.1 ender new_event.u.k.key = event->bytes[0]; 323 1.1 ender new_event.bytes[1] = 0xff; 324 1.5 scottr #if NAED > 0 325 1.28 nat int result; 326 1.28 nat 327 1.28 nat if ((result = aed_input(&new_event)) != 0) 328 1.28 nat return; 329 1.28 nat 330 1.28 nat if (adb_polling || !result) 331 1.5 scottr #endif 332 1.5 scottr #if NWSKBD > 0 333 1.9 scottr if (ksc->sc_wskbddev != NULL) /* wskbd is attached? */ 334 1.10 scottr kbd_intr(&new_event, ksc); 335 1.5 scottr #else 336 1.5 scottr /* do nothing */ ; 337 1.5 scottr #endif 338 1.1 ender if (event->bytes[1] != 0xff) { 339 1.1 ender new_event.u.k.key = event->bytes[1]; 340 1.1 ender new_event.bytes[0] = event->bytes[1]; 341 1.1 ender new_event.bytes[1] = 0xff; 342 1.5 scottr #if NAED > 0 343 1.5 scottr if (adb_polling || !aed_input(&new_event)) 344 1.5 scottr #endif 345 1.5 scottr #if NWSKBD > 0 346 1.9 scottr if (ksc->sc_wskbddev != NULL) /* wskbd is attached? */ 347 1.10 scottr kbd_intr(&new_event, ksc); 348 1.5 scottr #else 349 1.5 scottr /* do nothing */ ; 350 1.5 scottr #endif 351 1.1 ender } 352 1.1 ender 353 1.1 ender } 354 1.1 ender 355 1.1 ender #ifdef notyet 356 1.1 ender /* 357 1.1 ender * Get the actual hardware LED state and convert it to softc format. 358 1.1 ender */ 359 1.1 ender static u_char 360 1.17 chs getleds(int addr) 361 1.1 ender { 362 1.1 ender short cmd; 363 1.1 ender u_char buffer[9], leds; 364 1.1 ender 365 1.1 ender leds = 0x00; /* all off */ 366 1.1 ender buffer[0] = 0; 367 1.1 ender 368 1.7 scottr cmd = ADBTALK(addr, 2); 369 1.10 scottr if (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd) == 0 && 370 1.10 scottr buffer[0] > 0) 371 1.1 ender leds = ~(buffer[2]) & 0x07; 372 1.1 ender 373 1.1 ender return (leds); 374 1.1 ender } 375 1.1 ender 376 1.1 ender /* 377 1.1 ender * Set the keyboard LED's. 378 1.1 ender * 379 1.1 ender * Automatically translates from ioctl/softc format to the 380 1.1 ender * actual keyboard register format 381 1.1 ender */ 382 1.1 ender static int 383 1.17 chs setleds(struct akbd_softc *ksc, u_char leds) 384 1.1 ender { 385 1.1 ender int addr; 386 1.1 ender short cmd; 387 1.1 ender u_char buffer[9]; 388 1.1 ender 389 1.1 ender if ((leds & 0x07) == (ksc->sc_leds & 0x07)) 390 1.1 ender return (0); 391 1.1 ender 392 1.2 ender addr = ksc->adbaddr; 393 1.1 ender buffer[0] = 0; 394 1.1 ender 395 1.7 scottr cmd = ADBTALK(addr, 2); 396 1.10 scottr if (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd) || buffer[0] == 0) 397 1.1 ender return (EIO); 398 1.1 ender 399 1.1 ender leds = ~leds & 0x07; 400 1.1 ender buffer[2] &= 0xf8; 401 1.1 ender buffer[2] |= leds; 402 1.1 ender 403 1.7 scottr cmd = ADBLISTEN(addr, 2); 404 1.10 scottr adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd); 405 1.1 ender 406 1.1 ender /* talk R2 */ 407 1.7 scottr cmd = ADBTALK(addr, 2); 408 1.10 scottr if (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd) || buffer[0] == 0) 409 1.1 ender return (EIO); 410 1.1 ender 411 1.1 ender ksc->sc_leds = ~((u_int8_t)buffer[2]) & 0x07; 412 1.1 ender 413 1.1 ender if ((buffer[2] & 0xf8) != leds) 414 1.1 ender return (EIO); 415 1.1 ender else 416 1.1 ender return (0); 417 1.1 ender } 418 1.1 ender 419 1.1 ender /* 420 1.1 ender * Toggle all of the LED's on and off, just for show. 421 1.1 ender */ 422 1.1 ender static void 423 1.17 chs blinkleds(struct akbd_softc *ksc) 424 1.1 ender { 425 1.1 ender int addr, i; 426 1.1 ender u_char blinkleds, origleds; 427 1.1 ender 428 1.2 ender addr = ksc->adbaddr; 429 1.1 ender origleds = getleds(addr); 430 1.1 ender blinkleds = LED_NUMLOCK | LED_CAPSLOCK | LED_SCROLL_LOCK; 431 1.1 ender 432 1.1 ender (void)setleds(ksc, blinkleds); 433 1.1 ender 434 1.1 ender for (i = 0; i < 10000; i++) 435 1.1 ender delay(50); 436 1.1 ender 437 1.1 ender /* make sure that we restore the LED settings */ 438 1.1 ender i = 10; 439 1.1 ender do { 440 1.1 ender (void)setleds(ksc, (u_char)0x00); 441 1.1 ender } while (setleds(ksc, (u_char)0x00) && (i-- > 0)); 442 1.1 ender 443 1.1 ender return; 444 1.1 ender } 445 1.1 ender #endif 446 1.1 ender 447 1.1 ender int 448 1.17 chs akbd_is_console(void) 449 1.5 scottr { 450 1.5 scottr extern struct mac68k_machine_S mac68k_machine; 451 1.5 scottr 452 1.10 scottr return ((mac68k_machine.serial_console & 0x03) == 0); 453 1.5 scottr } 454 1.5 scottr 455 1.5 scottr int 456 1.17 chs akbd_enable(void *v, int on) 457 1.5 scottr { 458 1.5 scottr return 0; 459 1.5 scottr } 460 1.5 scottr 461 1.5 scottr void 462 1.17 chs akbd_set_leds(void *v, int on) 463 1.5 scottr { 464 1.5 scottr } 465 1.5 scottr 466 1.5 scottr int 467 1.19 christos akbd_ioctl(void *v, u_long cmd, void *data, int flag, struct lwp *l) 468 1.1 ender { 469 1.5 scottr switch (cmd) { 470 1.1 ender 471 1.5 scottr case WSKBDIO_GTYPE: 472 1.22 macallan *(int *)data = WSKBD_TYPE_ADB; 473 1.5 scottr return 0; 474 1.5 scottr case WSKBDIO_SETLEDS: 475 1.5 scottr return 0; 476 1.5 scottr case WSKBDIO_GETLEDS: 477 1.5 scottr *(int *)data = 0; 478 1.5 scottr return 0; 479 1.5 scottr case WSKBDIO_COMPLEXBELL: 480 1.5 scottr #define d ((struct wskbd_bell_data *)data) 481 1.12 thorpej mac68k_ring_bell(d->pitch, d->period * hz / 1000, 100); 482 1.5 scottr /* comes in as msec, goes out as ticks; volume ignored */ 483 1.5 scottr #undef d 484 1.5 scottr return (0); 485 1.5 scottr } 486 1.5 scottr /* kbdioctl(...); */ 487 1.1 ender 488 1.13 atatat return EPASSTHROUGH; 489 1.5 scottr } 490 1.5 scottr 491 1.5 scottr static int polledkey; 492 1.5 scottr extern int adb_polling; 493 1.5 scottr 494 1.5 scottr int 495 1.17 chs kbd_intr(adb_event_t *event, struct akbd_softc *sc) 496 1.5 scottr { 497 1.5 scottr int key, press, val; 498 1.5 scottr int type; 499 1.5 scottr 500 1.5 scottr key = event->u.k.key; 501 1.5 scottr press = ADBK_PRESS(key); 502 1.5 scottr val = ADBK_KEYVAL(key); 503 1.5 scottr 504 1.5 scottr type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP; 505 1.5 scottr 506 1.5 scottr if (key == 185) { /* Caps Lock released */ 507 1.5 scottr type = WSCONS_EVENT_KEY_DOWN; 508 1.5 scottr wskbd_input(sc->sc_wskbddev, type, val); 509 1.5 scottr type = WSCONS_EVENT_KEY_UP; 510 1.5 scottr } 511 1.5 scottr 512 1.5 scottr if (adb_polling) 513 1.5 scottr polledkey = key; 514 1.5 scottr else 515 1.5 scottr wskbd_input(sc->sc_wskbddev, type, val); 516 1.5 scottr 517 1.5 scottr return 0; 518 1.5 scottr } 519 1.5 scottr 520 1.5 scottr int 521 1.17 chs akbd_cnattach(void) 522 1.5 scottr { 523 1.5 scottr wskbd_cnattach(&akbd_consops, NULL, &akbd_keymapdata); 524 1.5 scottr 525 1.5 scottr return 0; 526 1.5 scottr } 527 1.5 scottr 528 1.5 scottr void 529 1.17 chs akbd_cngetc(void *v, u_int *type, int *data) 530 1.5 scottr { 531 1.5 scottr int intbits, key, press, val; 532 1.5 scottr int s; 533 1.5 scottr 534 1.5 scottr s = splhigh(); 535 1.5 scottr 536 1.5 scottr polledkey = -1; 537 1.5 scottr adb_polling = 1; 538 1.5 scottr 539 1.5 scottr while (polledkey == -1) { 540 1.5 scottr intbits = via_reg(VIA1, vIFR); 541 1.5 scottr 542 1.5 scottr if (intbits & V1IF_ADBRDY) { 543 1.5 scottr mrg_adbintr(); 544 1.5 scottr via_reg(VIA1, vIFR) = V1IF_ADBRDY; 545 1.5 scottr } 546 1.5 scottr if (intbits & 0x10) { 547 1.5 scottr mrg_pmintr(); 548 1.5 scottr via_reg(VIA1, vIFR) = 0x10; 549 1.5 scottr } 550 1.1 ender } 551 1.5 scottr 552 1.5 scottr adb_polling = 0; 553 1.5 scottr splx(s); 554 1.5 scottr 555 1.5 scottr key = polledkey; 556 1.5 scottr press = ADBK_PRESS(key); 557 1.5 scottr val = ADBK_KEYVAL(key); 558 1.5 scottr 559 1.5 scottr *data = val; 560 1.5 scottr *type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP; 561 1.5 scottr } 562 1.5 scottr 563 1.5 scottr void 564 1.17 chs akbd_cnpollc(void *v, int on) 565 1.5 scottr { 566 1.1 ender } 567