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*59648Sakito * @(#)sio.c 7.8 (Berkeley) 05/02/93 1254008Sfujita */ 1354008Sfujita 1454008Sfujita /* 1554008Sfujita * sio.c -- NEC uPD7201A UART Device Driver 1656873Sakito * remaked by A.Fujita, NOV-5-1992 1754008Sfujita */ 1854008Sfujita 1954008Sfujita #include "sio.h" 2054008Sfujita #if NSIO > 0 2154008Sfujita 2256873Sakito #include "bmc.h" 2354008Sfujita 2457058Sakito #include <sys/param.h> 2557058Sakito #include <sys/systm.h> 2657058Sakito #include <sys/ioctl.h> 2757058Sakito #include <sys/proc.h> 2857058Sakito #include <sys/tty.h> 2957058Sakito #include <sys/conf.h> 3057058Sakito #include <sys/file.h> 3157058Sakito #include <sys/uio.h> 3257058Sakito #include <sys/kernel.h> 3357058Sakito #include <sys/syslog.h> 3454008Sfujita 3557058Sakito #include <luna68k/dev/device.h> 3657058Sakito #include <luna68k/dev/sioreg.h> 3757058Sakito #include <luna68k/dev/siovar.h> 3854008Sfujita 3956873Sakito struct sio_portc *sio_port_assign(); 4057291Sakito struct sio_portc *sio_port_get(); 4154008Sfujita 4256873Sakito int sioprobe(); 4356873Sakito int sioopen(); 4456873Sakito void siostart(); 4556873Sakito int sioparam(); 4656873Sakito int siointr(); 4754008Sfujita 4854008Sfujita struct driver siodriver = { 4954008Sfujita sioprobe, "sio", 5054008Sfujita }; 5154008Sfujita 5256873Sakito struct sio_portc sio_portc[NPORT] = { 53*59648Sakito { -1, -1, 0, (struct siodevice *) 0x51000000, (int (*)()) 0 }, 54*59648Sakito { -1, -1, 1, (struct siodevice *) 0x51000004, (int (*)()) 0 } 5556873Sakito }; 5654008Sfujita 57*59648Sakito struct sio_softc sio_softc[NSIO]; 5854008Sfujita 5956873Sakito int sio_init_done = 0; 6054008Sfujita 6156873Sakito int siosoftCAR; 6256873Sakito int sio_active; 6357126Sakito int sioconsole = -1; 6456873Sakito int siodefaultrate = TTYDEF_SPEED; 6557291Sakito int siomajor = 12; 6654008Sfujita 67*59648Sakito struct tty sio_tty[NSIO]; 6854008Sfujita 6956873Sakito struct speedtab siospeedtab[] = { 7056873Sakito 2400, WR4_BAUD24, 7156873Sakito 4800, WR4_BAUD48, 7256873Sakito 9600, WR4_BAUD96, 7354008Sfujita }; 7454008Sfujita 7556873Sakito #define siounit(x) minor(x) 7654008Sfujita 7757126Sakito extern struct tty *constty; 7854008Sfujita 7954008Sfujita /* 8056873Sakito * probe routines 8154008Sfujita */ 8254008Sfujita 8354008Sfujita sioprobe(hd) 8454008Sfujita register struct hp_device *hd; 8554008Sfujita { 86*59648Sakito int unit = hd->hp_unit; 87*59648Sakito register struct sio_softc *sc = &sio_softc[unit]; 8856873Sakito register struct sio_portc *pc; 8954008Sfujita 90*59648Sakito if (sc->sc_pc != 0) { 91*59648Sakito pc = sc->sc_pc; 92*59648Sakito printf("sio%d: port %d, address 0x%x, intr 0x%x (console)\n", 93*59648Sakito pc->pc_unit, pc->pc_port, pc->pc_addr, pc->pc_intr); 94*59648Sakito return(0); 95*59648Sakito } 9654008Sfujita 97*59648Sakito sc->sc_pc = pc = sio_port_assign(SIO_PORT, siomajor, unit, siointr); 9854008Sfujita 99*59648Sakito printf("sio%d: port %d, address 0x%x, intr 0x%x\n", 100*59648Sakito pc->pc_unit, pc->pc_port, pc->pc_addr, pc->pc_intr); 10154008Sfujita 102*59648Sakito sio_active |= 1 << unit; 103*59648Sakito siosoftCAR |= 1 << unit; 104*59648Sakito return(1); 10556873Sakito } 10654008Sfujita 10756873Sakito struct sio_portc * 10856873Sakito sio_port_assign(port, major, unit, intr) 10956873Sakito int port, major, unit; 11056873Sakito int (*intr)(); 11156873Sakito { 11257291Sakito register struct sio_portc *pc; 11354008Sfujita 11457291Sakito pc = &sio_portc[port]; 11557291Sakito 11656873Sakito pc->pc_major = major; 11756873Sakito pc->pc_intr = intr; 11856873Sakito pc->pc_unit = unit; 11954008Sfujita 12056873Sakito return(pc); 12154008Sfujita } 12254008Sfujita 12357291Sakito struct sio_portc * 12457291Sakito sio_port_get(port) 12557291Sakito int port; 12657291Sakito { 12757291Sakito register struct sio_portc *pc; 12856873Sakito 12957291Sakito pc = &sio_portc[port]; 13057291Sakito 13157291Sakito return(pc); 13257291Sakito } 13357291Sakito 13457291Sakito int 13557291Sakito sio_port_info() 13657291Sakito { 13757291Sakito printf("sio_port_info[sio.c]:\t{%d} major = %d, unit = %d, intr = 0x%x\n", 13857291Sakito 0, sio_portc[0].pc_major, sio_portc[0].pc_unit, sio_portc[0].pc_intr); 13957291Sakito printf("sio_port_info[sio.c]:\t{%d} major = %d, unit = %d, intr = 0x%x\n", 14057291Sakito 1, sio_portc[1].pc_major, sio_portc[1].pc_unit, sio_portc[1].pc_intr); 14157291Sakito } 14257291Sakito 14357291Sakito 14456873Sakito /* 14556873Sakito * entry routines 14656873Sakito */ 14756873Sakito 14854008Sfujita /* ARGSUSED */ 14954008Sfujita #ifdef __STDC__ 15054008Sfujita sioopen(dev_t dev, int flag, int mode, struct proc *p) 15154008Sfujita #else 15254008Sfujita sioopen(dev, flag, mode, p) 15354008Sfujita dev_t dev; 15454008Sfujita int flag, mode; 15554008Sfujita struct proc *p; 15654008Sfujita #endif 15754008Sfujita { 15854008Sfujita register struct tty *tp; 15954008Sfujita register int unit; 16054008Sfujita int error = 0; 16154008Sfujita 16254008Sfujita unit = siounit(dev); 163*59648Sakito if (unit >= NSIO || (sio_active & (1 << unit)) == 0) 16454008Sfujita return (ENXIO); 16554008Sfujita tp = &sio_tty[unit]; 16654008Sfujita tp->t_oproc = siostart; 16754008Sfujita tp->t_param = sioparam; 16854008Sfujita tp->t_dev = dev; 16954008Sfujita if ((tp->t_state & TS_ISOPEN) == 0) { 17054008Sfujita tp->t_state |= TS_WOPEN; 17154008Sfujita ttychars(tp); 17254008Sfujita if (tp->t_ispeed == 0) { 17354008Sfujita tp->t_iflag = TTYDEF_IFLAG; 17454008Sfujita tp->t_oflag = TTYDEF_OFLAG; 17556873Sakito /* tp->t_cflag = TTYDEF_CFLAG; */ 17654008Sfujita tp->t_cflag = (CREAD | CS8 | HUPCL); 17754008Sfujita tp->t_lflag = TTYDEF_LFLAG; 17854008Sfujita tp->t_ispeed = tp->t_ospeed = siodefaultrate; 17954008Sfujita } 18054008Sfujita sioparam(tp, &tp->t_termios); 18154008Sfujita ttsetwater(tp); 18254008Sfujita } else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0) 18354008Sfujita return (EBUSY); 18456873Sakito (void) siomctl(dev, WR5_DTR | WR5_RTS, DMSET); 18556873Sakito if ((siosoftCAR & (1 << unit)) || (siomctl(dev, 0, DMGET) & RR0_DCD)) 18656873Sakito tp->t_state |= TS_CARR_ON; 18754008Sfujita (void) spltty(); 18854008Sfujita while ((flag&O_NONBLOCK) == 0 && (tp->t_cflag&CLOCAL) == 0 && 18954008Sfujita (tp->t_state & TS_CARR_ON) == 0) { 19054008Sfujita tp->t_state |= TS_WOPEN; 19154008Sfujita if (error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH, 19254008Sfujita ttopen, 0)) 19354008Sfujita break; 19454008Sfujita } 19554008Sfujita (void) spl0(); 19654008Sfujita if (error == 0) 19754008Sfujita error = (*linesw[tp->t_line].l_open)(dev, tp); 19854008Sfujita return (error); 19954008Sfujita } 20056873Sakito 20154008Sfujita /*ARGSUSED*/ 20254008Sfujita sioclose(dev, flag, mode, p) 20354008Sfujita dev_t dev; 20454008Sfujita int flag, mode; 20554008Sfujita struct proc *p; 20654008Sfujita { 20754008Sfujita register struct tty *tp; 20854008Sfujita register int unit; 20954008Sfujita 21054008Sfujita unit = siounit(dev); 21154008Sfujita tp = &sio_tty[unit]; 21254008Sfujita (*linesw[tp->t_line].l_close)(tp, flag); 21356873Sakito (void) siomctl(dev, WR5_BREAK, DMBIS); 21456873Sakito if (tp->t_cflag&HUPCL || tp->t_state&TS_WOPEN || 21556873Sakito (tp->t_state&TS_ISOPEN) == 0) 21656873Sakito (void) siomctl(dev, 0, DMSET); 21754008Sfujita ttyclose(tp); 21854008Sfujita return (0); 21954008Sfujita } 22054008Sfujita 22154008Sfujita sioread(dev, uio, flag) 22254008Sfujita dev_t dev; 22354008Sfujita struct uio *uio; 22454008Sfujita { 22554008Sfujita register struct tty *tp = &sio_tty[siounit(dev)]; 22654008Sfujita 22754008Sfujita return ((*linesw[tp->t_line].l_read)(tp, uio, flag)); 22854008Sfujita } 22954008Sfujita 23054008Sfujita siowrite(dev, uio, flag) 23154008Sfujita dev_t dev; 23254008Sfujita struct uio *uio; 23354008Sfujita { 23457126Sakito register int unit = siounit(dev); 23557126Sakito register struct tty *tp = &sio_tty[unit]; 23654008Sfujita 23757126Sakito if ((unit == sioconsole) && constty && 23857126Sakito (constty->t_state&(TS_CARR_ON|TS_ISOPEN))==(TS_CARR_ON|TS_ISOPEN)) 23957126Sakito tp = constty; 24057126Sakito 24154008Sfujita return ((*linesw[tp->t_line].l_write)(tp, uio, flag)); 24254008Sfujita } 24354008Sfujita 24456873Sakito /* 24556873Sakito * Stop output on a line. 24656873Sakito */ 24756873Sakito /*ARGSUSED*/ 24856873Sakito siostop(tp, flag) 24956873Sakito register struct tty *tp; 25054008Sfujita { 25156873Sakito register int s; 25254008Sfujita 25356873Sakito s = spltty(); 25456873Sakito if (tp->t_state & TS_BUSY) { 25556873Sakito if ((tp->t_state&TS_TTSTOP)==0) 25656873Sakito tp->t_state |= TS_FLUSH; 25754008Sfujita } 25856873Sakito splx(s); 25954008Sfujita } 26054008Sfujita 26154008Sfujita sioioctl(dev, cmd, data, flag, p) 26254008Sfujita dev_t dev; 26354008Sfujita int cmd; 26454008Sfujita caddr_t data; 26554008Sfujita int flag; 26654008Sfujita struct proc *p; 26754008Sfujita { 26854008Sfujita register struct tty *tp; 26954008Sfujita register int unit = siounit(dev); 27054008Sfujita register int error; 27156873Sakito 27254008Sfujita tp = &sio_tty[unit]; 27354008Sfujita error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p); 27454008Sfujita if (error >= 0) 27554008Sfujita return (error); 27654008Sfujita error = ttioctl(tp, cmd, data, flag); 27754008Sfujita if (error >= 0) 27854008Sfujita return (error); 27954008Sfujita 28054008Sfujita switch (cmd) { 28154008Sfujita 28254008Sfujita case TIOCSBRK: 28356873Sakito (void) siomctl(dev, WR5_BREAK, DMBIS); 28456873Sakito break; 28556873Sakito 28654008Sfujita case TIOCCBRK: 28756873Sakito (void) siomctl(dev, WR5_BREAK, DMBIC); 28856873Sakito break; 28956873Sakito 29054008Sfujita case TIOCSDTR: 29156873Sakito (void) siomctl(dev, WR5_DTR | WR5_RTS, DMBIS); 29256873Sakito break; 29356873Sakito 29454008Sfujita case TIOCCDTR: 29556873Sakito (void) siomctl(dev, WR5_DTR | WR5_RTS, DMBIC); 29656873Sakito break; 29756873Sakito 29854008Sfujita case TIOCMSET: 29956873Sakito (void) siomctl(dev, *(int *)data, DMSET); 30056873Sakito break; 30156873Sakito 30254008Sfujita case TIOCMBIS: 30356873Sakito (void) siomctl(dev, *(int *)data, DMBIS); 30456873Sakito break; 30556873Sakito 30654008Sfujita case TIOCMBIC: 30756873Sakito (void) siomctl(dev, *(int *)data, DMBIC); 30856873Sakito break; 30956873Sakito 31054008Sfujita case TIOCMGET: 31156873Sakito *(int *)data = siomctl(dev, 0, DMGET); 31256873Sakito break; 31356873Sakito 31454008Sfujita default: 31554008Sfujita return (ENOTTY); 31654008Sfujita } 31754008Sfujita return (0); 31854008Sfujita } 31954008Sfujita 32054008Sfujita 32156873Sakito /* 32256873Sakito * 32356873Sakito */ 32456873Sakito 32554008Sfujita void 32654008Sfujita siostart(tp) 32754008Sfujita register struct tty *tp; 32854008Sfujita { 32954008Sfujita register struct siodevice *sio; 33056873Sakito register int rr; 33156873Sakito int s, unit, c; 33254008Sfujita 33354008Sfujita unit = siounit(tp->t_dev); 33456873Sakito sio = sio_softc[unit].sc_pc->pc_addr; 33554008Sfujita s = spltty(); 33654008Sfujita if (tp->t_state & (TS_TIMEOUT|TS_TTSTOP)) 33754008Sfujita goto out; 33854008Sfujita if (tp->t_outq.c_cc <= tp->t_lowat) { 33954008Sfujita if (tp->t_state&TS_ASLEEP) { 34054008Sfujita tp->t_state &= ~TS_ASLEEP; 34154008Sfujita wakeup((caddr_t)&tp->t_outq); 34254008Sfujita } 34354008Sfujita selwakeup(&tp->t_wsel); 34454008Sfujita } 34554008Sfujita if (tp->t_outq.c_cc == 0) 34654008Sfujita goto out; 34756873Sakito rr = siogetreg(sio); 34854008Sfujita if (rr & RR_TXRDY) { 34954008Sfujita c = getc(&tp->t_outq); 35054008Sfujita tp->t_state |= TS_BUSY; 35154008Sfujita sio->sio_data = c; 35254008Sfujita } 35354008Sfujita out: 35454008Sfujita splx(s); 35554008Sfujita } 35656873Sakito 35756873Sakito sioparam(tp, t) 35856873Sakito register struct tty *tp; 35956873Sakito register struct termios *t; 36056873Sakito { 36156873Sakito int unit = siounit(tp->t_dev); 36256873Sakito register struct siodevice *sio; 36356873Sakito register cflag = t->c_cflag; 36456873Sakito register u_char wr; 36556873Sakito int ospeed = ttspeedtab(t->c_ospeed, siospeedtab); 36656873Sakito 36756873Sakito sio = sio_softc[unit].sc_pc->pc_addr; 36856873Sakito 36956873Sakito switch (cflag & CSIZE) { 37056873Sakito case CS5: 37156873Sakito case CS6: 37256873Sakito case CS7: 37356873Sakito case CS8: 37456873Sakito break; 37556873Sakito } 37656873Sakito 37756873Sakito wr = ospeed; 37856873Sakito 37956873Sakito if (cflag & PARENB) { 38056873Sakito wr |= WR4_PARENAB; 38156873Sakito if ((cflag&PARODD) == 0) 38256873Sakito wr |= WR4_EPARITY; 38356873Sakito } 38456873Sakito 38556873Sakito if (cflag & CSTOPB) 38656873Sakito wr |= WR4_STOP2; /* 2 stop bit */ 38756873Sakito else 38856873Sakito wr |= WR4_STOP1; /* 1 stop bit */ 38956873Sakito 39056873Sakito (void) sioreg(sio, WR4, wr); 39156873Sakito 39256873Sakito return (0); 39356873Sakito } 39456873Sakito 39556873Sakito siomctl() 39656873Sakito { 39756873Sakito return (0); 39856873Sakito } 39956873Sakito 40056873Sakito 40154008Sfujita /* 40256873Sakito * Interrupt handling 40354008Sfujita */ 40456873Sakito 40556873Sakito void 40656873Sakito _siointr() 40754008Sfujita { 40856873Sakito register int port; 40956873Sakito register struct sio_portc *pc; 41054008Sfujita 41156873Sakito for (port = 0; port < NPORT; port++) { 41256873Sakito pc = &sio_portc[port]; 41356873Sakito 41456873Sakito if (pc->pc_major != -1) 41556873Sakito (pc->pc_intr)(pc->pc_unit); 41654008Sfujita } 41754008Sfujita } 41854008Sfujita 41956873Sakito siointr(unit) 42056873Sakito register int unit; 42156873Sakito { 42256873Sakito register struct siodevice *sio = sio_softc[unit].sc_pc->pc_addr; 42356873Sakito register u_char code; 42456873Sakito register struct tty *tp; 42556873Sakito int s, rr; 42656873Sakito 42756873Sakito tp = &sio_tty[unit]; 42857850Sakito 42957850Sakito start: 43056873Sakito rr = siogetreg(sio); 43157850Sakito if (rr & RR_RXRDY) { 43257850Sakito if (rr & (RR_FRAMING | RR_OVERRUN | RR_PARITY)) { 43357850Sakito sioeint(unit, rr, sio); 43457850Sakito goto start; 43557850Sakito } 43656873Sakito 43756873Sakito code = sio->sio_data; 43856873Sakito if ((tp->t_state & TS_ISOPEN) != 0) 43956873Sakito (*linesw[tp->t_line].l_rint)(code, tp); 44057850Sakito 44157850Sakito while ((rr = siogetreg(sio)) & RR_RXRDY) { 44257850Sakito code = sio->sio_data; 44357850Sakito if ((tp->t_state & TS_ISOPEN) != 0) 44457850Sakito (*linesw[tp->t_line].l_rint)(code, tp); 44557850Sakito } 44656873Sakito } 44756873Sakito 44856873Sakito if (rr & RR_TXRDY) { 44956873Sakito sio->sio_cmd = WR0_RSTPEND; 45056873Sakito tp->t_state &= ~(TS_BUSY|TS_FLUSH); 45156873Sakito if (tp->t_line) 45256873Sakito (*linesw[tp->t_line].l_start)(tp); 45356873Sakito else 45456873Sakito siostart(tp); 45556873Sakito } 45656873Sakito } 45756873Sakito 45857850Sakito sioeint(unit, stat, sio) 45957850Sakito register int unit, stat; 46057850Sakito register struct siodevice *sio; 46157850Sakito { 46257850Sakito register struct tty *tp; 46357850Sakito register int code; 46457850Sakito 46557850Sakito tp = &sio_tty[unit]; 46657850Sakito 46757850Sakito code = sio->sio_data; 46857850Sakito 46957850Sakito sio->sio_cmd = WR0_ERRRST; 47057850Sakito 47157850Sakito if ((tp->t_state & TS_ISOPEN) == 0) 47257850Sakito return; 47357850Sakito 47457850Sakito if (stat & RR_FRAMING) 47557850Sakito code |= TTY_FE; 47657850Sakito else if (stat & RR_PARITY) 47757850Sakito code |= TTY_PE; 47857850Sakito 47957850Sakito (*linesw[tp->t_line].l_rint)(code, tp); 48057850Sakito } 48157850Sakito 48254008Sfujita /* 48354008Sfujita * Following are all routines needed for SIO to act as console 48454008Sfujita */ 48557058Sakito #include <luna68k/luna68k/cons.h> 48654008Sfujita 48754008Sfujita siocnprobe(cp) 48856873Sakito register struct consdev *cp; 48954008Sfujita { 49056873Sakito register int unit = 0; 49154008Sfujita 49254008Sfujita /* locate the major number */ 49354008Sfujita for (siomajor = 0; siomajor < nchrdev; siomajor++) 49454008Sfujita if (cdevsw[siomajor].d_open == sioopen) 49554008Sfujita break; 49654008Sfujita 49754008Sfujita /* initialize required fields */ 49854008Sfujita cp->cn_dev = makedev(siomajor, unit); 49956873Sakito cp->cn_tp = &sio_tty[unit]; 50054008Sfujita cp->cn_pri = CN_NORMAL; 50154008Sfujita } 50254008Sfujita 50354008Sfujita siocninit(cp) 50454008Sfujita struct consdev *cp; 50554008Sfujita { 50654008Sfujita int unit = siounit(cp->cn_dev); 50756873Sakito register struct sio_softc *sc = &sio_softc[unit]; 50854008Sfujita 50956873Sakito sioinit((struct siodevice *) SIO_HARDADDR, siodefaultrate); 51056873Sakito 51156873Sakito /* port assign */ 512*59648Sakito sc->sc_pc = sio_port_assign(SIO_PORT, siomajor, unit, siointr); 51356873Sakito 51454008Sfujita sioconsole = unit; 51556873Sakito sio_active |= 1 << unit; 51656873Sakito siosoftCAR |= 1 << unit; 51754008Sfujita } 51854008Sfujita 51954008Sfujita siocngetc(dev) 52054008Sfujita dev_t dev; 52154008Sfujita { 52256873Sakito struct sio_softc *sc = &sio_softc[siounit(dev)]; 52356873Sakito struct sio_portc *pc = sc->sc_pc; 52454008Sfujita 52556873Sakito return(sio_imgetc(pc->pc_addr)); 52654008Sfujita } 52754008Sfujita 52854008Sfujita siocnputc(dev, c) 52954008Sfujita dev_t dev; 53054008Sfujita int c; 53154008Sfujita { 53256873Sakito struct sio_softc *sc = &sio_softc[siounit(dev)]; 53356873Sakito struct sio_portc *pc = sc->sc_pc; 53454008Sfujita 53556873Sakito sio_imputc(pc->pc_addr, c); 53656873Sakito } 53754008Sfujita 53854008Sfujita 53956873Sakito /* 54056873Sakito * sio raw-level routines 54156873Sakito */ 54254008Sfujita 54356873Sakito sioinit(sio0, rate) 54456873Sakito register struct siodevice *sio0; 54556873Sakito register int rate; 54656873Sakito { 54756873Sakito register struct siodevice *sio1; 54856873Sakito int s; 54954008Sfujita 55056873Sakito rate = ttspeedtab(rate, siospeedtab); 55154008Sfujita 55256873Sakito if (sio_init_done) 55356873Sakito return; 55454008Sfujita 55556873Sakito sio1 = (struct siodevice *) ((u_long) sio0 + sizeof(struct siodevice)); 55654008Sfujita 55754008Sfujita s = splhigh(); 55854008Sfujita 55956873Sakito sioreg(sio0, WR0, WR0_CHANRST); /* Channel-A Reset */ 56054008Sfujita 56156873Sakito sioreg(sio0, WR2, (WR2_VEC86 | WR2_INTR_1)); /* Set CPU BUS Interface Mode */ 56256873Sakito sioreg(sio1, WR2, 0); /* Set Interrupt Vector */ 56354008Sfujita 56456873Sakito sioreg(sio0, WR0, WR0_RSTINT); /* Reset E/S Interrupt */ 56556873Sakito sioreg(sio0, WR4, (rate | WR4_STOP1 | WR4_NPARITY)); /* Tx/Rx */ 56656873Sakito sioreg(sio0, WR3, (WR3_RX8BIT | WR3_RXENBL)); /* Rx */ 56756873Sakito sioreg(sio0, WR5, (WR5_TX8BIT | WR5_TXENBL)); /* Tx */ 56856873Sakito sioreg(sio0, WR0, WR0_RSTINT); /* Reset E/S Interrupt */ 56956873Sakito sioreg(sio0, WR1, (WR1_RXALLS | WR1_TXENBL)); 57054008Sfujita 57156873Sakito sioreg(sio1, WR0, WR0_CHANRST); /* Channel-B Reset */ 57254008Sfujita 57356873Sakito sioreg(sio1, WR0, WR0_RSTINT); /* Reset E/S Interrupt */ 57456873Sakito sioreg(sio1, WR4, (rate | WR4_STOP1 | WR4_NPARITY)); /* Tx/Rx */ 57556873Sakito sioreg(sio1, WR3, (WR3_RX8BIT | WR3_RXENBL)); /* Rx */ 57656873Sakito sioreg(sio1, WR5, (WR5_TX8BIT | WR5_TXENBL)); /* Tx */ 57756873Sakito sioreg(sio1, WR0, WR0_RSTINT); /* Reset E/S Interrupt */ 57856873Sakito sioreg(sio1, WR1, (WR1_RXALLS | WR1_TXENBL)); 57956873Sakito 58054008Sfujita splx(s); 58156873Sakito 58256873Sakito sio_init_done = 1; 58354008Sfujita } 58454008Sfujita 58556873Sakito sio_imgetc(sio) 58656873Sakito register struct siodevice *sio; 58754008Sfujita { 58856873Sakito register int rr0, rr1; 58956873Sakito int c, s; 59054008Sfujita 59156873Sakito s = splhigh(); 59256873Sakito while (((rr0 = sioreg(sio, RR0, 0)) & RR0_RXAVAIL) == 0) 59356873Sakito ; 59456873Sakito c = sio->sio_data; 59556873Sakito sioreg(sio, WR0, WR0_RSTPEND); 59656873Sakito splx(s); 59756873Sakito return (c); 59854008Sfujita } 59954008Sfujita 60056873Sakito sio_imputc(sio, c) 60156873Sakito register struct siodevice *sio; 60254008Sfujita int c; 60354008Sfujita { 60454008Sfujita register u_char code; 60556873Sakito register int rr; 60656873Sakito int s; 60754008Sfujita 60854008Sfujita s = splhigh(); 60954008Sfujita 61056873Sakito sioreg(sio, WR1, WR1_RXALLS); 61156873Sakito 61254008Sfujita do { 61354008Sfujita DELAY(1); 61456873Sakito rr = siogetreg(sio); 61554008Sfujita } while (!(rr & RR_TXRDY)); 61656873Sakito 61756873Sakito code = (c & 0xFF); 61854008Sfujita sio->sio_data = code; 61954008Sfujita 62054008Sfujita do { 62154008Sfujita DELAY(1); 62256873Sakito rr = siogetreg(sio); 62354008Sfujita } while (!(rr & RR_TXRDY)); 62454008Sfujita 62556873Sakito sioreg(sio, WR1, (WR1_RXALLS | WR1_TXENBL)); 62656873Sakito 62754008Sfujita splx(s); 62854008Sfujita } 62954008Sfujita 63056873Sakito /* 63156873Sakito * uPD7201A register operation 63256873Sakito */ 63354008Sfujita 63454008Sfujita int 63556873Sakito siogetreg(sio) 63656873Sakito register struct siodevice *sio; 63754008Sfujita { 63854008Sfujita register int rr = 0; 63954008Sfujita 64054008Sfujita rr = sio->sio_stat; 64154008Sfujita rr <<= 8; 64254008Sfujita sio->sio_cmd = 1; /* Select RR1 */ 64354008Sfujita rr |= sio->sio_stat; 64454008Sfujita 64554008Sfujita return(rr); 64654008Sfujita } 64754008Sfujita 64854008Sfujita int 64956873Sakito sioreg(sio, reg, val) 65056873Sakito register struct siodevice *sio; 65154008Sfujita register int reg, val; 65254008Sfujita { 65354008Sfujita if (isStatusReg(reg)) { 65456873Sakito if (reg != 0) 65556873Sakito sio->sio_cmd = reg; 65656873Sakito val = sio->sio_stat; 65754008Sfujita } else { 65856873Sakito if (reg != 0) 65956873Sakito sio->sio_cmd = reg; 66056873Sakito sio->sio_cmd = val; 66154008Sfujita } 66256873Sakito 66356873Sakito return(val); 66454008Sfujita } 66554008Sfujita #endif 666