1 /* $NetBSD: spif.c,v 1.31 2014/07/25 08:10:38 dholland Exp $ */ 2 /* $OpenBSD: spif.c,v 1.12 2003/10/03 16:44:51 miod Exp $ */ 3 4 /* 5 * Copyright (c) 1999-2002 Jason L. Wright (jason@thought.net) 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 21 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 25 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 26 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 * 29 * Effort sponsored in part by the Defense Advanced Research Projects 30 * Agency (DARPA) and Air Force Research Laboratory, Air Force 31 * Materiel Command, USAF, under agreement number F30602-01-2-0537. 32 * 33 */ 34 35 /* 36 * Driver for the SUNW,spif: 8 serial, 1 parallel sbus board 37 * based heavily on Iain Hibbert's driver for the MAGMA cards 38 */ 39 40 /* Ported to NetBSD 2.0 by Hauke Fath */ 41 42 43 #include <sys/cdefs.h> 44 __KERNEL_RCSID(0, "$NetBSD: spif.c,v 1.31 2014/07/25 08:10:38 dholland Exp $"); 45 46 #include "spif.h" 47 #if NSPIF > 0 48 49 #include <sys/param.h> 50 #include <sys/systm.h> 51 #include <sys/proc.h> 52 #include <sys/device.h> 53 #include <sys/file.h> 54 #include <sys/ioctl.h> 55 #include <sys/malloc.h> 56 #include <sys/tty.h> 57 #include <sys/time.h> 58 #include <sys/kernel.h> 59 #include <sys/syslog.h> 60 #include <sys/conf.h> 61 #include <sys/errno.h> 62 #include <sys/kauth.h> 63 #include <sys/intr.h> 64 65 #include <sys/bus.h> 66 #include <machine/autoconf.h> 67 #include <machine/promlib.h> 68 69 #include <dev/sbus/sbusvar.h> 70 71 #include <dev/sbus/spifvar.h> 72 #include <dev/sbus/spifreg.h> 73 74 #include "ioconf.h" 75 76 /* Autoconfig stuff */ 77 78 CFATTACH_DECL_NEW(spif, sizeof(struct spif_softc), 79 spif_match, spif_attach, NULL, NULL); 80 81 CFATTACH_DECL_NEW(stty, sizeof(struct stty_softc), 82 stty_match, stty_attach, NULL, NULL); 83 84 CFATTACH_DECL_NEW(sbpp, sizeof(struct sbpp_softc), 85 sbpp_match, sbpp_attach, NULL, NULL); 86 87 dev_type_open(stty_open); 88 dev_type_close(stty_close); 89 dev_type_read(stty_read); 90 dev_type_write(stty_write); 91 dev_type_ioctl(stty_ioctl); 92 dev_type_stop(stty_stop); 93 dev_type_tty(stty_tty); 94 dev_type_poll(stty_poll); 95 96 const struct cdevsw stty_cdevsw = { 97 .d_open = stty_open, 98 .d_close = stty_close, 99 .d_read = stty_read, 100 .d_write = stty_write, 101 .d_ioctl = stty_ioctl, 102 .d_stop = stty_stop, 103 .d_tty = stty_tty, 104 .d_poll = stty_poll, 105 .d_mmap = nommap, 106 .d_kqfilter = ttykqfilter, 107 .d_discard = nodiscard, 108 .d_flag = D_TTY 109 }; 110 111 dev_type_open(sbpp_open); 112 dev_type_close(sbpp_close); 113 dev_type_read(sbpp_read); 114 dev_type_write(sbpp_write); 115 dev_type_ioctl(sbpp_ioctl); 116 dev_type_poll(sbpp_poll); 117 118 const struct cdevsw sbpp_cdevsw = { 119 .d_open = sbpp_open, 120 .d_close = sbpp_close, 121 .d_read = sbpp_read, 122 .d_write = sbpp_write, 123 .d_ioctl = sbpp_ioctl, 124 .d_stop = nostop, 125 .d_tty = notty, 126 .d_poll = sbpp_poll, 127 .d_mmap = nommap, 128 .d_kqfilter = nokqfilter, 129 .d_discard = nodiscard, 130 .d_flag = D_OTHER 131 }; 132 133 134 /* normal STC access */ 135 #define STC_WRITE(sc,r,v) \ 136 bus_space_write_1((sc)->sc_bustag, (sc)->sc_stch, (r), (v)) 137 #define STC_READ(sc,r) \ 138 bus_space_read_1((sc)->sc_bustag, (sc)->sc_stch, (r)) 139 140 /* IACK STC access */ 141 #define ISTC_WRITE(sc,r,v) \ 142 bus_space_write_1((sc)->sc_bustag, (sc)->sc_istch, (r), (v)) 143 #define ISTC_READ(sc,r) \ 144 bus_space_read_1((sc)->sc_bustag, (sc)->sc_istch, (r)) 145 146 /* PPC access */ 147 #define PPC_WRITE(sc,r,v) \ 148 bus_space_write_1((sc)->sc_bustag, (sc)->sc_ppch, (r), (v)) 149 #define PPC_READ(sc,r) \ 150 bus_space_read_1((sc)->sc_bustag, (sc)->sc_ppch, (r)) 151 152 #define DTR_WRITE(sc,port,v) \ 153 do { \ 154 sc->sc_ttys->sc_port[(port)].sp_dtr = v; \ 155 bus_space_write_1((sc)->sc_bustag, \ 156 sc->sc_dtrh, port, (v == 0) ? 1 : 0); \ 157 } while (0) 158 159 #define DTR_READ(sc,port) ((sc)->sc_ttys->sc_port[(port)].sp_dtr) 160 161 162 int 163 spif_match(device_t parent, cfdata_t vcf, void *aux) 164 { 165 struct sbus_attach_args *sa = aux; 166 167 if (strcmp(vcf->cf_name, sa->sa_name) && 168 strcmp("SUNW,spif", sa->sa_name)) 169 return (0); 170 return (1); 171 } 172 173 void 174 spif_attach(device_t parent, device_t self, void *aux) 175 { 176 struct spif_softc *sc = device_private(self); 177 struct sbus_attach_args *sa = aux; 178 179 sc->sc_dev = self; 180 181 if (sa->sa_nintr != 2) { 182 printf(": expected %d interrupts, got %d\n", 2, sa->sa_nintr); 183 return; 184 } 185 186 if (sa->sa_nreg != 1) { 187 printf(": expected %d registers, got %d\n", 1, sa->sa_nreg); 188 return; 189 } 190 191 sc->sc_bustag = sa->sa_bustag; 192 if (sbus_bus_map(sa->sa_bustag, sa->sa_slot, 193 sa->sa_offset, sa->sa_size, 194 0, &sc->sc_regh) != 0) { 195 printf(": can't map registers\n"); 196 return; 197 } 198 199 if (bus_space_subregion(sc->sc_bustag, sc->sc_regh, 200 DTR_REG_OFFSET, DTR_REG_LEN, &sc->sc_dtrh) != 0) { 201 printf(": can't map dtr regs\n"); 202 goto fail_unmapregs; 203 } 204 205 if (bus_space_subregion(sc->sc_bustag, sc->sc_regh, 206 STC_REG_OFFSET, STC_REG_LEN, &sc->sc_stch) != 0) { 207 printf(": can't map dtr regs\n"); 208 goto fail_unmapregs; 209 } 210 211 if (bus_space_subregion(sc->sc_bustag, sc->sc_regh, 212 ISTC_REG_OFFSET, ISTC_REG_LEN, &sc->sc_istch) != 0) { 213 printf(": can't map dtr regs\n"); 214 goto fail_unmapregs; 215 } 216 217 if (bus_space_subregion(sc->sc_bustag, sc->sc_regh, 218 PPC_REG_OFFSET, PPC_REG_LEN, &sc->sc_ppch) != 0) { 219 printf(": can't map dtr regs\n"); 220 goto fail_unmapregs; 221 } 222 223 sc->sc_ppcih = bus_intr_establish(sa->sa_bustag, 224 sa->sa_intr[PARALLEL_INTR].oi_pri, IPL_SERIAL, spif_ppcintr, sc); 225 if (sc->sc_ppcih == NULL) { 226 printf(": failed to establish ppc interrupt\n"); 227 goto fail_unmapregs; 228 } 229 230 sc->sc_stcih = bus_intr_establish(sa->sa_bustag, 231 sa->sa_intr[SERIAL_INTR].oi_pri, IPL_SERIAL, spif_stcintr, sc); 232 if (sc->sc_stcih == NULL) { 233 printf(": failed to establish stc interrupt\n"); 234 goto fail_unmapregs; 235 } 236 237 sc->sc_softih = softint_establish(SOFTINT_SERIAL, spif_softintr, sc); 238 if (sc->sc_softih == NULL) { 239 printf(": can't get soft intr\n"); 240 goto fail_unmapregs; 241 } 242 243 sc->sc_node = sa->sa_node; 244 245 sc->sc_rev = prom_getpropint(sc->sc_node, "revlev", 0); 246 247 sc->sc_osc = prom_getpropint(sc->sc_node, "verosc", 0); 248 switch (sc->sc_osc) { 249 case SPIF_OSC10: 250 sc->sc_osc = 10000000; 251 break; 252 case SPIF_OSC9: 253 default: 254 sc->sc_osc = 9830400; 255 break; 256 } 257 258 sc->sc_nser = 8; 259 sc->sc_npar = 1; 260 261 sc->sc_rev2 = STC_READ(sc, STC_GFRCR); 262 STC_WRITE(sc, STC_GSVR, 0); 263 264 stty_write_ccr(sc, CD180_CCR_CMD_RESET | CD180_CCR_RESETALL); 265 while (STC_READ(sc, STC_GSVR) != 0xff); 266 while (STC_READ(sc, STC_GFRCR) != sc->sc_rev2); 267 268 STC_WRITE(sc, STC_PPRH, CD180_PPRH); 269 STC_WRITE(sc, STC_PPRL, CD180_PPRL); 270 STC_WRITE(sc, STC_MSMR, SPIF_MSMR); 271 STC_WRITE(sc, STC_TSMR, SPIF_TSMR); 272 STC_WRITE(sc, STC_RSMR, SPIF_RSMR); 273 STC_WRITE(sc, STC_GSVR, 0); 274 STC_WRITE(sc, STC_GSCR1, 0); 275 STC_WRITE(sc, STC_GSCR2, 0); 276 STC_WRITE(sc, STC_GSCR3, 0); 277 278 printf(": rev %x chiprev %x osc %sMHz\n", 279 sc->sc_rev, sc->sc_rev2, clockfreq(sc->sc_osc)); 280 281 (void)config_found(self, stty_match, NULL); 282 (void)config_found(self, sbpp_match, NULL); 283 284 return; 285 286 fail_unmapregs: 287 bus_space_unmap(sa->sa_bustag, sc->sc_regh, sa->sa_size); 288 } 289 290 int 291 stty_match(device_t parent, cfdata_t vcf, void *aux) 292 { 293 struct spif_softc *sc = device_private(parent); 294 295 return (aux == stty_match && sc->sc_ttys == NULL); 296 } 297 298 void 299 stty_attach(device_t parent, device_t dev, void *aux) 300 { 301 struct spif_softc *sc = device_private(parent); 302 struct stty_softc *ssc = device_private(dev); 303 int port; 304 305 sc->sc_dev = dev; 306 sc->sc_ttys = ssc; 307 308 for (port = 0; port < sc->sc_nser; port++) { 309 struct stty_port *sp = &ssc->sc_port[port]; 310 struct tty *tp; 311 312 DTR_WRITE(sc, port, 0); 313 314 tp = tty_alloc(); 315 316 tp->t_oproc = stty_start; 317 tp->t_param = stty_param; 318 319 sp->sp_tty = tp; 320 sp->sp_sc = sc; 321 sp->sp_channel = port; 322 323 sp->sp_rbuf = malloc(STTY_RBUF_SIZE, M_DEVBUF, M_NOWAIT); 324 if(sp->sp_rbuf == NULL) 325 break; 326 327 sp->sp_rend = sp->sp_rbuf + STTY_RBUF_SIZE; 328 } 329 330 ssc->sc_nports = port; 331 332 printf(": %d tty%s\n", port, port == 1 ? "" : "s"); 333 } 334 335 int 336 stty_open(dev_t dev, int flags, int mode, struct lwp *l) 337 { 338 struct spif_softc *csc; 339 struct stty_softc *sc; 340 struct stty_port *sp; 341 struct tty *tp; 342 int card = SPIF_CARD(dev); 343 int port = SPIF_PORT(dev); 344 345 sc = device_lookup_private(&stty_cd, card); 346 csc = device_lookup_private(&spif_cd, card); 347 if (sc == NULL || csc == NULL) 348 return (ENXIO); 349 350 if (port >= sc->sc_nports) 351 return (ENXIO); 352 353 sp = &sc->sc_port[port]; 354 tp = sp->sp_tty; 355 tp->t_dev = dev; 356 357 if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) 358 return (EBUSY); 359 360 mutex_spin_enter(&tty_lock); 361 if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { 362 ttychars(tp); 363 tp->t_iflag = TTYDEF_IFLAG; 364 tp->t_oflag = TTYDEF_OFLAG; 365 tp->t_cflag = TTYDEF_CFLAG; 366 if (ISSET(sp->sp_openflags, TIOCFLAG_CLOCAL)) 367 SET(tp->t_cflag, CLOCAL); 368 if (ISSET(sp->sp_openflags, TIOCFLAG_CRTSCTS)) 369 SET(tp->t_cflag, CRTSCTS); 370 if (ISSET(sp->sp_openflags, TIOCFLAG_MDMBUF)) 371 SET(tp->t_cflag, MDMBUF); 372 tp->t_lflag = TTYDEF_LFLAG; 373 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; 374 375 sp->sp_rput = sp->sp_rget = sp->sp_rbuf; 376 377 STC_WRITE(csc, STC_CAR, sp->sp_channel); 378 stty_write_ccr(csc, CD180_CCR_CMD_RESET|CD180_CCR_RESETCHAN); 379 STC_WRITE(csc, STC_CAR, sp->sp_channel); 380 381 stty_param(tp, &tp->t_termios); 382 383 ttsetwater(tp); 384 385 STC_WRITE(csc, STC_SRER, CD180_SRER_CD | CD180_SRER_RXD); 386 387 if (ISSET(sp->sp_openflags, TIOCFLAG_SOFTCAR) || sp->sp_carrier) 388 SET(tp->t_state, TS_CARR_ON); 389 else 390 CLR(tp->t_state, TS_CARR_ON); 391 } 392 393 if (!ISSET(flags, O_NONBLOCK)) { 394 while (!ISSET(tp->t_cflag, CLOCAL) && 395 !ISSET(tp->t_state, TS_CARR_ON)) { 396 int error; 397 error = ttysleep(tp, &tp->t_rawcv, true, 0); 398 if (error != 0) { 399 mutex_spin_exit(&tty_lock); 400 return (error); 401 } 402 } 403 } 404 mutex_spin_exit(&tty_lock); 405 406 return ((*tp->t_linesw->l_open)(dev, tp)); 407 } 408 409 int 410 stty_close(dev_t dev, int flags, int mode, struct lwp *l) 411 { 412 struct stty_softc *sc = device_lookup_private(&stty_cd, SPIF_CARD(dev)); 413 struct stty_port *sp = &sc->sc_port[SPIF_PORT(dev)]; 414 struct spif_softc *csc = sp->sp_sc; 415 struct tty *tp = sp->sp_tty; 416 int port = SPIF_PORT(dev); 417 int s; 418 419 (*tp->t_linesw->l_close)(tp, flags); 420 s = spltty(); 421 422 if (ISSET(tp->t_cflag, HUPCL) || !ISSET(tp->t_state, TS_ISOPEN)) { 423 stty_modem_control(sp, 0, DMSET); 424 STC_WRITE(csc, STC_CAR, port); 425 STC_WRITE(csc, STC_CCR, 426 CD180_CCR_CMD_RESET|CD180_CCR_RESETCHAN); 427 } 428 429 splx(s); 430 ttyclose(tp); 431 return (0); 432 } 433 434 int 435 stty_ioctl(dev_t dev, u_long cmd, void *data, int flags, struct lwp *l) 436 { 437 struct stty_softc *stc = device_lookup_private(&stty_cd, 438 SPIF_CARD(dev)); 439 struct stty_port *sp = &stc->sc_port[SPIF_PORT(dev)]; 440 struct spif_softc *sc = sp->sp_sc; 441 struct tty *tp = sp->sp_tty; 442 int error; 443 444 error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flags, l); 445 if (error >= 0) 446 return (error); 447 448 error = ttioctl(tp, cmd, data, flags, l); 449 if (error >= 0) 450 return (error); 451 452 error = 0; 453 454 switch (cmd) { 455 case TIOCSBRK: 456 SET(sp->sp_flags, STTYF_SET_BREAK); 457 STC_WRITE(sc, STC_CAR, sp->sp_channel); 458 STC_WRITE(sc, STC_SRER, 459 STC_READ(sc, STC_SRER) | CD180_SRER_TXD); 460 break; 461 case TIOCCBRK: 462 SET(sp->sp_flags, STTYF_CLR_BREAK); 463 STC_WRITE(sc, STC_CAR, sp->sp_channel); 464 STC_WRITE(sc, STC_SRER, 465 STC_READ(sc, STC_SRER) | CD180_SRER_TXD); 466 break; 467 case TIOCSDTR: 468 stty_modem_control(sp, TIOCM_DTR, DMBIS); 469 break; 470 case TIOCCDTR: 471 stty_modem_control(sp, TIOCM_DTR, DMBIC); 472 break; 473 case TIOCMBIS: 474 stty_modem_control(sp, *((int *)data), DMBIS); 475 break; 476 case TIOCMBIC: 477 stty_modem_control(sp, *((int *)data), DMBIC); 478 break; 479 case TIOCMGET: 480 *((int *)data) = stty_modem_control(sp, 0, DMGET); 481 break; 482 case TIOCMSET: 483 stty_modem_control(sp, *((int *)data), DMSET); 484 break; 485 case TIOCGFLAGS: 486 *((int *)data) = sp->sp_openflags; 487 break; 488 case TIOCSFLAGS: 489 if (kauth_authorize_device_tty(l->l_cred, 490 KAUTH_DEVICE_TTY_PRIVSET, tp)) 491 error = EPERM; 492 else 493 sp->sp_openflags = *((int *)data) & 494 (TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL | 495 TIOCFLAG_CRTSCTS | TIOCFLAG_MDMBUF); 496 break; 497 default: 498 error = ENOTTY; 499 } 500 501 return (error); 502 } 503 504 int 505 stty_modem_control(struct stty_port *sp, int bits, int how) 506 { 507 struct spif_softc *csc = sp->sp_sc; 508 struct tty *tp = sp->sp_tty; 509 int s, msvr; 510 511 s = spltty(); 512 STC_WRITE(csc, STC_CAR, sp->sp_channel); 513 514 switch (how) { 515 case DMGET: 516 bits = TIOCM_LE; 517 if (DTR_READ(csc, sp->sp_channel)) 518 bits |= TIOCM_DTR; 519 msvr = STC_READ(csc, STC_MSVR); 520 if (ISSET(msvr, CD180_MSVR_DSR)) 521 bits |= TIOCM_DSR; 522 if (ISSET(msvr, CD180_MSVR_CD)) 523 bits |= TIOCM_CD; 524 if (ISSET(msvr, CD180_MSVR_CTS)) 525 bits |= TIOCM_CTS; 526 if (ISSET(msvr, CD180_MSVR_RTS)) 527 bits |= TIOCM_RTS; 528 break; 529 case DMSET: 530 DTR_WRITE(csc, sp->sp_channel, ISSET(bits, TIOCM_DTR) ? 1 : 0); 531 if (ISSET(bits, TIOCM_RTS)) 532 STC_WRITE(csc, STC_MSVR, 533 STC_READ(csc, STC_MSVR) & (~CD180_MSVR_RTS)); 534 else 535 STC_WRITE(csc, STC_MSVR, 536 STC_READ(csc, STC_MSVR) | CD180_MSVR_RTS); 537 break; 538 case DMBIS: 539 if (ISSET(bits, TIOCM_DTR)) 540 DTR_WRITE(csc, sp->sp_channel, 1); 541 if (ISSET(bits, TIOCM_RTS) && !ISSET(tp->t_cflag, CRTSCTS)) 542 STC_WRITE(csc, STC_MSVR, 543 STC_READ(csc, STC_MSVR) & (~CD180_MSVR_RTS)); 544 break; 545 case DMBIC: 546 if (ISSET(bits, TIOCM_DTR)) 547 DTR_WRITE(csc, sp->sp_channel, 0); 548 if (ISSET(bits, TIOCM_RTS)) 549 STC_WRITE(csc, STC_MSVR, 550 STC_READ(csc, STC_MSVR) | CD180_MSVR_RTS); 551 break; 552 } 553 554 splx(s); 555 return (bits); 556 } 557 558 int 559 stty_param(struct tty *tp, struct termios *t) 560 { 561 struct stty_softc *st = device_lookup_private(&stty_cd, 562 SPIF_CARD(tp->t_dev)); 563 struct stty_port *sp = &st->sc_port[SPIF_PORT(tp->t_dev)]; 564 struct spif_softc *sc = sp->sp_sc; 565 uint8_t rbprl = 0, rbprh = 0, tbprl = 0, tbprh = 0; 566 int s, opt; 567 568 if (t->c_ospeed && 569 stty_compute_baud(t->c_ospeed, sc->sc_osc, &tbprl, &tbprh)) 570 return (EINVAL); 571 572 if (t->c_ispeed && 573 stty_compute_baud(t->c_ispeed, sc->sc_osc, &rbprl, &rbprh)) 574 return (EINVAL); 575 576 s = spltty(); 577 578 /* hang up line if ospeed is zero, otherwise raise DTR */ 579 stty_modem_control(sp, TIOCM_DTR, 580 (t->c_ospeed == 0 ? DMBIC : DMBIS)); 581 582 STC_WRITE(sc, STC_CAR, sp->sp_channel); 583 584 opt = 0; 585 if (ISSET(t->c_cflag, PARENB)) { 586 opt |= CD180_COR1_PARMODE_NORMAL; 587 opt |= (ISSET(t->c_cflag, PARODD) ? 588 CD180_COR1_ODDPAR : 589 CD180_COR1_EVENPAR); 590 } 591 else 592 opt |= CD180_COR1_PARMODE_NO; 593 594 if (!ISSET(t->c_iflag, INPCK)) 595 opt |= CD180_COR1_IGNPAR; 596 597 if (ISSET(t->c_cflag, CSTOPB)) 598 opt |= CD180_COR1_STOP2; 599 600 switch (t->c_cflag & CSIZE) { 601 case CS5: 602 opt |= CD180_COR1_CS5; 603 break; 604 case CS6: 605 opt |= CD180_COR1_CS6; 606 break; 607 case CS7: 608 opt |= CD180_COR1_CS7; 609 break; 610 default: 611 opt |= CD180_COR1_CS8; 612 break; 613 } 614 STC_WRITE(sc, STC_COR1, opt); 615 stty_write_ccr(sc, CD180_CCR_CMD_COR|CD180_CCR_CORCHG1); 616 617 opt = CD180_COR2_ETC; 618 if (ISSET(t->c_cflag, CRTSCTS)) 619 opt |= CD180_COR2_CTSAE; 620 STC_WRITE(sc, STC_COR2, opt); 621 stty_write_ccr(sc, CD180_CCR_CMD_COR|CD180_CCR_CORCHG2); 622 623 STC_WRITE(sc, STC_COR3, STTY_RX_FIFO_THRESHOLD); 624 stty_write_ccr(sc, CD180_CCR_CMD_COR|CD180_CCR_CORCHG3); 625 626 STC_WRITE(sc, STC_SCHR1, 0x11); 627 STC_WRITE(sc, STC_SCHR2, 0x13); 628 STC_WRITE(sc, STC_SCHR3, 0x11); 629 STC_WRITE(sc, STC_SCHR4, 0x13); 630 STC_WRITE(sc, STC_RTPR, 0x12); 631 632 STC_WRITE(sc, STC_MCOR1, CD180_MCOR1_CDZD | STTY_RX_DTR_THRESHOLD); 633 STC_WRITE(sc, STC_MCOR2, CD180_MCOR2_CDOD); 634 STC_WRITE(sc, STC_MCR, 0); 635 636 if (t->c_ospeed) { 637 STC_WRITE(sc, STC_TBPRH, tbprh); 638 STC_WRITE(sc, STC_TBPRL, tbprl); 639 } 640 641 if (t->c_ispeed) { 642 STC_WRITE(sc, STC_RBPRH, rbprh); 643 STC_WRITE(sc, STC_RBPRL, rbprl); 644 } 645 646 stty_write_ccr(sc, CD180_CCR_CMD_CHAN | 647 CD180_CCR_CHAN_TXEN | CD180_CCR_CHAN_RXEN); 648 649 sp->sp_carrier = STC_READ(sc, STC_MSVR) & CD180_MSVR_CD; 650 651 splx(s); 652 return (0); 653 } 654 655 int 656 stty_read(dev_t dev, struct uio *uio, int flags) 657 { 658 struct stty_softc *sc = device_lookup_private(&stty_cd, SPIF_CARD(dev)); 659 struct stty_port *sp = &sc->sc_port[SPIF_PORT(dev)]; 660 struct tty *tp = sp->sp_tty; 661 662 return ((*tp->t_linesw->l_read)(tp, uio, flags)); 663 } 664 665 int 666 stty_write(dev_t dev, struct uio *uio, int flags) 667 { 668 struct stty_softc *sc = device_lookup_private(&stty_cd, SPIF_CARD(dev)); 669 struct stty_port *sp = &sc->sc_port[SPIF_PORT(dev)]; 670 struct tty *tp = sp->sp_tty; 671 672 return ((*tp->t_linesw->l_write)(tp, uio, flags)); 673 } 674 675 int 676 stty_poll(dev_t dev, int events, struct lwp *l) 677 { 678 struct stty_softc *sc = device_lookup_private(&stty_cd, SPIF_CARD(dev)); 679 struct stty_port *sp = &sc->sc_port[SPIF_PORT(dev)]; 680 struct tty *tp = sp->sp_tty; 681 682 return ((*tp->t_linesw->l_poll)(tp, events, l)); 683 } 684 685 struct tty * 686 stty_tty(dev_t dev) 687 { 688 struct stty_softc *sc = device_lookup_private(&stty_cd, SPIF_CARD(dev)); 689 struct stty_port *sp = &sc->sc_port[SPIF_PORT(dev)]; 690 691 return (sp->sp_tty); 692 } 693 694 void 695 stty_stop(struct tty *tp, int flags) 696 { 697 struct stty_softc *sc = device_lookup_private(&stty_cd, 698 SPIF_CARD(tp->t_dev)); 699 struct stty_port *sp = &sc->sc_port[SPIF_PORT(tp->t_dev)]; 700 int s; 701 702 s = spltty(); 703 if (ISSET(tp->t_state, TS_BUSY)) { 704 if (!ISSET(tp->t_state, TS_TTSTOP)) 705 SET(tp->t_state, TS_FLUSH); 706 SET(sp->sp_flags, STTYF_STOP); 707 } 708 splx(s); 709 } 710 711 void 712 stty_start(struct tty *tp) 713 { 714 struct stty_softc *stc = device_lookup_private(&stty_cd, 715 SPIF_CARD(tp->t_dev)); 716 struct stty_port *sp = &stc->sc_port[SPIF_PORT(tp->t_dev)]; 717 struct spif_softc *sc = sp->sp_sc; 718 int s; 719 720 s = spltty(); 721 722 if (!ISSET(tp->t_state, TS_TTSTOP | TS_TIMEOUT | TS_BUSY)) { 723 if (ttypull(tp)) { 724 sp->sp_txc = ndqb(&tp->t_outq, 0); 725 sp->sp_txp = tp->t_outq.c_cf; 726 SET(tp->t_state, TS_BUSY); 727 STC_WRITE(sc, STC_CAR, sp->sp_channel); 728 STC_WRITE(sc, STC_SRER, 729 STC_READ(sc, STC_SRER) | CD180_SRER_TXD); 730 } 731 } 732 733 splx(s); 734 } 735 736 int 737 spif_stcintr_rxexception(struct spif_softc *sc, int *needsoftp) 738 { 739 struct stty_port *sp; 740 uint8_t channel, *ptr; 741 742 channel = CD180_GSCR_CHANNEL(STC_READ(sc, STC_GSCR1)); 743 sp = &sc->sc_ttys->sc_port[channel]; 744 ptr = sp->sp_rput; 745 *ptr++ = STC_READ(sc, STC_RCSR); 746 *ptr++ = STC_READ(sc, STC_RDR); 747 if (ptr == sp->sp_rend) 748 ptr = sp->sp_rbuf; 749 if (ptr == sp->sp_rget) { 750 if (ptr == sp->sp_rbuf) 751 ptr = sp->sp_rend; 752 ptr -= 2; 753 SET(sp->sp_flags, STTYF_RING_OVERFLOW); 754 } 755 STC_WRITE(sc, STC_EOSRR, 0); 756 *needsoftp = 1; 757 sp->sp_rput = ptr; 758 return (1); 759 } 760 761 int 762 spif_stcintr_rx(struct spif_softc *sc, int *needsoftp) 763 { 764 struct stty_port *sp; 765 uint8_t channel, *ptr, cnt; 766 int i; 767 768 channel = CD180_GSCR_CHANNEL(STC_READ(sc, STC_GSCR1)); 769 sp = &sc->sc_ttys->sc_port[channel]; 770 ptr = sp->sp_rput; 771 cnt = STC_READ(sc, STC_RDCR); 772 for (i = 0; i < cnt; i++) { 773 *ptr++ = 0; 774 (void)STC_READ(sc, STC_RCSR); 775 *ptr++ = STC_READ(sc, STC_RDR); 776 if (ptr == sp->sp_rend) 777 ptr = sp->sp_rbuf; 778 if (ptr == sp->sp_rget) { 779 if (ptr == sp->sp_rbuf) 780 ptr = sp->sp_rend; 781 ptr -= 2; 782 SET(sp->sp_flags, STTYF_RING_OVERFLOW); 783 break; 784 } 785 } 786 STC_WRITE(sc, STC_EOSRR, 0); 787 if (cnt) { 788 *needsoftp = 1; 789 sp->sp_rput = ptr; 790 } 791 return (1); 792 } 793 794 int 795 spif_stcintr_tx(struct spif_softc *sc, int *needsoftp) 796 { 797 struct stty_port *sp; 798 uint8_t channel, ch; 799 int cnt = 0; 800 801 channel = CD180_GSCR_CHANNEL(STC_READ(sc, STC_GSCR1)); 802 sp = &sc->sc_ttys->sc_port[channel]; 803 if (!ISSET(sp->sp_flags, STTYF_STOP)) { 804 if (ISSET(sp->sp_flags, STTYF_SET_BREAK)) { 805 STC_WRITE(sc, STC_TDR, 0); 806 STC_WRITE(sc, STC_TDR, 0x81); 807 CLR(sp->sp_flags, STTYF_SET_BREAK); 808 cnt += 2; 809 } 810 if (ISSET(sp->sp_flags, STTYF_CLR_BREAK)) { 811 STC_WRITE(sc, STC_TDR, 0); 812 STC_WRITE(sc, STC_TDR, 0x83); 813 CLR(sp->sp_flags, STTYF_CLR_BREAK); 814 cnt += 2; 815 } 816 817 while (sp->sp_txc > 0 && cnt < (CD180_TX_FIFO_SIZE-1)) { 818 ch = *sp->sp_txp; 819 sp->sp_txc--; 820 sp->sp_txp++; 821 822 if (ch == 0) { 823 STC_WRITE(sc, STC_TDR, ch); 824 cnt++; 825 } 826 STC_WRITE(sc, STC_TDR, ch); 827 cnt++; 828 } 829 } 830 831 if (sp->sp_txc == 0 || 832 ISSET(sp->sp_flags, STTYF_STOP)) { 833 STC_WRITE(sc, STC_SRER, STC_READ(sc, STC_SRER) & 834 (~CD180_SRER_TXD)); 835 CLR(sp->sp_flags, STTYF_STOP); 836 SET(sp->sp_flags, STTYF_DONE); 837 *needsoftp = 1; 838 } 839 840 STC_WRITE(sc, STC_EOSRR, 0); 841 842 return (1); 843 } 844 845 int 846 spif_stcintr_mx(struct spif_softc *sc, int *needsoftp) 847 { 848 struct stty_port *sp; 849 uint8_t channel, mcr; 850 851 channel = CD180_GSCR_CHANNEL(STC_READ(sc, STC_GSCR1)); 852 sp = &sc->sc_ttys->sc_port[channel]; 853 mcr = STC_READ(sc, STC_MCR); 854 if (mcr & CD180_MCR_CD) { 855 SET(sp->sp_flags, STTYF_CDCHG); 856 *needsoftp = 1; 857 } 858 STC_WRITE(sc, STC_MCR, 0); 859 STC_WRITE(sc, STC_EOSRR, 0); 860 return (1); 861 } 862 863 int 864 spif_stcintr(void *vsc) 865 { 866 struct spif_softc *sc = (struct spif_softc *)vsc; 867 int needsoft = 0, r = 0, i; 868 uint8_t ar; 869 870 for (i = 0; i < 8; i++) { 871 ar = ISTC_READ(sc, STC_RRAR) & CD180_GSVR_IMASK; 872 if (ar == CD180_GSVR_RXGOOD) 873 r |= spif_stcintr_rx(sc, &needsoft); 874 else if (ar == CD180_GSVR_RXEXCEPTION) 875 r |= spif_stcintr_rxexception(sc, &needsoft); 876 } 877 878 for (i = 0; i < 8; i++) { 879 ar = ISTC_READ(sc, STC_TRAR) & CD180_GSVR_IMASK; 880 if (ar == CD180_GSVR_TXDATA) 881 r |= spif_stcintr_tx(sc, &needsoft); 882 } 883 884 for (i = 0; i < 8; i++) { 885 ar = ISTC_READ(sc, STC_MRAR) & CD180_GSVR_IMASK; 886 if (ar == CD180_GSVR_STATCHG) 887 r |= spif_stcintr_mx(sc, &needsoft); 888 } 889 890 if (needsoft) 891 softint_schedule(sc->sc_softih); 892 return (r); 893 } 894 895 void 896 spif_softintr(void *vsc) 897 { 898 struct spif_softc *sc = (struct spif_softc *)vsc; 899 struct stty_softc *stc = sc->sc_ttys; 900 int i, data, s, flags; 901 uint8_t stat, msvr; 902 struct stty_port *sp; 903 struct tty *tp; 904 905 if (stc != NULL) { 906 for (i = 0; i < stc->sc_nports; i++) { 907 sp = &stc->sc_port[i]; 908 tp = sp->sp_tty; 909 910 if (!ISSET(tp->t_state, TS_ISOPEN)) 911 continue; 912 913 while (sp->sp_rget != sp->sp_rput) { 914 stat = sp->sp_rget[0]; 915 data = sp->sp_rget[1]; 916 sp->sp_rget += 2; 917 if (sp->sp_rget == sp->sp_rend) 918 sp->sp_rget = sp->sp_rbuf; 919 920 if (stat & (CD180_RCSR_BE | CD180_RCSR_FE)) 921 data |= TTY_FE; 922 923 if (stat & CD180_RCSR_PE) 924 data |= TTY_PE; 925 926 (*tp->t_linesw->l_rint)(data, tp); 927 } 928 929 s = splhigh(); 930 flags = sp->sp_flags; 931 CLR(sp->sp_flags, STTYF_DONE | STTYF_CDCHG | 932 STTYF_RING_OVERFLOW); 933 splx(s); 934 935 if (ISSET(flags, STTYF_CDCHG)) { 936 s = spltty(); 937 STC_WRITE(sc, STC_CAR, i); 938 msvr = STC_READ(sc, STC_MSVR); 939 splx(s); 940 941 sp->sp_carrier = msvr & CD180_MSVR_CD; 942 (*tp->t_linesw->l_modem)(tp, 943 sp->sp_carrier); 944 } 945 946 if (ISSET(flags, STTYF_RING_OVERFLOW)) { 947 log(LOG_WARNING, "%s-%x: ring overflow\n", 948 device_xname(stc->sc_dev), i); 949 } 950 951 if (ISSET(flags, STTYF_DONE)) { 952 ndflush(&tp->t_outq, 953 sp->sp_txp - tp->t_outq.c_cf); 954 CLR(tp->t_state, TS_BUSY); 955 (*tp->t_linesw->l_start)(tp); 956 } 957 } 958 } 959 } 960 961 void 962 stty_write_ccr(struct spif_softc *sc, uint8_t val) 963 { 964 int tries = 100000; 965 966 while (STC_READ(sc, STC_CCR) && tries--) 967 /*EMPTY*/; 968 if (tries == 0) 969 aprint_error_dev(sc->sc_dev, "ccr timeout\n"); 970 STC_WRITE(sc, STC_CCR, val); 971 } 972 973 int 974 stty_compute_baud(speed_t speed, int clock, uint8_t *bprlp, uint8_t *bprhp) 975 { 976 uint32_t rate; 977 978 rate = (2 * clock) / (16 * speed); 979 if (rate & 1) 980 rate = (rate >> 1) + 1; 981 else 982 rate = rate >> 1; 983 984 if (rate > 0xffff || rate == 0) 985 return (1); 986 987 *bprlp = rate & 0xff; 988 *bprhp = (rate >> 8) & 0xff; 989 return (0); 990 } 991 992 int 993 sbpp_match(device_t parent, cfdata_t vcf, void *aux) 994 { 995 struct spif_softc *sc = device_private(parent); 996 997 return (aux == sbpp_match && sc->sc_bpps == NULL); 998 } 999 1000 void 1001 sbpp_attach(device_t parent, device_t dev, void *aux) 1002 { 1003 struct spif_softc *sc = device_private(parent); 1004 struct sbpp_softc *psc = device_private(dev); 1005 int port; 1006 1007 sc->sc_bpps = psc; 1008 1009 for (port = 0; port < sc->sc_npar; port++) { 1010 } 1011 1012 psc->sc_nports = port; 1013 printf(": %d port%s\n", port, port == 1 ? "" : "s"); 1014 } 1015 1016 int 1017 sbpp_open(dev_t dev, int flags, int mode, struct lwp *l) 1018 { 1019 return (ENXIO); 1020 } 1021 1022 int 1023 sbpp_close(dev_t dev, int flags, int mode, struct lwp *l) 1024 { 1025 return (ENXIO); 1026 } 1027 1028 int 1029 spif_ppcintr(void *v) 1030 { 1031 return (0); 1032 } 1033 1034 int 1035 sbpp_read(dev_t dev, struct uio *uio, int flags) 1036 { 1037 return (sbpp_rw(dev, uio)); 1038 } 1039 1040 int 1041 sbpp_write(dev_t dev, struct uio *uio, int flags) 1042 { 1043 return (sbpp_rw(dev, uio)); 1044 } 1045 1046 int 1047 sbpp_rw(dev_t dev, struct uio *uio) 1048 { 1049 return (ENXIO); 1050 } 1051 1052 int 1053 sbpp_poll(dev_t dev, int events, struct lwp *l) 1054 { 1055 return (seltrue(dev, events, l)); 1056 } 1057 1058 int 1059 sbpp_ioctl(dev_t dev, u_long cmd, void *data, int flags, struct lwp *l) 1060 { 1061 int error; 1062 1063 error = ENOTTY; 1064 1065 return (error); 1066 } 1067 1068 #endif /* NSPIF */ 1069