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*57126Sakito * @(#)sio.c 7.5 (Berkeley) 12/14/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(); 4054008Sfujita 4156873Sakito int sioprobe(); 4256873Sakito int sioopen(); 4356873Sakito void siostart(); 4456873Sakito int sioparam(); 4556873Sakito int siointr(); 4654008Sfujita 4754008Sfujita struct driver siodriver = { 4854008Sfujita sioprobe, "sio", 4954008Sfujita }; 5054008Sfujita 5156873Sakito #define NPORT 2 /* uPD7201A has 2 serial-port */ 5256873Sakito #define NLINE 1 /* number of active line */ 5354008Sfujita 5456873Sakito struct sio_portc sio_portc[NPORT] = { 5556873Sakito { -1, -1, (struct siodevice *) 0x51000000, (int (*)()) 0 }, 5656873Sakito { -1, -1, (struct siodevice *) 0x51000004, (int (*)()) 0 } 5756873Sakito }; 5854008Sfujita 5956873Sakito struct sio_softc sio_softc[NLINE]; 6054008Sfujita 6156873Sakito int sio_init_done = 0; 6256873Sakito int siounitbase = 0; /* This counter is used unit number assignment */ 6354008Sfujita 6456873Sakito int siosoftCAR; 6556873Sakito int sio_active; 66*57126Sakito int sioconsole = -1; 6756873Sakito int siodefaultrate = TTYDEF_SPEED; 6856873Sakito int siomajor = 0; 6954008Sfujita 7056873Sakito struct tty sio_tty[NLINE]; 7154008Sfujita 7256873Sakito struct speedtab siospeedtab[] = { 7356873Sakito 2400, WR4_BAUD24, 7456873Sakito 4800, WR4_BAUD48, 7556873Sakito 9600, WR4_BAUD96, 7654008Sfujita }; 7754008Sfujita 7856873Sakito #define siounit(x) minor(x) 7954008Sfujita 80*57126Sakito extern struct tty *constty; 8154008Sfujita 8254008Sfujita /* 8356873Sakito * probe routines 8454008Sfujita */ 8554008Sfujita 8654008Sfujita sioprobe(hd) 8754008Sfujita register struct hp_device *hd; 8854008Sfujita { 8956873Sakito register int port; 9056873Sakito register struct sio_portc *pc; 9156873Sakito register struct sio_softc *sc; 9254008Sfujita 9356873Sakito sioinit((struct siodevice *) hd->hp_addr, siodefaultrate); 9454008Sfujita 9556873Sakito /* locate the major number */ 9656873Sakito for (siomajor = 0; siomajor < nchrdev; siomajor++) 9756873Sakito if (cdevsw[siomajor].d_open == sioopen) 9856873Sakito break; 9954008Sfujita 10056873Sakito for (port = 0; port < NPORT; port++) { 10156873Sakito pc = &sio_portc[port]; 10254008Sfujita 10356873Sakito if (pc->pc_major != -1) { 10456873Sakito printf("%s%d: port %d, address 0x%x, intr 0x%x (console)\n", 10556873Sakito (pc->pc_major == siomajor ? "sio" : "bmc" ), 10656873Sakito pc->pc_unit, port, pc->pc_addr, pc->pc_intr); 10756873Sakito continue; 10856873Sakito } 10954008Sfujita 11056873Sakito pc->pc_addr = 11156873Sakito (struct siodevice *)((u_long) hd->hp_addr + (sizeof(struct siodevice) * port)); 11256873Sakito #if NBMC > 0 11356873Sakito if (bmcinit(port)) 11456873Sakito continue; 11556873Sakito #endif 11656873Sakito if (++siounitbase < NLINE) { 11756873Sakito pc->pc_major = siomajor; 11856873Sakito pc->pc_intr = siointr; 11956873Sakito pc->pc_unit = siounitbase; 12056873Sakito printf("sio%d: port %d, address 0x%x\n", pc->pc_unit, port, pc->pc_addr); 12154008Sfujita 12256873Sakito sc = &sio_softc[pc->pc_unit]; 12356873Sakito sc->sc_pc = pc; 12454008Sfujita 12556873Sakito sio_active |= 1 << pc->pc_unit; 12656873Sakito siosoftCAR |= 1 << pc->pc_unit; 12756873Sakito } 12856873Sakito } 12956873Sakito } 13054008Sfujita 13156873Sakito struct sio_portc * 13256873Sakito sio_port_assign(port, major, unit, intr) 13356873Sakito int port, major, unit; 13456873Sakito int (*intr)(); 13556873Sakito { 13656873Sakito register struct sio_portc *pc = &sio_portc[port]; 13754008Sfujita 13856873Sakito if (pc->pc_major != -1) 13956873Sakito return((struct sio_portc *) 0); 14054008Sfujita 14156873Sakito pc->pc_major = major; 14256873Sakito pc->pc_intr = intr; 14356873Sakito pc->pc_unit = unit; 14454008Sfujita 14556873Sakito return(pc); 14654008Sfujita } 14754008Sfujita 14856873Sakito 14956873Sakito /* 15056873Sakito * entry routines 15156873Sakito */ 15256873Sakito 15354008Sfujita /* ARGSUSED */ 15454008Sfujita #ifdef __STDC__ 15554008Sfujita sioopen(dev_t dev, int flag, int mode, struct proc *p) 15654008Sfujita #else 15754008Sfujita sioopen(dev, flag, mode, p) 15854008Sfujita dev_t dev; 15954008Sfujita int flag, mode; 16054008Sfujita struct proc *p; 16154008Sfujita #endif 16254008Sfujita { 16354008Sfujita register struct tty *tp; 16454008Sfujita register int unit; 16554008Sfujita int error = 0; 16654008Sfujita 16754008Sfujita unit = siounit(dev); 16856873Sakito if (unit >= NLINE || (sio_active & (1 << unit)) == 0) 16954008Sfujita return (ENXIO); 17054008Sfujita tp = &sio_tty[unit]; 17154008Sfujita tp->t_oproc = siostart; 17254008Sfujita tp->t_param = sioparam; 17354008Sfujita tp->t_dev = dev; 17454008Sfujita if ((tp->t_state & TS_ISOPEN) == 0) { 17554008Sfujita tp->t_state |= TS_WOPEN; 17654008Sfujita ttychars(tp); 17754008Sfujita if (tp->t_ispeed == 0) { 17854008Sfujita tp->t_iflag = TTYDEF_IFLAG; 17954008Sfujita tp->t_oflag = TTYDEF_OFLAG; 18056873Sakito /* tp->t_cflag = TTYDEF_CFLAG; */ 18154008Sfujita tp->t_cflag = (CREAD | CS8 | HUPCL); 18254008Sfujita tp->t_lflag = TTYDEF_LFLAG; 18354008Sfujita tp->t_ispeed = tp->t_ospeed = siodefaultrate; 18454008Sfujita } 18554008Sfujita sioparam(tp, &tp->t_termios); 18654008Sfujita ttsetwater(tp); 18754008Sfujita } else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0) 18854008Sfujita return (EBUSY); 18956873Sakito (void) siomctl(dev, WR5_DTR | WR5_RTS, DMSET); 19056873Sakito if ((siosoftCAR & (1 << unit)) || (siomctl(dev, 0, DMGET) & RR0_DCD)) 19156873Sakito tp->t_state |= TS_CARR_ON; 19254008Sfujita (void) spltty(); 19354008Sfujita while ((flag&O_NONBLOCK) == 0 && (tp->t_cflag&CLOCAL) == 0 && 19454008Sfujita (tp->t_state & TS_CARR_ON) == 0) { 19554008Sfujita tp->t_state |= TS_WOPEN; 19654008Sfujita if (error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH, 19754008Sfujita ttopen, 0)) 19854008Sfujita break; 19954008Sfujita } 20054008Sfujita (void) spl0(); 20154008Sfujita if (error == 0) 20254008Sfujita error = (*linesw[tp->t_line].l_open)(dev, tp); 20354008Sfujita return (error); 20454008Sfujita } 20556873Sakito 20654008Sfujita /*ARGSUSED*/ 20754008Sfujita sioclose(dev, flag, mode, p) 20854008Sfujita dev_t dev; 20954008Sfujita int flag, mode; 21054008Sfujita struct proc *p; 21154008Sfujita { 21254008Sfujita register struct tty *tp; 21354008Sfujita register int unit; 21454008Sfujita 21554008Sfujita unit = siounit(dev); 21654008Sfujita tp = &sio_tty[unit]; 21754008Sfujita (*linesw[tp->t_line].l_close)(tp, flag); 21856873Sakito (void) siomctl(dev, WR5_BREAK, DMBIS); 21956873Sakito if (tp->t_cflag&HUPCL || tp->t_state&TS_WOPEN || 22056873Sakito (tp->t_state&TS_ISOPEN) == 0) 22156873Sakito (void) siomctl(dev, 0, DMSET); 22254008Sfujita ttyclose(tp); 22354008Sfujita return (0); 22454008Sfujita } 22554008Sfujita 22654008Sfujita sioread(dev, uio, flag) 22754008Sfujita dev_t dev; 22854008Sfujita struct uio *uio; 22954008Sfujita { 23054008Sfujita register struct tty *tp = &sio_tty[siounit(dev)]; 23154008Sfujita 23254008Sfujita return ((*linesw[tp->t_line].l_read)(tp, uio, flag)); 23354008Sfujita } 23454008Sfujita 23554008Sfujita siowrite(dev, uio, flag) 23654008Sfujita dev_t dev; 23754008Sfujita struct uio *uio; 23854008Sfujita { 239*57126Sakito register int unit = siounit(dev); 240*57126Sakito register struct tty *tp = &sio_tty[unit]; 24154008Sfujita 242*57126Sakito if ((unit == sioconsole) && constty && 243*57126Sakito (constty->t_state&(TS_CARR_ON|TS_ISOPEN))==(TS_CARR_ON|TS_ISOPEN)) 244*57126Sakito tp = constty; 245*57126Sakito 24654008Sfujita return ((*linesw[tp->t_line].l_write)(tp, uio, flag)); 24754008Sfujita } 24854008Sfujita 24956873Sakito /* 25056873Sakito * Stop output on a line. 25156873Sakito */ 25256873Sakito /*ARGSUSED*/ 25356873Sakito siostop(tp, flag) 25456873Sakito register struct tty *tp; 25554008Sfujita { 25656873Sakito register int s; 25754008Sfujita 25856873Sakito s = spltty(); 25956873Sakito if (tp->t_state & TS_BUSY) { 26056873Sakito if ((tp->t_state&TS_TTSTOP)==0) 26156873Sakito tp->t_state |= TS_FLUSH; 26254008Sfujita } 26356873Sakito splx(s); 26454008Sfujita } 26554008Sfujita 26654008Sfujita sioioctl(dev, cmd, data, flag, p) 26754008Sfujita dev_t dev; 26854008Sfujita int cmd; 26954008Sfujita caddr_t data; 27054008Sfujita int flag; 27154008Sfujita struct proc *p; 27254008Sfujita { 27354008Sfujita register struct tty *tp; 27454008Sfujita register int unit = siounit(dev); 27554008Sfujita register int error; 27656873Sakito 27754008Sfujita tp = &sio_tty[unit]; 27854008Sfujita error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p); 27954008Sfujita if (error >= 0) 28054008Sfujita return (error); 28154008Sfujita error = ttioctl(tp, cmd, data, flag); 28254008Sfujita if (error >= 0) 28354008Sfujita return (error); 28454008Sfujita 28554008Sfujita switch (cmd) { 28654008Sfujita 28754008Sfujita case TIOCSBRK: 28856873Sakito (void) siomctl(dev, WR5_BREAK, DMBIS); 28956873Sakito break; 29056873Sakito 29154008Sfujita case TIOCCBRK: 29256873Sakito (void) siomctl(dev, WR5_BREAK, DMBIC); 29356873Sakito break; 29456873Sakito 29554008Sfujita case TIOCSDTR: 29656873Sakito (void) siomctl(dev, WR5_DTR | WR5_RTS, DMBIS); 29756873Sakito break; 29856873Sakito 29954008Sfujita case TIOCCDTR: 30056873Sakito (void) siomctl(dev, WR5_DTR | WR5_RTS, DMBIC); 30156873Sakito break; 30256873Sakito 30354008Sfujita case TIOCMSET: 30456873Sakito (void) siomctl(dev, *(int *)data, DMSET); 30556873Sakito break; 30656873Sakito 30754008Sfujita case TIOCMBIS: 30856873Sakito (void) siomctl(dev, *(int *)data, DMBIS); 30956873Sakito break; 31056873Sakito 31154008Sfujita case TIOCMBIC: 31256873Sakito (void) siomctl(dev, *(int *)data, DMBIC); 31356873Sakito break; 31456873Sakito 31554008Sfujita case TIOCMGET: 31656873Sakito *(int *)data = siomctl(dev, 0, DMGET); 31756873Sakito break; 31856873Sakito 31954008Sfujita default: 32054008Sfujita return (ENOTTY); 32154008Sfujita } 32254008Sfujita return (0); 32354008Sfujita } 32454008Sfujita 32554008Sfujita 32656873Sakito /* 32756873Sakito * 32856873Sakito */ 32956873Sakito 33054008Sfujita void 33154008Sfujita siostart(tp) 33254008Sfujita register struct tty *tp; 33354008Sfujita { 33454008Sfujita register struct siodevice *sio; 33556873Sakito register int rr; 33656873Sakito int s, unit, c; 33754008Sfujita 33854008Sfujita unit = siounit(tp->t_dev); 33956873Sakito sio = sio_softc[unit].sc_pc->pc_addr; 34054008Sfujita s = spltty(); 34154008Sfujita if (tp->t_state & (TS_TIMEOUT|TS_TTSTOP)) 34254008Sfujita goto out; 34354008Sfujita if (tp->t_outq.c_cc <= tp->t_lowat) { 34454008Sfujita if (tp->t_state&TS_ASLEEP) { 34554008Sfujita tp->t_state &= ~TS_ASLEEP; 34654008Sfujita wakeup((caddr_t)&tp->t_outq); 34754008Sfujita } 34854008Sfujita selwakeup(&tp->t_wsel); 34954008Sfujita } 35054008Sfujita if (tp->t_outq.c_cc == 0) 35154008Sfujita goto out; 35256873Sakito rr = siogetreg(sio); 35354008Sfujita if (rr & RR_TXRDY) { 35454008Sfujita c = getc(&tp->t_outq); 35554008Sfujita tp->t_state |= TS_BUSY; 35654008Sfujita sio->sio_data = c; 35754008Sfujita } 35854008Sfujita out: 35954008Sfujita splx(s); 36054008Sfujita } 36156873Sakito 36256873Sakito sioparam(tp, t) 36356873Sakito register struct tty *tp; 36456873Sakito register struct termios *t; 36556873Sakito { 36656873Sakito int unit = siounit(tp->t_dev); 36756873Sakito register struct siodevice *sio; 36856873Sakito register cflag = t->c_cflag; 36956873Sakito register u_char wr; 37056873Sakito int ospeed = ttspeedtab(t->c_ospeed, siospeedtab); 37156873Sakito 37256873Sakito sio = sio_softc[unit].sc_pc->pc_addr; 37356873Sakito 37456873Sakito switch (cflag & CSIZE) { 37556873Sakito case CS5: 37656873Sakito case CS6: 37756873Sakito case CS7: 37856873Sakito case CS8: 37956873Sakito break; 38056873Sakito } 38156873Sakito 38256873Sakito wr = ospeed; 38356873Sakito 38456873Sakito if (cflag & PARENB) { 38556873Sakito wr |= WR4_PARENAB; 38656873Sakito if ((cflag&PARODD) == 0) 38756873Sakito wr |= WR4_EPARITY; 38856873Sakito } 38956873Sakito 39056873Sakito if (cflag & CSTOPB) 39156873Sakito wr |= WR4_STOP2; /* 2 stop bit */ 39256873Sakito else 39356873Sakito wr |= WR4_STOP1; /* 1 stop bit */ 39456873Sakito 39556873Sakito (void) sioreg(sio, WR4, wr); 39656873Sakito 39756873Sakito return (0); 39856873Sakito } 39956873Sakito 40056873Sakito siomctl() 40156873Sakito { 40256873Sakito return (0); 40356873Sakito } 40456873Sakito 40556873Sakito 40654008Sfujita /* 40756873Sakito * Interrupt handling 40854008Sfujita */ 40956873Sakito 41056873Sakito void 41156873Sakito _siointr() 41254008Sfujita { 41356873Sakito register int port; 41456873Sakito register struct sio_portc *pc; 41554008Sfujita 41656873Sakito for (port = 0; port < NPORT; port++) { 41756873Sakito pc = &sio_portc[port]; 41856873Sakito 41956873Sakito if (pc->pc_major != -1) 42056873Sakito (pc->pc_intr)(pc->pc_unit); 42154008Sfujita } 42254008Sfujita } 42354008Sfujita 42456873Sakito siointr(unit) 42556873Sakito register int unit; 42656873Sakito { 42756873Sakito register struct siodevice *sio = sio_softc[unit].sc_pc->pc_addr; 42856873Sakito register u_char code; 42956873Sakito register struct tty *tp; 43056873Sakito int s, rr; 43156873Sakito 43256873Sakito tp = &sio_tty[unit]; 43356873Sakito rr = siogetreg(sio); 43456873Sakito 43556873Sakito if (rr & RR_RXRDY) { 43656873Sakito code = sio->sio_data; 43756873Sakito if ((tp->t_state & TS_ISOPEN) != 0) 43856873Sakito (*linesw[tp->t_line].l_rint)(code, tp); 43956873Sakito } 44056873Sakito 44156873Sakito if (rr & RR_TXRDY) { 44256873Sakito sio->sio_cmd = WR0_RSTPEND; 44356873Sakito tp->t_state &= ~(TS_BUSY|TS_FLUSH); 44456873Sakito if (tp->t_line) 44556873Sakito (*linesw[tp->t_line].l_start)(tp); 44656873Sakito else 44756873Sakito siostart(tp); 44856873Sakito } 44956873Sakito } 45056873Sakito 45154008Sfujita /* 45254008Sfujita * Following are all routines needed for SIO to act as console 45354008Sfujita */ 45457058Sakito #include <luna68k/luna68k/cons.h> 45554008Sfujita 45654008Sfujita siocnprobe(cp) 45756873Sakito register struct consdev *cp; 45854008Sfujita { 45956873Sakito register int unit = 0; 46054008Sfujita 46154008Sfujita /* locate the major number */ 46254008Sfujita for (siomajor = 0; siomajor < nchrdev; siomajor++) 46354008Sfujita if (cdevsw[siomajor].d_open == sioopen) 46454008Sfujita break; 46554008Sfujita 46656873Sakito siounitbase = -1; 46754008Sfujita 46854008Sfujita /* initialize required fields */ 46954008Sfujita cp->cn_dev = makedev(siomajor, unit); 47056873Sakito cp->cn_tp = &sio_tty[unit]; 47154008Sfujita cp->cn_pri = CN_NORMAL; 47254008Sfujita } 47354008Sfujita 47454008Sfujita siocninit(cp) 47554008Sfujita struct consdev *cp; 47654008Sfujita { 47754008Sfujita int unit = siounit(cp->cn_dev); 47856873Sakito register struct sio_softc *sc = &sio_softc[unit]; 47954008Sfujita 48056873Sakito sioinit((struct siodevice *) SIO_HARDADDR, siodefaultrate); 48156873Sakito 48256873Sakito /* port assign */ 48356873Sakito sc->sc_pc = sio_port_assign(0, siomajor, unit, siointr); 48456873Sakito 48554008Sfujita sioconsole = unit; 48656873Sakito siounitbase = 0; 48756873Sakito 48856873Sakito sio_active |= 1 << unit; 48956873Sakito siosoftCAR |= 1 << unit; 49054008Sfujita } 49154008Sfujita 49254008Sfujita siocngetc(dev) 49354008Sfujita dev_t dev; 49454008Sfujita { 49556873Sakito struct sio_softc *sc = &sio_softc[siounit(dev)]; 49656873Sakito struct sio_portc *pc = sc->sc_pc; 49754008Sfujita 49856873Sakito return(sio_imgetc(pc->pc_addr)); 49954008Sfujita } 50054008Sfujita 50154008Sfujita siocnputc(dev, c) 50254008Sfujita dev_t dev; 50354008Sfujita int c; 50454008Sfujita { 50556873Sakito struct sio_softc *sc = &sio_softc[siounit(dev)]; 50656873Sakito struct sio_portc *pc = sc->sc_pc; 50754008Sfujita 50856873Sakito sio_imputc(pc->pc_addr, c); 50956873Sakito } 51054008Sfujita 51154008Sfujita 51256873Sakito /* 51356873Sakito * sio raw-level routines 51456873Sakito */ 51554008Sfujita 51656873Sakito sioinit(sio0, rate) 51756873Sakito register struct siodevice *sio0; 51856873Sakito register int rate; 51956873Sakito { 52056873Sakito register struct siodevice *sio1; 52156873Sakito int s; 52254008Sfujita 52356873Sakito rate = ttspeedtab(rate, siospeedtab); 52454008Sfujita 52556873Sakito if (sio_init_done) 52656873Sakito return; 52754008Sfujita 52856873Sakito sio1 = (struct siodevice *) ((u_long) sio0 + sizeof(struct siodevice)); 52954008Sfujita 53054008Sfujita s = splhigh(); 53154008Sfujita 53256873Sakito sioreg(sio0, WR0, WR0_CHANRST); /* Channel-A Reset */ 53354008Sfujita 53456873Sakito sioreg(sio0, WR2, (WR2_VEC86 | WR2_INTR_1)); /* Set CPU BUS Interface Mode */ 53556873Sakito sioreg(sio1, WR2, 0); /* Set Interrupt Vector */ 53654008Sfujita 53756873Sakito sioreg(sio0, WR0, WR0_RSTINT); /* Reset E/S Interrupt */ 53856873Sakito sioreg(sio0, WR4, (rate | WR4_STOP1 | WR4_NPARITY)); /* Tx/Rx */ 53956873Sakito sioreg(sio0, WR3, (WR3_RX8BIT | WR3_RXENBL)); /* Rx */ 54056873Sakito sioreg(sio0, WR5, (WR5_TX8BIT | WR5_TXENBL)); /* Tx */ 54156873Sakito sioreg(sio0, WR0, WR0_RSTINT); /* Reset E/S Interrupt */ 54256873Sakito sioreg(sio0, WR1, (WR1_RXALLS | WR1_TXENBL)); 54354008Sfujita 54456873Sakito sioreg(sio1, WR0, WR0_CHANRST); /* Channel-B Reset */ 54554008Sfujita 54656873Sakito sioreg(sio1, WR0, WR0_RSTINT); /* Reset E/S Interrupt */ 54756873Sakito sioreg(sio1, WR4, (rate | WR4_STOP1 | WR4_NPARITY)); /* Tx/Rx */ 54856873Sakito sioreg(sio1, WR3, (WR3_RX8BIT | WR3_RXENBL)); /* Rx */ 54956873Sakito sioreg(sio1, WR5, (WR5_TX8BIT | WR5_TXENBL)); /* Tx */ 55056873Sakito sioreg(sio1, WR0, WR0_RSTINT); /* Reset E/S Interrupt */ 55156873Sakito sioreg(sio1, WR1, (WR1_RXALLS | WR1_TXENBL)); 55256873Sakito 55354008Sfujita splx(s); 55456873Sakito 55556873Sakito sio_init_done = 1; 55654008Sfujita } 55754008Sfujita 55856873Sakito sio_imgetc(sio) 55956873Sakito register struct siodevice *sio; 56054008Sfujita { 56156873Sakito register int rr0, rr1; 56256873Sakito int c, s; 56354008Sfujita 56456873Sakito s = splhigh(); 56556873Sakito while (((rr0 = sioreg(sio, RR0, 0)) & RR0_RXAVAIL) == 0) 56656873Sakito ; 56756873Sakito c = sio->sio_data; 56856873Sakito sioreg(sio, WR0, WR0_RSTPEND); 56956873Sakito splx(s); 57056873Sakito return (c); 57154008Sfujita } 57254008Sfujita 57356873Sakito sio_imputc(sio, c) 57456873Sakito register struct siodevice *sio; 57554008Sfujita int c; 57654008Sfujita { 57754008Sfujita register u_char code; 57856873Sakito register int rr; 57956873Sakito int s; 58054008Sfujita 58154008Sfujita s = splhigh(); 58254008Sfujita 58356873Sakito sioreg(sio, WR1, WR1_RXALLS); 58456873Sakito 58554008Sfujita do { 58654008Sfujita DELAY(1); 58756873Sakito rr = siogetreg(sio); 58854008Sfujita } while (!(rr & RR_TXRDY)); 58956873Sakito 59056873Sakito code = (c & 0xFF); 59154008Sfujita sio->sio_data = code; 59254008Sfujita 59354008Sfujita do { 59454008Sfujita DELAY(1); 59556873Sakito rr = siogetreg(sio); 59654008Sfujita } while (!(rr & RR_TXRDY)); 59754008Sfujita 59856873Sakito sioreg(sio, WR1, (WR1_RXALLS | WR1_TXENBL)); 59956873Sakito 60054008Sfujita splx(s); 60154008Sfujita } 60254008Sfujita 60356873Sakito /* 60456873Sakito * uPD7201A register operation 60556873Sakito */ 60654008Sfujita 60754008Sfujita int 60856873Sakito siogetreg(sio) 60956873Sakito register struct siodevice *sio; 61054008Sfujita { 61154008Sfujita register int rr = 0; 61254008Sfujita 61354008Sfujita rr = sio->sio_stat; 61454008Sfujita rr <<= 8; 61554008Sfujita sio->sio_cmd = 1; /* Select RR1 */ 61654008Sfujita rr |= sio->sio_stat; 61754008Sfujita 61854008Sfujita return(rr); 61954008Sfujita } 62054008Sfujita 62154008Sfujita int 62256873Sakito sioreg(sio, reg, val) 62356873Sakito register struct siodevice *sio; 62454008Sfujita register int reg, val; 62554008Sfujita { 62654008Sfujita if (isStatusReg(reg)) { 62756873Sakito if (reg != 0) 62856873Sakito sio->sio_cmd = reg; 62956873Sakito val = sio->sio_stat; 63054008Sfujita } else { 63156873Sakito if (reg != 0) 63256873Sakito sio->sio_cmd = reg; 63356873Sakito sio->sio_cmd = val; 63454008Sfujita } 63556873Sakito 63656873Sakito return(val); 63754008Sfujita } 63854008Sfujita #endif 639