1 /* $NetBSD: cy.c,v 1.10 1998/03/22 19:36:52 mycroft Exp $ */ 2 3 /* 4 * cy.c 5 * 6 * Driver for Cyclades Cyclom-8/16/32 multiport serial cards 7 * (currently not tested with Cyclom-32 cards) 8 * 9 * Timo Rossi, 1996 10 * 11 * Supports both ISA and PCI Cyclom cards 12 * 13 * Uses CD1400 automatic CTS flow control, and 14 * if CY_HW_RTS is defined, uses CD1400 automatic input flow control. 15 * This requires a special cable that exchanges the RTS and DTR lines. 16 * 17 * Lots of debug output can be enabled by defining CY_DEBUG 18 * Some debugging counters (number of receive/transmit interrupts etc.) 19 * can be enabled by defining CY_DEBUG1 20 */ 21 22 #include <sys/types.h> 23 #include <sys/param.h> 24 #include <sys/ioctl.h> 25 #include <sys/syslog.h> 26 #include <sys/fcntl.h> 27 #include <sys/tty.h> 28 #include <sys/proc.h> 29 #include <sys/conf.h> 30 #include <sys/user.h> 31 #include <sys/ioctl.h> 32 #include <sys/select.h> 33 #include <sys/device.h> 34 #include <sys/malloc.h> 35 #include <sys/systm.h> 36 37 #include <machine/bus.h> 38 39 #include <dev/ic/cd1400reg.h> 40 #include <dev/ic/cyreg.h> 41 #include <dev/ic/cyvar.h> 42 43 /* Macros to clear/set/test flags. */ 44 #define SET(t, f) (t) |= (f) 45 #define CLR(t, f) (t) &= ~(f) 46 #define ISSET(t, f) ((t) & (f)) 47 48 static int cyparam __P((struct tty *, struct termios *)); 49 static void cystart __P((struct tty *)); 50 static void cy_poll __P((void *)); 51 static int cy_modem_control __P((struct cy_softc *, 52 struct cy_port *, int, int)); 53 static void cy_enable_transmitter __P((struct cy_softc *, struct cy_port *)); 54 static void cd1400_channel_cmd __P((struct cy_softc *, struct cy_port *, int)); 55 static int cy_speed __P((speed_t, int *, int *)); 56 57 extern struct cfdriver cy_cd; 58 59 static int cy_open = 0; 60 static int cy_events = 0; 61 62 cdev_decl(cy); 63 64 /* 65 * Common probe routine 66 */ 67 int 68 cy_find(sc) 69 struct cy_softc *sc; 70 { 71 int cy_chip, chip; 72 u_char firmware_ver; 73 bus_space_tag_t tag = sc->sc_memt; 74 bus_space_handle_t bsh = sc->sc_bsh; 75 int bustype = sc->sc_bustype; 76 77 /* Cyclom card hardware reset */ 78 bus_space_write_1(tag, bsh, CY16_RESET << bustype, 0); 79 DELAY(500); /* wait for reset to complete */ 80 bus_space_write_1(tag, bsh, CY_CLEAR_INTR << bustype, 0); 81 82 #ifdef CY_DEBUG 83 printf("cy: card reset done\n"); 84 #endif 85 sc->sc_nchips = 0; 86 87 for (cy_chip = 0, chip = 0; cy_chip < CY_MAX_CD1400s; 88 cy_chip++, chip += (CY_CD1400_MEMSPACING << bustype)) { 89 int i; 90 91 /* 92 * the last 4 nchips are 'interleaved' with the first 4 on 93 * 32-port boards 94 */ 95 if (cy_chip == 4) 96 chip -= (CY32_ADDR_FIX << bustype); 97 98 #ifdef CY_DEBUG 99 printf("%s probe chip %d offset 0x%x ... ", 100 sc->sc_dev.dv_xname, cy_chip, chip); 101 #endif 102 103 /* wait until the chip is ready for command */ 104 DELAY(1000); 105 if (bus_space_read_1(tag, bsh, chip + 106 ((CD1400_CCR << 1) << bustype)) != 0) { 107 #ifdef CY_DEBUG 108 printf("not ready for command\n"); 109 #endif 110 break; 111 } 112 /* clear the firmware version reg. */ 113 bus_space_write_1(tag, bsh, chip + 114 ((CD1400_GFRCR << 1) << bustype), 0); 115 116 /* 117 * On Cyclom-16 references to non-existent chip 4 118 * actually access chip 0 (address line 9 not decoded). 119 * Here we check if the clearing of chip 4 GFRCR actually 120 * cleared chip 0 GFRCR. In that case we have a 16 port card. 121 */ 122 if (cy_chip == 4 && 123 bus_space_read_1(tag, bsh, /* off for chip 0 (0) + */ 124 ((CD1400_GFRCR << 1) << bustype)) == 0) 125 break; 126 127 /* reset the chip */ 128 bus_space_write_1(tag, bsh, chip + 129 ((CD1400_CCR << 1) << bustype), 130 CD1400_CCR_CMDRESET | CD1400_CCR_FULLRESET); 131 132 /* wait for the chip to initialize itself */ 133 for (i = 0; i < 200; i++) { 134 DELAY(50); 135 firmware_ver = bus_space_read_1(tag, bsh, chip + 136 ((CD1400_GFRCR << 1) << bustype)); 137 if ((firmware_ver & 0xf0) == 0x40) /* found a CD1400 */ 138 break; 139 } 140 #ifdef CY_DEBUG 141 printf("firmware version 0x%x\n", firmware_ver); 142 #endif 143 144 if ((firmware_ver & 0xf0) != 0x40) 145 break; 146 147 /* firmware version OK, CD1400 found */ 148 sc->sc_nchips++; 149 } 150 151 if (sc->sc_nchips == 0) { 152 #ifdef CY_DEBUG 153 printf("no CD1400s found\n"); 154 #endif 155 return 0; 156 } 157 #ifdef CY_DEBUG 158 printf("found %d CD1400s\n", sc->sc_nchips); 159 #endif 160 161 return 1; 162 } 163 164 void 165 cy_attach(parent, self, aux) 166 struct device *parent, *self; 167 void *aux; 168 { 169 int port, cy_chip, num_chips, cdu, chip; 170 struct cy_softc *sc = (void *) self; 171 172 num_chips = sc->sc_nchips; 173 if (num_chips == 0) 174 return; 175 176 bzero(sc->sc_ports, sizeof(sc->sc_ports)); 177 178 port = 0; 179 for (cy_chip = 0, chip = 0; cy_chip < num_chips; cy_chip++, 180 chip += (CY_CD1400_MEMSPACING << sc->sc_bustype)) { 181 182 if (cy_chip == 4) 183 chip -= (CY32_ADDR_FIX << sc->sc_bustype); 184 185 #ifdef CY_DEBUG 186 printf("attach CD1400 #%d offset 0x%x\n", cy_chip, chip); 187 #endif 188 sc->sc_cd1400_offs[cy_chip] = chip; 189 190 /* 191 * configure port 0 as serial port (should already be after 192 * reset) 193 */ 194 cd_write_reg(sc, cy_chip, CD1400_GCR, 0); 195 196 /* set up a receive timeout period (1ms) */ 197 cd_write_reg(sc, cy_chip, CD1400_PPR, 198 (CY_CLOCK / CD1400_PPR_PRESCALER / 1000) + 1); 199 200 for (cdu = 0; cdu < CD1400_NO_OF_CHANNELS; cdu++) { 201 sc->sc_ports[port].cy_port_num = port; 202 sc->sc_ports[port].cy_chip = cy_chip; 203 204 /* should we initialize anything else here? */ 205 port++; 206 } /* for(each port on one CD1400...) */ 207 208 } /* for(each CD1400 on a card... ) */ 209 210 printf(": %d ports\n", port); 211 212 /* ensure an edge for the next interrupt */ 213 bus_space_write_1(sc->sc_memt, sc->sc_bsh, 214 CY_CLEAR_INTR << sc->sc_bustype, 0); 215 } 216 217 /* 218 * open routine. returns zero if successfull, else error code 219 */ 220 int 221 cyopen(dev, flag, mode, p) 222 dev_t dev; 223 int flag, mode; 224 struct proc *p; 225 { 226 int card = CY_CARD(dev); 227 int port = CY_PORT(dev); 228 struct cy_softc *sc; 229 struct cy_port *cy; 230 struct tty *tp; 231 int s, error; 232 233 #ifdef CY_DEBUG 234 printf("cy%d open port %d flag 0x%x mode 0x%x\n", 235 card, port, flag, mode); 236 #endif 237 238 if (card >= cy_cd.cd_ndevs || (sc = cy_cd.cd_devs[card]) == NULL) 239 return ENXIO; 240 241 cy = &sc->sc_ports[port]; 242 243 s = spltty(); 244 if (cy->cy_tty == NULL) { 245 if ((cy->cy_tty = ttymalloc()) == NULL) { 246 splx(s); 247 printf("cy%d: port %d: can't allocate tty\n", 248 card, port); 249 return ENOMEM; 250 } 251 tty_attach(cy->cy_tty); 252 } 253 splx(s); 254 255 tp = cy->cy_tty; 256 tp->t_oproc = cystart; 257 tp->t_param = cyparam; 258 tp->t_dev = dev; 259 260 if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { 261 ttychars(tp); 262 tp->t_iflag = TTYDEF_IFLAG; 263 tp->t_oflag = TTYDEF_OFLAG; 264 tp->t_cflag = TTYDEF_CFLAG; 265 if (ISSET(cy->cy_openflags, TIOCFLAG_CLOCAL)) 266 SET(tp->t_cflag, CLOCAL); 267 if (ISSET(cy->cy_openflags, TIOCFLAG_CRTSCTS)) 268 SET(tp->t_cflag, CRTSCTS); 269 if (ISSET(cy->cy_openflags, TIOCFLAG_MDMBUF)) 270 SET(tp->t_cflag, MDMBUF); 271 tp->t_lflag = TTYDEF_LFLAG; 272 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; 273 274 s = spltty(); 275 276 /* 277 * Allocate input ring buffer if we don't already have one 278 */ 279 if (cy->cy_ibuf == NULL) { 280 cy->cy_ibuf = malloc(CY_IBUF_SIZE, M_DEVBUF, M_NOWAIT); 281 if (cy->cy_ibuf == NULL) { 282 printf("%s: port %d: can't allocate input buffer\n", 283 sc->sc_dev.dv_xname, port); 284 splx(s); 285 return ENOMEM; 286 } 287 cy->cy_ibuf_end = cy->cy_ibuf + CY_IBUF_SIZE; 288 } 289 /* mark the ring buffer as empty */ 290 cy->cy_ibuf_rd_ptr = cy->cy_ibuf_wr_ptr = cy->cy_ibuf; 291 292 /* select CD1400 channel */ 293 cd_write_reg(sc, cy->cy_chip, CD1400_CAR, 294 port & CD1400_CAR_CHAN); 295 /* reset the channel */ 296 cd1400_channel_cmd(sc, cy, CD1400_CCR_CMDRESET); 297 /* encode unit (port) number in LIVR */ 298 /* there is just enough space for 5 bits (32 ports) */ 299 cd_write_reg(sc, cy->cy_chip, CD1400_LIVR, port << 3); 300 301 cy->cy_channel_control = 0; 302 303 /* hmm... need spltty() here? */ 304 if (cy_open == 0) { 305 cy_open = 1; 306 timeout(cy_poll, NULL, 1); 307 } 308 /* this sets parameters and raises DTR */ 309 cyparam(tp, &tp->t_termios); 310 311 ttsetwater(tp); 312 313 /* raise RTS too */ 314 cy_modem_control(sc, cy, TIOCM_RTS, DMBIS); 315 316 cy->cy_carrier_stat = 317 cd_read_reg(sc, cy->cy_chip, CD1400_MSVR2); 318 319 /* enable receiver and modem change interrupts */ 320 cd_write_reg(sc, cy->cy_chip, CD1400_SRER, 321 CD1400_SRER_MDMCH | CD1400_SRER_RXDATA); 322 323 if (CY_DIALOUT(dev) || 324 ISSET(cy->cy_openflags, TIOCFLAG_SOFTCAR) || 325 ISSET(tp->t_cflag, MDMBUF) || 326 ISSET(cy->cy_carrier_stat, CD1400_MSVR2_CD)) 327 SET(tp->t_state, TS_CARR_ON); 328 else 329 CLR(tp->t_state, TS_CARR_ON); 330 } else if (ISSET(tp->t_state, TS_XCLUDE) && p->p_ucred->cr_uid != 0) { 331 return EBUSY; 332 } else { 333 s = spltty(); 334 } 335 336 /* wait for carrier if necessary */ 337 if (!ISSET(flag, O_NONBLOCK)) { 338 while (!ISSET(tp->t_cflag, CLOCAL) && 339 !ISSET(tp->t_state, TS_CARR_ON)) { 340 tp->t_wopen++; 341 error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH, 342 "cydcd", 0); 343 tp->t_wopen--; 344 if (error != 0) { 345 splx(s); 346 return error; 347 } 348 } 349 } 350 splx(s); 351 352 return (*linesw[tp->t_line].l_open) (dev, tp); 353 } 354 355 /* 356 * close routine. returns zero if successfull, else error code 357 */ 358 int 359 cyclose(dev, flag, mode, p) 360 dev_t dev; 361 int flag, mode; 362 struct proc *p; 363 { 364 int card = CY_CARD(dev); 365 int port = CY_PORT(dev); 366 struct cy_softc *sc = cy_cd.cd_devs[card]; 367 struct cy_port *cy = &sc->sc_ports[port]; 368 struct tty *tp = cy->cy_tty; 369 int s; 370 371 #ifdef CY_DEBUG 372 printf("%s: close port %d, flag 0x%x, mode 0x%x\n", 373 sc->sc_dev.dv_xname, port, flag, mode); 374 #endif 375 376 (*linesw[tp->t_line].l_close) (tp, flag); 377 s = spltty(); 378 379 if (ISSET(tp->t_cflag, HUPCL) && 380 !ISSET(cy->cy_openflags, TIOCFLAG_SOFTCAR)) { 381 /* 382 * drop DTR and RTS (should we wait for output buffer to 383 * become empty first?) 384 */ 385 cy_modem_control(sc, cy, 0, DMSET); 386 } 387 /* 388 * XXX should we disable modem change and 389 * receive interrupts here or somewhere ? 390 */ 391 CLR(tp->t_state, TS_BUSY | TS_FLUSH); 392 393 splx(s); 394 ttyclose(tp); 395 396 return 0; 397 } 398 399 /* 400 * Read routine 401 */ 402 int 403 cyread(dev, uio, flag) 404 dev_t dev; 405 struct uio *uio; 406 int flag; 407 { 408 int card = CY_CARD(dev); 409 int port = CY_PORT(dev); 410 struct cy_softc *sc = cy_cd.cd_devs[card]; 411 struct cy_port *cy = &sc->sc_ports[port]; 412 struct tty *tp = cy->cy_tty; 413 414 #ifdef CY_DEBUG 415 printf("%s: read port %d uio 0x%x flag 0x%x\n", 416 sc->sc_dev.dv_xname, port, uio, flag); 417 #endif 418 419 return ((*linesw[tp->t_line].l_read) (tp, uio, flag)); 420 } 421 422 /* 423 * Write routine 424 */ 425 int 426 cywrite(dev, uio, flag) 427 dev_t dev; 428 struct uio *uio; 429 int flag; 430 { 431 int card = CY_CARD(dev); 432 int port = CY_PORT(dev); 433 struct cy_softc *sc = cy_cd.cd_devs[card]; 434 struct cy_port *cy = &sc->sc_ports[port]; 435 struct tty *tp = cy->cy_tty; 436 437 #ifdef CY_DEBUG 438 printf("%s: write port %d uio 0x%x flag 0x%x\n", 439 sc->sc_dev.dv_xname, port, uio, flag); 440 #endif 441 442 return ((*linesw[tp->t_line].l_write) (tp, uio, flag)); 443 } 444 445 /* 446 * return tty pointer 447 */ 448 struct tty * 449 cytty(dev) 450 dev_t dev; 451 { 452 int card = CY_CARD(dev); 453 int port = CY_PORT(dev); 454 struct cy_softc *sc = cy_cd.cd_devs[card]; 455 struct cy_port *cy = &sc->sc_ports[port]; 456 struct tty *tp = cy->cy_tty; 457 458 #ifdef CY_DEBUG 459 printf("%s: tty port %d tp 0x%x\n", sc->sc_dev.dv_xname, port, tp); 460 #endif 461 return tp; 462 } 463 464 /* 465 * ioctl routine 466 */ 467 int 468 cyioctl(dev, cmd, data, flag, p) 469 dev_t dev; 470 u_long cmd; 471 caddr_t data; 472 int flag; 473 struct proc *p; 474 { 475 int card = CY_CARD(dev); 476 int port = CY_PORT(dev); 477 struct cy_softc *sc = cy_cd.cd_devs[card]; 478 struct cy_port *cy = &sc->sc_ports[port]; 479 struct tty *tp = cy->cy_tty; 480 int error; 481 482 #ifdef CY_DEBUG 483 printf("%s: port %d ioctl cmd 0x%x data 0x%x flag 0x%x\n", 484 sc->sc_dev.dv_xname, port, cmd, data, flag); 485 #endif 486 487 error = (*linesw[tp->t_line].l_ioctl) (tp, cmd, data, flag, p); 488 if (error >= 0) 489 return error; 490 491 error = ttioctl(tp, cmd, data, flag, p); 492 if (error >= 0) 493 return error; 494 495 /* XXX should not allow dropping DTR when dialin? */ 496 497 switch (cmd) { 498 case TIOCSBRK: /* start break */ 499 SET(cy->cy_flags, CY_F_START_BREAK); 500 cy_enable_transmitter(sc, cy); 501 break; 502 503 case TIOCCBRK: /* stop break */ 504 SET(cy->cy_flags, CY_F_END_BREAK); 505 cy_enable_transmitter(sc, cy); 506 break; 507 508 case TIOCSDTR: /* DTR on */ 509 cy_modem_control(sc, cy, TIOCM_DTR, DMBIS); 510 break; 511 512 case TIOCCDTR: /* DTR off */ 513 cy_modem_control(sc, cy, TIOCM_DTR, DMBIC); 514 break; 515 516 case TIOCMSET: /* set new modem control line values */ 517 cy_modem_control(sc, cy, *((int *) data), DMSET); 518 break; 519 520 case TIOCMBIS: /* turn modem control bits on */ 521 cy_modem_control(sc, cy, *((int *) data), DMBIS); 522 break; 523 524 case TIOCMBIC: /* turn modem control bits off */ 525 cy_modem_control(sc, cy, *((int *) data), DMBIC); 526 break; 527 528 case TIOCMGET: /* get modem control/status line state */ 529 *((int *) data) = cy_modem_control(sc, cy, 0, DMGET); 530 break; 531 532 case TIOCGFLAGS: 533 *((int *) data) = cy->cy_openflags | 534 (CY_DIALOUT(dev) ? TIOCFLAG_SOFTCAR : 0); 535 break; 536 537 case TIOCSFLAGS: 538 error = suser(p->p_ucred, &p->p_acflag); 539 if (error != 0) 540 return EPERM; 541 542 cy->cy_openflags = *((int *) data) & 543 (TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL | 544 TIOCFLAG_CRTSCTS | TIOCFLAG_MDMBUF); 545 break; 546 547 default: 548 return ENOTTY; 549 } 550 551 return 0; 552 } 553 554 /* 555 * start output 556 */ 557 void 558 cystart(tp) 559 struct tty *tp; 560 { 561 int card = CY_CARD(tp->t_dev); 562 int port = CY_PORT(tp->t_dev); 563 struct cy_softc *sc = cy_cd.cd_devs[card]; 564 struct cy_port *cy = &sc->sc_ports[port]; 565 int s; 566 567 #ifdef CY_DEBUG 568 printf("%s: port %d start, tty 0x%x\n", sc->sc_dev.dv_xname, port, tp); 569 #endif 570 571 572 s = spltty(); 573 574 #ifdef CY_DEBUG1 575 cy->cy_start_count++; 576 #endif 577 578 if (!ISSET(tp->t_state, TS_TTSTOP | TS_TIMEOUT | TS_BUSY)) { 579 if (tp->t_outq.c_cc <= tp->t_lowat) { 580 if (ISSET(tp->t_state, TS_ASLEEP)) { 581 CLR(tp->t_state, TS_ASLEEP); 582 wakeup(&tp->t_outq); 583 } 584 selwakeup(&tp->t_wsel); 585 586 if (tp->t_outq.c_cc == 0) 587 goto out; 588 } 589 SET(tp->t_state, TS_BUSY); 590 cy_enable_transmitter(sc, cy); 591 } 592 out: 593 594 splx(s); 595 } 596 597 /* 598 * stop output 599 */ 600 void 601 cystop(tp, flag) 602 struct tty *tp; 603 int flag; 604 { 605 int card = CY_CARD(tp->t_dev); 606 int port = CY_PORT(tp->t_dev); 607 struct cy_softc *sc = cy_cd.cd_devs[card]; 608 struct cy_port *cy = &sc->sc_ports[port]; 609 int s; 610 611 #ifdef CY_DEBUG 612 printf("%s: port %d stop tty 0x%x flag 0x%x\n", 613 sc->sc_dev.dv_xname, port, tp, flag); 614 #endif 615 616 s = spltty(); 617 618 if (ISSET(tp->t_state, TS_BUSY)) { 619 if (!ISSET(tp->t_state, TS_TTSTOP)) 620 SET(tp->t_state, TS_FLUSH); 621 622 /* 623 * the transmit interrupt routine will disable transmit when it 624 * notices that CY_F_STOP has been set. 625 */ 626 SET(cy->cy_flags, CY_F_STOP); 627 } 628 splx(s); 629 } 630 631 /* 632 * parameter setting routine. 633 * returns 0 if successfull, else returns error code 634 */ 635 static int 636 cyparam(tp, t) 637 struct tty *tp; 638 struct termios *t; 639 { 640 int card = CY_CARD(tp->t_dev); 641 int port = CY_PORT(tp->t_dev); 642 struct cy_softc *sc = cy_cd.cd_devs[card]; 643 struct cy_port *cy = &sc->sc_ports[port]; 644 int ibpr, obpr, i_clk_opt, o_clk_opt; 645 int s, opt; 646 647 #ifdef CY_DEBUG 648 printf("%s: port %d param tty 0x%x termios 0x%x\n", 649 sc->sc_dev.dv_xname, port, tp, t); 650 printf("ispeed %d ospeed %d\n", t->c_ispeed, t->c_ospeed); 651 #endif 652 653 if (t->c_ospeed != 0 && cy_speed(t->c_ospeed, &o_clk_opt, &obpr) < 0) 654 return EINVAL; 655 656 if (t->c_ispeed != 0 && cy_speed(t->c_ispeed, &i_clk_opt, &ibpr) < 0) 657 return EINVAL; 658 659 s = spltty(); 660 661 /* hang up the line is ospeed is zero, else turn DTR on */ 662 cy_modem_control(sc, cy, TIOCM_DTR, (t->c_ospeed == 0 ? DMBIC : DMBIS)); 663 664 /* channel was selected by the above call to cy_modem_control() */ 665 #if 0 666 cd_write_reg(sc, cy->cy_chip, CD1400_CAR, port & CD1400_CAR_CHAN); 667 #endif 668 669 /* set transmit speed */ 670 if (t->c_ospeed != 0) { 671 cd_write_reg(sc, cy->cy_chip, CD1400_TCOR, o_clk_opt); 672 cd_write_reg(sc, cy->cy_chip, CD1400_TBPR, obpr); 673 } 674 /* set receive speed */ 675 if (t->c_ispeed != 0) { 676 cd_write_reg(sc, cy->cy_chip, CD1400_RCOR, i_clk_opt); 677 cd_write_reg(sc, cy->cy_chip, CD1400_RBPR, ibpr); 678 } 679 opt = CD1400_CCR_CMDCHANCTL | CD1400_CCR_XMTEN 680 | (ISSET(t->c_cflag, CREAD) ? CD1400_CCR_RCVEN : CD1400_CCR_RCVDIS); 681 682 if (opt != cy->cy_channel_control) { 683 cy->cy_channel_control = opt; 684 cd1400_channel_cmd(sc, cy, opt); 685 } 686 /* compute COR1 contents */ 687 opt = 0; 688 if (ISSET(t->c_cflag, PARENB)) { 689 if (ISSET(t->c_cflag, PARODD)) 690 opt |= CD1400_COR1_PARODD; 691 opt |= CD1400_COR1_PARNORMAL; 692 } 693 if (!ISSET(t->c_iflag, INPCK)) 694 opt |= CD1400_COR1_NOINPCK; /* no parity checking */ 695 696 if (ISSET(t->c_cflag, CSTOPB)) 697 opt |= CD1400_COR1_STOP2; 698 699 switch (t->c_cflag & CSIZE) { 700 case CS5: 701 opt |= CD1400_COR1_CS5; 702 break; 703 704 case CS6: 705 opt |= CD1400_COR1_CS6; 706 break; 707 708 case CS7: 709 opt |= CD1400_COR1_CS7; 710 break; 711 712 default: 713 opt |= CD1400_COR1_CS8; 714 break; 715 } 716 717 cd_write_reg(sc, cy->cy_chip, CD1400_COR1, opt); 718 719 #ifdef CY_DEBUG 720 printf("cor1 = 0x%x...", opt); 721 #endif 722 723 /* 724 * use the CD1400 automatic CTS flow control if CRTSCTS is set 725 * 726 * CD1400_COR2_ETC is used because breaks are generated with 727 * embedded transmit commands 728 */ 729 cd_write_reg(sc, cy->cy_chip, CD1400_COR2, 730 CD1400_COR2_ETC | 731 (ISSET(t->c_cflag, CRTSCTS) ? CD1400_COR2_CCTS_OFLOW : 0)); 732 733 cd_write_reg(sc, cy->cy_chip, CD1400_COR3, CY_RX_FIFO_THRESHOLD); 734 735 cd1400_channel_cmd(sc, cy, CD1400_CCR_CMDCORCHG | 736 CD1400_CCR_COR1 | CD1400_CCR_COR2 | CD1400_CCR_COR3); 737 738 cd_write_reg(sc, cy->cy_chip, CD1400_COR4, CD1400_COR4_PFO_EXCEPTION); 739 cd_write_reg(sc, cy->cy_chip, CD1400_COR5, 0); 740 741 /* 742 * set modem change option registers to generate interrupts 743 * on carrier detect changes. 744 * 745 * if hardware RTS handshaking is used (CY_HW_RTS, DTR and RTS lines 746 * exchanged), also set the handshaking threshold. 747 */ 748 #ifdef CY_HW_RTS 749 cd_write_reg(sc, cy->cy_chip, CD1400_MCOR1, CD1400_MCOR1_CDzd | 750 (ISSET(t->c_cflag, CRTSCTS) ? RX_DTR_THRESHOLD : 0)); 751 #else 752 cd_write_reg(sc, cy->cy_chip, CD1400_MCOR1, CD1400_MCOR1_CDzd); 753 #endif /* CY_HW_RTS */ 754 755 cd_write_reg(sc, cy->cy_chip, CD1400_MCOR2, CD1400_MCOR2_CDod); 756 757 /* 758 * set receive timeout to approx. 2ms 759 * could use more complex logic here... 760 * (but is it actually needed or even useful?) 761 */ 762 cd_write_reg(sc, cy->cy_chip, CD1400_RTPR, 2); 763 764 /* 765 * should do anything else here? 766 * XXX check MDMBUF handshaking like in com.c? 767 */ 768 769 splx(s); 770 return 0; 771 } 772 773 /* 774 * set/get modem line status 775 * 776 * bits can be: TIOCM_DTR, TIOCM_RTS, TIOCM_CTS, TIOCM_CD, TIOCM_RI, TIOCM_DSR 777 * 778 * RTS and DTR are exchanged if CY_HW_RTS is set 779 * 780 */ 781 static int 782 cy_modem_control(sc, cy, bits, howto) 783 struct cy_softc *sc; 784 struct cy_port *cy; 785 int bits; 786 int howto; 787 { 788 int s, msvr; 789 struct tty *tp = cy->cy_tty; 790 791 s = spltty(); 792 793 /* select channel */ 794 cd_write_reg(sc, cy->cy_chip, CD1400_CAR, 795 cy->cy_port_num & CD1400_CAR_CHAN); 796 797 /* does not manipulate RTS if it is used for flow control */ 798 switch (howto) { 799 case DMGET: 800 splx(s); 801 bits = 0; 802 if (cy->cy_channel_control & CD1400_CCR_RCVEN) 803 bits |= TIOCM_LE; 804 msvr = cd_read_reg(sc, cy->cy_chip, CD1400_MSVR2); 805 #ifdef CY_HW_RTS 806 if (cd_read_reg(sc, cy->cy_chip, CD1400_MSVR1) & 807 CD1400_MSVR1_RTS) 808 bits |= TIOCM_DTR; 809 if (msvr & CD1400_MSVR2_DTR) 810 bits |= TIOCM_RTS; 811 #else 812 if (cd_read_reg(sc, cy->cy_chip, CD1400_MSVR1) & 813 CD1400_MSVR1_RTS) 814 bits |= TIOCM_RTS; 815 if (msvr & CD1400_MSVR2_DTR) 816 bits |= TIOCM_DTR; 817 #endif /* CY_HW_RTS */ 818 if (msvr & CD1400_MSVR2_CTS) 819 bits |= TIOCM_CTS; 820 if (msvr & CD1400_MSVR2_CD) 821 bits |= TIOCM_CD; 822 if (msvr & CD1400_MSVR2_DSR) /* not connected on some 823 * Cyclom cards? */ 824 bits |= TIOCM_DSR; 825 if (msvr & CD1400_MSVR2_RI) /* not connected on Cyclom-8Y 826 * cards? */ 827 bits |= TIOCM_RI; 828 splx(s); 829 return bits; 830 831 case DMSET: /* replace old values with new ones */ 832 #ifdef CY_HW_RTS 833 if (!ISSET(tp->>t_cflag, CRTSCTS)) 834 cd_write_reg(sc, cy->cy_chip, CD1400_MSVR2, 835 ((bits & TIOCM_RTS) ? CD1400_MSVR2_DTR : 0)); 836 cd_write_reg(sc, cy->cy_chip, CD1400_MSVR1, 837 ((bits & TIOCM_DTR) ? CD1400_MSVR1_RTS : 0)); 838 #else 839 if (!ISSET(tp->t_cflag, CRTSCTS)) 840 cd_write_reg(sc, cy->cy_chip, CD1400_MSVR1, 841 ((bits & TIOCM_RTS) ? CD1400_MSVR1_RTS : 0)); 842 cd_write_reg(sc, cy->cy_chip, CD1400_MSVR2, 843 ((bits & TIOCM_DTR) ? CD1400_MSVR2_DTR : 0)); 844 #endif /* CY_HW_RTS */ 845 break; 846 847 case DMBIS: /* set bits */ 848 #ifdef CY_HW_RTS 849 if (!ISSET(tp->t_cflag, CRTSCTS) && (bits & TIOCM_RTS) != 0) 850 cd_write_reg(sc, cy->cy_chip, CD1400_MSVR2, 851 CD1400_MSVR2_DTR); 852 if (bits & TIOCM_DTR) 853 cd_write_reg(sc, cy->cy_chip, CD1400_MSVR1, 854 CD1400_MSVR1_RTS); 855 #else 856 if (!ISSET(tp->t_cflag, CRTSCTS) && (bits & TIOCM_RTS) != 0) 857 cd_write_reg(sc, cy->cy_chip, CD1400_MSVR1, 858 CD1400_MSVR1_RTS); 859 if (bits & TIOCM_DTR) 860 cd_write_reg(sc, cy->cy_chip, CD1400_MSVR2, 861 CD1400_MSVR2_DTR); 862 #endif /* CY_HW_RTS */ 863 break; 864 865 case DMBIC: /* clear bits */ 866 #ifdef CY_HW_RTS 867 if (!ISSET(tp->t_cflag, CRTSCTS) && (bits & TIOCM_RTS)) 868 cd_write_reg(sc, cy->cy_chip, CD1400_MSVR2, 0); 869 if (bits & TIOCM_DTR) 870 cd_write_reg(sc, cy->cy_chip, CD1400_MSVR1, 0); 871 #else 872 if (!ISSET(tp->t_cflag, CRTSCTS) && (bits & TIOCM_RTS)) 873 cd_write_reg(sc, cy->cy_chip, CD1400_MSVR1, 0); 874 if (bits & TIOCM_DTR) 875 cd_write_reg(sc, cy->cy_chip, CD1400_MSVR2, 0); 876 #endif /* CY_HW_RTS */ 877 break; 878 } 879 splx(s); 880 return 0; 881 } 882 883 /* 884 * Upper-level handler loop (called from timer interrupt?) 885 * This routine is common for multiple cards 886 */ 887 static void 888 cy_poll(arg) 889 void *arg; 890 { 891 int card, port; 892 struct cy_softc *sc; 893 struct cy_port *cy; 894 struct tty *tp; 895 static int counter = 0; 896 #ifdef CY_DEBUG1 897 int did_something; 898 #endif 899 int s = spltty(); 900 901 if (cy_events == 0 && ++counter < 200) { 902 splx(s); 903 goto out; 904 } 905 cy_events = 0; 906 splx(s); 907 908 for (card = 0; card < cy_cd.cd_ndevs; card++) { 909 sc = cy_cd.cd_devs[card]; 910 if (sc == NULL) 911 continue; 912 913 #ifdef CY_DEBUG1 914 sc->sc_poll_count1++; 915 did_something = 0; 916 #endif 917 918 for (port = 0; port < sc->sc_nchips * CD1400_NO_OF_CHANNELS; 919 port++) { 920 cy = &sc->sc_ports[port]; 921 if ((tp = cy->cy_tty) == NULL || cy->cy_ibuf == NULL || 922 (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0)) 923 continue; 924 925 /* 926 * handle received data 927 */ 928 while (cy->cy_ibuf_rd_ptr != cy->cy_ibuf_wr_ptr) { 929 u_char line_stat; 930 int chr; 931 932 line_stat = cy->cy_ibuf_rd_ptr[0]; 933 chr = cy->cy_ibuf_rd_ptr[1]; 934 935 if (line_stat & 936 (CD1400_RDSR_BREAK | CD1400_RDSR_FE)) 937 chr |= TTY_FE; 938 if (line_stat & CD1400_RDSR_PE) 939 chr |= TTY_PE; 940 941 /* 942 * on an overrun error the data is treated as 943 * good just as it should be. 944 */ 945 946 #ifdef CY_DEBUG 947 printf("%s: port %d ttyinput 0x%x\n", 948 sc->sc_dev.dv_xname, port, chr); 949 #endif 950 951 (*linesw[tp->t_line].l_rint) (chr, tp); 952 953 s = spltty(); /* really necessary? */ 954 if ((cy->cy_ibuf_rd_ptr += 2) == 955 cy->cy_ibuf_end) 956 cy->cy_ibuf_rd_ptr = cy->cy_ibuf; 957 splx(s); 958 959 #ifdef CY_DEBUG1 960 did_something = 1; 961 #endif 962 } 963 964 #ifndef CY_HW_RTS 965 /* 966 * If we don't have any received data in ibuf and 967 * CRTSCTS is on and RTS is turned off, it is time to 968 * turn RTS back on 969 */ 970 if (ISSET(tp->t_cflag, CRTSCTS)) { 971 /* 972 * we can't use cy_modem_control() here as it 973 * doesn't change RTS if RTSCTS is on 974 */ 975 cd_write_reg(sc, cy->cy_chip, CD1400_CAR, 976 port & CD1400_CAR_CHAN); 977 978 if ((cd_read_reg(sc, cy->cy_chip, 979 CD1400_MSVR1) & CD1400_MSVR1_RTS) == 0) { 980 cd_write_reg(sc, cy->cy_chip, CD1400_MSVR1, 981 CD1400_MSVR1_RTS); 982 #ifdef CY_DEBUG1 983 did_something = 1; 984 #endif 985 } 986 } 987 #endif /* CY_HW_RTS */ 988 989 /* 990 * handle carrier changes 991 */ 992 s = spltty(); 993 if (ISSET(cy->cy_flags, CY_F_CARRIER_CHANGED)) { 994 int carrier; 995 996 CLR(cy->cy_flags, CY_F_CARRIER_CHANGED); 997 splx(s); 998 999 carrier = ((cy->cy_carrier_stat & 1000 CD1400_MSVR2_CD) != 0); 1001 1002 #ifdef CY_DEBUG 1003 printf("cy_poll: carrier change " 1004 "(card %d, port %d, carrier %d)\n", 1005 card, port, carrier); 1006 #endif 1007 if (CY_DIALIN(tp->t_dev) && 1008 !(*linesw[tp->t_line].l_modem)(tp, carrier)) 1009 cy_modem_control(sc, cy, 1010 TIOCM_DTR, DMBIC); 1011 1012 #ifdef CY_DEBUG1 1013 did_something = 1; 1014 #endif 1015 } else 1016 splx(s); 1017 1018 s = spltty(); 1019 if (ISSET(cy->cy_flags, CY_F_START)) { 1020 CLR(cy->cy_flags, CY_F_START); 1021 splx(s); 1022 1023 (*linesw[tp->t_line].l_start) (tp); 1024 1025 #ifdef CY_DEBUG1 1026 did_something = 1; 1027 #endif 1028 } else 1029 splx(s); 1030 1031 /* could move this to even upper level... */ 1032 if (cy->cy_fifo_overruns) { 1033 cy->cy_fifo_overruns = 0; 1034 /* 1035 * doesn't report overrun count, but 1036 * shouldn't really matter 1037 */ 1038 log(LOG_WARNING, "%s: port %d fifo overrun\n", 1039 sc->sc_dev.dv_xname, port); 1040 } 1041 if (cy->cy_ibuf_overruns) { 1042 cy->cy_ibuf_overruns = 0; 1043 log(LOG_WARNING, "%s: port %d ibuf overrun\n", 1044 sc->sc_dev.dv_xname, port); 1045 } 1046 } /* for(port...) */ 1047 #ifdef CY_DEBUG1 1048 if (did_something && counter >= 200) 1049 sc->sc_poll_count2++; 1050 #endif 1051 } /* for(card...) */ 1052 1053 counter = 0; 1054 1055 out: 1056 timeout(cy_poll, NULL, 1); 1057 } 1058 1059 /* 1060 * hardware interrupt routine 1061 */ 1062 int 1063 cy_intr(arg) 1064 void *arg; 1065 { 1066 struct cy_softc *sc = arg; 1067 struct cy_port *cy; 1068 int cy_chip, stat; 1069 int int_serviced = 0; 1070 1071 /* 1072 * Check interrupt status of each CD1400 chip on this card 1073 * (multiple cards cannot share the same interrupt) 1074 */ 1075 for (cy_chip = 0; cy_chip < sc->sc_nchips; cy_chip++) { 1076 1077 stat = cd_read_reg(sc, cy_chip, CD1400_SVRR); 1078 if (stat == 0) 1079 continue; 1080 1081 if (ISSET(stat, CD1400_SVRR_RXRDY)) { 1082 u_char save_car, save_rir, serv_type; 1083 u_char line_stat, recv_data, n_chars; 1084 u_char *buf_p; 1085 1086 save_rir = cd_read_reg(sc, cy_chip, CD1400_RIR); 1087 save_car = cd_read_reg(sc, cy_chip, CD1400_CAR); 1088 /* enter rx service */ 1089 cd_write_reg(sc, cy_chip, CD1400_CAR, save_rir); 1090 1091 serv_type = cd_read_reg(sc, cy_chip, CD1400_RIVR); 1092 cy = &sc->sc_ports[serv_type >> 3]; 1093 1094 #ifdef CY_DEBUG1 1095 cy->cy_rx_int_count++; 1096 #endif 1097 1098 if (cy->cy_tty == NULL || 1099 !ISSET(cy->cy_tty->t_state, TS_ISOPEN)) 1100 goto end_rx_serv; 1101 1102 buf_p = cy->cy_ibuf_wr_ptr; 1103 1104 if (ISSET(serv_type, CD1400_RIVR_EXCEPTION)) { 1105 line_stat = cd_read_reg(sc, cy->cy_chip, 1106 CD1400_RDSR); 1107 recv_data = cd_read_reg(sc, cy->cy_chip, 1108 CD1400_RDSR); 1109 1110 #ifdef CY_DEBUG 1111 printf("cy%d port %d recv exception, line_stat 0x%x, char 0x%x\n", 1112 card, cy->cy_port_num, line_stat, recv_data); 1113 #endif 1114 if (ISSET(line_stat, CD1400_RDSR_OE)) 1115 cy->cy_fifo_overruns++; 1116 1117 *buf_p++ = line_stat; 1118 *buf_p++ = recv_data; 1119 if (buf_p == cy->cy_ibuf_end) 1120 buf_p = cy->cy_ibuf; 1121 1122 if (buf_p == cy->cy_ibuf_rd_ptr) { 1123 if (buf_p == cy->cy_ibuf) 1124 buf_p = cy->cy_ibuf_end; 1125 buf_p -= 2; 1126 cy->cy_ibuf_overruns++; 1127 } 1128 cy_events = 1; 1129 } else {/* no exception, received data OK */ 1130 n_chars = cd_read_reg(sc, cy->cy_chip, 1131 CD1400_RDCR); 1132 #ifdef CY_DEBUG 1133 printf("cy%d port %d receive ok %d chars\n", 1134 card, cy->cy_port_num, n_chars); 1135 #endif 1136 while (n_chars--) { 1137 *buf_p++ = 0; /* status: OK */ 1138 /* data byte */ 1139 *buf_p++ = cd_read_reg(sc, 1140 cy->cy_chip, CD1400_RDSR); 1141 if (buf_p == cy->cy_ibuf_end) 1142 buf_p = cy->cy_ibuf; 1143 if (buf_p == cy->cy_ibuf_rd_ptr) { 1144 if (buf_p == cy->cy_ibuf) 1145 buf_p = cy->cy_ibuf_end; 1146 buf_p -= 2; 1147 cy->cy_ibuf_overruns++; 1148 break; 1149 } 1150 } 1151 cy_events = 1; 1152 } 1153 1154 cy->cy_ibuf_wr_ptr = buf_p; 1155 1156 #ifndef CY_HW_RTS 1157 /* RTS handshaking for incoming data */ 1158 if (ISSET(cy->cy_tty->t_cflag, CRTSCTS)) { 1159 int bf; 1160 1161 bf = buf_p - cy->cy_ibuf_rd_ptr; 1162 if (bf < 0) 1163 bf += CY_IBUF_SIZE; 1164 1165 if (bf > (CY_IBUF_SIZE / 2)) /* turn RTS off */ 1166 cd_write_reg(sc, cy->cy_chip, CD1400_MSVR1, 0); 1167 } 1168 #endif /* CY_HW_RTS */ 1169 1170 end_rx_serv: 1171 /* terminate service context */ 1172 cd_write_reg(sc, cy->cy_chip, CD1400_RIR, save_rir & 0x3f); 1173 cd_write_reg(sc, cy->cy_chip, CD1400_CAR, save_car); 1174 int_serviced = 1; 1175 } /* if(rx_service...) */ 1176 if (ISSET(stat, CD1400_SVRR_MDMCH)) { 1177 u_char save_car, save_mir, serv_type, modem_stat; 1178 1179 save_mir = cd_read_reg(sc, cy_chip, CD1400_MIR); 1180 save_car = cd_read_reg(sc, cy_chip, CD1400_CAR); 1181 /* enter modem service */ 1182 cd_write_reg(sc, cy_chip, CD1400_CAR, save_mir); 1183 1184 serv_type = cd_read_reg(sc, cy_chip, CD1400_MIVR); 1185 cy = &sc->sc_ports[serv_type >> 3]; 1186 1187 #ifdef CY_DEBUG1 1188 cy->cy_modem_int_count++; 1189 #endif 1190 1191 modem_stat = cd_read_reg(sc, cy->cy_chip, CD1400_MSVR2); 1192 1193 #ifdef CY_DEBUG 1194 printf("cy%d port %d modem line change, new stat 0x%x\n", 1195 card, cy->cy_port_num, modem_stat); 1196 #endif 1197 if (ISSET((cy->cy_carrier_stat ^ modem_stat), CD1400_MSVR2_CD)) { 1198 SET(cy->cy_flags, CY_F_CARRIER_CHANGED); 1199 cy_events = 1; 1200 } 1201 cy->cy_carrier_stat = modem_stat; 1202 1203 /* terminate service context */ 1204 cd_write_reg(sc, cy->cy_chip, CD1400_MIR, save_mir & 0x3f); 1205 cd_write_reg(sc, cy->cy_chip, CD1400_CAR, save_car); 1206 int_serviced = 1; 1207 } /* if(modem_service...) */ 1208 if (ISSET(stat, CD1400_SVRR_TXRDY)) { 1209 u_char save_car, save_tir, serv_type, 1210 count, ch; 1211 struct tty *tp; 1212 1213 save_tir = cd_read_reg(sc, cy_chip, CD1400_TIR); 1214 save_car = cd_read_reg(sc, cy_chip, CD1400_CAR); 1215 /* enter tx service */ 1216 cd_write_reg(sc, cy_chip, CD1400_CAR, save_tir); 1217 1218 serv_type = cd_read_reg(sc, cy_chip, CD1400_TIVR); 1219 cy = &sc->sc_ports[serv_type >> 3]; 1220 1221 #ifdef CY_DEBUG1 1222 cy->cy_tx_int_count++; 1223 #endif 1224 #ifdef CY_DEBUG 1225 printf("cy%d port %d tx service\n", card, 1226 cy->cy_port_num); 1227 #endif 1228 1229 /* stop transmitting if no tty or CY_F_STOP set */ 1230 tp = cy->cy_tty; 1231 if (tp == NULL || ISSET(cy->cy_flags, CY_F_STOP)) 1232 goto txdone; 1233 1234 count = 0; 1235 if (ISSET(cy->cy_flags, CY_F_SEND_NUL)) { 1236 cd_write_reg(sc, cy->cy_chip, CD1400_TDR, 0); 1237 cd_write_reg(sc, cy->cy_chip, CD1400_TDR, 0); 1238 count += 2; 1239 CLR(cy->cy_flags, CY_F_SEND_NUL); 1240 } 1241 if (tp->t_outq.c_cc > 0) { 1242 SET(tp->t_state, TS_BUSY); 1243 while (tp->t_outq.c_cc > 0 && 1244 count < CD1400_TX_FIFO_SIZE) { 1245 ch = getc(&tp->t_outq); 1246 /* 1247 * remember to double NUL characters 1248 * because embedded transmit commands 1249 * are enabled 1250 */ 1251 if (ch == 0) { 1252 if (count >= CD1400_TX_FIFO_SIZE - 2) { 1253 SET(cy->cy_flags, CY_F_SEND_NUL); 1254 break; 1255 } 1256 cd_write_reg(sc, cy->cy_chip, 1257 CD1400_TDR, ch); 1258 count++; 1259 } 1260 cd_write_reg(sc, cy->cy_chip, 1261 CD1400_TDR, ch); 1262 count++; 1263 } 1264 } else { 1265 /* 1266 * no data to send -- check if we should 1267 * start/stop a break 1268 */ 1269 /* 1270 * XXX does this cause too much delay before 1271 * breaks? 1272 */ 1273 if (ISSET(cy->cy_flags, CY_F_START_BREAK)) { 1274 cd_write_reg(sc, cy->cy_chip, 1275 CD1400_TDR, 0); 1276 cd_write_reg(sc, cy->cy_chip, 1277 CD1400_TDR, 0x81); 1278 CLR(cy->cy_flags, CY_F_START_BREAK); 1279 } 1280 if (ISSET(cy->cy_flags, CY_F_END_BREAK)) { 1281 cd_write_reg(sc, cy->cy_chip, 1282 CD1400_TDR, 0); 1283 cd_write_reg(sc, cy->cy_chip, 1284 CD1400_TDR, 0x83); 1285 CLR(cy->cy_flags, CY_F_END_BREAK); 1286 } 1287 } 1288 1289 if (tp->t_outq.c_cc == 0) { 1290 txdone: 1291 /* 1292 * No data to send or requested to stop. 1293 * Disable transmit interrupt 1294 */ 1295 cd_write_reg(sc, cy->cy_chip, CD1400_SRER, 1296 cd_read_reg(sc, cy->cy_chip, CD1400_SRER) 1297 & ~CD1400_SRER_TXRDY); 1298 CLR(cy->cy_flags, CY_F_STOP); 1299 CLR(tp->t_state, TS_BUSY); 1300 } 1301 if (tp->t_outq.c_cc <= tp->t_lowat) { 1302 SET(cy->cy_flags, CY_F_START); 1303 cy_events = 1; 1304 } 1305 /* terminate service context */ 1306 cd_write_reg(sc, cy->cy_chip, CD1400_TIR, save_tir & 0x3f); 1307 cd_write_reg(sc, cy->cy_chip, CD1400_CAR, save_car); 1308 int_serviced = 1; 1309 } /* if(tx_service...) */ 1310 } /* for(...all CD1400s on a card) */ 1311 1312 /* ensure an edge for next interrupt */ 1313 bus_space_write_1(sc->sc_memt, sc->sc_bsh, 1314 CY_CLEAR_INTR << sc->sc_bustype, 0); 1315 return int_serviced; 1316 } 1317 1318 /* 1319 * subroutine to enable CD1400 transmitter 1320 */ 1321 static void 1322 cy_enable_transmitter(sc, cy) 1323 struct cy_softc *sc; 1324 struct cy_port *cy; 1325 { 1326 int s = spltty(); 1327 cd_write_reg(sc, cy->cy_chip, CD1400_CAR, 1328 cy->cy_port_num & CD1400_CAR_CHAN); 1329 cd_write_reg(sc, cy->cy_chip, CD1400_SRER, 1330 cd_read_reg(sc, cy->cy_chip, CD1400_SRER) | CD1400_SRER_TXRDY); 1331 splx(s); 1332 } 1333 1334 /* 1335 * Execute a CD1400 channel command 1336 */ 1337 static void 1338 cd1400_channel_cmd(sc, cy, cmd) 1339 struct cy_softc *sc; 1340 struct cy_port *cy; 1341 int cmd; 1342 { 1343 u_int waitcnt = 5 * 8 * 1024; /* approx 5 ms */ 1344 1345 #ifdef CY_DEBUG 1346 printf("c1400_channel_cmd cy 0x%x command 0x%x\n", cy, cmd); 1347 #endif 1348 1349 /* wait until cd1400 is ready to process a new command */ 1350 while (cd_read_reg(sc, cy->cy_chip, CD1400_CCR) != 0 && waitcnt-- > 0); 1351 1352 if (waitcnt == 0) 1353 log(LOG_ERR, "%s: channel command timeout\n", 1354 sc->sc_dev.dv_xname); 1355 1356 cd_write_reg(sc, cy->cy_chip, CD1400_CCR, cmd); 1357 } 1358 1359 /* 1360 * Compute clock option register and baud rate register values 1361 * for a given speed. Return 0 on success, -1 on failure. 1362 * 1363 * The error between requested and actual speed seems 1364 * to be well within allowed limits (less than 3%) 1365 * with every speed value between 50 and 150000 bps. 1366 */ 1367 static int 1368 cy_speed(speed, cor, bpr) 1369 speed_t speed; 1370 int *cor, *bpr; 1371 { 1372 int c, co, br; 1373 1374 if (speed < 50 || speed > 150000) 1375 return -1; 1376 1377 for (c = 0, co = 8; co <= 2048; co <<= 2, c++) { 1378 br = (CY_CLOCK + (co * speed) / 2) / (co * speed); 1379 if (br < 0x100) { 1380 *bpr = br; 1381 *cor = c; 1382 return 0; 1383 } 1384 } 1385 1386 return -1; 1387 } 1388