1 /* $NetBSD: adb.c,v 1.23 1998/04/13 02:36:24 scottr Exp $ */ 2 3 /*- 4 * Copyright (C) 1994 Bradley A. Grantham 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 e* notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Bradley A. Grantham. 18 * 4. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #include "opt_adb.h" 34 35 #include <sys/param.h> 36 #include <sys/device.h> 37 #include <sys/fcntl.h> 38 #include <sys/poll.h> 39 #include <sys/select.h> 40 #include <sys/proc.h> 41 #include <sys/signalvar.h> 42 #include <sys/systm.h> 43 44 #include <machine/autoconf.h> 45 #include <machine/keyboard.h> 46 47 #include <mac68k/mac68k/macrom.h> 48 #include <mac68k/dev/adbvar.h> 49 #include <mac68k/dev/itevar.h> 50 51 /* 52 * Function declarations. 53 */ 54 static int adbmatch __P((struct device *, struct cfdata *, void *)); 55 static void adbattach __P((struct device *, struct device *, void *)); 56 57 /* 58 * Global variables. 59 */ 60 int adb_polling = 0; /* Are we polling? (Debugger mode) */ 61 int adb_initted = 0; /* adb_init() has completed successfully */ 62 #ifdef ADB_DEBUG 63 int adb_debug = 0; /* Output debugging messages */ 64 #endif /* ADB_DEBUG */ 65 66 /* 67 * Local variables. 68 */ 69 70 /* External keyboard translation matrix */ 71 extern unsigned char keyboard[128][3]; 72 73 /* Event queue definitions */ 74 #if !defined(ADB_MAX_EVENTS) 75 #define ADB_MAX_EVENTS 200 /* Maximum events to be kept in queue */ 76 /* maybe should be higher for slower macs? */ 77 #endif /* !defined(ADB_MAX_EVENTS) */ 78 static adb_event_t adb_evq[ADB_MAX_EVENTS]; /* ADB event queue */ 79 static int adb_evq_tail = 0; /* event queue tail */ 80 static int adb_evq_len = 0; /* event queue length */ 81 82 /* ADB device state information */ 83 static int adb_isopen = 0; /* Are we queuing events for adb_read? */ 84 static struct selinfo adb_selinfo; /* select() info */ 85 static struct proc *adb_ioproc = NULL; /* process to wakeup */ 86 87 /* Key repeat parameters */ 88 static int adb_rptdelay = 20; /* ticks before auto-repeat */ 89 static int adb_rptinterval = 6; /* ticks between auto-repeat */ 90 static int adb_repeating = -1; /* key that is auto-repeating */ 91 static adb_event_t adb_rptevent;/* event to auto-repeat */ 92 93 /* Mouse button state */ 94 static int adb_ms_buttons = 0; 95 96 /* Driver definition. -- This should probably be a bus... */ 97 struct cfattach adb_ca = { 98 sizeof(struct device), adbmatch, adbattach 99 }; 100 101 static int 102 adbmatch(parent, cf, aux) 103 struct device *parent; 104 struct cfdata *cf; 105 void *aux; 106 { 107 static int adb_matched = 0; 108 109 /* Allow only one instance. */ 110 if (adb_matched) 111 return (0); 112 113 adb_matched = 1; 114 return (1); 115 } 116 117 static void 118 adbattach(parent, dev, aux) 119 struct device *parent, *dev; 120 void *aux; 121 { 122 printf(" (ADB event device)\n"); 123 adb_init(); 124 } 125 126 void 127 adb_enqevent(event) 128 adb_event_t *event; 129 { 130 int s; 131 132 s = spladb(); 133 134 #ifdef DIAGNOSTIC 135 if (adb_evq_tail < 0 || adb_evq_tail >= ADB_MAX_EVENTS) 136 panic("adb: event queue tail is out of bounds"); 137 138 if (adb_evq_len < 0 || adb_evq_len > ADB_MAX_EVENTS) 139 panic("adb: event queue len is out of bounds"); 140 #endif 141 142 if (adb_evq_len == ADB_MAX_EVENTS) { 143 splx(s); 144 return; /* Oh, well... */ 145 } 146 adb_evq[(adb_evq_len + adb_evq_tail) % ADB_MAX_EVENTS] = 147 *event; 148 adb_evq_len++; 149 150 selwakeup(&adb_selinfo); 151 if (adb_ioproc) 152 psignal(adb_ioproc, SIGIO); 153 154 splx(s); 155 } 156 157 void 158 adb_handoff(event) 159 adb_event_t *event; 160 { 161 if (adb_isopen && !adb_polling) { 162 adb_enqevent(event); 163 } else { 164 if (event->def_addr == 2) 165 ite_intr(event); 166 } 167 } 168 169 170 void 171 adb_autorepeat(keyp) 172 void *keyp; 173 { 174 int key = (int)keyp; 175 176 adb_rptevent.bytes[0] |= 0x80; 177 microtime(&adb_rptevent.timestamp); 178 adb_handoff(&adb_rptevent); /* do key up */ 179 180 adb_rptevent.bytes[0] &= 0x7f; 181 microtime(&adb_rptevent.timestamp); 182 adb_handoff(&adb_rptevent); /* do key down */ 183 184 if (adb_repeating == key) { 185 timeout(adb_autorepeat, keyp, adb_rptinterval); 186 } 187 } 188 189 190 void 191 adb_dokeyupdown(event) 192 adb_event_t *event; 193 { 194 int adb_key; 195 196 if (event->def_addr == 2) { 197 adb_key = event->u.k.key & 0x7f; 198 if (!(event->u.k.key & 0x80) && 199 keyboard[event->u.k.key & 0x7f][0] != 0) { 200 /* ignore shift & control */ 201 if (adb_repeating != -1) { 202 untimeout(adb_autorepeat, 203 (void *)adb_rptevent.u.k.key); 204 } 205 adb_rptevent = *event; 206 adb_repeating = adb_key; 207 timeout(adb_autorepeat, 208 (void *)adb_key, adb_rptdelay); 209 } else { 210 if (adb_repeating != -1) { 211 adb_repeating = -1; 212 untimeout(adb_autorepeat, 213 (void *)adb_rptevent.u.k.key); 214 } 215 adb_rptevent = *event; 216 } 217 } 218 adb_handoff(event); 219 } 220 221 void 222 adb_keymaybemouse(event) 223 adb_event_t *event; 224 { 225 static int optionkey_down = 0; 226 adb_event_t new_event; 227 228 if (event->u.k.key == ADBK_KEYDOWN(ADBK_OPTION)) { 229 optionkey_down = 1; 230 } else if (event->u.k.key == ADBK_KEYUP(ADBK_OPTION)) { 231 /* key up */ 232 optionkey_down = 0; 233 if (adb_ms_buttons & 0xfe) { 234 adb_ms_buttons &= 1; 235 new_event.def_addr = ADBADDR_MS; 236 new_event.u.m.buttons = adb_ms_buttons; 237 new_event.u.m.dx = new_event.u.m.dy = 0; 238 microtime(&new_event.timestamp); 239 adb_dokeyupdown(&new_event); 240 } 241 } else if (optionkey_down) { 242 #ifdef ALTXBUTTONS 243 if (event->u.k.key == ADBK_KEYDOWN(ADBK_1)) { 244 adb_ms_buttons |= 1; /* left down */ 245 new_event.def_addr = ADBADDR_MS; 246 new_event.u.m.buttons = adb_ms_buttons; 247 new_event.u.m.dx = new_event.u.m.dy = 0; 248 microtime(&new_event.timestamp); 249 adb_dokeyupdown(&new_event); 250 } else if (event->u.k.key == ADBK_KEYUP(ADBK_1)) { 251 adb_ms_buttons &= ~1; /* left up */ 252 new_event.def_addr = ADBADDR_MS; 253 new_event.u.m.buttons = adb_ms_buttons; 254 new_event.u.m.dx = new_event.u.m.dy = 0; 255 microtime(&new_event.timestamp); 256 adb_dokeyupdown(&new_event); 257 } else 258 #endif 259 if (event->u.k.key == ADBK_KEYDOWN(ADBK_LEFT) 260 #ifdef ALTXBUTTONS 261 || event->u.k.key == ADBK_KEYDOWN(ADBK_2) 262 #endif 263 ) { 264 adb_ms_buttons |= 2; /* middle down */ 265 new_event.def_addr = ADBADDR_MS; 266 new_event.u.m.buttons = adb_ms_buttons; 267 new_event.u.m.dx = new_event.u.m.dy = 0; 268 microtime(&new_event.timestamp); 269 adb_dokeyupdown(&new_event); 270 } else if (event->u.k.key == ADBK_KEYUP(ADBK_LEFT) 271 #ifdef ALTXBUTTONS 272 || event->u.k.key == ADBK_KEYUP(ADBK_2) 273 #endif 274 ) { 275 adb_ms_buttons &= ~2; /* middle up */ 276 new_event.def_addr = ADBADDR_MS; 277 new_event.u.m.buttons = adb_ms_buttons; 278 new_event.u.m.dx = new_event.u.m.dy = 0; 279 microtime(&new_event.timestamp); 280 adb_dokeyupdown(&new_event); 281 } else if (event->u.k.key == ADBK_KEYDOWN(ADBK_RIGHT) 282 #ifdef ALTXBUTTONS 283 || event->u.k.key == ADBK_KEYDOWN(ADBK_3) 284 #endif 285 ) { 286 adb_ms_buttons |= 4; /* right down */ 287 new_event.def_addr = ADBADDR_MS; 288 new_event.u.m.buttons = adb_ms_buttons; 289 new_event.u.m.dx = new_event.u.m.dy = 0; 290 microtime(&new_event.timestamp); 291 adb_dokeyupdown(&new_event); 292 } else if (event->u.k.key == ADBK_KEYUP(ADBK_RIGHT) 293 #ifdef ALTXBUTTONS 294 || event->u.k.key == ADBK_KEYUP(ADBK_3) 295 #endif 296 ) { 297 adb_ms_buttons &= ~4; /* right up */ 298 new_event.def_addr = ADBADDR_MS; 299 new_event.u.m.buttons = adb_ms_buttons; 300 new_event.u.m.dx = new_event.u.m.dy = 0; 301 microtime(&new_event.timestamp); 302 adb_dokeyupdown(&new_event); 303 } else if (ADBK_MODIFIER(event->u.k.key)) { 304 /* ctrl, shift, cmd */ 305 adb_dokeyupdown(event); 306 } else if (!(event->u.k.key & 0x80)) { 307 /* key down */ 308 new_event = *event; 309 310 /* send option-down */ 311 new_event.u.k.key = ADBK_KEYDOWN(ADBK_OPTION); 312 new_event.bytes[0] = new_event.u.k.key; 313 microtime(&new_event.timestamp); 314 adb_dokeyupdown(&new_event); 315 316 /* send key-down */ 317 new_event.u.k.key = event->bytes[0]; 318 new_event.bytes[0] = new_event.u.k.key; 319 microtime(&new_event.timestamp); 320 adb_dokeyupdown(&new_event); 321 322 /* send key-up */ 323 new_event.u.k.key = 324 ADBK_KEYUP(ADBK_KEYVAL(event->bytes[0])); 325 microtime(&new_event.timestamp); 326 new_event.bytes[0] = new_event.u.k.key; 327 adb_dokeyupdown(&new_event); 328 329 /* send option-up */ 330 new_event.u.k.key = ADBK_KEYUP(ADBK_OPTION); 331 new_event.bytes[0] = new_event.u.k.key; 332 microtime(&new_event.timestamp); 333 adb_dokeyupdown(&new_event); 334 } else { 335 /* option-keyup -- do nothing. */ 336 } 337 } else { 338 adb_dokeyupdown(event); 339 } 340 } 341 342 343 void 344 adb_processevent(event) 345 adb_event_t *event; 346 { 347 adb_event_t new_event; 348 int i, button_bit, max_byte, mask, buttons; 349 350 new_event = *event; 351 buttons = 0; 352 353 switch (event->def_addr) { 354 case ADBADDR_KBD: 355 new_event.u.k.key = event->bytes[0]; 356 new_event.bytes[1] = 0xff; 357 adb_keymaybemouse(&new_event); 358 if (event->bytes[1] != 0xff) { 359 new_event.u.k.key = event->bytes[1]; 360 new_event.bytes[0] = event->bytes[1]; 361 new_event.bytes[1] = 0xff; 362 adb_keymaybemouse(&new_event); 363 } 364 break; 365 case ADBADDR_MS: 366 /* 367 * This should handle both plain ol' Apple mice and mice 368 * that claim to support the Extended Apple Mouse Protocol. 369 */ 370 max_byte = event->byte_count; 371 button_bit = 1; 372 switch (event->hand_id) { 373 case ADBMS_USPEED: 374 /* MicroSpeed mouse */ 375 if (max_byte == 4) 376 buttons = (~event->bytes[2]) & 0xff; 377 else 378 buttons = (event->bytes[0] & 0x80) ? 0 : 1; 379 break; 380 case ADBMS_MSA3: 381 /* Mouse Systems A3 mouse */ 382 if (max_byte == 3) 383 buttons = (~event->bytes[2]) & 0x07; 384 else 385 buttons = (event->bytes[0] & 0x80) ? 0 : 1; 386 break; 387 default: 388 /* Classic Mouse Protocol (up to 2 buttons) */ 389 for (i = 0; i < 2; i++, button_bit <<= 1) 390 /* 0 when button down */ 391 if (!(event->bytes[i] & 0x80)) 392 buttons |= button_bit; 393 else 394 buttons &= ~button_bit; 395 /* Extended Protocol (up to 6 more buttons) */ 396 for (mask = 0x80; i < max_byte; 397 i += (mask == 0x80), button_bit <<= 1) { 398 /* 0 when button down */ 399 if (!(event->bytes[i] & mask)) 400 buttons |= button_bit; 401 else 402 buttons &= ~button_bit; 403 mask = ((mask >> 4) & 0xf) 404 | ((mask & 0xf) << 4); 405 } 406 break; 407 } 408 new_event.u.m.buttons = adb_ms_buttons | buttons; 409 new_event.u.m.dx = ((signed int) (event->bytes[1] & 0x3f)) - 410 ((event->bytes[1] & 0x40) ? 64 : 0); 411 new_event.u.m.dy = ((signed int) (event->bytes[0] & 0x3f)) - 412 ((event->bytes[0] & 0x40) ? 64 : 0); 413 adb_dokeyupdown(&new_event); 414 break; 415 default: /* God only knows. */ 416 adb_dokeyupdown(event); 417 } 418 } 419 420 421 int 422 adbopen(dev, flag, mode, p) 423 dev_t dev; 424 int flag, mode; 425 struct proc *p; 426 { 427 register int unit; 428 int error = 0; 429 int s; 430 431 unit = minor(dev); 432 if (unit != 0 || !adb_initted) 433 return (ENXIO); 434 435 s = spladb(); 436 if (adb_isopen) { 437 splx(s); 438 return (EBUSY); 439 } 440 adb_evq_tail = 0; 441 adb_evq_len = 0; 442 adb_isopen = 1; 443 adb_ioproc = p; 444 splx(s); 445 446 return (error); 447 } 448 449 450 int 451 adbclose(dev, flag, mode, p) 452 dev_t dev; 453 int flag, mode; 454 struct proc *p; 455 { 456 int s = spladb(); 457 458 adb_isopen = 0; 459 adb_ioproc = NULL; 460 splx(s); 461 462 return (0); 463 } 464 465 466 int 467 adbread(dev, uio, flag) 468 dev_t dev; 469 struct uio *uio; 470 int flag; 471 { 472 int s, error; 473 int willfit; 474 int total; 475 int firstmove; 476 int moremove; 477 478 if (uio->uio_resid < sizeof(adb_event_t)) 479 return (EMSGSIZE); /* close enough. */ 480 481 s = spladb(); 482 if (adb_evq_len == 0) { 483 splx(s); 484 return (0); 485 } 486 willfit = howmany(uio->uio_resid, sizeof(adb_event_t)); 487 total = (adb_evq_len < willfit) ? adb_evq_len : willfit; 488 489 firstmove = (adb_evq_tail + total > ADB_MAX_EVENTS) 490 ? (ADB_MAX_EVENTS - adb_evq_tail) : total; 491 492 error = uiomove((caddr_t) & adb_evq[adb_evq_tail], 493 firstmove * sizeof(adb_event_t), uio); 494 if (error) { 495 splx(s); 496 return (error); 497 } 498 moremove = total - firstmove; 499 500 if (moremove > 0) { 501 error = uiomove((caddr_t) & adb_evq[0], 502 moremove * sizeof(adb_event_t), uio); 503 if (error) { 504 splx(s); 505 return (error); 506 } 507 } 508 adb_evq_tail = (adb_evq_tail + total) % ADB_MAX_EVENTS; 509 adb_evq_len -= total; 510 splx(s); 511 return (0); 512 } 513 514 515 int 516 adbwrite(dev, uio, flag) 517 dev_t dev; 518 struct uio *uio; 519 int flag; 520 { 521 return 0; 522 } 523 524 525 int 526 adbioctl(dev, cmd, data, flag, p) 527 dev_t dev; 528 int cmd; 529 caddr_t data; 530 int flag; 531 struct proc *p; 532 { 533 switch (cmd) { 534 case ADBIOC_DEVSINFO: { 535 adb_devinfo_t *di; 536 ADBDataBlock adbdata; 537 int totaldevs; 538 int adbaddr; 539 int i; 540 541 di = (void *)data; 542 543 /* Initialize to no devices */ 544 for (i = 0; i < 16; i++) 545 di->dev[i].addr = -1; 546 547 totaldevs = CountADBs(); 548 for (i = 1; i <= totaldevs; i++) { 549 adbaddr = GetIndADB(&adbdata, i); 550 di->dev[adbaddr].addr = adbaddr; 551 di->dev[adbaddr].default_addr = adbdata.origADBAddr; 552 di->dev[adbaddr].handler_id = adbdata.devType; 553 } 554 555 /* Must call ADB Manager to get devices now */ 556 break; 557 } 558 559 case ADBIOC_GETREPEAT:{ 560 adb_rptinfo_t *ri; 561 562 ri = (void *)data; 563 ri->delay_ticks = adb_rptdelay; 564 ri->interval_ticks = adb_rptinterval; 565 break; 566 } 567 568 case ADBIOC_SETREPEAT:{ 569 adb_rptinfo_t *ri; 570 571 ri = (void *)data; 572 adb_rptdelay = ri->delay_ticks; 573 adb_rptinterval = ri->interval_ticks; 574 break; 575 } 576 577 case ADBIOC_RESET: 578 adb_init(); 579 break; 580 581 case ADBIOC_LISTENCMD:{ 582 adb_listencmd_t *lc; 583 584 lc = (void *)data; 585 } 586 587 default: 588 return (EINVAL); 589 } 590 return (0); 591 } 592 593 594 int 595 adbpoll(dev, events, p) 596 dev_t dev; 597 int events; 598 struct proc *p; 599 { 600 int s, revents; 601 602 revents = events & (POLLOUT | POLLWRNORM); 603 604 if ((events & (POLLIN | POLLRDNORM)) == 0) 605 return (revents); 606 607 s = spladb(); 608 if (adb_evq_len > 0) 609 revents |= events & (POLLIN | POLLRDNORM); 610 else 611 selrecord(p, &adb_selinfo); 612 splx(s); 613 614 return (revents); 615 } 616