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