|
|
1.1 ! root 1: /* ! 2: * Mach Operating System ! 3: * Copyright (c) 1993,1992 Carnegie Mellon University ! 4: * All Rights Reserved. ! 5: * ! 6: * Permission to use, copy, modify and distribute this software and its ! 7: * documentation is hereby granted, provided that both the copyright ! 8: * notice and this permission notice appear in all copies of the ! 9: * software, derivative works or modified versions, and any portions ! 10: * thereof, and that both notices appear in supporting documentation. ! 11: * ! 12: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" ! 13: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR ! 14: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ! 15: * ! 16: * Carnegie Mellon requests users of this software to return to ! 17: * ! 18: * Software Distribution Coordinator or [email protected] ! 19: * School of Computer Science ! 20: * Carnegie Mellon University ! 21: * Pittsburgh PA 15213-3890 ! 22: * ! 23: * any improvements or extensions that they make and grant Carnegie Mellon ! 24: * the rights to redistribute these changes. ! 25: */ ! 26: /* ! 27: * File: dtop_hdw.c ! 28: * Author: Alessandro Forin, Carnegie Mellon University ! 29: * Date: 1/92 ! 30: * ! 31: * Hardware-level operations for the Desktop serial line ! 32: * bus (i2c aka ACCESS). ! 33: */ ! 34: ! 35: #include <dtop.h> ! 36: #if NDTOP > 0 ! 37: #include <bm.h> ! 38: #include <platforms.h> ! 39: ! 40: #include <machine/machspl.h> /* spl definitions */ ! 41: #include <mach/std_types.h> ! 42: #include <device/io_req.h> ! 43: #include <device/tty.h> ! 44: ! 45: #include <chips/busses.h> ! 46: #include <chips/serial_defs.h> ! 47: #include <chips/screen_defs.h> ! 48: #include <chips/lk201.h> ! 49: #include <mips/PMAX/tc.h> ! 50: ! 51: #include <chips/dtop.h> ! 52: ! 53: #define DTOP_MAX_POLL 0x7fff /* about half a sec */ ! 54: ! 55: #ifdef MAXINE ! 56: ! 57: typedef volatile unsigned int *data_reg_t; /* uC */ ! 58: #define DTOP_GET_BYTE(data) (((*(data)) >> 8) & 0xff) ! 59: #define DTOP_PUT_BYTE(data,c) { *(data) = (c) << 8; } ! 60: ! 61: typedef volatile unsigned int *poll_reg_t; /* SIR */ ! 62: #define DTOP_RX_AVAIL(poll) (*(poll) & 1) ! 63: #define DTOP_TX_AVAIL(poll) (*(poll) & 2) ! 64: ! 65: #else ! 66: ! 67: define how to get/put DTOP packets on this box ! 68: ! 69: #endif ! 70: ! 71: /* ! 72: * Driver status ! 73: */ ! 74: ! 75: struct dtop_softc { ! 76: data_reg_t data; ! 77: poll_reg_t poll; ! 78: char polling_mode; ! 79: char probed_once; ! 80: short bad_pkts; ! 81: ! 82: struct dtop_ds { ! 83: int (*handler)(dtop_device_t, ! 84: dtop_message_t, ! 85: int, ! 86: unsigned char); ! 87: dtop_device status; ! 88: } device[(DTOP_ADDR_DEFAULT - DTOP_ADDR_FIRST) >> 1]; ! 89: ! 90: # define DTOP_DEVICE_NO(address) (((address)-DTOP_ADDR_FIRST)>>1) ! 91: ! 92: } dtop_softc_data[NDTOP]; ! 93: ! 94: typedef struct dtop_softc *dtop_softc_t; ! 95: ! 96: dtop_softc_t dtop_softc[NDTOP]; ! 97: ! 98: /* ! 99: * Definition of the driver for the auto-configuration program. ! 100: */ ! 101: ! 102: int dtop_probe(), dtop_intr(); ! 103: static void dtop_attach(); ! 104: ! 105: vm_offset_t dtop_std[NDTOP] = { 0 }; ! 106: struct bus_device *dtop_info[NDTOP]; ! 107: struct bus_driver dtop_driver = ! 108: { dtop_probe, 0, dtop_attach, 0, dtop_std, "dtop", dtop_info,}; ! 109: ! 110: ! 111: int dtop_print_debug = 0; ! 112: ! 113: /* ! 114: * Adapt/Probe/Attach functions ! 115: */ ! 116: ! 117: set_dtop_address( dtopunit, poll_reg) ! 118: data_reg_t poll_reg; ! 119: { ! 120: int i; ! 121: ! 122: extern int dtop_probe(), dtop_param(), dtop_start(), ! 123: dtop_putc(), dtop_getc(), ! 124: dtop_pollc(), dtop_mctl(), dtop_softCAR(); ! 125: ! 126: dtop_std[dtopunit] = (vm_offset_t)poll_reg; ! 127: ! 128: /* Do this here */ ! 129: console_probe = dtop_probe; ! 130: console_param = dtop_param; ! 131: console_start = dtop_start; ! 132: console_putc = dtop_putc; ! 133: console_getc = dtop_getc; ! 134: console_pollc = dtop_pollc; ! 135: console_mctl = dtop_mctl; ! 136: console_softCAR = dtop_softCAR; ! 137: ! 138: } ! 139: ! 140: dtop_probe( data_reg, ui) ! 141: data_reg_t data_reg; ! 142: struct bus_device *ui; ! 143: { ! 144: int dtopunit = ui->unit, i; ! 145: dtop_softc_t dtop; ! 146: ! 147: dtop = &dtop_softc_data[dtopunit]; ! 148: dtop_softc[dtopunit] = dtop; ! 149: ! 150: dtop->poll = (poll_reg_t)dtop_std[dtopunit]; ! 151: dtop->data = data_reg; ! 152: ! 153: for (i = 0; i < DTOP_MAX_DEVICES; i++) ! 154: dtop->device[i].handler = dtop_null_device_handler; ! 155: ! 156: /* a lot more needed here, fornow: */ ! 157: dtop->device[DTOP_DEVICE_NO(0x6a)].handler = dtop_locator_handler; ! 158: dtop->device[DTOP_DEVICE_NO(0x6a)].status.locator.type = ! 159: DEV_MOUSE; ! 160: dtop->device[DTOP_DEVICE_NO(0x6a)].status.locator.relative = ! 161: 1; ! 162: dtop->device[DTOP_DEVICE_NO(0x6a)].status.locator.button_code[0] = ! 163: KEY_LEFT_BUTTON; ! 164: dtop->device[DTOP_DEVICE_NO(0x6a)].status.locator.button_code[1] = ! 165: KEY_RIGHT_BUTTON; ! 166: dtop->device[DTOP_DEVICE_NO(0x6a)].status.locator.button_code[2] = ! 167: KEY_MIDDLE_BUTTON; ! 168: dtop->device[DTOP_DEVICE_NO(0x6a)].status.locator.n_coords = ! 169: 2; ! 170: ! 171: dtop->device[DTOP_DEVICE_NO(0x6c)].handler = dtop_keyboard_handler; ! 172: dtop->device[DTOP_DEVICE_NO(0x6c)].status.keyboard.poll_frequency = ! 173: (hz * 5) / 100; /* x0.01 secs */ ! 174: dtop->device[DTOP_DEVICE_NO(0x6c)].status.keyboard.bell_volume = ! 175: DTOP_CLICK_VOLUME_MAX; ! 176: ! 177: return 1; ! 178: } ! 179: ! 180: static void ! 181: dtop_attach(ui) ! 182: struct bus_device *ui; ! 183: { ! 184: int i; ! 185: ! 186: /* Initialize all the console ttys */ ! 187: for (i = 0; i < 4; i++) ! 188: ttychars(console_tty[i]); ! 189: /* Mark keyboard and mouse present */ ! 190: for (i = 0; i < 2; i++) ! 191: console_tty[i]->t_addr = (char*)1; ! 192: } ! 193: ! 194: /* ! 195: * Polled I/O (debugger) ! 196: */ ! 197: dtop_pollc(unit, on) ! 198: boolean_t on; ! 199: { ! 200: dtop_softc_t dtop; ! 201: ! 202: dtop = dtop_softc[unit]; ! 203: if (on) { ! 204: dtop->polling_mode++; ! 205: #if NBM > 0 ! 206: screen_on_off(unit, TRUE); ! 207: #endif NBM > 0 ! 208: } else ! 209: dtop->polling_mode--; ! 210: } ! 211: ! 212: /* ! 213: * Interrupt routine ! 214: */ ! 215: dtop_intr (unit, spllevel, recvd) ! 216: spl_t spllevel; ! 217: boolean_t recvd; ! 218: { ! 219: ! 220: if (recvd) { ! 221: dtop_message msg; ! 222: int devno; ! 223: dtop_softc_t dtop; ! 224: ! 225: ssaver_bump(unit); ! 226: ! 227: #ifdef mips ! 228: splx(spllevel); ! 229: #endif ! 230: ! 231: dtop = dtop_softc[unit]; ! 232: if (dtop_get_packet(dtop, &msg) < 0) { ! 233: if (dtop_print_debug) ! 234: printf("%s", "dtop: overrun (or stray)\n"); ! 235: return; ! 236: } ! 237: ! 238: devno = DTOP_DEVICE_NO(msg.src_address); ! 239: if (devno < 0 || devno > 15) return; /* sanity */ ! 240: ! 241: (void) (*dtop->device[devno].handler) ! 242: (&dtop->device[devno].status, &msg, ! 243: DTOP_EVENT_RECEIVE_PACKET, 0); ! 244: ! 245: } else { ! 246: /* fornow xmit is not intr based */ ! 247: (*tc_enable_interrupt)( dtop_info[unit]->adaptor, FALSE, TRUE); ! 248: } ! 249: } ! 250: ! 251: boolean_t ! 252: dtop_start(tp) ! 253: struct tty *tp; ! 254: { ! 255: register int line, temp; ! 256: ! 257: /* no, we do not need a char out first */ ! 258: return FALSE; ! 259: } ! 260: ! 261: dtop_w_test(n, a,b,c,d,e,f,g,h) ! 262: { ! 263: int *p = (int*)0xbc2a0000; ! 264: ! 265: if (n <= 0) return; ! 266: ! 267: a <<= 8; *p = a; ! 268: if (--n == 0) goto out; ! 269: delay(20); ! 270: b <<= 8; *p = b; ! 271: if (--n == 0) goto out; ! 272: delay(20); ! 273: c <<= 8; *p = c; ! 274: if (--n == 0) goto out; ! 275: delay(20); ! 276: d <<= 8; *p = d; ! 277: if (--n == 0) goto out; ! 278: delay(20); ! 279: e <<= 8; *p = e; ! 280: if (--n == 0) goto out; ! 281: delay(20); ! 282: f <<= 8; *p = f; ! 283: if (--n == 0) goto out; ! 284: delay(20); ! 285: g <<= 8; *p = g; ! 286: if (--n == 0) goto out; ! 287: delay(20); ! 288: h <<= 8; *p = h; ! 289: out: ! 290: delay(10000); ! 291: { ! 292: int buf[100]; ! 293: ! 294: delay(20); ! 295: a = *p; ! 296: buf[0] = a; ! 297: c = 1; ! 298: for (n = 0; n < 100; n++) { ! 299: delay(20); ! 300: b = *p; ! 301: if (b != a) { ! 302: buf[c++] = b; ! 303: b = a; ! 304: } ! 305: } ! 306: for (n = 0; n < c; n++) ! 307: db_printf("%x ", ((buf[n])>>8)&0xff); ! 308: } ! 309: return c; ! 310: } ! 311: ! 312: /* ! 313: * Take a packet off dtop interface ! 314: * A packet MUST be there, this is not checked for. ! 315: */ ! 316: #define DTOP_ESC_CHAR 0xf8 ! 317: dtop_escape(c) ! 318: { ! 319: /* I donno much about this stuff.. */ ! 320: switch (c) { ! 321: case 0xe8: return 0xf8; ! 322: case 0xe9: return 0xf9; ! 323: case 0xea: return 0xfa; ! 324: case 0xeb: return 0xfb; ! 325: default: /* printf("{esc %x}", c); */ ! 326: return c; ! 327: } ! 328: } ! 329: ! 330: dtop_get_packet(dtop, pkt) ! 331: dtop_softc_t dtop; ! 332: dtop_message_t pkt; ! 333: { ! 334: register poll_reg_t poll; ! 335: register data_reg_t data; ! 336: register int max, i, len; ! 337: register unsigned char c; ! 338: ! 339: poll = dtop->poll; ! 340: data = dtop->data; ! 341: ! 342: /* ! 343: * The interface does not handle us the first byte, ! 344: * which is our address and cannot ever be anything ! 345: * else but 0x50. This is a good thing, it makes ! 346: * the average packet exactly one word long, too. ! 347: */ ! 348: pkt->src_address = DTOP_GET_BYTE(data); ! 349: ! 350: for (max = 0; (max < DTOP_MAX_POLL) && !DTOP_RX_AVAIL(poll); max++) ! 351: delay(16); ! 352: if (max == DTOP_MAX_POLL) goto bad; ! 353: pkt->code.bits = DTOP_GET_BYTE(data); ! 354: ! 355: /* ! 356: * Now get data and checksum ! 357: */ ! 358: len = pkt->code.val.len + 1; ! 359: c = 0; ! 360: for (i = 0; i < len; i++) { ! 361: ! 362: again: for (max = 0; (max < DTOP_MAX_POLL) && !DTOP_RX_AVAIL(poll); max++) ! 363: delay(16); ! 364: if (max == DTOP_MAX_POLL) goto bad; ! 365: if (c == DTOP_ESC_CHAR) { ! 366: c = dtop_escape(DTOP_GET_BYTE(data) & 0xff); ! 367: } else { ! 368: c = DTOP_GET_BYTE(data); ! 369: if (c == DTOP_ESC_CHAR) ! 370: goto again; ! 371: } ! 372: ! 373: pkt->body[i] = c; ! 374: } ! 375: return len; ! 376: bad: ! 377: dtop->bad_pkts++; ! 378: return -1; ! 379: } ! 380: ! 381: /* Conversely... */ ! 382: dtop_put_packet(dtop, pkt) ! 383: dtop_softc_t dtop; ! 384: dtop_message_t pkt; ! 385: { ! 386: register int i, max; ! 387: register unsigned char *cp; ! 388: register unsigned int spl; ! 389: register unsigned char c; ! 390: ! 391: spl = spltty(); ! 392: pkt->src_address = pkt->dest_address; ! 393: i = 0; ! 394: cp = (unsigned char *)&pkt->src_address; ! 395: while (i < pkt->code.val.len + 2) { ! 396: for (max = 0; max < DTOP_MAX_POLL && !DTOP_TX_AVAIL(dtop->poll); ! 397: max++); ! 398: if (max == DTOP_MAX_POLL) ! 399: goto bad; ! 400: DTOP_PUT_BYTE(dtop->data, *cp); ! 401: cp++; ! 402: i++; ! 403: } ! 404: for (max = 0; (max < DTOP_MAX_POLL) && !DTOP_RX_AVAIL(dtop->poll); max++) ! 405: delay(16); ! 406: if (max == DTOP_MAX_POLL) ! 407: goto bad; ! 408: c = DTOP_GET_BYTE(dtop->data); ! 409: if (c == DTOP_ESC_CHAR) { ! 410: for (max = 0; (max < DTOP_MAX_POLL) ! 411: && !DTOP_RX_AVAIL(dtop->poll); max++) ! 412: delay(16); ! 413: if (max == DTOP_MAX_POLL) ! 414: goto bad; ! 415: c = DTOP_GET_BYTE(dtop->data); ! 416: } ! 417: splx(spl); ! 418: switch (c) { ! 419: case 0xfb: /* XMT, ok */ ! 420: break; ! 421: default: ! 422: return 0; ! 423: } ! 424: return 1; ! 425: bad: ! 426: splx(spl); ! 427: return 0; ! 428: } ! 429: ! 430: ! 431: /* ! 432: * Get a char from a specific DTOP line ! 433: * [this is only used for console&screen purposes] ! 434: */ ! 435: dtop_getc( unit, line, wait, raw ) ! 436: boolean_t wait; ! 437: boolean_t raw; ! 438: { ! 439: register int c; ! 440: dtop_softc_t dtop; ! 441: ! 442: dtop = dtop_softc[unit]; ! 443: again: ! 444: c = -1; ! 445: ! 446: /* ! 447: * Try rconsole first ! 448: */ ! 449: if (rcline && line == SCREEN_LINE_KEYBOARD) { ! 450: c = scc_getc( 0, rcline, FALSE, raw); ! 451: if (c != -1) return c; ! 452: } ! 453: ! 454: /* ! 455: * Now check keyboard ! 456: */ ! 457: if (DTOP_RX_AVAIL(dtop->poll)) { ! 458: ! 459: dtop_message msg; ! 460: struct dtop_ds *ds; ! 461: ! 462: if (dtop_get_packet(dtop, &msg) >= 0) { ! 463: ! 464: ds = &dtop->device[DTOP_DEVICE_NO(msg.src_address)]; ! 465: if (ds->handler == dtop_keyboard_handler) { ! 466: ! 467: c = dtop_keyboard_handler( ! 468: &ds->status, &msg, ! 469: DTOP_EVENT_RECEIVE_PACKET, -1); ! 470: ! 471: if (c > 0) return c; ! 472: ! 473: c = -1; ! 474: } ! 475: } ! 476: } ! 477: ! 478: if (wait && (c == -1)) { ! 479: delay(100); ! 480: goto again; ! 481: } ! 482: ! 483: return c; ! 484: } ! 485: ! 486: /* ! 487: * Put a char on a specific DTOP line ! 488: */ ! 489: dtop_putc( unit, line, c ) ! 490: { ! 491: if (rcline && line == rcline) { ! 492: scc_putc(0, rcline, c); ! 493: } ! 494: /* dprintf("%c", c); */ ! 495: } ! 496: ! 497: dtop_param(tp, line) ! 498: struct tty *tp; ! 499: { ! 500: if (tp->t_ispeed == 0) ! 501: ttymodem(tp, 0); ! 502: else ! 503: /* called too early to invoke ttymodem, sigh */ ! 504: tp->t_state |= TS_CARR_ON; ! 505: } ! 506: ! 507: /* ! 508: * Modem control functions, we don't need 'em ! 509: */ ! 510: dtop_mctl(dev, bits, how) ! 511: int dev; ! 512: int bits, how; ! 513: { ! 514: return 0; ! 515: } ! 516: ! 517: dtop_softCAR(unit, line, on) ! 518: { ! 519: } ! 520: ! 521: /* Some keyboard specific stuff, probably belongs elsewhere */ ! 522: ! 523: dtop_kbd_probe(unit) ! 524: { ! 525: if (dtop_std[unit]) { ! 526: lk201_probe(unit); ! 527: return 1; ! 528: } ! 529: return 0; ! 530: } ! 531: ! 532: io_return_t ! 533: dtop_set_status(unit, flavor, status, status_count) ! 534: int unit; ! 535: int flavor; ! 536: dev_status_t status; ! 537: unsigned int status_count; ! 538: { ! 539: dtop_device_t dev; ! 540: ! 541: dev = &dtop_softc[unit]->device[DTOP_DEVICE_NO(0x6c)].status; ! 542: ! 543: switch (flavor) { ! 544: case LK201_SEND_CMD: { ! 545: register lk201_cmd_t *cmd = (lk201_cmd_t *)status; ! 546: unsigned int cnt; ! 547: ! 548: if ((status_count < (sizeof(*cmd)/sizeof(int))) || ! 549: ((cnt = cmd->len) > 2)) ! 550: return D_INVALID_SIZE; ! 551: switch (cmd->command) { ! 552: case LK_CMD_ENB_BELL: ! 553: cmd->params[0] ^= 0x7; ! 554: if (dtop_print_debug) ! 555: printf("LK_CMD_ENB_BELL %d\n", cmd->params[0]); ! 556: dev->keyboard.bell_volume = cmd->params[0] & 0x7; ! 557: break; ! 558: case LK_CMD_DIS_BELL: ! 559: dev->keyboard.bell_volume = 0; ! 560: break; ! 561: case LK_CMD_BELL: ! 562: dtop_ring_bell(unit); ! 563: break; ! 564: case LK_CMD_LEDS_ON: ! 565: cmd->params[0] &= ~0x80; ! 566: if (dtop_print_debug) ! 567: printf("LK_CMD_LEDS_ON %d %x\n", ! 568: cmd->params[0], cmd->params[0]); ! 569: dev->keyboard.led_status |= cmd->params[0]; ! 570: dtop_leds(unit, dev->keyboard.led_status); ! 571: break; ! 572: case LK_CMD_LEDS_OFF: ! 573: cmd->params[0] &= ~0x80; ! 574: dev->keyboard.led_status &= ~cmd->params[0]; ! 575: dtop_leds(unit, dev->keyboard.led_status); ! 576: break; ! 577: case LK_CMD_ENB_KEYCLK: ! 578: case LK_CMD_DIS_KEYCLK: ! 579: case LK_CMD_SOUND_CLK: ! 580: case LK_CMD_DIS_CTLCLK: ! 581: case LK_CMD_ENB_CTLCLK: ! 582: break; ! 583: default: ! 584: break; ! 585: } ! 586: break; ! 587: } ! 588: default: ! 589: break; ! 590: } ! 591: return lk201_set_status(unit, flavor, status, status_count); ! 592: } ! 593: ! 594: dtop_kbd_reset(unit) ! 595: { ! 596: return lk201_reset(unit); ! 597: } ! 598: ! 599: #define DTOP_BITS(p, len) (((p) << 7) | (len)) ! 600: ! 601: dtop_ring_bell(unit) ! 602: { ! 603: dtop_message msg; ! 604: dtop_device_t dev; ! 605: int vol; ! 606: ! 607: dev = &dtop_softc[unit]->device[DTOP_DEVICE_NO(0x6c)].status; ! 608: vol = dev->keyboard.bell_volume; ! 609: ! 610: if (dtop_print_debug) ! 611: printf("dtop_ring_bell: %d\n", vol); ! 612: msg.dest_address = DTOP_ADDR_KBD; ! 613: msg.code.bits = DTOP_BITS(1, 2); ! 614: msg.body[0] = DTOP_KMSG_BELL; ! 615: msg.body[1] = vol; ! 616: if (!dtop_put_packet(dtop_softc[unit], &msg)) { ! 617: if (dtop_print_debug) ! 618: printf("dtop_ring_bell: dtop_put_packet failed\n"); ! 619: return -1; ! 620: } ! 621: return 0; ! 622: } ! 623: ! 624: dtop_leds(unit, mask) ! 625: { ! 626: dtop_message msg; ! 627: ! 628: if (dtop_print_debug) ! 629: printf("dtop_leds %x\n", mask); ! 630: msg.dest_address = DTOP_ADDR_KBD; ! 631: msg.code.bits = DTOP_BITS(1, 2); ! 632: msg.body[0] = DTOP_KMSG_LED; ! 633: msg.body[1] = mask; ! 634: if (!dtop_put_packet(dtop_softc[unit], &msg)) { ! 635: if (dtop_print_debug) ! 636: printf("dtop_leds: dtop_put_packet failed\n"); ! 637: return -1; ! 638: } ! 639: return 0; ! 640: } ! 641: ! 642: ! 643: ! 644: #endif NDTOP > 0
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.