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*57291Sakito * @(#)sio.c 7.6 (Berkeley) 12/25/92 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(); 40*57291Sakito 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 #define NPORT 2 /* uPD7201A has 2 serial-port */ 5356873Sakito #define NLINE 1 /* number of active line */ 5454008Sfujita 5556873Sakito struct sio_portc sio_portc[NPORT] = { 5656873Sakito { -1, -1, (struct siodevice *) 0x51000000, (int (*)()) 0 }, 5756873Sakito { -1, -1, (struct siodevice *) 0x51000004, (int (*)()) 0 } 5856873Sakito }; 5954008Sfujita 6056873Sakito struct sio_softc sio_softc[NLINE]; 6154008Sfujita 6256873Sakito int sio_init_done = 0; 6356873Sakito int siounitbase = 0; /* This counter is used unit number assignment */ 6454008Sfujita 6556873Sakito int siosoftCAR; 6656873Sakito int sio_active; 6757126Sakito int sioconsole = -1; 6856873Sakito int siodefaultrate = TTYDEF_SPEED; 69*57291Sakito int siomajor = 12; 7054008Sfujita 7156873Sakito struct tty sio_tty[NLINE]; 7254008Sfujita 7356873Sakito struct speedtab siospeedtab[] = { 7456873Sakito 2400, WR4_BAUD24, 7556873Sakito 4800, WR4_BAUD48, 7656873Sakito 9600, WR4_BAUD96, 7754008Sfujita }; 7854008Sfujita 7956873Sakito #define siounit(x) minor(x) 8054008Sfujita 8157126Sakito extern struct tty *constty; 8254008Sfujita 8354008Sfujita /* 8456873Sakito * probe routines 8554008Sfujita */ 8654008Sfujita 8754008Sfujita sioprobe(hd) 8854008Sfujita register struct hp_device *hd; 8954008Sfujita { 9056873Sakito register int port; 9156873Sakito register struct sio_portc *pc; 9256873Sakito register struct sio_softc *sc; 9354008Sfujita 9456873Sakito sioinit((struct siodevice *) hd->hp_addr, siodefaultrate); 9554008Sfujita 9656873Sakito /* locate the major number */ 9756873Sakito for (siomajor = 0; siomajor < nchrdev; siomajor++) 9856873Sakito if (cdevsw[siomajor].d_open == sioopen) 9956873Sakito break; 10054008Sfujita 10156873Sakito for (port = 0; port < NPORT; port++) { 10256873Sakito pc = &sio_portc[port]; 10354008Sfujita 10456873Sakito if (pc->pc_major != -1) { 10556873Sakito printf("%s%d: port %d, address 0x%x, intr 0x%x (console)\n", 10656873Sakito (pc->pc_major == siomajor ? "sio" : "bmc" ), 10756873Sakito pc->pc_unit, port, pc->pc_addr, pc->pc_intr); 10856873Sakito continue; 10956873Sakito } 11054008Sfujita 11156873Sakito pc->pc_addr = 11256873Sakito (struct siodevice *)((u_long) hd->hp_addr + (sizeof(struct siodevice) * port)); 11356873Sakito #if NBMC > 0 11456873Sakito if (bmcinit(port)) 11556873Sakito continue; 11656873Sakito #endif 11756873Sakito if (++siounitbase < NLINE) { 11856873Sakito pc->pc_major = siomajor; 11956873Sakito pc->pc_intr = siointr; 12056873Sakito pc->pc_unit = siounitbase; 12156873Sakito printf("sio%d: port %d, address 0x%x\n", pc->pc_unit, port, pc->pc_addr); 12254008Sfujita 12356873Sakito sc = &sio_softc[pc->pc_unit]; 12456873Sakito sc->sc_pc = pc; 12554008Sfujita 12656873Sakito sio_active |= 1 << pc->pc_unit; 12756873Sakito siosoftCAR |= 1 << pc->pc_unit; 12856873Sakito } 12956873Sakito } 13056873Sakito } 13154008Sfujita 13256873Sakito struct sio_portc * 13356873Sakito sio_port_assign(port, major, unit, intr) 13456873Sakito int port, major, unit; 13556873Sakito int (*intr)(); 13656873Sakito { 137*57291Sakito register struct sio_portc *pc; 13854008Sfujita 139*57291Sakito pc = &sio_portc[port]; 140*57291Sakito 141*57291Sakito /* 142*57291Sakito if ((pc->pc_major != -1) && (major != 2)) 14356873Sakito return((struct sio_portc *) 0); 144*57291Sakito */ 14556873Sakito pc->pc_major = major; 14656873Sakito pc->pc_intr = intr; 14756873Sakito pc->pc_unit = unit; 14854008Sfujita 14956873Sakito return(pc); 15054008Sfujita } 15154008Sfujita 152*57291Sakito struct sio_portc * 153*57291Sakito sio_port_get(port) 154*57291Sakito int port; 155*57291Sakito { 156*57291Sakito register struct sio_portc *pc; 15756873Sakito 158*57291Sakito pc = &sio_portc[port]; 159*57291Sakito 160*57291Sakito return(pc); 161*57291Sakito } 162*57291Sakito 163*57291Sakito int 164*57291Sakito sio_port_info() 165*57291Sakito { 166*57291Sakito printf("sio_port_info[sio.c]:\t{%d} major = %d, unit = %d, intr = 0x%x\n", 167*57291Sakito 0, sio_portc[0].pc_major, sio_portc[0].pc_unit, sio_portc[0].pc_intr); 168*57291Sakito printf("sio_port_info[sio.c]:\t{%d} major = %d, unit = %d, intr = 0x%x\n", 169*57291Sakito 1, sio_portc[1].pc_major, sio_portc[1].pc_unit, sio_portc[1].pc_intr); 170*57291Sakito } 171*57291Sakito 172*57291Sakito 17356873Sakito /* 17456873Sakito * entry routines 17556873Sakito */ 17656873Sakito 17754008Sfujita /* ARGSUSED */ 17854008Sfujita #ifdef __STDC__ 17954008Sfujita sioopen(dev_t dev, int flag, int mode, struct proc *p) 18054008Sfujita #else 18154008Sfujita sioopen(dev, flag, mode, p) 18254008Sfujita dev_t dev; 18354008Sfujita int flag, mode; 18454008Sfujita struct proc *p; 18554008Sfujita #endif 18654008Sfujita { 18754008Sfujita register struct tty *tp; 18854008Sfujita register int unit; 18954008Sfujita int error = 0; 19054008Sfujita 19154008Sfujita unit = siounit(dev); 19256873Sakito if (unit >= NLINE || (sio_active & (1 << unit)) == 0) 19354008Sfujita return (ENXIO); 19454008Sfujita tp = &sio_tty[unit]; 19554008Sfujita tp->t_oproc = siostart; 19654008Sfujita tp->t_param = sioparam; 19754008Sfujita tp->t_dev = dev; 19854008Sfujita if ((tp->t_state & TS_ISOPEN) == 0) { 19954008Sfujita tp->t_state |= TS_WOPEN; 20054008Sfujita ttychars(tp); 20154008Sfujita if (tp->t_ispeed == 0) { 20254008Sfujita tp->t_iflag = TTYDEF_IFLAG; 20354008Sfujita tp->t_oflag = TTYDEF_OFLAG; 20456873Sakito /* tp->t_cflag = TTYDEF_CFLAG; */ 20554008Sfujita tp->t_cflag = (CREAD | CS8 | HUPCL); 20654008Sfujita tp->t_lflag = TTYDEF_LFLAG; 20754008Sfujita tp->t_ispeed = tp->t_ospeed = siodefaultrate; 20854008Sfujita } 20954008Sfujita sioparam(tp, &tp->t_termios); 21054008Sfujita ttsetwater(tp); 21154008Sfujita } else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0) 21254008Sfujita return (EBUSY); 21356873Sakito (void) siomctl(dev, WR5_DTR | WR5_RTS, DMSET); 21456873Sakito if ((siosoftCAR & (1 << unit)) || (siomctl(dev, 0, DMGET) & RR0_DCD)) 21556873Sakito tp->t_state |= TS_CARR_ON; 21654008Sfujita (void) spltty(); 21754008Sfujita while ((flag&O_NONBLOCK) == 0 && (tp->t_cflag&CLOCAL) == 0 && 21854008Sfujita (tp->t_state & TS_CARR_ON) == 0) { 21954008Sfujita tp->t_state |= TS_WOPEN; 22054008Sfujita if (error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH, 22154008Sfujita ttopen, 0)) 22254008Sfujita break; 22354008Sfujita } 22454008Sfujita (void) spl0(); 22554008Sfujita if (error == 0) 22654008Sfujita error = (*linesw[tp->t_line].l_open)(dev, tp); 22754008Sfujita return (error); 22854008Sfujita } 22956873Sakito 23054008Sfujita /*ARGSUSED*/ 23154008Sfujita sioclose(dev, flag, mode, p) 23254008Sfujita dev_t dev; 23354008Sfujita int flag, mode; 23454008Sfujita struct proc *p; 23554008Sfujita { 23654008Sfujita register struct tty *tp; 23754008Sfujita register int unit; 23854008Sfujita 23954008Sfujita unit = siounit(dev); 24054008Sfujita tp = &sio_tty[unit]; 24154008Sfujita (*linesw[tp->t_line].l_close)(tp, flag); 24256873Sakito (void) siomctl(dev, WR5_BREAK, DMBIS); 24356873Sakito if (tp->t_cflag&HUPCL || tp->t_state&TS_WOPEN || 24456873Sakito (tp->t_state&TS_ISOPEN) == 0) 24556873Sakito (void) siomctl(dev, 0, DMSET); 24654008Sfujita ttyclose(tp); 24754008Sfujita return (0); 24854008Sfujita } 24954008Sfujita 25054008Sfujita sioread(dev, uio, flag) 25154008Sfujita dev_t dev; 25254008Sfujita struct uio *uio; 25354008Sfujita { 25454008Sfujita register struct tty *tp = &sio_tty[siounit(dev)]; 25554008Sfujita 25654008Sfujita return ((*linesw[tp->t_line].l_read)(tp, uio, flag)); 25754008Sfujita } 25854008Sfujita 25954008Sfujita siowrite(dev, uio, flag) 26054008Sfujita dev_t dev; 26154008Sfujita struct uio *uio; 26254008Sfujita { 26357126Sakito register int unit = siounit(dev); 26457126Sakito register struct tty *tp = &sio_tty[unit]; 26554008Sfujita 26657126Sakito if ((unit == sioconsole) && constty && 26757126Sakito (constty->t_state&(TS_CARR_ON|TS_ISOPEN))==(TS_CARR_ON|TS_ISOPEN)) 26857126Sakito tp = constty; 26957126Sakito 27054008Sfujita return ((*linesw[tp->t_line].l_write)(tp, uio, flag)); 27154008Sfujita } 27254008Sfujita 27356873Sakito /* 27456873Sakito * Stop output on a line. 27556873Sakito */ 27656873Sakito /*ARGSUSED*/ 27756873Sakito siostop(tp, flag) 27856873Sakito register struct tty *tp; 27954008Sfujita { 28056873Sakito register int s; 28154008Sfujita 28256873Sakito s = spltty(); 28356873Sakito if (tp->t_state & TS_BUSY) { 28456873Sakito if ((tp->t_state&TS_TTSTOP)==0) 28556873Sakito tp->t_state |= TS_FLUSH; 28654008Sfujita } 28756873Sakito splx(s); 28854008Sfujita } 28954008Sfujita 29054008Sfujita sioioctl(dev, cmd, data, flag, p) 29154008Sfujita dev_t dev; 29254008Sfujita int cmd; 29354008Sfujita caddr_t data; 29454008Sfujita int flag; 29554008Sfujita struct proc *p; 29654008Sfujita { 29754008Sfujita register struct tty *tp; 29854008Sfujita register int unit = siounit(dev); 29954008Sfujita register int error; 30056873Sakito 30154008Sfujita tp = &sio_tty[unit]; 30254008Sfujita error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p); 30354008Sfujita if (error >= 0) 30454008Sfujita return (error); 30554008Sfujita error = ttioctl(tp, cmd, data, flag); 30654008Sfujita if (error >= 0) 30754008Sfujita return (error); 30854008Sfujita 30954008Sfujita switch (cmd) { 31054008Sfujita 31154008Sfujita case TIOCSBRK: 31256873Sakito (void) siomctl(dev, WR5_BREAK, DMBIS); 31356873Sakito break; 31456873Sakito 31554008Sfujita case TIOCCBRK: 31656873Sakito (void) siomctl(dev, WR5_BREAK, DMBIC); 31756873Sakito break; 31856873Sakito 31954008Sfujita case TIOCSDTR: 32056873Sakito (void) siomctl(dev, WR5_DTR | WR5_RTS, DMBIS); 32156873Sakito break; 32256873Sakito 32354008Sfujita case TIOCCDTR: 32456873Sakito (void) siomctl(dev, WR5_DTR | WR5_RTS, DMBIC); 32556873Sakito break; 32656873Sakito 32754008Sfujita case TIOCMSET: 32856873Sakito (void) siomctl(dev, *(int *)data, DMSET); 32956873Sakito break; 33056873Sakito 33154008Sfujita case TIOCMBIS: 33256873Sakito (void) siomctl(dev, *(int *)data, DMBIS); 33356873Sakito break; 33456873Sakito 33554008Sfujita case TIOCMBIC: 33656873Sakito (void) siomctl(dev, *(int *)data, DMBIC); 33756873Sakito break; 33856873Sakito 33954008Sfujita case TIOCMGET: 34056873Sakito *(int *)data = siomctl(dev, 0, DMGET); 34156873Sakito break; 34256873Sakito 34354008Sfujita default: 34454008Sfujita return (ENOTTY); 34554008Sfujita } 34654008Sfujita return (0); 34754008Sfujita } 34854008Sfujita 34954008Sfujita 35056873Sakito /* 35156873Sakito * 35256873Sakito */ 35356873Sakito 35454008Sfujita void 35554008Sfujita siostart(tp) 35654008Sfujita register struct tty *tp; 35754008Sfujita { 35854008Sfujita register struct siodevice *sio; 35956873Sakito register int rr; 36056873Sakito int s, unit, c; 36154008Sfujita 36254008Sfujita unit = siounit(tp->t_dev); 36356873Sakito sio = sio_softc[unit].sc_pc->pc_addr; 36454008Sfujita s = spltty(); 36554008Sfujita if (tp->t_state & (TS_TIMEOUT|TS_TTSTOP)) 36654008Sfujita goto out; 36754008Sfujita if (tp->t_outq.c_cc <= tp->t_lowat) { 36854008Sfujita if (tp->t_state&TS_ASLEEP) { 36954008Sfujita tp->t_state &= ~TS_ASLEEP; 37054008Sfujita wakeup((caddr_t)&tp->t_outq); 37154008Sfujita } 37254008Sfujita selwakeup(&tp->t_wsel); 37354008Sfujita } 37454008Sfujita if (tp->t_outq.c_cc == 0) 37554008Sfujita goto out; 37656873Sakito rr = siogetreg(sio); 37754008Sfujita if (rr & RR_TXRDY) { 37854008Sfujita c = getc(&tp->t_outq); 37954008Sfujita tp->t_state |= TS_BUSY; 38054008Sfujita sio->sio_data = c; 38154008Sfujita } 38254008Sfujita out: 38354008Sfujita splx(s); 38454008Sfujita } 38556873Sakito 38656873Sakito sioparam(tp, t) 38756873Sakito register struct tty *tp; 38856873Sakito register struct termios *t; 38956873Sakito { 39056873Sakito int unit = siounit(tp->t_dev); 39156873Sakito register struct siodevice *sio; 39256873Sakito register cflag = t->c_cflag; 39356873Sakito register u_char wr; 39456873Sakito int ospeed = ttspeedtab(t->c_ospeed, siospeedtab); 39556873Sakito 39656873Sakito sio = sio_softc[unit].sc_pc->pc_addr; 39756873Sakito 39856873Sakito switch (cflag & CSIZE) { 39956873Sakito case CS5: 40056873Sakito case CS6: 40156873Sakito case CS7: 40256873Sakito case CS8: 40356873Sakito break; 40456873Sakito } 40556873Sakito 40656873Sakito wr = ospeed; 40756873Sakito 40856873Sakito if (cflag & PARENB) { 40956873Sakito wr |= WR4_PARENAB; 41056873Sakito if ((cflag&PARODD) == 0) 41156873Sakito wr |= WR4_EPARITY; 41256873Sakito } 41356873Sakito 41456873Sakito if (cflag & CSTOPB) 41556873Sakito wr |= WR4_STOP2; /* 2 stop bit */ 41656873Sakito else 41756873Sakito wr |= WR4_STOP1; /* 1 stop bit */ 41856873Sakito 41956873Sakito (void) sioreg(sio, WR4, wr); 42056873Sakito 42156873Sakito return (0); 42256873Sakito } 42356873Sakito 42456873Sakito siomctl() 42556873Sakito { 42656873Sakito return (0); 42756873Sakito } 42856873Sakito 42956873Sakito 43054008Sfujita /* 43156873Sakito * Interrupt handling 43254008Sfujita */ 43356873Sakito 43456873Sakito void 43556873Sakito _siointr() 43654008Sfujita { 43756873Sakito register int port; 43856873Sakito register struct sio_portc *pc; 43954008Sfujita 44056873Sakito for (port = 0; port < NPORT; port++) { 44156873Sakito pc = &sio_portc[port]; 44256873Sakito 44356873Sakito if (pc->pc_major != -1) 44456873Sakito (pc->pc_intr)(pc->pc_unit); 44554008Sfujita } 44654008Sfujita } 44754008Sfujita 44856873Sakito siointr(unit) 44956873Sakito register int unit; 45056873Sakito { 45156873Sakito register struct siodevice *sio = sio_softc[unit].sc_pc->pc_addr; 45256873Sakito register u_char code; 45356873Sakito register struct tty *tp; 45456873Sakito int s, rr; 45556873Sakito 45656873Sakito tp = &sio_tty[unit]; 45756873Sakito rr = siogetreg(sio); 45856873Sakito 45956873Sakito if (rr & RR_RXRDY) { 46056873Sakito code = sio->sio_data; 46156873Sakito if ((tp->t_state & TS_ISOPEN) != 0) 46256873Sakito (*linesw[tp->t_line].l_rint)(code, tp); 46356873Sakito } 46456873Sakito 46556873Sakito if (rr & RR_TXRDY) { 46656873Sakito sio->sio_cmd = WR0_RSTPEND; 46756873Sakito tp->t_state &= ~(TS_BUSY|TS_FLUSH); 46856873Sakito if (tp->t_line) 46956873Sakito (*linesw[tp->t_line].l_start)(tp); 47056873Sakito else 47156873Sakito siostart(tp); 47256873Sakito } 47356873Sakito } 47456873Sakito 47554008Sfujita /* 47654008Sfujita * Following are all routines needed for SIO to act as console 47754008Sfujita */ 47857058Sakito #include <luna68k/luna68k/cons.h> 47954008Sfujita 48054008Sfujita siocnprobe(cp) 48156873Sakito register struct consdev *cp; 48254008Sfujita { 48356873Sakito register int unit = 0; 48454008Sfujita 48554008Sfujita /* locate the major number */ 48654008Sfujita for (siomajor = 0; siomajor < nchrdev; siomajor++) 48754008Sfujita if (cdevsw[siomajor].d_open == sioopen) 48854008Sfujita break; 48954008Sfujita 49056873Sakito siounitbase = -1; 49154008Sfujita 49254008Sfujita /* initialize required fields */ 49354008Sfujita cp->cn_dev = makedev(siomajor, unit); 49456873Sakito cp->cn_tp = &sio_tty[unit]; 49554008Sfujita cp->cn_pri = CN_NORMAL; 49654008Sfujita } 49754008Sfujita 49854008Sfujita siocninit(cp) 49954008Sfujita struct consdev *cp; 50054008Sfujita { 50154008Sfujita int unit = siounit(cp->cn_dev); 50256873Sakito register struct sio_softc *sc = &sio_softc[unit]; 50354008Sfujita 50456873Sakito sioinit((struct siodevice *) SIO_HARDADDR, siodefaultrate); 50556873Sakito 50656873Sakito /* port assign */ 50756873Sakito sc->sc_pc = sio_port_assign(0, siomajor, unit, siointr); 50856873Sakito 50954008Sfujita sioconsole = unit; 51056873Sakito siounitbase = 0; 51156873Sakito 51256873Sakito sio_active |= 1 << unit; 51356873Sakito siosoftCAR |= 1 << unit; 51454008Sfujita } 51554008Sfujita 51654008Sfujita siocngetc(dev) 51754008Sfujita dev_t dev; 51854008Sfujita { 51956873Sakito struct sio_softc *sc = &sio_softc[siounit(dev)]; 52056873Sakito struct sio_portc *pc = sc->sc_pc; 52154008Sfujita 52256873Sakito return(sio_imgetc(pc->pc_addr)); 52354008Sfujita } 52454008Sfujita 52554008Sfujita siocnputc(dev, c) 52654008Sfujita dev_t dev; 52754008Sfujita int c; 52854008Sfujita { 52956873Sakito struct sio_softc *sc = &sio_softc[siounit(dev)]; 53056873Sakito struct sio_portc *pc = sc->sc_pc; 53154008Sfujita 53256873Sakito sio_imputc(pc->pc_addr, c); 53356873Sakito } 53454008Sfujita 53554008Sfujita 53656873Sakito /* 53756873Sakito * sio raw-level routines 53856873Sakito */ 53954008Sfujita 54056873Sakito sioinit(sio0, rate) 54156873Sakito register struct siodevice *sio0; 54256873Sakito register int rate; 54356873Sakito { 54456873Sakito register struct siodevice *sio1; 54556873Sakito int s; 54654008Sfujita 54756873Sakito rate = ttspeedtab(rate, siospeedtab); 54854008Sfujita 54956873Sakito if (sio_init_done) 55056873Sakito return; 55154008Sfujita 55256873Sakito sio1 = (struct siodevice *) ((u_long) sio0 + sizeof(struct siodevice)); 55354008Sfujita 55454008Sfujita s = splhigh(); 55554008Sfujita 55656873Sakito sioreg(sio0, WR0, WR0_CHANRST); /* Channel-A Reset */ 55754008Sfujita 55856873Sakito sioreg(sio0, WR2, (WR2_VEC86 | WR2_INTR_1)); /* Set CPU BUS Interface Mode */ 55956873Sakito sioreg(sio1, WR2, 0); /* Set Interrupt Vector */ 56054008Sfujita 56156873Sakito sioreg(sio0, WR0, WR0_RSTINT); /* Reset E/S Interrupt */ 56256873Sakito sioreg(sio0, WR4, (rate | WR4_STOP1 | WR4_NPARITY)); /* Tx/Rx */ 56356873Sakito sioreg(sio0, WR3, (WR3_RX8BIT | WR3_RXENBL)); /* Rx */ 56456873Sakito sioreg(sio0, WR5, (WR5_TX8BIT | WR5_TXENBL)); /* Tx */ 56556873Sakito sioreg(sio0, WR0, WR0_RSTINT); /* Reset E/S Interrupt */ 56656873Sakito sioreg(sio0, WR1, (WR1_RXALLS | WR1_TXENBL)); 56754008Sfujita 56856873Sakito sioreg(sio1, WR0, WR0_CHANRST); /* Channel-B Reset */ 56954008Sfujita 57056873Sakito sioreg(sio1, WR0, WR0_RSTINT); /* Reset E/S Interrupt */ 57156873Sakito sioreg(sio1, WR4, (rate | WR4_STOP1 | WR4_NPARITY)); /* Tx/Rx */ 57256873Sakito sioreg(sio1, WR3, (WR3_RX8BIT | WR3_RXENBL)); /* Rx */ 57356873Sakito sioreg(sio1, WR5, (WR5_TX8BIT | WR5_TXENBL)); /* Tx */ 57456873Sakito sioreg(sio1, WR0, WR0_RSTINT); /* Reset E/S Interrupt */ 57556873Sakito sioreg(sio1, WR1, (WR1_RXALLS | WR1_TXENBL)); 57656873Sakito 57754008Sfujita splx(s); 57856873Sakito 57956873Sakito sio_init_done = 1; 58054008Sfujita } 58154008Sfujita 58256873Sakito sio_imgetc(sio) 58356873Sakito register struct siodevice *sio; 58454008Sfujita { 58556873Sakito register int rr0, rr1; 58656873Sakito int c, s; 58754008Sfujita 58856873Sakito s = splhigh(); 58956873Sakito while (((rr0 = sioreg(sio, RR0, 0)) & RR0_RXAVAIL) == 0) 59056873Sakito ; 59156873Sakito c = sio->sio_data; 59256873Sakito sioreg(sio, WR0, WR0_RSTPEND); 59356873Sakito splx(s); 59456873Sakito return (c); 59554008Sfujita } 59654008Sfujita 59756873Sakito sio_imputc(sio, c) 59856873Sakito register struct siodevice *sio; 59954008Sfujita int c; 60054008Sfujita { 60154008Sfujita register u_char code; 60256873Sakito register int rr; 60356873Sakito int s; 60454008Sfujita 60554008Sfujita s = splhigh(); 60654008Sfujita 60756873Sakito sioreg(sio, WR1, WR1_RXALLS); 60856873Sakito 60954008Sfujita do { 61054008Sfujita DELAY(1); 61156873Sakito rr = siogetreg(sio); 61254008Sfujita } while (!(rr & RR_TXRDY)); 61356873Sakito 61456873Sakito code = (c & 0xFF); 61554008Sfujita sio->sio_data = code; 61654008Sfujita 61754008Sfujita do { 61854008Sfujita DELAY(1); 61956873Sakito rr = siogetreg(sio); 62054008Sfujita } while (!(rr & RR_TXRDY)); 62154008Sfujita 62256873Sakito sioreg(sio, WR1, (WR1_RXALLS | WR1_TXENBL)); 62356873Sakito 62454008Sfujita splx(s); 62554008Sfujita } 62654008Sfujita 62756873Sakito /* 62856873Sakito * uPD7201A register operation 62956873Sakito */ 63054008Sfujita 63154008Sfujita int 63256873Sakito siogetreg(sio) 63356873Sakito register struct siodevice *sio; 63454008Sfujita { 63554008Sfujita register int rr = 0; 63654008Sfujita 63754008Sfujita rr = sio->sio_stat; 63854008Sfujita rr <<= 8; 63954008Sfujita sio->sio_cmd = 1; /* Select RR1 */ 64054008Sfujita rr |= sio->sio_stat; 64154008Sfujita 64254008Sfujita return(rr); 64354008Sfujita } 64454008Sfujita 64554008Sfujita int 64656873Sakito sioreg(sio, reg, val) 64756873Sakito register struct siodevice *sio; 64854008Sfujita register int reg, val; 64954008Sfujita { 65054008Sfujita if (isStatusReg(reg)) { 65156873Sakito if (reg != 0) 65256873Sakito sio->sio_cmd = reg; 65356873Sakito val = sio->sio_stat; 65454008Sfujita } else { 65556873Sakito if (reg != 0) 65656873Sakito sio->sio_cmd = reg; 65756873Sakito sio->sio_cmd = val; 65854008Sfujita } 65956873Sakito 66056873Sakito return(val); 66154008Sfujita } 66254008Sfujita #endif 663