|
|
1.1 ! root 1: /* ! 2: * File: albaud.c ! 3: * ! 4: * Purpose: common code for various async drivers ! 5: * ! 6: * $Log: albaud.c,v $ ! 7: * Revision 2.2 93/07/26 15:27:51 nigel ! 8: * Nigel's R80 ! 9: * ! 10: * Revision 1.2 93/04/14 10:24:08 root ! 11: * r75 ! 12: * ! 13: * Revision 1.1 92/04/30 08:58:54 hal ! 14: * Add asy. Remove silos from tty struct. ! 15: * ! 16: */ ! 17: ! 18: /* ! 19: * ---------------------------------------------------------------------- ! 20: * Includes. ! 21: */ ! 22: #include <sys/coherent.h> ! 23: #include <sys/ins8250.h> ! 24: ! 25: /* ! 26: * ---------------------------------------------------------------------- ! 27: * Definitions. ! 28: * Constants. ! 29: * Macros with argument lists. ! 30: * Typedefs. ! 31: * Enums. ! 32: */ ! 33: #define TESTBAUD 0x03A5 ! 34: ! 35: /* ! 36: * ---------------------------------------------------------------------- ! 37: * Functions. ! 38: * Import Functions. ! 39: * Export Functions. ! 40: * Local Functions. ! 41: */ ! 42: int uart_sense(); ! 43: ! 44: /* ! 45: * ---------------------------------------------------------------------- ! 46: * Global Data. ! 47: * Import Variables. ! 48: * Export Variables. ! 49: * Local Variables. ! 50: */ ! 51: ! 52: int albaud[] ={ ! 53: 0, /* 0 */ ! 54: 2304, /* 50 */ ! 55: 1536, /* 75 */ ! 56: 1047, /* 110 */ ! 57: 857, /* 134.5 */ ! 58: 768, /* 150 */ ! 59: 576, /* 200 */ ! 60: 384, /* 300 */ ! 61: 192, /* 600 */ ! 62: 96, /* 1200 */ ! 63: 64, /* 1800 */ ! 64: #ifdef _I386 ! 65: 48, /* 2400 */ ! 66: 24, /* 4800 */ ! 67: 12, /* 9600 */ ! 68: 6, /* 19200 */ ! 69: 3 /* 38400 */ ! 70: #else ! 71: 58, /* 2000 */ ! 72: 48, /* 2400 */ ! 73: 32, /* 3600 */ ! 74: 24, /* 4800 */ ! 75: 16, /* 7200 */ ! 76: 12, /* 9600 */ ! 77: 6, /* 19200 */ ! 78: 0, /* EXTA */ ! 79: 0 /* EXTB */ ! 80: #endif ! 81: }; ! 82: ! 83: /* ! 84: * alp_rate[] is tied to albaud[] - it gives the minimum polling ! 85: * rate for the corresponding port speed; it must be a multiple ! 86: * of 100 (system clock Hz) and >= baud/6 ! 87: */ ! 88: int alp_rate[] ={ /* baud/6 or zero */ ! 89: 0, /* 0 */ ! 90: 1*HZ, /* 50 */ ! 91: 1*HZ, /* 75 */ ! 92: 1*HZ, /* 110 */ ! 93: 1*HZ, /* 134.5 */ ! 94: 1*HZ, /* 150 */ ! 95: 1*HZ, /* 200 */ ! 96: 1*HZ, /* 300 */ ! 97: 1*HZ, /* 600 */ ! 98: 2*HZ, /* 1200 */ ! 99: 3*HZ, /* 1800 */ ! 100: #ifdef _I386 ! 101: 4*HZ, /* 2400 */ ! 102: 8*HZ, /* 4800 */ ! 103: 16*HZ, /* 9600 */ ! 104: 32*HZ, /* 19200 */ ! 105: 64*HZ /* 38400 */ ! 106: #else ! 107: 4*HZ, /* 2000 */ ! 108: 4*HZ, /* 2400 */ ! 109: 6*HZ, /* 3600 */ ! 110: 8*HZ, /* 4800 */ ! 111: 12*HZ, /* 7200 */ ! 112: 16*HZ, /* 9600 */ ! 113: 32*HZ, /* 19200 */ ! 114: 0, /* EXTA */ ! 115: 0 /* EXTB */ ! 116: #endif ! 117: }; ! 118: ! 119: /* ! 120: * ---------------------------------------------------------------------- ! 121: * Code. ! 122: */ ! 123: ! 124: /* ! 125: * uart_sense() ! 126: * ! 127: * Given port address, return what type of 8250-family chip is found there. ! 128: * ! 129: * 0 - no chip ! 130: * 1 - 8250 or 8250B ! 131: * 2 - 8250A or 16450 ! 132: * 3 - 16550 ! 133: * 4 - 16550A ! 134: * ! 135: * Only the last of these has usable on-chip FIFO. ! 136: */ ! 137: int uart_sense(port) ! 138: int port; ! 139: { ! 140: int ret = US_NONE; ! 141: unsigned ch; ! 142: short testbaud; ! 143: char lcr, dll, dlh; ! 144: ! 145: /* ! 146: * See if UART is detected at port address. ! 147: * UART should have IER = 0000 xxxx ! 148: * MCR = 000x xxxx ! 149: * IIR = xx00 xxxx ! 150: * and should be write and read back the baud rate regs. ! 151: */ ! 152: if (inb(port+IER) & 0xF0 ! 153: || inb(port+MCR) & 0xE0 ! 154: || inb(port+IIR) & 0x30) { ! 155: goto done; ! 156: } ! 157: lcr = inb(port + LCR); ! 158: outb(port+LCR, LC_DLAB); ! 159: dll = inb(port + DLL); ! 160: dlh = inb(port + DLH); ! 161: outb(port+DLL, TESTBAUD & 0xFF); ! 162: outb(port+DLH, TESTBAUD >> 8); ! 163: testbaud = inb(port+DLL) | inb(port+DLH) << 8; ! 164: outb(port+LCR, LC_CS8); ! 165: if (testbaud != TESTBAUD){ ! 166: goto done; ! 167: } else { ! 168: outb(port+LCR, LC_DLAB); ! 169: outb(port+DLL, dll); ! 170: outb(port+DLH, dlh); ! 171: outb(port+LCR, lcr); ! 172: } ! 173: ! 174: /* ! 175: * Scratch register NOT found on 8250/8250B. ! 176: */ ! 177: outb(port+SCR, 0x55); ! 178: ch = inb(port+SCR); ! 179: if (ch != 0x55) { ! 180: ret = US_8250; ! 181: } ! 182: ! 183: /* ! 184: * After trying to turn on FIFO mode, ! 185: * If IIR is 00xx xxxx, it's 8250A/16450 (no FIFO). ! 186: * If IIR is 10xx xxxx, it's 16550 (broken FIFO). ! 187: * If IIR is 11xx xxxx, it's 16550A (usable FIFO). ! 188: */ ! 189: outb(port+FCR, 0x01); ! 190: ch = inb(port+FCR); ! 191: switch (ch & 0xC0) { ! 192: case 0x00: ! 193: if (ret == US_NONE) ! 194: ret = US_16450; ! 195: break; ! 196: case 0x80: ! 197: if (ret == US_NONE) ! 198: ret = US_16550; ! 199: break; ! 200: case 0xC0: ! 201: ret = US_16550A; ! 202: break; ! 203: } ! 204: outb(port+FCR, 0x00); ! 205: done: ! 206: ! 207: switch(port){ ! 208: case 0x3F8: ! 209: printf("com1 "); ! 210: break; ! 211: case 0x2F8: ! 212: printf("com2 "); ! 213: break; ! 214: case 0x3E8: ! 215: printf("com3 "); ! 216: break; ! 217: case 0x2E8: ! 218: printf("com4 "); ! 219: break; ! 220: } ! 221: printf("port %x: ", port); ! 222: switch (ret) { ! 223: case US_NONE: ! 224: printf("no UART "); ! 225: break; ! 226: case US_8250: ! 227: printf("8250/8250B "); ! 228: break; ! 229: case US_16450: ! 230: printf("8250A/16450 "); ! 231: break; ! 232: case US_16550: ! 233: printf("16550 - no FIFO "); ! 234: break; ! 235: case US_16550A: ! 236: printf("16550A - FIFO "); ! 237: break; ! 238: } ! 239: return ret; ! 240: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.