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*57058Sakito * @(#)sio.c 7.4 (Berkeley) 12/10/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 24*57058Sakito #include <sys/param.h> 25*57058Sakito #include <sys/systm.h> 26*57058Sakito #include <sys/ioctl.h> 27*57058Sakito #include <sys/proc.h> 28*57058Sakito #include <sys/tty.h> 29*57058Sakito #include <sys/conf.h> 30*57058Sakito #include <sys/file.h> 31*57058Sakito #include <sys/uio.h> 32*57058Sakito #include <sys/kernel.h> 33*57058Sakito #include <sys/syslog.h> 3454008Sfujita 35*57058Sakito #include <luna68k/dev/device.h> 36*57058Sakito #include <luna68k/dev/sioreg.h> 37*57058Sakito #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; 6656873Sakito int sioconsole; 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 8054008Sfujita 8154008Sfujita /* 8256873Sakito * probe routines 8354008Sfujita */ 8454008Sfujita 8554008Sfujita sioprobe(hd) 8654008Sfujita register struct hp_device *hd; 8754008Sfujita { 8856873Sakito register int port; 8956873Sakito register struct sio_portc *pc; 9056873Sakito register struct sio_softc *sc; 9154008Sfujita 9256873Sakito sioinit((struct siodevice *) hd->hp_addr, siodefaultrate); 9354008Sfujita 9456873Sakito /* locate the major number */ 9556873Sakito for (siomajor = 0; siomajor < nchrdev; siomajor++) 9656873Sakito if (cdevsw[siomajor].d_open == sioopen) 9756873Sakito break; 9854008Sfujita 9956873Sakito for (port = 0; port < NPORT; port++) { 10056873Sakito pc = &sio_portc[port]; 10154008Sfujita 10256873Sakito if (pc->pc_major != -1) { 10356873Sakito printf("%s%d: port %d, address 0x%x, intr 0x%x (console)\n", 10456873Sakito (pc->pc_major == siomajor ? "sio" : "bmc" ), 10556873Sakito pc->pc_unit, port, pc->pc_addr, pc->pc_intr); 10656873Sakito continue; 10756873Sakito } 10854008Sfujita 10956873Sakito pc->pc_addr = 11056873Sakito (struct siodevice *)((u_long) hd->hp_addr + (sizeof(struct siodevice) * port)); 11156873Sakito #if NBMC > 0 11256873Sakito if (bmcinit(port)) 11356873Sakito continue; 11456873Sakito #endif 11556873Sakito if (++siounitbase < NLINE) { 11656873Sakito pc->pc_major = siomajor; 11756873Sakito pc->pc_intr = siointr; 11856873Sakito pc->pc_unit = siounitbase; 11956873Sakito printf("sio%d: port %d, address 0x%x\n", pc->pc_unit, port, pc->pc_addr); 12054008Sfujita 12156873Sakito sc = &sio_softc[pc->pc_unit]; 12256873Sakito sc->sc_pc = pc; 12354008Sfujita 12456873Sakito sio_active |= 1 << pc->pc_unit; 12556873Sakito siosoftCAR |= 1 << pc->pc_unit; 12656873Sakito } 12756873Sakito } 12856873Sakito } 12954008Sfujita 13056873Sakito struct sio_portc * 13156873Sakito sio_port_assign(port, major, unit, intr) 13256873Sakito int port, major, unit; 13356873Sakito int (*intr)(); 13456873Sakito { 13556873Sakito register struct sio_portc *pc = &sio_portc[port]; 13654008Sfujita 13756873Sakito if (pc->pc_major != -1) 13856873Sakito return((struct sio_portc *) 0); 13954008Sfujita 14056873Sakito pc->pc_major = major; 14156873Sakito pc->pc_intr = intr; 14256873Sakito pc->pc_unit = unit; 14354008Sfujita 14456873Sakito return(pc); 14554008Sfujita } 14654008Sfujita 14756873Sakito 14856873Sakito /* 14956873Sakito * entry routines 15056873Sakito */ 15156873Sakito 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); 16756873Sakito 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; 17956873Sakito /* 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); 18856873Sakito (void) siomctl(dev, WR5_DTR | WR5_RTS, DMSET); 18956873Sakito if ((siosoftCAR & (1 << unit)) || (siomctl(dev, 0, DMGET) & RR0_DCD)) 19056873Sakito 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 } 20456873Sakito 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); 21756873Sakito (void) siomctl(dev, WR5_BREAK, DMBIS); 21856873Sakito if (tp->t_cflag&HUPCL || tp->t_state&TS_WOPEN || 21956873Sakito (tp->t_state&TS_ISOPEN) == 0) 22056873Sakito (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 24356873Sakito /* 24456873Sakito * Stop output on a line. 24556873Sakito */ 24656873Sakito /*ARGSUSED*/ 24756873Sakito siostop(tp, flag) 24856873Sakito register struct tty *tp; 24954008Sfujita { 25056873Sakito register int s; 25154008Sfujita 25256873Sakito s = spltty(); 25356873Sakito if (tp->t_state & TS_BUSY) { 25456873Sakito if ((tp->t_state&TS_TTSTOP)==0) 25556873Sakito tp->t_state |= TS_FLUSH; 25654008Sfujita } 25756873Sakito 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; 27056873Sakito 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: 28256873Sakito (void) siomctl(dev, WR5_BREAK, DMBIS); 28356873Sakito break; 28456873Sakito 28554008Sfujita case TIOCCBRK: 28656873Sakito (void) siomctl(dev, WR5_BREAK, DMBIC); 28756873Sakito break; 28856873Sakito 28954008Sfujita case TIOCSDTR: 29056873Sakito (void) siomctl(dev, WR5_DTR | WR5_RTS, DMBIS); 29156873Sakito break; 29256873Sakito 29354008Sfujita case TIOCCDTR: 29456873Sakito (void) siomctl(dev, WR5_DTR | WR5_RTS, DMBIC); 29556873Sakito break; 29656873Sakito 29754008Sfujita case TIOCMSET: 29856873Sakito (void) siomctl(dev, *(int *)data, DMSET); 29956873Sakito break; 30056873Sakito 30154008Sfujita case TIOCMBIS: 30256873Sakito (void) siomctl(dev, *(int *)data, DMBIS); 30356873Sakito break; 30456873Sakito 30554008Sfujita case TIOCMBIC: 30656873Sakito (void) siomctl(dev, *(int *)data, DMBIC); 30756873Sakito break; 30856873Sakito 30954008Sfujita case TIOCMGET: 31056873Sakito *(int *)data = siomctl(dev, 0, DMGET); 31156873Sakito break; 31256873Sakito 31354008Sfujita default: 31454008Sfujita return (ENOTTY); 31554008Sfujita } 31654008Sfujita return (0); 31754008Sfujita } 31854008Sfujita 31954008Sfujita 32056873Sakito /* 32156873Sakito * 32256873Sakito */ 32356873Sakito 32454008Sfujita void 32554008Sfujita siostart(tp) 32654008Sfujita register struct tty *tp; 32754008Sfujita { 32854008Sfujita register struct siodevice *sio; 32956873Sakito register int rr; 33056873Sakito int s, unit, c; 33154008Sfujita 33254008Sfujita unit = siounit(tp->t_dev); 33356873Sakito 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; 34656873Sakito 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 } 35556873Sakito 35656873Sakito sioparam(tp, t) 35756873Sakito register struct tty *tp; 35856873Sakito register struct termios *t; 35956873Sakito { 36056873Sakito int unit = siounit(tp->t_dev); 36156873Sakito register struct siodevice *sio; 36256873Sakito register cflag = t->c_cflag; 36356873Sakito register u_char wr; 36456873Sakito int ospeed = ttspeedtab(t->c_ospeed, siospeedtab); 36556873Sakito 36656873Sakito sio = sio_softc[unit].sc_pc->pc_addr; 36756873Sakito 36856873Sakito switch (cflag & CSIZE) { 36956873Sakito case CS5: 37056873Sakito case CS6: 37156873Sakito case CS7: 37256873Sakito case CS8: 37356873Sakito break; 37456873Sakito } 37556873Sakito 37656873Sakito wr = ospeed; 37756873Sakito 37856873Sakito if (cflag & PARENB) { 37956873Sakito wr |= WR4_PARENAB; 38056873Sakito if ((cflag&PARODD) == 0) 38156873Sakito wr |= WR4_EPARITY; 38256873Sakito } 38356873Sakito 38456873Sakito if (cflag & CSTOPB) 38556873Sakito wr |= WR4_STOP2; /* 2 stop bit */ 38656873Sakito else 38756873Sakito wr |= WR4_STOP1; /* 1 stop bit */ 38856873Sakito 38956873Sakito (void) sioreg(sio, WR4, wr); 39056873Sakito 39156873Sakito return (0); 39256873Sakito } 39356873Sakito 39456873Sakito siomctl() 39556873Sakito { 39656873Sakito return (0); 39756873Sakito } 39856873Sakito 39956873Sakito 40054008Sfujita /* 40156873Sakito * Interrupt handling 40254008Sfujita */ 40356873Sakito 40456873Sakito void 40556873Sakito _siointr() 40654008Sfujita { 40756873Sakito register int port; 40856873Sakito register struct sio_portc *pc; 40954008Sfujita 41056873Sakito for (port = 0; port < NPORT; port++) { 41156873Sakito pc = &sio_portc[port]; 41256873Sakito 41356873Sakito if (pc->pc_major != -1) 41456873Sakito (pc->pc_intr)(pc->pc_unit); 41554008Sfujita } 41654008Sfujita } 41754008Sfujita 41856873Sakito siointr(unit) 41956873Sakito register int unit; 42056873Sakito { 42156873Sakito register struct siodevice *sio = sio_softc[unit].sc_pc->pc_addr; 42256873Sakito register u_char code; 42356873Sakito register struct tty *tp; 42456873Sakito int s, rr; 42556873Sakito 42656873Sakito tp = &sio_tty[unit]; 42756873Sakito rr = siogetreg(sio); 42856873Sakito 42956873Sakito if (rr & RR_RXRDY) { 43056873Sakito code = sio->sio_data; 43156873Sakito if ((tp->t_state & TS_ISOPEN) != 0) 43256873Sakito (*linesw[tp->t_line].l_rint)(code, tp); 43356873Sakito } 43456873Sakito 43556873Sakito if (rr & RR_TXRDY) { 43656873Sakito sio->sio_cmd = WR0_RSTPEND; 43756873Sakito tp->t_state &= ~(TS_BUSY|TS_FLUSH); 43856873Sakito if (tp->t_line) 43956873Sakito (*linesw[tp->t_line].l_start)(tp); 44056873Sakito else 44156873Sakito siostart(tp); 44256873Sakito } 44356873Sakito } 44456873Sakito 44554008Sfujita /* 44654008Sfujita * Following are all routines needed for SIO to act as console 44754008Sfujita */ 448*57058Sakito #include <luna68k/luna68k/cons.h> 44954008Sfujita 45054008Sfujita siocnprobe(cp) 45156873Sakito register struct consdev *cp; 45254008Sfujita { 45356873Sakito 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 46056873Sakito siounitbase = -1; 46154008Sfujita 46254008Sfujita /* initialize required fields */ 46354008Sfujita cp->cn_dev = makedev(siomajor, unit); 46456873Sakito 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); 47256873Sakito register struct sio_softc *sc = &sio_softc[unit]; 47354008Sfujita 47456873Sakito sioinit((struct siodevice *) SIO_HARDADDR, siodefaultrate); 47556873Sakito 47656873Sakito /* port assign */ 47756873Sakito sc->sc_pc = sio_port_assign(0, siomajor, unit, siointr); 47856873Sakito 47954008Sfujita sioconsole = unit; 48056873Sakito siounitbase = 0; 48156873Sakito 48256873Sakito sio_active |= 1 << unit; 48356873Sakito siosoftCAR |= 1 << unit; 48454008Sfujita } 48554008Sfujita 48654008Sfujita siocngetc(dev) 48754008Sfujita dev_t dev; 48854008Sfujita { 48956873Sakito struct sio_softc *sc = &sio_softc[siounit(dev)]; 49056873Sakito struct sio_portc *pc = sc->sc_pc; 49154008Sfujita 49256873Sakito return(sio_imgetc(pc->pc_addr)); 49354008Sfujita } 49454008Sfujita 49554008Sfujita siocnputc(dev, c) 49654008Sfujita dev_t dev; 49754008Sfujita int c; 49854008Sfujita { 49956873Sakito struct sio_softc *sc = &sio_softc[siounit(dev)]; 50056873Sakito struct sio_portc *pc = sc->sc_pc; 50154008Sfujita 50256873Sakito sio_imputc(pc->pc_addr, c); 50356873Sakito } 50454008Sfujita 50554008Sfujita 50656873Sakito /* 50756873Sakito * sio raw-level routines 50856873Sakito */ 50954008Sfujita 51056873Sakito sioinit(sio0, rate) 51156873Sakito register struct siodevice *sio0; 51256873Sakito register int rate; 51356873Sakito { 51456873Sakito register struct siodevice *sio1; 51556873Sakito int s; 51654008Sfujita 51756873Sakito rate = ttspeedtab(rate, siospeedtab); 51854008Sfujita 51956873Sakito if (sio_init_done) 52056873Sakito return; 52154008Sfujita 52256873Sakito sio1 = (struct siodevice *) ((u_long) sio0 + sizeof(struct siodevice)); 52354008Sfujita 52454008Sfujita s = splhigh(); 52554008Sfujita 52656873Sakito sioreg(sio0, WR0, WR0_CHANRST); /* Channel-A Reset */ 52754008Sfujita 52856873Sakito sioreg(sio0, WR2, (WR2_VEC86 | WR2_INTR_1)); /* Set CPU BUS Interface Mode */ 52956873Sakito sioreg(sio1, WR2, 0); /* Set Interrupt Vector */ 53054008Sfujita 53156873Sakito sioreg(sio0, WR0, WR0_RSTINT); /* Reset E/S Interrupt */ 53256873Sakito sioreg(sio0, WR4, (rate | WR4_STOP1 | WR4_NPARITY)); /* Tx/Rx */ 53356873Sakito sioreg(sio0, WR3, (WR3_RX8BIT | WR3_RXENBL)); /* Rx */ 53456873Sakito sioreg(sio0, WR5, (WR5_TX8BIT | WR5_TXENBL)); /* Tx */ 53556873Sakito sioreg(sio0, WR0, WR0_RSTINT); /* Reset E/S Interrupt */ 53656873Sakito sioreg(sio0, WR1, (WR1_RXALLS | WR1_TXENBL)); 53754008Sfujita 53856873Sakito sioreg(sio1, WR0, WR0_CHANRST); /* Channel-B Reset */ 53954008Sfujita 54056873Sakito sioreg(sio1, WR0, WR0_RSTINT); /* Reset E/S Interrupt */ 54156873Sakito sioreg(sio1, WR4, (rate | WR4_STOP1 | WR4_NPARITY)); /* Tx/Rx */ 54256873Sakito sioreg(sio1, WR3, (WR3_RX8BIT | WR3_RXENBL)); /* Rx */ 54356873Sakito sioreg(sio1, WR5, (WR5_TX8BIT | WR5_TXENBL)); /* Tx */ 54456873Sakito sioreg(sio1, WR0, WR0_RSTINT); /* Reset E/S Interrupt */ 54556873Sakito sioreg(sio1, WR1, (WR1_RXALLS | WR1_TXENBL)); 54656873Sakito 54754008Sfujita splx(s); 54856873Sakito 54956873Sakito sio_init_done = 1; 55054008Sfujita } 55154008Sfujita 55256873Sakito sio_imgetc(sio) 55356873Sakito register struct siodevice *sio; 55454008Sfujita { 55556873Sakito register int rr0, rr1; 55656873Sakito int c, s; 55754008Sfujita 55856873Sakito s = splhigh(); 55956873Sakito while (((rr0 = sioreg(sio, RR0, 0)) & RR0_RXAVAIL) == 0) 56056873Sakito ; 56156873Sakito c = sio->sio_data; 56256873Sakito sioreg(sio, WR0, WR0_RSTPEND); 56356873Sakito splx(s); 56456873Sakito return (c); 56554008Sfujita } 56654008Sfujita 56756873Sakito sio_imputc(sio, c) 56856873Sakito register struct siodevice *sio; 56954008Sfujita int c; 57054008Sfujita { 57154008Sfujita register u_char code; 57256873Sakito register int rr; 57356873Sakito int s; 57454008Sfujita 57554008Sfujita s = splhigh(); 57654008Sfujita 57756873Sakito sioreg(sio, WR1, WR1_RXALLS); 57856873Sakito 57954008Sfujita do { 58054008Sfujita DELAY(1); 58156873Sakito rr = siogetreg(sio); 58254008Sfujita } while (!(rr & RR_TXRDY)); 58356873Sakito 58456873Sakito code = (c & 0xFF); 58554008Sfujita sio->sio_data = code; 58654008Sfujita 58754008Sfujita do { 58854008Sfujita DELAY(1); 58956873Sakito rr = siogetreg(sio); 59054008Sfujita } while (!(rr & RR_TXRDY)); 59154008Sfujita 59256873Sakito sioreg(sio, WR1, (WR1_RXALLS | WR1_TXENBL)); 59356873Sakito 59454008Sfujita splx(s); 59554008Sfujita } 59654008Sfujita 59756873Sakito /* 59856873Sakito * uPD7201A register operation 59956873Sakito */ 60054008Sfujita 60154008Sfujita int 60256873Sakito siogetreg(sio) 60356873Sakito 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 61656873Sakito sioreg(sio, reg, val) 61756873Sakito register struct siodevice *sio; 61854008Sfujita register int reg, val; 61954008Sfujita { 62054008Sfujita if (isStatusReg(reg)) { 62156873Sakito if (reg != 0) 62256873Sakito sio->sio_cmd = reg; 62356873Sakito val = sio->sio_stat; 62454008Sfujita } else { 62556873Sakito if (reg != 0) 62656873Sakito sio->sio_cmd = reg; 62756873Sakito sio->sio_cmd = val; 62854008Sfujita } 62956873Sakito 63056873Sakito return(val); 63154008Sfujita } 63254008Sfujita #endif 633