csigma.c revision 250460
1/*- 2 * Low-level subroutines for Cronyx-Sigma adapter. 3 * 4 * Copyright (C) 1994-2000 Cronyx Engineering. 5 * Author: Serge Vakulenko, <vak@cronyx.ru> 6 * 7 * This software is distributed with NO WARRANTIES, not even the implied 8 * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 9 * 10 * Authors grant any other persons or organisations permission to use 11 * or modify this software as long as this message is kept with the software, 12 * all derivative works or modified versions. 13 * 14 * Cronyx Id: csigma.c,v 1.1.2.1 2003/11/12 17:13:41 rik Exp $ 15 * $FreeBSD: head/sys/dev/cx/csigma.c 250460 2013-05-10 16:41:26Z eadler $ 16 */ 17#include <dev/cx/machdep.h> 18#include <dev/cx/cxddk.h> 19#include <dev/cx/cxreg.h> 20#include <dev/cx/cronyxfw.h> 21 22#define DMA_MASK 0xd4 /* DMA mask register */ 23#define DMA_MASK_CLEAR 0x04 /* DMA clear mask */ 24#define DMA_MODE 0xd6 /* DMA mode register */ 25#define DMA_MODE_MASTER 0xc0 /* DMA master mode */ 26 27#define BYTE *(unsigned char*)& 28 29static unsigned char irqmask [] = { 30 BCR0_IRQ_DIS, BCR0_IRQ_DIS, BCR0_IRQ_DIS, BCR0_IRQ_3, 31 BCR0_IRQ_DIS, BCR0_IRQ_5, BCR0_IRQ_DIS, BCR0_IRQ_7, 32 BCR0_IRQ_DIS, BCR0_IRQ_DIS, BCR0_IRQ_10, BCR0_IRQ_11, 33 BCR0_IRQ_12, BCR0_IRQ_DIS, BCR0_IRQ_DIS, BCR0_IRQ_15, 34}; 35 36static unsigned char dmamask [] = { 37 BCR0_DMA_DIS, BCR0_DMA_DIS, BCR0_DMA_DIS, BCR0_DMA_DIS, 38 BCR0_DMA_DIS, BCR0_DMA_5, BCR0_DMA_6, BCR0_DMA_7, 39}; 40 41/* standard base port set */ 42static short porttab [] = { 43 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 44 0x300, 0x320, 0x340, 0x360, 0x380, 0x3a0, 0x3c0, 0x3e0, 0 45}; 46 47/* valid IRQs and DRQs */ 48static short irqtab [] = { 3, 5, 7, 10, 11, 12, 15, 0 }; 49static short dmatab [] = { 5, 6, 7, 0 }; 50 51static int valid (short value, short *list) 52{ 53 while (*list) 54 if (value == *list++) 55 return 1; 56 return 0; 57} 58 59long cx_rxbaud = 9600; /* receiver baud rate */ 60long cx_txbaud = 9600; /* transmitter baud rate */ 61 62int cx_univ_mode = M_HDLC; /* univ. chan. mode: async or sync */ 63int cx_sync_mode = M_HDLC; /* sync. chan. mode: HDLC, Bisync or X.21 */ 64int cx_iftype = 0; /* univ. chan. interface: upper/lower */ 65 66static int cx_probe_chip (port_t base); 67static void cx_setup_chip (cx_chan_t *c); 68 69/* 70 * Wait for CCR to clear. 71 */ 72void cx_cmd (port_t base, int cmd) 73{ 74 port_t port = CCR(base); 75 int count; 76 77 /* Wait 10 msec for the previous command to complete. */ 78 for (count=0; inb(port) && count<20000; ++count) 79 continue; 80 81 /* Issue the command. */ 82 outb (port, cmd); 83 84 /* Wait 10 msec for the command to complete. */ 85 for (count=0; inb(port) && count<20000; ++count) 86 continue; 87} 88 89/* 90 * Reset the chip. 91 */ 92static int cx_reset (port_t port) 93{ 94 int count; 95 96 /* Wait up to 10 msec for revision code to appear after reset. */ 97 for (count=0; count<20000; ++count) 98 if (inb(GFRCR(port)) != 0) 99 break; 100 101 cx_cmd (port, CCR_RSTALL); 102 103 /* Firmware revision code should clear imediately. */ 104 /* Wait up to 10 msec for revision code to appear again. */ 105 for (count=0; count<20000; ++count) 106 if (inb(GFRCR(port)) != 0) 107 return (1); 108 109 /* Reset failed. */ 110 return (0); 111} 112 113int cx_download (port_t port, const unsigned char *firmware, long bits, 114 const cr_dat_tst_t *tst) 115{ 116 unsigned char cr2, sr; 117 long i, n, maxn = (bits + 7) / 8; 118 int v, b; 119 120 inb (BDET(port)); 121 for (i=n=0; n<maxn; ++n) { 122 v = ((firmware[n] ^ ' ') << 1) | (firmware[n] >> 7 & 1); 123 for (b=0; b<7; b+=2, i+=2) { 124 if (i >= bits) 125 break; 126 cr2 = 0; 127 if (v >> b & 1) cr2 |= BCR2_TMS; 128 if (v >> b & 2) cr2 |= BCR2_TDI; 129 outb (BCR2(port), cr2); 130 sr = inb (BSR(port)); 131 outb (BCR0(port), BCR0800_TCK); 132 outb (BCR0(port), 0); 133 if (i >= tst->end) 134 ++tst; 135 if (i >= tst->start && (sr & BSR800_LERR)) 136 return (0); 137 } 138 } 139 return (1); 140} 141 142/* 143 * Check if the Sigma-XXX board is present at the given base port. 144 */ 145static int cx_probe_chained_board (port_t port, int *c0, int *c1) 146{ 147 int rev, i; 148 149 /* Read and check the board revision code. */ 150 rev = inb (BSR(port)); 151 *c0 = *c1 = 0; 152 switch (rev & BSR_VAR_MASK) { 153 case CRONYX_100: *c0 = 1; break; 154 case CRONYX_400: *c1 = 1; break; 155 case CRONYX_500: *c0 = *c1 = 1; break; 156 case CRONYX_410: *c0 = 1; break; 157 case CRONYX_810: *c0 = *c1 = 1; break; 158 case CRONYX_410s: *c0 = 1; break; 159 case CRONYX_810s: *c0 = *c1 = 1; break; 160 case CRONYX_440: *c0 = 1; break; 161 case CRONYX_840: *c0 = *c1 = 1; break; 162 case CRONYX_401: *c0 = 1; break; 163 case CRONYX_801: *c0 = *c1 = 1; break; 164 case CRONYX_401s: *c0 = 1; break; 165 case CRONYX_801s: *c0 = *c1 = 1; break; 166 case CRONYX_404: *c0 = 1; break; 167 case CRONYX_703: *c0 = *c1 = 1; break; 168 default: return (0); /* invalid variant code */ 169 } 170 171 switch (rev & BSR_OSC_MASK) { 172 case BSR_OSC_20: /* 20 MHz */ 173 case BSR_OSC_18432: /* 18.432 MHz */ 174 break; 175 default: 176 return (0); /* oscillator frequency does not match */ 177 } 178 179 for (i=2; i<0x10; i+=2) 180 if ((inb (BSR(port)+i) & BSR_REV_MASK) != (rev & BSR_REV_MASK)) 181 return (0); /* status changed? */ 182 return (1); 183} 184 185/* 186 * Check if the Sigma-800 board is present at the given base port. 187 * Read board status register 1 and check identification bits 188 * which should invert every next read. 189 */ 190static int cx_probe_800_chained_board (port_t port) 191{ 192 unsigned char det, odet; 193 int i; 194 195 odet = inb (BDET(port)); 196 if ((odet & (BDET_IB | BDET_IB_NEG)) != BDET_IB && 197 (odet & (BDET_IB | BDET_IB_NEG)) != BDET_IB_NEG) 198 return (0); 199 for (i=0; i<100; ++i) { 200 det = inb (BDET(port)); 201 if (((det ^ odet) & (BDET_IB | BDET_IB_NEG)) != 202 (BDET_IB | BDET_IB_NEG)) 203 return (0); 204 odet = det; 205 } 206 /* Reset the controller. */ 207 outb (BCR0(port), 0); 208 outb (BCR1(port), 0); 209 outb (BCR2(port), 0); 210 return (1); 211} 212 213/* 214 * Check if the Sigma-2x board is present at the given base port. 215 */ 216static int cx_probe_2x_board (port_t port) 217{ 218 int rev, i; 219 220 /* Read and check the board revision code. */ 221 rev = inb (BSR(port)); 222 if ((rev & BSR2X_VAR_MASK) != CRONYX_22 && 223 (rev & BSR2X_VAR_MASK) != CRONYX_24) 224 return (0); /* invalid variant code */ 225 226 for (i=2; i<0x10; i+=2) 227 if ((inb (BSR(port)+i) & BSR2X_REV_MASK) != 228 (rev & BSR2X_REV_MASK)) 229 return (0); /* status changed? */ 230 return (1); 231} 232 233/* 234 * Check if the Cronyx-Sigma board is present at the given base port. 235 */ 236int cx_probe_board (port_t port, int irq, int dma) 237{ 238 int c0, c1, c2=0, c3=0, result; 239 240 if (! valid (port, porttab)) 241 return 0; 242 243 if (irq > 0 && ! valid (irq, irqtab)) 244 return 0; 245 246 if (dma > 0 && ! valid (dma, dmatab)) 247 return 0; 248 249 if (cx_probe_800_chained_board (port)) { 250 /* Sigma-800 detected. */ 251 if (! (inb (BSR(port)) & BSR_NOCHAIN)) { 252 /* chained board attached */ 253 if (! cx_probe_800_chained_board (port+0x10)) 254 /* invalid chained board? */ 255 return (0); 256 if (! (inb (BSR(port+0x10)) & BSR_NOCHAIN)) 257 /* invalid chained board flag? */ 258 return (0); 259 } 260 return 1; 261 } 262 if (cx_probe_chained_board (port, &c0, &c1)) { 263 /* Sigma-XXX detected. */ 264 if (! (inb (BSR(port)) & BSR_NOCHAIN)) { 265 /* chained board attached */ 266 if (! cx_probe_chained_board (port+0x10, &c2, &c3)) 267 /* invalid chained board? */ 268 return (0); 269 if (! (inb (BSR(port+0x10)) & BSR_NOCHAIN)) 270 /* invalid chained board flag? */ 271 return (0); 272 } 273 } else if (cx_probe_2x_board (port)) { 274 c0 = 1; /* Sigma-2x detected. */ 275 c1 = 0; 276 } else 277 return (0); /* no board detected */ 278 279 /* Turn off the reset bit. */ 280 outb (BCR0(port), BCR0_NORESET); 281 if (c2 || c3) 282 outb (BCR0(port + 0x10), BCR0_NORESET); 283 284 result = 1; 285 if (c0 && ! cx_probe_chip (CS0(port))) 286 result = 0; /* no CD2400 chip here */ 287 else if (c1 && ! cx_probe_chip (CS1A(port)) && 288 ! cx_probe_chip (CS1(port))) 289 result = 0; /* no second CD2400 chip */ 290 else if (c2 && ! cx_probe_chip (CS0(port + 0x10))) 291 result = 0; /* no CD2400 chip on the slave board */ 292 else if (c3 && ! cx_probe_chip (CS1(port + 0x10))) 293 result = 0; /* no second CD2400 chip on the slave board */ 294 295 /* Reset the controller. */ 296 outb (BCR0(port), 0); 297 if (c2 || c3) 298 outb (BCR0(port + 0x10), 0); 299 300 /* Yes, we really have valid Sigma board. */ 301 return (result); 302} 303 304/* 305 * Check if the CD2400 chip is present at the given base port. 306 */ 307static int cx_probe_chip (port_t base) 308{ 309 int rev, newrev, count; 310 311 /* Wait up to 10 msec for revision code to appear after reset. */ 312 rev = 0; 313 for (count=0; rev==0; ++count) { 314 if (count >= 20000) 315 return (0); /* reset failed */ 316 rev = inb (GFRCR(base)); 317 } 318 319 /* Read and check the global firmware revision code. */ 320 if (! (rev>=REVCL_MIN && rev<=REVCL_MAX) && 321 ! (rev>=REVCL31_MIN && rev<=REVCL31_MAX)) 322 return (0); /* CD2400/2431 revision does not match */ 323 324 /* Reset the chip. */ 325 if (! cx_reset (base)) 326 return (0); 327 328 /* Read and check the new global firmware revision code. */ 329 newrev = inb (GFRCR(base)); 330 if (newrev != rev) 331 return (0); /* revision changed */ 332 333 /* Yes, we really have CD2400/2431 chip here. */ 334 return (1); 335} 336 337/* 338 * Check that the irq is functional. 339 * irq>0 - activate the interrupt from the adapter (irq=on) 340 * irq<0 - deactivate the interrupt (irq=off) 341 * irq==0 - free the interrupt line (irq=tri-state) 342 * Return the interrupt mask _before_ activating irq. 343 */ 344int cx_probe_irq (cx_board_t *b, int irq) 345{ 346 int mask, rev; 347 port_t port; 348 349 rev = inb (BSR(b->port)); 350 port = ((rev & BSR_VAR_MASK) != CRONYX_400) ? CS0(b->port) : CS1(b->port); 351 352 outb (0x20, 0x0a); 353 mask = inb (0x20); 354 outb (0xa0, 0x0a); 355 mask |= inb (0xa0) << 8; 356 357 if (irq > 0) { 358 outb (BCR0(b->port), BCR0_NORESET | irqmask[irq]); 359 outb (CAR(port), 0); 360 cx_cmd (port, CCR_CLRCH); 361 outb (CMR(port), CMR_HDLC); 362 outb (TCOR(port), 0); 363 outb (TBPR(port), 1); 364 cx_cmd (port, CCR_INITCH | CCR_ENTX); 365 outb (IER(port), IER_TXMPTY); 366 } else if (irq < 0) { 367 cx_reset (port); 368 if (-irq > 7) { 369 outb (0xa0, 0x60 | ((-irq) & 7)); 370 outb (0x20, 0x62); 371 } else 372 outb (0x20, 0x60 | (-irq)); 373 } else 374 outb (BCR0(b->port), 0); 375 return mask; 376} 377 378static int cx_chip_revision (port_t port, int rev) 379{ 380 int count; 381 382 /* Model 400 has no first chip. */ 383 port = ((rev & BSR_VAR_MASK) != CRONYX_400) ? CS0(port) : CS1(port); 384 385 /* Wait up to 10 msec for revision code to appear after reset. */ 386 for (count=0; inb(GFRCR(port))==0; ++count) 387 if (count >= 20000) 388 return (0); /* reset failed */ 389 390 return inb (GFRCR (port)); 391} 392 393/* 394 * Probe and initialize the board structure. 395 */ 396void cx_init (cx_board_t *b, int num, port_t port, int irq, int dma) 397{ 398 int gfrcr, rev, chain, mod = 0, rev2 = 0, mod2 = 0; 399 400 rev = inb (BSR(port)); 401 chain = ! (rev & BSR_NOCHAIN); 402 if (cx_probe_800_chained_board (port)) { 403 cx_init_800 (b, num, port, irq, dma, chain); 404 return; 405 } 406 if ((rev & BSR2X_VAR_MASK) == CRONYX_22 || 407 (rev & BSR2X_VAR_MASK) == CRONYX_24) { 408 cx_init_2x (b, num, port, irq, dma, 409 (rev & BSR2X_VAR_MASK), (rev & BSR2X_OSC_33)); 410 return; 411 } 412 413 outb (BCR0(port), BCR0_NORESET); 414 if (chain) 415 outb (BCR0(port+0x10), BCR0_NORESET); 416 gfrcr = cx_chip_revision (port, rev); 417 if (gfrcr >= REVCL31_MIN && gfrcr <= REVCL31_MAX) 418 mod = 1; 419 if (chain) { 420 rev2 = inb (BSR(port+0x10)); 421 gfrcr = cx_chip_revision (port+0x10, rev2); 422 if (gfrcr >= REVCL31_MIN && gfrcr <= REVCL31_MAX) 423 mod2 = 1; 424 outb (BCR0(port+0x10), 0); 425 } 426 outb (BCR0(port), 0); 427 428 cx_init_board (b, num, port, irq, dma, chain, 429 (rev & BSR_VAR_MASK), (rev & BSR_OSC_MASK), mod, 430 (rev2 & BSR_VAR_MASK), (rev2 & BSR_OSC_MASK), mod2); 431} 432 433/* 434 * Initialize the board structure, given the type of the board. 435 */ 436void cx_init_board (cx_board_t *b, int num, port_t port, int irq, int dma, 437 int chain, int rev, int osc, int mod, int rev2, int osc2, int mod2) 438{ 439 cx_chan_t *c; 440 char *type; 441 int i; 442 443 /* Initialize board structure. */ 444 b->port = port; 445 b->num = num; 446 b->irq = irq; 447 b->dma = dma; 448 b->opt = board_opt_dflt; 449 450 b->type = B_SIGMA_XXX; 451 b->if0type = b->if8type = cx_iftype; 452 453 /* Set channels 0 and 8 mode, set DMA and IRQ. */ 454 b->bcr0 = b->bcr0b = BCR0_NORESET | dmamask[b->dma] | irqmask[b->irq]; 455 456 /* Clear DTR[0..3] and DTR[8..12]. */ 457 b->bcr1 = b->bcr1b = 0; 458 459 /*------------------ Master board -------------------*/ 460 461 /* Read and check the board revision code. */ 462 strcpy (b->name, mod ? "m" : ""); 463 switch (rev) { 464 default: type = ""; break; 465 case CRONYX_100: type = "100"; break; 466 case CRONYX_400: type = "400"; break; 467 case CRONYX_500: type = "500"; break; 468 case CRONYX_410: type = "410"; break; 469 case CRONYX_810: type = "810"; break; 470 case CRONYX_410s: type = "410s"; break; 471 case CRONYX_810s: type = "810s"; break; 472 case CRONYX_440: type = "440"; break; 473 case CRONYX_840: type = "840"; break; 474 case CRONYX_401: type = "401"; break; 475 case CRONYX_801: type = "801"; break; 476 case CRONYX_401s: type = "401s"; break; 477 case CRONYX_801s: type = "801s"; break; 478 case CRONYX_404: type = "404"; break; 479 case CRONYX_703: type = "703"; break; 480 } 481 strcat (b->name, type); 482 483 switch (osc) { 484 default: 485 case BSR_OSC_20: /* 20 MHz */ 486 b->chan[0].oscfreq = b->chan[1].oscfreq = 487 b->chan[2].oscfreq = b->chan[3].oscfreq = 488 b->chan[4].oscfreq = b->chan[5].oscfreq = 489 b->chan[6].oscfreq = b->chan[7].oscfreq = 490 mod ? 33000000L : 20000000L; 491 strcat (b->name, "a"); 492 break; 493 case BSR_OSC_18432: /* 18.432 MHz */ 494 b->chan[0].oscfreq = b->chan[1].oscfreq = 495 b->chan[2].oscfreq = b->chan[3].oscfreq = 496 b->chan[4].oscfreq = b->chan[5].oscfreq = 497 b->chan[6].oscfreq = b->chan[7].oscfreq = 498 mod ? 20000000L : 18432000L; 499 strcat (b->name, "b"); 500 break; 501 } 502 503 /*------------------ Slave board -------------------*/ 504 505 if (chain) { 506 /* Read and check the board revision code. */ 507 strcat (b->name, mod2 ? "/m" : "/"); 508 switch (rev2) { 509 default: type = ""; break; 510 case CRONYX_100: type = "100"; break; 511 case CRONYX_400: type = "400"; break; 512 case CRONYX_500: type = "500"; break; 513 case CRONYX_410: type = "410"; break; 514 case CRONYX_810: type = "810"; break; 515 case CRONYX_410s: type = "410s"; break; 516 case CRONYX_810s: type = "810s"; break; 517 case CRONYX_440: type = "440"; break; 518 case CRONYX_840: type = "840"; break; 519 case CRONYX_401: type = "401"; break; 520 case CRONYX_801: type = "801"; break; 521 case CRONYX_401s: type = "401s"; break; 522 case CRONYX_801s: type = "801s"; break; 523 case CRONYX_404: type = "404"; break; 524 case CRONYX_703: type = "703"; break; 525 } 526 strcat (b->name, type); 527 528 switch (osc2) { 529 default: 530 case BSR_OSC_20: /* 20 MHz */ 531 b->chan[8].oscfreq = b->chan[9].oscfreq = 532 b->chan[10].oscfreq = b->chan[11].oscfreq = 533 b->chan[12].oscfreq = b->chan[13].oscfreq = 534 b->chan[14].oscfreq = b->chan[15].oscfreq = 535 mod2 ? 33000000L : 20000000L; 536 strcat (b->name, "a"); 537 break; 538 case BSR_OSC_18432: /* 18.432 MHz */ 539 b->chan[8].oscfreq = b->chan[9].oscfreq = 540 b->chan[10].oscfreq = b->chan[11].oscfreq = 541 b->chan[12].oscfreq = b->chan[13].oscfreq = 542 b->chan[14].oscfreq = b->chan[15].oscfreq = 543 mod2 ? 20000000L : 18432000L; 544 strcat (b->name, "b"); 545 break; 546 } 547 } 548 549 /* Initialize channel structures. */ 550 for (i=0; i<4; ++i) { 551 b->chan[i+0].port = CS0(port); 552 b->chan[i+4].port = cx_probe_chip (CS1A(port)) ? 553 CS1A(port) : CS1(port); 554 b->chan[i+8].port = CS0(port+0x10); 555 b->chan[i+12].port = CS1(port+0x10); 556 } 557 for (c=b->chan; c<b->chan+NCHAN; ++c) { 558 c->board = b; 559 c->num = c - b->chan; 560 c->type = T_NONE; 561 } 562 563 /*------------------ Master board -------------------*/ 564 565 switch (rev) { 566 case CRONYX_400: 567 for (i=4; i<8; ++i) 568 b->chan[i].type = T_UNIV_RS232; 569 break; 570 case CRONYX_100: 571 b->chan[0].type = T_UNIV_RS232; 572 break; 573 case CRONYX_500: 574 b->chan[0].type = T_UNIV_RS232; 575 for (i=4; i<8; ++i) 576 b->chan[i].type = T_UNIV_RS232; 577 break; 578 case CRONYX_410: 579 b->chan[0].type = T_UNIV_V35; 580 for (i=1; i<4; ++i) 581 b->chan[i].type = T_UNIV_RS232; 582 break; 583 case CRONYX_810: 584 b->chan[0].type = T_UNIV_V35; 585 for (i=1; i<8; ++i) 586 b->chan[i].type = T_UNIV_RS232; 587 break; 588 case CRONYX_410s: 589 b->chan[0].type = T_UNIV_V35; 590 for (i=1; i<4; ++i) 591 b->chan[i].type = T_SYNC_RS232; 592 break; 593 case CRONYX_810s: 594 b->chan[0].type = T_UNIV_V35; 595 for (i=1; i<4; ++i) 596 b->chan[i].type = T_SYNC_RS232; 597 for (i=4; i<8; ++i) 598 b->chan[i].type = T_UNIV_RS232; 599 break; 600 case CRONYX_440: 601 b->chan[0].type = T_UNIV_V35; 602 for (i=1; i<4; ++i) 603 b->chan[i].type = T_SYNC_V35; 604 break; 605 case CRONYX_840: 606 b->chan[0].type = T_UNIV_V35; 607 for (i=1; i<4; ++i) 608 b->chan[i].type = T_SYNC_V35; 609 for (i=4; i<8; ++i) 610 b->chan[i].type = T_UNIV_RS232; 611 break; 612 case CRONYX_401: 613 b->chan[0].type = T_UNIV_RS449; 614 for (i=1; i<4; ++i) 615 b->chan[i].type = T_UNIV_RS232; 616 break; 617 case CRONYX_801: 618 b->chan[0].type = T_UNIV_RS449; 619 for (i=1; i<8; ++i) 620 b->chan[i].type = T_UNIV_RS232; 621 break; 622 case CRONYX_401s: 623 b->chan[0].type = T_UNIV_RS449; 624 for (i=1; i<4; ++i) 625 b->chan[i].type = T_SYNC_RS232; 626 break; 627 case CRONYX_801s: 628 b->chan[0].type = T_UNIV_RS449; 629 for (i=1; i<4; ++i) 630 b->chan[i].type = T_SYNC_RS232; 631 for (i=4; i<8; ++i) 632 b->chan[i].type = T_UNIV_RS232; 633 break; 634 case CRONYX_404: 635 b->chan[0].type = T_UNIV_RS449; 636 for (i=1; i<4; ++i) 637 b->chan[i].type = T_SYNC_RS449; 638 break; 639 case CRONYX_703: 640 b->chan[0].type = T_UNIV_RS449; 641 for (i=1; i<3; ++i) 642 b->chan[i].type = T_SYNC_RS449; 643 for (i=4; i<8; ++i) 644 b->chan[i].type = T_UNIV_RS232; 645 break; 646 } 647 648 /*------------------ Slave board -------------------*/ 649 650 if (chain) { 651 switch (rev2) { 652 case CRONYX_400: 653 break; 654 case CRONYX_100: 655 b->chan[8].type = T_UNIV_RS232; 656 break; 657 case CRONYX_500: 658 b->chan[8].type = T_UNIV_RS232; 659 for (i=12; i<16; ++i) 660 b->chan[i].type = T_UNIV_RS232; 661 break; 662 case CRONYX_410: 663 b->chan[8].type = T_UNIV_V35; 664 for (i=9; i<12; ++i) 665 b->chan[i].type = T_UNIV_RS232; 666 break; 667 case CRONYX_810: 668 b->chan[8].type = T_UNIV_V35; 669 for (i=9; i<16; ++i) 670 b->chan[i].type = T_UNIV_RS232; 671 break; 672 case CRONYX_410s: 673 b->chan[8].type = T_UNIV_V35; 674 for (i=9; i<12; ++i) 675 b->chan[i].type = T_SYNC_RS232; 676 break; 677 case CRONYX_810s: 678 b->chan[8].type = T_UNIV_V35; 679 for (i=9; i<12; ++i) 680 b->chan[i].type = T_SYNC_RS232; 681 for (i=12; i<16; ++i) 682 b->chan[i].type = T_UNIV_RS232; 683 break; 684 case CRONYX_440: 685 b->chan[8].type = T_UNIV_V35; 686 for (i=9; i<12; ++i) 687 b->chan[i].type = T_SYNC_V35; 688 break; 689 case CRONYX_840: 690 b->chan[8].type = T_UNIV_V35; 691 for (i=9; i<12; ++i) 692 b->chan[i].type = T_SYNC_V35; 693 for (i=12; i<16; ++i) 694 b->chan[i].type = T_UNIV_RS232; 695 break; 696 case CRONYX_401: 697 b->chan[8].type = T_UNIV_RS449; 698 for (i=9; i<12; ++i) 699 b->chan[i].type = T_UNIV_RS232; 700 break; 701 case CRONYX_801: 702 b->chan[8].type = T_UNIV_RS449; 703 for (i=9; i<16; ++i) 704 b->chan[i].type = T_UNIV_RS232; 705 break; 706 case CRONYX_401s: 707 b->chan[8].type = T_UNIV_RS449; 708 for (i=9; i<12; ++i) 709 b->chan[i].type = T_UNIV_RS232; 710 break; 711 case CRONYX_801s: 712 b->chan[8].type = T_UNIV_RS449; 713 for (i=9; i<12; ++i) 714 b->chan[i].type = T_SYNC_RS232; 715 for (i=12; i<16; ++i) 716 b->chan[i].type = T_UNIV_RS232; 717 break; 718 case CRONYX_404: 719 b->chan[8].type = T_UNIV_RS449; 720 for (i=9; i<12; ++i) 721 b->chan[i].type = T_SYNC_RS449; 722 break; 723 case CRONYX_703: 724 b->chan[8].type = T_UNIV_RS449; 725 for (i=9; i<11; ++i) 726 b->chan[i].type = T_SYNC_RS449; 727 for (i=12; i<16; ++i) 728 b->chan[i].type = T_UNIV_RS232; 729 break; 730 } 731 } 732 733 b->nuniv = b->nsync = b->nasync = 0; 734 for (c=b->chan; c<b->chan+NCHAN; ++c) 735 switch (c->type) { 736 case T_ASYNC: ++b->nasync; break; 737 case T_UNIV: 738 case T_UNIV_RS232: 739 case T_UNIV_RS449: 740 case T_UNIV_V35: ++b->nuniv; break; 741 case T_SYNC_RS232: 742 case T_SYNC_V35: 743 case T_SYNC_RS449: ++b->nsync; break; 744 } 745 746 cx_reinit_board (b); 747} 748 749/* 750 * Initialize the Sigma-800 board structure. 751 */ 752void cx_init_800 (cx_board_t *b, int num, port_t port, int irq, int dma, 753 int chain) 754{ 755 cx_chan_t *c; 756 int i; 757 758 /* Initialize board structure. */ 759 b->port = port; 760 b->num = num; 761 b->irq = irq; 762 b->dma = dma; 763 b->opt = board_opt_dflt; 764 b->type = B_SIGMA_800; 765 766 /* Set channels 0 and 8 mode, set DMA and IRQ. */ 767 b->bcr0 = b->bcr0b = dmamask[b->dma] | irqmask[b->irq]; 768 769 /* Clear DTR[0..7] and DTR[8..15]. */ 770 b->bcr1 = b->bcr1b = 0; 771 772 strcpy (b->name, "800"); 773 if (chain) 774 strcat (b->name, "/800"); 775 776 /* Initialize channel structures. */ 777 for (i=0; i<4; ++i) { 778 b->chan[i+0].port = CS0(port); 779 b->chan[i+4].port = cx_probe_chip (CS1A(port)) ? 780 CS1A(port) : CS1(port); 781 b->chan[i+8].port = CS0(port+0x10); 782 b->chan[i+12].port = CS1(port+0x10); 783 } 784 for (c=b->chan; c<b->chan+NCHAN; ++c) { 785 c->board = b; 786 c->num = c - b->chan; 787 c->oscfreq = 33000000L; 788 c->type = (c->num < 8 || chain) ? T_UNIV_RS232 : T_NONE; 789 } 790 791 b->nuniv = b->nsync = b->nasync = 0; 792 for (c=b->chan; c<b->chan+NCHAN; ++c) 793 switch (c->type) { 794 case T_ASYNC: ++b->nasync; break; 795 case T_UNIV: 796 case T_UNIV_RS232: 797 case T_UNIV_RS449: 798 case T_UNIV_V35: ++b->nuniv; break; 799 case T_SYNC_RS232: 800 case T_SYNC_V35: 801 case T_SYNC_RS449: ++b->nsync; break; 802 } 803 804 cx_reinit_board (b); 805} 806 807/* 808 * Initialize the Sigma-2x board structure. 809 */ 810void cx_init_2x (cx_board_t *b, int num, port_t port, int irq, int dma, 811 int rev, int osc) 812{ 813 cx_chan_t *c; 814 int i; 815 816 /* Initialize board structure. */ 817 b->port = port; 818 b->num = num; 819 b->irq = irq; 820 b->dma = dma; 821 b->opt = board_opt_dflt; 822 823 b->type = B_SIGMA_2X; 824 825 /* Set channels 0 and 8 mode, set DMA and IRQ. */ 826 b->bcr0 = BCR0_NORESET | dmamask[b->dma] | irqmask[b->irq]; 827 if (b->type == B_SIGMA_2X && b->opt.fast) 828 b->bcr0 |= BCR02X_FAST; 829 830 /* Clear DTR[0..3] and DTR[8..12]. */ 831 b->bcr1 = 0; 832 833 /* Initialize channel structures. */ 834 for (i=0; i<4; ++i) { 835 b->chan[i+0].port = CS0(port); 836 b->chan[i+4].port = CS1(port); 837 b->chan[i+8].port = CS0(port+0x10); 838 b->chan[i+12].port = CS1(port+0x10); 839 } 840 for (c=b->chan; c<b->chan+NCHAN; ++c) { 841 c->board = b; 842 c->num = c - b->chan; 843 c->type = T_NONE; 844 c->oscfreq = (osc & BSR2X_OSC_33) ? 33000000L : 20000000L; 845 } 846 847 /* Check the board revision code. */ 848 strcpy (b->name, "22"); 849 b->chan[0].type = T_UNIV; 850 b->chan[1].type = T_UNIV; 851 b->nsync = b->nasync = 0; 852 b->nuniv = 2; 853 if (rev == CRONYX_24) { 854 strcpy (b->name, "24"); 855 b->chan[2].type = T_UNIV; 856 b->chan[3].type = T_UNIV; 857 b->nuniv += 2; 858 } 859 strcat (b->name, (osc & BSR2X_OSC_33) ? "c" : "a"); 860 cx_reinit_board (b); 861} 862 863/* 864 * Reinitialize all channels, using new options and baud rate. 865 */ 866void cx_reinit_board (cx_board_t *b) 867{ 868 cx_chan_t *c; 869 870 b->opt = board_opt_dflt; 871 if (b->type == B_SIGMA_2X) { 872 b->bcr0 &= ~BCR02X_FAST; 873 if (b->opt.fast) 874 b->bcr0 |= BCR02X_FAST; 875 } else 876 b->if0type = b->if8type = cx_iftype; 877 for (c=b->chan; c<b->chan+NCHAN; ++c) { 878 switch (c->type) { 879 default: 880 case T_NONE: 881 continue; 882 case T_UNIV: 883 case T_UNIV_RS232: 884 case T_UNIV_RS449: 885 case T_UNIV_V35: 886 c->mode = (cx_univ_mode == M_ASYNC) ? 887 M_ASYNC : cx_sync_mode; 888 break; 889 case T_SYNC_RS232: 890 case T_SYNC_V35: 891 case T_SYNC_RS449: 892 c->mode = cx_sync_mode; 893 break; 894 case T_ASYNC: 895 c->mode = M_ASYNC; 896 break; 897 } 898 c->rxbaud = cx_rxbaud; 899 c->txbaud = cx_txbaud; 900 c->opt = chan_opt_dflt; 901 c->aopt = opt_async_dflt; 902 c->hopt = opt_hdlc_dflt; 903 } 904} 905 906/* 907 * Set up the board. 908 */ 909int cx_setup_board (cx_board_t *b, const unsigned char *firmware, 910 long bits, const cr_dat_tst_t *tst) 911{ 912 int i; 913#ifndef NDIS_MINIPORT_DRIVER 914 /* Disable DMA channel. */ 915 outb (DMA_MASK, (b->dma & 3) | DMA_MASK_CLEAR); 916#endif 917 /* Reset the controller. */ 918 outb (BCR0(b->port), 0); 919 if (b->chan[8].type || b->chan[12].type) 920 outb (BCR0(b->port+0x10), 0); 921 922 /* Load the firmware. */ 923 if (b->type == B_SIGMA_800) { 924 /* Reset the controllers. */ 925 outb (BCR2(b->port), BCR2_TMS); 926 if (b->chan[8].type || b->chan[12].type) 927 outb (BCR2(b->port+0x10), BCR2_TMS); 928 outb (BCR2(b->port), 0); 929 if (b->chan[8].type || b->chan[12].type) 930 outb (BCR2(b->port+0x10), 0); 931 932 if (firmware && 933 (! cx_download (b->port, firmware, bits, tst) || 934 ((b->chan[8].type || b->chan[12].type) && 935 ! cx_download (b->port+0x10, firmware, bits, tst)))) 936 return (0); 937 } 938 939 /* 940 * Set channels 0 and 8 to RS232 async. mode. 941 * Enable DMA and IRQ. 942 */ 943 outb (BCR0(b->port), b->bcr0); 944 if (b->chan[8].type || b->chan[12].type) 945 outb (BCR0(b->port+0x10), b->bcr0b); 946 947 /* Clear DTR[0..3] and DTR[8..12]. */ 948 outw (BCR1(b->port), b->bcr1); 949 if (b->chan[8].type || b->chan[12].type) 950 outw (BCR1(b->port+0x10), b->bcr1b); 951 952 if (b->type == B_SIGMA_800) 953 outb (BCR2(b->port), b->opt.fast & 954 (BCR2_BUS0 | BCR2_BUS1)); 955 956 /* Initialize all controllers. */ 957 for (i=0; i<NCHAN; i+=4) 958 if (b->chan[i].type != T_NONE) 959 cx_setup_chip (b->chan + i); 960#ifndef NDIS_MINIPORT_DRIVER 961 /* Set up DMA channel to master mode. */ 962 outb (DMA_MODE, (b->dma & 3) | DMA_MODE_MASTER); 963 964 /* Enable DMA channel. */ 965 outb (DMA_MASK, b->dma & 3); 966#endif 967 /* Initialize all channels. */ 968 for (i=0; i<NCHAN; ++i) 969 if (b->chan[i].type != T_NONE) 970 cx_setup_chan (b->chan + i); 971 return (1); 972} 973 974/* 975 * Initialize the board. 976 */ 977static void cx_setup_chip (cx_chan_t *c) 978{ 979 /* Reset the chip. */ 980 cx_reset (c->port); 981 982 /* 983 * Set all interrupt level registers to the same value. 984 * This enables the internal CD2400 priority scheme. 985 */ 986 outb (RPILR(c->port), BRD_INTR_LEVEL); 987 outb (TPILR(c->port), BRD_INTR_LEVEL); 988 outb (MPILR(c->port), BRD_INTR_LEVEL); 989 990 /* Set bus error count to zero. */ 991 outb (BERCNT(c->port), 0); 992 993 /* Set 16-bit DMA mode. */ 994 outb (DMR(c->port), 0); 995 996 /* Set timer period register to 1 msec (approximately). */ 997 outb (TPR(c->port), 10); 998} 999 1000/* 1001 * Initialize the CD2400 channel. 1002 */ 1003void cx_update_chan (cx_chan_t *c) 1004{ 1005 int clock, period; 1006 1007 if (c->board->type == B_SIGMA_XXX) 1008 switch (c->num) { 1009 case 0: 1010 c->board->bcr0 &= ~BCR0_UMASK; 1011 if (c->mode != M_ASYNC) 1012 c->board->bcr0 |= BCR0_UM_SYNC; 1013 if (c->board->if0type && 1014 (c->type==T_UNIV_RS449 || c->type==T_UNIV_V35)) 1015 c->board->bcr0 |= BCR0_UI_RS449; 1016 outb (BCR0(c->board->port), c->board->bcr0); 1017 break; 1018 case 8: 1019 c->board->bcr0b &= ~BCR0_UMASK; 1020 if (c->mode != M_ASYNC) 1021 c->board->bcr0b |= BCR0_UM_SYNC; 1022 if (c->board->if8type && 1023 (c->type==T_UNIV_RS449 || c->type==T_UNIV_V35)) 1024 c->board->bcr0b |= BCR0_UI_RS449; 1025 outb (BCR0(c->board->port+0x10), c->board->bcr0b); 1026 break; 1027 } 1028 1029 /* set current channel number */ 1030 outb (CAR(c->port), c->num & 3); 1031 1032 switch (c->mode) { /* initialize the channel mode */ 1033 case M_ASYNC: 1034 /* set receiver timeout register */ 1035 outw (RTPR(c->port), 10); /* 10 msec, see TPR */ 1036 c->opt.rcor.encod = ENCOD_NRZ; 1037 1038 outb (CMR(c->port), CMR_RXDMA | CMR_TXDMA | CMR_ASYNC); 1039 outb (COR1(c->port), BYTE c->aopt.cor1); 1040 outb (COR2(c->port), BYTE c->aopt.cor2); 1041 outb (COR3(c->port), BYTE c->aopt.cor3); 1042 outb (COR6(c->port), BYTE c->aopt.cor6); 1043 outb (COR7(c->port), BYTE c->aopt.cor7); 1044 outb (SCHR1(c->port), c->aopt.schr1); 1045 outb (SCHR2(c->port), c->aopt.schr2); 1046 outb (SCHR3(c->port), c->aopt.schr3); 1047 outb (SCHR4(c->port), c->aopt.schr4); 1048 outb (SCRL(c->port), c->aopt.scrl); 1049 outb (SCRH(c->port), c->aopt.scrh); 1050 outb (LNXT(c->port), c->aopt.lnxt); 1051 break; 1052 case M_HDLC: 1053 outb (CMR(c->port), CMR_RXDMA | CMR_TXDMA | CMR_HDLC); 1054 outb (COR1(c->port), BYTE c->hopt.cor1); 1055 outb (COR2(c->port), BYTE c->hopt.cor2); 1056 outb (COR3(c->port), BYTE c->hopt.cor3); 1057 outb (RFAR1(c->port), c->hopt.rfar1); 1058 outb (RFAR2(c->port), c->hopt.rfar2); 1059 outb (RFAR3(c->port), c->hopt.rfar3); 1060 outb (RFAR4(c->port), c->hopt.rfar4); 1061 outb (CPSR(c->port), c->hopt.cpsr); 1062 break; 1063 } 1064 1065 /* set mode-independent options */ 1066 outb (COR4(c->port), BYTE c->opt.cor4); 1067 outb (COR5(c->port), BYTE c->opt.cor5); 1068 1069 /* set up receiver clock values */ 1070 if (c->mode == M_ASYNC || c->opt.rcor.dpll || c->opt.tcor.llm) { 1071 cx_clock (c->oscfreq, c->rxbaud, &clock, &period); 1072 c->opt.rcor.clk = clock; 1073 } else { 1074 c->opt.rcor.clk = CLK_EXT; 1075 period = 1; 1076 } 1077 outb (RCOR(c->port), BYTE c->opt.rcor); 1078 outb (RBPR(c->port), period); 1079 1080 /* set up transmitter clock values */ 1081 if (c->mode == M_ASYNC || !c->opt.tcor.ext1x) { 1082 unsigned ext1x = c->opt.tcor.ext1x; 1083 c->opt.tcor.ext1x = 0; 1084 cx_clock (c->oscfreq, c->txbaud, &clock, &period); 1085 c->opt.tcor.clk = clock; 1086 c->opt.tcor.ext1x = ext1x; 1087 } else { 1088 c->opt.tcor.clk = CLK_EXT; 1089 period = 1; 1090 } 1091 outb (TCOR(c->port), BYTE c->opt.tcor); 1092 outb (TBPR(c->port), period); 1093} 1094 1095/* 1096 * Initialize the CD2400 channel. 1097 */ 1098void cx_setup_chan (cx_chan_t *c) 1099{ 1100 /* set current channel number */ 1101 outb (CAR(c->port), c->num & 3); 1102 1103 /* reset the channel */ 1104 cx_cmd (c->port, CCR_CLRCH); 1105 1106 /* set LIVR to contain the board and channel numbers */ 1107 outb (LIVR(c->port), c->board->num << 6 | c->num << 2); 1108 1109 /* clear DTR, RTS, set TXCout/DTR pin */ 1110 outb (MSVR_RTS(c->port), 0); 1111 outb (MSVR_DTR(c->port), c->mode==M_ASYNC ? 0 : MSV_TXCOUT); 1112 1113 /* set receiver A buffer physical address */ 1114 outw (ARBADRU(c->port), (unsigned short) (c->arphys>>16)); 1115 outw (ARBADRL(c->port), (unsigned short) c->arphys); 1116 1117 /* set receiver B buffer physical address */ 1118 outw (BRBADRU(c->port), (unsigned short) (c->brphys>>16)); 1119 outw (BRBADRL(c->port), (unsigned short) c->brphys); 1120 1121 /* set transmitter A buffer physical address */ 1122 outw (ATBADRU(c->port), (unsigned short) (c->atphys>>16)); 1123 outw (ATBADRL(c->port), (unsigned short) c->atphys); 1124 1125 /* set transmitter B buffer physical address */ 1126 outw (BTBADRU(c->port), (unsigned short) (c->btphys>>16)); 1127 outw (BTBADRL(c->port), (unsigned short) c->btphys); 1128 1129 c->dtr = 0; 1130 c->rts = 0; 1131 1132 cx_update_chan (c); 1133} 1134 1135/* 1136 * Control DTR signal for the channel. 1137 * Turn it on/off. 1138 */ 1139void cx_set_dtr (cx_chan_t *c, int on) 1140{ 1141 cx_board_t *b = c->board; 1142 1143 c->dtr = on ? 1 : 0; 1144 1145 if (b->type == B_SIGMA_2X) { 1146 if (on) b->bcr1 |= BCR1_DTR(c->num); 1147 else b->bcr1 &= ~BCR1_DTR(c->num); 1148 outw (BCR1(b->port), b->bcr1); 1149 return; 1150 } 1151 if (b->type == B_SIGMA_800) { 1152 if (c->num >= 8) { 1153 if (on) b->bcr1b |= BCR1800_DTR(c->num); 1154 else b->bcr1b &= ~BCR1800_DTR(c->num); 1155 outb (BCR1(b->port+0x10), b->bcr1b); 1156 } else { 1157 if (on) b->bcr1 |= BCR1800_DTR(c->num); 1158 else b->bcr1 &= ~BCR1800_DTR(c->num); 1159 outb (BCR1(b->port), b->bcr1); 1160 } 1161 return; 1162 } 1163 if (c->mode == M_ASYNC) { 1164 outb (CAR(c->port), c->num & 3); 1165 outb (MSVR_DTR(c->port), on ? MSV_DTR : 0); 1166 return; 1167 } 1168 1169 switch (c->num) { 1170 default: 1171 /* Channels 4..7 and 12..15 in synchronous mode 1172 * have no DTR signal. */ 1173 break; 1174 1175 case 1: case 2: case 3: 1176 if (c->type == T_UNIV_RS232) 1177 break; 1178 case 0: 1179 if (on) b->bcr1 |= BCR1_DTR(c->num); 1180 else b->bcr1 &= ~BCR1_DTR(c->num); 1181 outw (BCR1(b->port), b->bcr1); 1182 break; 1183 1184 case 9: case 10: case 11: 1185 if (c->type == T_UNIV_RS232) 1186 break; 1187 case 8: 1188 if (on) b->bcr1b |= BCR1_DTR(c->num & 3); 1189 else b->bcr1b &= ~BCR1_DTR(c->num & 3); 1190 outw (BCR1(b->port+0x10), b->bcr1b); 1191 break; 1192 } 1193} 1194 1195/* 1196 * Control RTS signal for the channel. 1197 * Turn it on/off. 1198 */ 1199void cx_set_rts (cx_chan_t *c, int on) 1200{ 1201 c->rts = on ? 1 : 0; 1202 outb (CAR(c->port), c->num & 3); 1203 outb (MSVR_RTS(c->port), on ? MSV_RTS : 0); 1204} 1205 1206/* 1207 * Get the state of DSR signal of the channel. 1208 */ 1209int cx_get_dsr (cx_chan_t *c) 1210{ 1211 unsigned char sigval; 1212 1213 if (c->board->type == B_SIGMA_2X || 1214 c->board->type == B_SIGMA_800 || 1215 c->mode == M_ASYNC) { 1216 outb (CAR(c->port), c->num & 3); 1217 return (inb (MSVR(c->port)) & MSV_DSR ? 1 : 0); 1218 } 1219 1220 /* 1221 * Channels 4..7 and 12..15 don't have DSR signal available. 1222 */ 1223 switch (c->num) { 1224 default: 1225 return (1); 1226 1227 case 1: case 2: case 3: 1228 if (c->type == T_UNIV_RS232) 1229 return (1); 1230 case 0: 1231 sigval = inw (BSR(c->board->port)) >> 8; 1232 break; 1233 1234 case 9: case 10: case 11: 1235 if (c->type == T_UNIV_RS232) 1236 return (1); 1237 case 8: 1238 sigval = inw (BSR(c->board->port+0x10)) >> 8; 1239 break; 1240 } 1241 return (~sigval >> (c->num & 3) & 1); 1242} 1243 1244/* 1245 * Get the state of CARRIER signal of the channel. 1246 */ 1247int cx_get_cd (cx_chan_t *c) 1248{ 1249 unsigned char sigval; 1250 1251 if (c->board->type == B_SIGMA_2X || 1252 c->board->type == B_SIGMA_800 || 1253 c->mode == M_ASYNC) { 1254 outb (CAR(c->port), c->num & 3); 1255 return (inb (MSVR(c->port)) & MSV_CD ? 1 : 0); 1256 } 1257 1258 /* 1259 * Channels 4..7 and 12..15 don't have CD signal available. 1260 */ 1261 switch (c->num) { 1262 default: 1263 return (1); 1264 1265 case 1: case 2: case 3: 1266 if (c->type == T_UNIV_RS232) 1267 return (1); 1268 case 0: 1269 sigval = inw (BSR(c->board->port)) >> 8; 1270 break; 1271 1272 case 9: case 10: case 11: 1273 if (c->type == T_UNIV_RS232) 1274 return (1); 1275 case 8: 1276 sigval = inw (BSR(c->board->port+0x10)) >> 8; 1277 break; 1278 } 1279 return (~sigval >> 4 >> (c->num & 3) & 1); 1280} 1281 1282/* 1283 * Get the state of CTS signal of the channel. 1284 */ 1285int cx_get_cts (cx_chan_t *c) 1286{ 1287 outb (CAR(c->port), c->num & 3); 1288 return (inb (MSVR(c->port)) & MSV_CTS ? 1 : 0); 1289} 1290 1291/* 1292 * Compute CD2400 clock values. 1293 */ 1294void cx_clock (long hz, long ba, int *clk, int *div) 1295{ 1296 static short clocktab[] = { 8, 32, 128, 512, 2048, 0 }; 1297 1298 for (*clk=0; clocktab[*clk]; ++*clk) { 1299 long c = ba * clocktab[*clk]; 1300 if (hz <= c*256) { 1301 *div = (2 * hz + c) / (2 * c) - 1; 1302 return; 1303 } 1304 } 1305 /* Incorrect baud rate. Return some meaningful values. */ 1306 *clk = 0; 1307 *div = 255; 1308} 1309 1310/* 1311 * Turn LED on/off. 1312 */ 1313void cx_led (cx_board_t *b, int on) 1314{ 1315 switch (b->type) { 1316 case B_SIGMA_2X: 1317 if (on) b->bcr0 |= BCR02X_LED; 1318 else b->bcr0 &= ~BCR02X_LED; 1319 outb (BCR0(b->port), b->bcr0); 1320 break; 1321 } 1322} 1323 1324void cx_disable_dma (cx_board_t *b) 1325{ 1326#ifndef NDIS_MINIPORT_DRIVER 1327 /* Disable DMA channel. */ 1328 outb (DMA_MASK, (b->dma & 3) | DMA_MASK_CLEAR); 1329#endif 1330} 1331 1332cx_board_opt_t board_opt_dflt = { /* board options */ 1333 BUS_NORMAL, /* normal bus master timing */ 1334}; 1335 1336cx_chan_opt_t chan_opt_dflt = { /* mode-independent options */ 1337 { /* cor4 */ 1338 7, /* FIFO threshold, odd is better */ 1339 0, 1340 0, /* don't detect 1 to 0 on CTS */ 1341 1, /* detect 1 to 0 on CD */ 1342 0, /* detect 1 to 0 on DSR */ 1343 }, 1344 { /* cor5 */ 1345 0, /* receive flow control FIFO threshold */ 1346 0, 1347 0, /* don't detect 0 to 1 on CTS */ 1348 1, /* detect 0 to 1 on CD */ 1349 0, /* detect 0 to 1 on DSR */ 1350 }, 1351 { /* rcor */ 1352 0, /* dummy clock source */ 1353 ENCOD_NRZ, /* NRZ mode */ 1354 0, /* disable DPLL */ 1355 0, 1356 0, /* transmit line value */ 1357 }, 1358 { /* tcor */ 1359 0, 1360 0, /* local loopback mode */ 1361 0, 1362 1, /* external 1x clock mode */ 1363 0, 1364 0, /* dummy transmit clock source */ 1365 }, 1366}; 1367 1368cx_opt_async_t opt_async_dflt = { /* default async options */ 1369 { /* cor1 */ 1370 8-1, /* 8-bit char length */ 1371 0, /* don't ignore parity */ 1372 PARM_NOPAR, /* no parity */ 1373 PAR_EVEN, /* even parity */ 1374 }, 1375 { /* cor2 */ 1376 0, /* disable automatic DSR */ 1377 1, /* enable automatic CTS */ 1378 0, /* disable automatic RTS */ 1379 0, /* no remote loopback */ 1380 0, 1381 0, /* disable embedded cmds */ 1382 0, /* disable XON/XOFF */ 1383 0, /* disable XANY */ 1384 }, 1385 { /* cor3 */ 1386 STOPB_1, /* 1 stop bit */ 1387 0, 1388 0, /* disable special char detection */ 1389 FLOWCC_PASS, /* pass flow ctl chars to the host */ 1390 0, /* range detect disable */ 1391 0, /* disable extended spec. char detect */ 1392 }, 1393 { /* cor6 */ 1394 PERR_INTR, /* generate exception on parity errors */ 1395 BRK_INTR, /* generate exception on break condition */ 1396 0, /* don't translate NL to CR on input */ 1397 0, /* don't translate CR to NL on input */ 1398 0, /* don't discard CR on input */ 1399 }, 1400 { /* cor7 */ 1401 0, /* don't translate CR to NL on output */ 1402 0, /* don't translate NL to CR on output */ 1403 0, 1404 0, /* don't process flow ctl err chars */ 1405 0, /* disable LNext option */ 1406 0, /* don't strip 8 bit on input */ 1407 }, 1408 0, 0, 0, 0, 0, 0, 0, /* clear schr1-4, scrl, scrh, lnxt */ 1409}; 1410 1411cx_opt_hdlc_t opt_hdlc_dflt = { /* default hdlc options */ 1412 { /* cor1 */ 1413 2, /* 2 inter-frame flags */ 1414 0, /* no-address mode */ 1415 CLRDET_DISABLE, /* disable clear detect */ 1416 AFLO_1OCT, /* 1-byte address field length */ 1417 }, 1418 { /* cor2 */ 1419 0, /* disable automatic DSR */ 1420 0, /* disable automatic CTS */ 1421 0, /* disable automatic RTS */ 1422 0, 1423 CRC_INVERT, /* use CRC V.41 */ 1424 0, 1425 FCS_NOTPASS, /* don't pass received CRC to the host */ 1426 0, 1427 }, 1428 { /* cor3 */ 1429 0, /* 0 pad characters sent */ 1430 IDLE_FLAG, /* idle in flag */ 1431 0, /* enable FCS */ 1432 FCSP_ONES, /* FCS preset to all ones (V.41) */ 1433 SYNC_AA, /* use AAh as sync char */ 1434 0, /* disable pad characters */ 1435 }, 1436 0, 0, 0, 0, /* clear rfar1-4 */ 1437 POLY_V41, /* use V.41 CRC polynomial */ 1438}; 1439