154008Sfujita /* 254008Sfujita * Copyright (c) 1992 OMRON Corporation. 354008Sfujita * Copyright (c) 1992 The Regents of the University of California. 454008Sfujita * All rights reserved. 554008Sfujita * 654008Sfujita * This code is derived from software contributed to Berkeley by 754008Sfujita * OMRON Corporation. 854008Sfujita * 954008Sfujita * %sccs.include.redist.c% 1054008Sfujita * 11*56873Sakito * @(#)sio.c 7.3 (Berkeley) 11/17/92 1254008Sfujita */ 1354008Sfujita 1454008Sfujita /* 1554008Sfujita * sio.c -- NEC uPD7201A UART Device Driver 16*56873Sakito * remaked by A.Fujita, NOV-5-1992 1754008Sfujita */ 1854008Sfujita 1954008Sfujita #include "sio.h" 2054008Sfujita #if NSIO > 0 2154008Sfujita 22*56873Sakito #include "bmc.h" 2354008Sfujita 24*56873Sakito #include "sys/param.h" 25*56873Sakito #include "sys/systm.h" 26*56873Sakito #include "sys/ioctl.h" 27*56873Sakito #include "sys/proc.h" 28*56873Sakito #include "sys/tty.h" 29*56873Sakito #include "sys/conf.h" 30*56873Sakito #include "sys/file.h" 31*56873Sakito #include "sys/uio.h" 32*56873Sakito #include "sys/kernel.h" 33*56873Sakito #include "sys/syslog.h" 3454008Sfujita 35*56873Sakito #include "device.h" 36*56873Sakito #include "sioreg.h" 37*56873Sakito #include "siovar.h" 3854008Sfujita 39*56873Sakito struct sio_portc *sio_port_assign(); 4054008Sfujita 41*56873Sakito int sioprobe(); 42*56873Sakito int sioopen(); 43*56873Sakito void siostart(); 44*56873Sakito int sioparam(); 45*56873Sakito int siointr(); 4654008Sfujita 4754008Sfujita struct driver siodriver = { 4854008Sfujita sioprobe, "sio", 4954008Sfujita }; 5054008Sfujita 51*56873Sakito #define NPORT 2 /* uPD7201A has 2 serial-port */ 52*56873Sakito #define NLINE 1 /* number of active line */ 5354008Sfujita 54*56873Sakito struct sio_portc sio_portc[NPORT] = { 55*56873Sakito { -1, -1, (struct siodevice *) 0x51000000, (int (*)()) 0 }, 56*56873Sakito { -1, -1, (struct siodevice *) 0x51000004, (int (*)()) 0 } 57*56873Sakito }; 5854008Sfujita 59*56873Sakito struct sio_softc sio_softc[NLINE]; 6054008Sfujita 61*56873Sakito int sio_init_done = 0; 62*56873Sakito int siounitbase = 0; /* This counter is used unit number assignment */ 6354008Sfujita 64*56873Sakito int siosoftCAR; 65*56873Sakito int sio_active; 66*56873Sakito int sioconsole; 67*56873Sakito int siodefaultrate = TTYDEF_SPEED; 68*56873Sakito int siomajor = 0; 6954008Sfujita 70*56873Sakito struct tty sio_tty[NLINE]; 7154008Sfujita 72*56873Sakito struct speedtab siospeedtab[] = { 73*56873Sakito 2400, WR4_BAUD24, 74*56873Sakito 4800, WR4_BAUD48, 75*56873Sakito 9600, WR4_BAUD96, 7654008Sfujita }; 7754008Sfujita 78*56873Sakito #define siounit(x) minor(x) 7954008Sfujita 8054008Sfujita 8154008Sfujita /* 82*56873Sakito * probe routines 8354008Sfujita */ 8454008Sfujita 8554008Sfujita sioprobe(hd) 8654008Sfujita register struct hp_device *hd; 8754008Sfujita { 88*56873Sakito register int port; 89*56873Sakito register struct sio_portc *pc; 90*56873Sakito register struct sio_softc *sc; 9154008Sfujita 92*56873Sakito sioinit((struct siodevice *) hd->hp_addr, siodefaultrate); 9354008Sfujita 94*56873Sakito /* locate the major number */ 95*56873Sakito for (siomajor = 0; siomajor < nchrdev; siomajor++) 96*56873Sakito if (cdevsw[siomajor].d_open == sioopen) 97*56873Sakito break; 9854008Sfujita 99*56873Sakito for (port = 0; port < NPORT; port++) { 100*56873Sakito pc = &sio_portc[port]; 10154008Sfujita 102*56873Sakito if (pc->pc_major != -1) { 103*56873Sakito printf("%s%d: port %d, address 0x%x, intr 0x%x (console)\n", 104*56873Sakito (pc->pc_major == siomajor ? "sio" : "bmc" ), 105*56873Sakito pc->pc_unit, port, pc->pc_addr, pc->pc_intr); 106*56873Sakito continue; 107*56873Sakito } 10854008Sfujita 109*56873Sakito pc->pc_addr = 110*56873Sakito (struct siodevice *)((u_long) hd->hp_addr + (sizeof(struct siodevice) * port)); 111*56873Sakito #if NBMC > 0 112*56873Sakito if (bmcinit(port)) 113*56873Sakito continue; 114*56873Sakito #endif 115*56873Sakito if (++siounitbase < NLINE) { 116*56873Sakito pc->pc_major = siomajor; 117*56873Sakito pc->pc_intr = siointr; 118*56873Sakito pc->pc_unit = siounitbase; 119*56873Sakito printf("sio%d: port %d, address 0x%x\n", pc->pc_unit, port, pc->pc_addr); 12054008Sfujita 121*56873Sakito sc = &sio_softc[pc->pc_unit]; 122*56873Sakito sc->sc_pc = pc; 12354008Sfujita 124*56873Sakito sio_active |= 1 << pc->pc_unit; 125*56873Sakito siosoftCAR |= 1 << pc->pc_unit; 126*56873Sakito } 127*56873Sakito } 128*56873Sakito } 12954008Sfujita 130*56873Sakito struct sio_portc * 131*56873Sakito sio_port_assign(port, major, unit, intr) 132*56873Sakito int port, major, unit; 133*56873Sakito int (*intr)(); 134*56873Sakito { 135*56873Sakito register struct sio_portc *pc = &sio_portc[port]; 13654008Sfujita 137*56873Sakito if (pc->pc_major != -1) 138*56873Sakito return((struct sio_portc *) 0); 13954008Sfujita 140*56873Sakito pc->pc_major = major; 141*56873Sakito pc->pc_intr = intr; 142*56873Sakito pc->pc_unit = unit; 14354008Sfujita 144*56873Sakito return(pc); 14554008Sfujita } 14654008Sfujita 147*56873Sakito 148*56873Sakito /* 149*56873Sakito * entry routines 150*56873Sakito */ 151*56873Sakito 15254008Sfujita /* ARGSUSED */ 15354008Sfujita #ifdef __STDC__ 15454008Sfujita sioopen(dev_t dev, int flag, int mode, struct proc *p) 15554008Sfujita #else 15654008Sfujita sioopen(dev, flag, mode, p) 15754008Sfujita dev_t dev; 15854008Sfujita int flag, mode; 15954008Sfujita struct proc *p; 16054008Sfujita #endif 16154008Sfujita { 16254008Sfujita register struct tty *tp; 16354008Sfujita register int unit; 16454008Sfujita int error = 0; 16554008Sfujita 16654008Sfujita unit = siounit(dev); 167*56873Sakito if (unit >= NLINE || (sio_active & (1 << unit)) == 0) 16854008Sfujita return (ENXIO); 16954008Sfujita tp = &sio_tty[unit]; 17054008Sfujita tp->t_oproc = siostart; 17154008Sfujita tp->t_param = sioparam; 17254008Sfujita tp->t_dev = dev; 17354008Sfujita if ((tp->t_state & TS_ISOPEN) == 0) { 17454008Sfujita tp->t_state |= TS_WOPEN; 17554008Sfujita ttychars(tp); 17654008Sfujita if (tp->t_ispeed == 0) { 17754008Sfujita tp->t_iflag = TTYDEF_IFLAG; 17854008Sfujita tp->t_oflag = TTYDEF_OFLAG; 179*56873Sakito /* tp->t_cflag = TTYDEF_CFLAG; */ 18054008Sfujita tp->t_cflag = (CREAD | CS8 | HUPCL); 18154008Sfujita tp->t_lflag = TTYDEF_LFLAG; 18254008Sfujita tp->t_ispeed = tp->t_ospeed = siodefaultrate; 18354008Sfujita } 18454008Sfujita sioparam(tp, &tp->t_termios); 18554008Sfujita ttsetwater(tp); 18654008Sfujita } else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0) 18754008Sfujita return (EBUSY); 188*56873Sakito (void) siomctl(dev, WR5_DTR | WR5_RTS, DMSET); 189*56873Sakito if ((siosoftCAR & (1 << unit)) || (siomctl(dev, 0, DMGET) & RR0_DCD)) 190*56873Sakito tp->t_state |= TS_CARR_ON; 19154008Sfujita (void) spltty(); 19254008Sfujita while ((flag&O_NONBLOCK) == 0 && (tp->t_cflag&CLOCAL) == 0 && 19354008Sfujita (tp->t_state & TS_CARR_ON) == 0) { 19454008Sfujita tp->t_state |= TS_WOPEN; 19554008Sfujita if (error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH, 19654008Sfujita ttopen, 0)) 19754008Sfujita break; 19854008Sfujita } 19954008Sfujita (void) spl0(); 20054008Sfujita if (error == 0) 20154008Sfujita error = (*linesw[tp->t_line].l_open)(dev, tp); 20254008Sfujita return (error); 20354008Sfujita } 204*56873Sakito 20554008Sfujita /*ARGSUSED*/ 20654008Sfujita sioclose(dev, flag, mode, p) 20754008Sfujita dev_t dev; 20854008Sfujita int flag, mode; 20954008Sfujita struct proc *p; 21054008Sfujita { 21154008Sfujita register struct tty *tp; 21254008Sfujita register int unit; 21354008Sfujita 21454008Sfujita unit = siounit(dev); 21554008Sfujita tp = &sio_tty[unit]; 21654008Sfujita (*linesw[tp->t_line].l_close)(tp, flag); 217*56873Sakito (void) siomctl(dev, WR5_BREAK, DMBIS); 218*56873Sakito if (tp->t_cflag&HUPCL || tp->t_state&TS_WOPEN || 219*56873Sakito (tp->t_state&TS_ISOPEN) == 0) 220*56873Sakito (void) siomctl(dev, 0, DMSET); 22154008Sfujita ttyclose(tp); 22254008Sfujita return (0); 22354008Sfujita } 22454008Sfujita 22554008Sfujita sioread(dev, uio, flag) 22654008Sfujita dev_t dev; 22754008Sfujita struct uio *uio; 22854008Sfujita { 22954008Sfujita register struct tty *tp = &sio_tty[siounit(dev)]; 23054008Sfujita 23154008Sfujita return ((*linesw[tp->t_line].l_read)(tp, uio, flag)); 23254008Sfujita } 23354008Sfujita 23454008Sfujita siowrite(dev, uio, flag) 23554008Sfujita dev_t dev; 23654008Sfujita struct uio *uio; 23754008Sfujita { 23854008Sfujita register struct tty *tp = &sio_tty[siounit(dev)]; 23954008Sfujita 24054008Sfujita return ((*linesw[tp->t_line].l_write)(tp, uio, flag)); 24154008Sfujita } 24254008Sfujita 243*56873Sakito /* 244*56873Sakito * Stop output on a line. 245*56873Sakito */ 246*56873Sakito /*ARGSUSED*/ 247*56873Sakito siostop(tp, flag) 248*56873Sakito register struct tty *tp; 24954008Sfujita { 250*56873Sakito register int s; 25154008Sfujita 252*56873Sakito s = spltty(); 253*56873Sakito if (tp->t_state & TS_BUSY) { 254*56873Sakito if ((tp->t_state&TS_TTSTOP)==0) 255*56873Sakito tp->t_state |= TS_FLUSH; 25654008Sfujita } 257*56873Sakito splx(s); 25854008Sfujita } 25954008Sfujita 26054008Sfujita sioioctl(dev, cmd, data, flag, p) 26154008Sfujita dev_t dev; 26254008Sfujita int cmd; 26354008Sfujita caddr_t data; 26454008Sfujita int flag; 26554008Sfujita struct proc *p; 26654008Sfujita { 26754008Sfujita register struct tty *tp; 26854008Sfujita register int unit = siounit(dev); 26954008Sfujita register int error; 270*56873Sakito 27154008Sfujita tp = &sio_tty[unit]; 27254008Sfujita error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p); 27354008Sfujita if (error >= 0) 27454008Sfujita return (error); 27554008Sfujita error = ttioctl(tp, cmd, data, flag); 27654008Sfujita if (error >= 0) 27754008Sfujita return (error); 27854008Sfujita 27954008Sfujita switch (cmd) { 28054008Sfujita 28154008Sfujita case TIOCSBRK: 282*56873Sakito (void) siomctl(dev, WR5_BREAK, DMBIS); 283*56873Sakito break; 284*56873Sakito 28554008Sfujita case TIOCCBRK: 286*56873Sakito (void) siomctl(dev, WR5_BREAK, DMBIC); 287*56873Sakito break; 288*56873Sakito 28954008Sfujita case TIOCSDTR: 290*56873Sakito (void) siomctl(dev, WR5_DTR | WR5_RTS, DMBIS); 291*56873Sakito break; 292*56873Sakito 29354008Sfujita case TIOCCDTR: 294*56873Sakito (void) siomctl(dev, WR5_DTR | WR5_RTS, DMBIC); 295*56873Sakito break; 296*56873Sakito 29754008Sfujita case TIOCMSET: 298*56873Sakito (void) siomctl(dev, *(int *)data, DMSET); 299*56873Sakito break; 300*56873Sakito 30154008Sfujita case TIOCMBIS: 302*56873Sakito (void) siomctl(dev, *(int *)data, DMBIS); 303*56873Sakito break; 304*56873Sakito 30554008Sfujita case TIOCMBIC: 306*56873Sakito (void) siomctl(dev, *(int *)data, DMBIC); 307*56873Sakito break; 308*56873Sakito 30954008Sfujita case TIOCMGET: 310*56873Sakito *(int *)data = siomctl(dev, 0, DMGET); 311*56873Sakito break; 312*56873Sakito 31354008Sfujita default: 31454008Sfujita return (ENOTTY); 31554008Sfujita } 31654008Sfujita return (0); 31754008Sfujita } 31854008Sfujita 31954008Sfujita 320*56873Sakito /* 321*56873Sakito * 322*56873Sakito */ 323*56873Sakito 32454008Sfujita void 32554008Sfujita siostart(tp) 32654008Sfujita register struct tty *tp; 32754008Sfujita { 32854008Sfujita register struct siodevice *sio; 329*56873Sakito register int rr; 330*56873Sakito int s, unit, c; 33154008Sfujita 33254008Sfujita unit = siounit(tp->t_dev); 333*56873Sakito sio = sio_softc[unit].sc_pc->pc_addr; 33454008Sfujita s = spltty(); 33554008Sfujita if (tp->t_state & (TS_TIMEOUT|TS_TTSTOP)) 33654008Sfujita goto out; 33754008Sfujita if (tp->t_outq.c_cc <= tp->t_lowat) { 33854008Sfujita if (tp->t_state&TS_ASLEEP) { 33954008Sfujita tp->t_state &= ~TS_ASLEEP; 34054008Sfujita wakeup((caddr_t)&tp->t_outq); 34154008Sfujita } 34254008Sfujita selwakeup(&tp->t_wsel); 34354008Sfujita } 34454008Sfujita if (tp->t_outq.c_cc == 0) 34554008Sfujita goto out; 346*56873Sakito rr = siogetreg(sio); 34754008Sfujita if (rr & RR_TXRDY) { 34854008Sfujita c = getc(&tp->t_outq); 34954008Sfujita tp->t_state |= TS_BUSY; 35054008Sfujita sio->sio_data = c; 35154008Sfujita } 35254008Sfujita out: 35354008Sfujita splx(s); 35454008Sfujita } 355*56873Sakito 356*56873Sakito sioparam(tp, t) 357*56873Sakito register struct tty *tp; 358*56873Sakito register struct termios *t; 359*56873Sakito { 360*56873Sakito int unit = siounit(tp->t_dev); 361*56873Sakito register struct siodevice *sio; 362*56873Sakito register cflag = t->c_cflag; 363*56873Sakito register u_char wr; 364*56873Sakito int ospeed = ttspeedtab(t->c_ospeed, siospeedtab); 365*56873Sakito 366*56873Sakito sio = sio_softc[unit].sc_pc->pc_addr; 367*56873Sakito 368*56873Sakito switch (cflag & CSIZE) { 369*56873Sakito case CS5: 370*56873Sakito case CS6: 371*56873Sakito case CS7: 372*56873Sakito case CS8: 373*56873Sakito break; 374*56873Sakito } 375*56873Sakito 376*56873Sakito wr = ospeed; 377*56873Sakito 378*56873Sakito if (cflag & PARENB) { 379*56873Sakito wr |= WR4_PARENAB; 380*56873Sakito if ((cflag&PARODD) == 0) 381*56873Sakito wr |= WR4_EPARITY; 382*56873Sakito } 383*56873Sakito 384*56873Sakito if (cflag & CSTOPB) 385*56873Sakito wr |= WR4_STOP2; /* 2 stop bit */ 386*56873Sakito else 387*56873Sakito wr |= WR4_STOP1; /* 1 stop bit */ 388*56873Sakito 389*56873Sakito (void) sioreg(sio, WR4, wr); 390*56873Sakito 391*56873Sakito return (0); 392*56873Sakito } 393*56873Sakito 394*56873Sakito siomctl() 395*56873Sakito { 396*56873Sakito return (0); 397*56873Sakito } 398*56873Sakito 399*56873Sakito 40054008Sfujita /* 401*56873Sakito * Interrupt handling 40254008Sfujita */ 403*56873Sakito 404*56873Sakito void 405*56873Sakito _siointr() 40654008Sfujita { 407*56873Sakito register int port; 408*56873Sakito register struct sio_portc *pc; 40954008Sfujita 410*56873Sakito for (port = 0; port < NPORT; port++) { 411*56873Sakito pc = &sio_portc[port]; 412*56873Sakito 413*56873Sakito if (pc->pc_major != -1) 414*56873Sakito (pc->pc_intr)(pc->pc_unit); 41554008Sfujita } 41654008Sfujita } 41754008Sfujita 418*56873Sakito siointr(unit) 419*56873Sakito register int unit; 420*56873Sakito { 421*56873Sakito register struct siodevice *sio = sio_softc[unit].sc_pc->pc_addr; 422*56873Sakito register u_char code; 423*56873Sakito register struct tty *tp; 424*56873Sakito int s, rr; 425*56873Sakito 426*56873Sakito tp = &sio_tty[unit]; 427*56873Sakito rr = siogetreg(sio); 428*56873Sakito 429*56873Sakito if (rr & RR_RXRDY) { 430*56873Sakito code = sio->sio_data; 431*56873Sakito if ((tp->t_state & TS_ISOPEN) != 0) 432*56873Sakito (*linesw[tp->t_line].l_rint)(code, tp); 433*56873Sakito } 434*56873Sakito 435*56873Sakito if (rr & RR_TXRDY) { 436*56873Sakito sio->sio_cmd = WR0_RSTPEND; 437*56873Sakito tp->t_state &= ~(TS_BUSY|TS_FLUSH); 438*56873Sakito if (tp->t_line) 439*56873Sakito (*linesw[tp->t_line].l_start)(tp); 440*56873Sakito else 441*56873Sakito siostart(tp); 442*56873Sakito } 443*56873Sakito } 444*56873Sakito 44554008Sfujita /* 44654008Sfujita * Following are all routines needed for SIO to act as console 44754008Sfujita */ 448*56873Sakito #include "../luna68k/cons.h" 44954008Sfujita 45054008Sfujita siocnprobe(cp) 451*56873Sakito register struct consdev *cp; 45254008Sfujita { 453*56873Sakito register int unit = 0; 45454008Sfujita 45554008Sfujita /* locate the major number */ 45654008Sfujita for (siomajor = 0; siomajor < nchrdev; siomajor++) 45754008Sfujita if (cdevsw[siomajor].d_open == sioopen) 45854008Sfujita break; 45954008Sfujita 460*56873Sakito siounitbase = -1; 46154008Sfujita 46254008Sfujita /* initialize required fields */ 46354008Sfujita cp->cn_dev = makedev(siomajor, unit); 464*56873Sakito cp->cn_tp = &sio_tty[unit]; 46554008Sfujita cp->cn_pri = CN_NORMAL; 46654008Sfujita } 46754008Sfujita 46854008Sfujita siocninit(cp) 46954008Sfujita struct consdev *cp; 47054008Sfujita { 47154008Sfujita int unit = siounit(cp->cn_dev); 472*56873Sakito register struct sio_softc *sc = &sio_softc[unit]; 47354008Sfujita 474*56873Sakito sioinit((struct siodevice *) SIO_HARDADDR, siodefaultrate); 475*56873Sakito 476*56873Sakito /* port assign */ 477*56873Sakito sc->sc_pc = sio_port_assign(0, siomajor, unit, siointr); 478*56873Sakito 47954008Sfujita sioconsole = unit; 480*56873Sakito siounitbase = 0; 481*56873Sakito 482*56873Sakito sio_active |= 1 << unit; 483*56873Sakito siosoftCAR |= 1 << unit; 48454008Sfujita } 48554008Sfujita 48654008Sfujita siocngetc(dev) 48754008Sfujita dev_t dev; 48854008Sfujita { 489*56873Sakito struct sio_softc *sc = &sio_softc[siounit(dev)]; 490*56873Sakito struct sio_portc *pc = sc->sc_pc; 49154008Sfujita 492*56873Sakito return(sio_imgetc(pc->pc_addr)); 49354008Sfujita } 49454008Sfujita 49554008Sfujita siocnputc(dev, c) 49654008Sfujita dev_t dev; 49754008Sfujita int c; 49854008Sfujita { 499*56873Sakito struct sio_softc *sc = &sio_softc[siounit(dev)]; 500*56873Sakito struct sio_portc *pc = sc->sc_pc; 50154008Sfujita 502*56873Sakito sio_imputc(pc->pc_addr, c); 503*56873Sakito } 50454008Sfujita 50554008Sfujita 506*56873Sakito /* 507*56873Sakito * sio raw-level routines 508*56873Sakito */ 50954008Sfujita 510*56873Sakito sioinit(sio0, rate) 511*56873Sakito register struct siodevice *sio0; 512*56873Sakito register int rate; 513*56873Sakito { 514*56873Sakito register struct siodevice *sio1; 515*56873Sakito int s; 51654008Sfujita 517*56873Sakito rate = ttspeedtab(rate, siospeedtab); 51854008Sfujita 519*56873Sakito if (sio_init_done) 520*56873Sakito return; 52154008Sfujita 522*56873Sakito sio1 = (struct siodevice *) ((u_long) sio0 + sizeof(struct siodevice)); 52354008Sfujita 52454008Sfujita s = splhigh(); 52554008Sfujita 526*56873Sakito sioreg(sio0, WR0, WR0_CHANRST); /* Channel-A Reset */ 52754008Sfujita 528*56873Sakito sioreg(sio0, WR2, (WR2_VEC86 | WR2_INTR_1)); /* Set CPU BUS Interface Mode */ 529*56873Sakito sioreg(sio1, WR2, 0); /* Set Interrupt Vector */ 53054008Sfujita 531*56873Sakito sioreg(sio0, WR0, WR0_RSTINT); /* Reset E/S Interrupt */ 532*56873Sakito sioreg(sio0, WR4, (rate | WR4_STOP1 | WR4_NPARITY)); /* Tx/Rx */ 533*56873Sakito sioreg(sio0, WR3, (WR3_RX8BIT | WR3_RXENBL)); /* Rx */ 534*56873Sakito sioreg(sio0, WR5, (WR5_TX8BIT | WR5_TXENBL)); /* Tx */ 535*56873Sakito sioreg(sio0, WR0, WR0_RSTINT); /* Reset E/S Interrupt */ 536*56873Sakito sioreg(sio0, WR1, (WR1_RXALLS | WR1_TXENBL)); 53754008Sfujita 538*56873Sakito sioreg(sio1, WR0, WR0_CHANRST); /* Channel-B Reset */ 53954008Sfujita 540*56873Sakito sioreg(sio1, WR0, WR0_RSTINT); /* Reset E/S Interrupt */ 541*56873Sakito sioreg(sio1, WR4, (rate | WR4_STOP1 | WR4_NPARITY)); /* Tx/Rx */ 542*56873Sakito sioreg(sio1, WR3, (WR3_RX8BIT | WR3_RXENBL)); /* Rx */ 543*56873Sakito sioreg(sio1, WR5, (WR5_TX8BIT | WR5_TXENBL)); /* Tx */ 544*56873Sakito sioreg(sio1, WR0, WR0_RSTINT); /* Reset E/S Interrupt */ 545*56873Sakito sioreg(sio1, WR1, (WR1_RXALLS | WR1_TXENBL)); 546*56873Sakito 54754008Sfujita splx(s); 548*56873Sakito 549*56873Sakito sio_init_done = 1; 55054008Sfujita } 55154008Sfujita 552*56873Sakito sio_imgetc(sio) 553*56873Sakito register struct siodevice *sio; 55454008Sfujita { 555*56873Sakito register int rr0, rr1; 556*56873Sakito int c, s; 55754008Sfujita 558*56873Sakito s = splhigh(); 559*56873Sakito while (((rr0 = sioreg(sio, RR0, 0)) & RR0_RXAVAIL) == 0) 560*56873Sakito ; 561*56873Sakito c = sio->sio_data; 562*56873Sakito sioreg(sio, WR0, WR0_RSTPEND); 563*56873Sakito splx(s); 564*56873Sakito return (c); 56554008Sfujita } 56654008Sfujita 567*56873Sakito sio_imputc(sio, c) 568*56873Sakito register struct siodevice *sio; 56954008Sfujita int c; 57054008Sfujita { 57154008Sfujita register u_char code; 572*56873Sakito register int rr; 573*56873Sakito int s; 57454008Sfujita 57554008Sfujita s = splhigh(); 57654008Sfujita 577*56873Sakito sioreg(sio, WR1, WR1_RXALLS); 578*56873Sakito 57954008Sfujita do { 58054008Sfujita DELAY(1); 581*56873Sakito rr = siogetreg(sio); 58254008Sfujita } while (!(rr & RR_TXRDY)); 583*56873Sakito 584*56873Sakito code = (c & 0xFF); 58554008Sfujita sio->sio_data = code; 58654008Sfujita 58754008Sfujita do { 58854008Sfujita DELAY(1); 589*56873Sakito rr = siogetreg(sio); 59054008Sfujita } while (!(rr & RR_TXRDY)); 59154008Sfujita 592*56873Sakito sioreg(sio, WR1, (WR1_RXALLS | WR1_TXENBL)); 593*56873Sakito 59454008Sfujita splx(s); 59554008Sfujita } 59654008Sfujita 597*56873Sakito /* 598*56873Sakito * uPD7201A register operation 599*56873Sakito */ 60054008Sfujita 60154008Sfujita int 602*56873Sakito siogetreg(sio) 603*56873Sakito register struct siodevice *sio; 60454008Sfujita { 60554008Sfujita register int rr = 0; 60654008Sfujita 60754008Sfujita rr = sio->sio_stat; 60854008Sfujita rr <<= 8; 60954008Sfujita sio->sio_cmd = 1; /* Select RR1 */ 61054008Sfujita rr |= sio->sio_stat; 61154008Sfujita 61254008Sfujita return(rr); 61354008Sfujita } 61454008Sfujita 61554008Sfujita int 616*56873Sakito sioreg(sio, reg, val) 617*56873Sakito register struct siodevice *sio; 61854008Sfujita register int reg, val; 61954008Sfujita { 62054008Sfujita if (isStatusReg(reg)) { 621*56873Sakito if (reg != 0) 622*56873Sakito sio->sio_cmd = reg; 623*56873Sakito val = sio->sio_stat; 62454008Sfujita } else { 625*56873Sakito if (reg != 0) 626*56873Sakito sio->sio_cmd = reg; 627*56873Sakito sio->sio_cmd = val; 62854008Sfujita } 629*56873Sakito 630*56873Sakito return(val); 63154008Sfujita } 63254008Sfujita #endif 633