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*62579Sakito * @(#)sio.c 7.9 (Berkeley) 06/08/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] = { 5359648Sakito { -1, -1, 0, (struct siodevice *) 0x51000000, (int (*)()) 0 }, 5459648Sakito { -1, -1, 1, (struct siodevice *) 0x51000004, (int (*)()) 0 } 5556873Sakito }; 5654008Sfujita 5759648Sakito 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 6759648Sakito 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 79*62579Sakito #ifdef KGDB 8054008Sfujita /* 81*62579Sakito * Kernel GDB support 82*62579Sakito */ 83*62579Sakito #include <machine/remote-sl.h> 84*62579Sakito 85*62579Sakito extern dev_t kgdb_dev; 86*62579Sakito extern int kgdb_rate; 87*62579Sakito extern int kgdb_debug_init; 88*62579Sakito #endif 89*62579Sakito 90*62579Sakito /* 9156873Sakito * probe routines 9254008Sfujita */ 9354008Sfujita 9454008Sfujita sioprobe(hd) 9554008Sfujita register struct hp_device *hd; 9654008Sfujita { 9759648Sakito int unit = hd->hp_unit; 9859648Sakito register struct sio_softc *sc = &sio_softc[unit]; 9956873Sakito register struct sio_portc *pc; 10054008Sfujita 10159648Sakito if (sc->sc_pc != 0) { 10259648Sakito pc = sc->sc_pc; 10359648Sakito printf("sio%d: port %d, address 0x%x, intr 0x%x (console)\n", 10459648Sakito pc->pc_unit, pc->pc_port, pc->pc_addr, pc->pc_intr); 105*62579Sakito return(1); 10659648Sakito } 10754008Sfujita 108*62579Sakito sc->sc_pc = pc = sio_port_assign(unit, siomajor, unit, siointr); 10954008Sfujita 11059648Sakito printf("sio%d: port %d, address 0x%x, intr 0x%x\n", 11159648Sakito pc->pc_unit, pc->pc_port, pc->pc_addr, pc->pc_intr); 11254008Sfujita 11359648Sakito sio_active |= 1 << unit; 114*62579Sakito 115*62579Sakito #ifdef KGDB 116*62579Sakito if (major(kgdb_dev) == siomajor) { 117*62579Sakito #ifdef notdef 118*62579Sakito if (sioconsole == siounit(kgdb_dev)) { 119*62579Sakito kgdb_dev = NODEV; /* can't debug over console port */ 120*62579Sakito } else { 121*62579Sakito #endif 122*62579Sakito /* 123*62579Sakito * The following could potentially be replaced 124*62579Sakito * by the corresponding code in dcmcnprobe. 125*62579Sakito */ 126*62579Sakito if (kgdb_debug_init) { 127*62579Sakito printf("sio%d: ", siounit(kgdb_dev)); 128*62579Sakito kgdb_connect(1); 129*62579Sakito } else 130*62579Sakito printf("sio%d: kgdb enabled\n", siounit(kgdb_dev)); 131*62579Sakito #ifdef notdef 132*62579Sakito } 133*62579Sakito #endif 134*62579Sakito /* end could be replaced */ 135*62579Sakito } 136*62579Sakito #endif 137*62579Sakito 13859648Sakito siosoftCAR |= 1 << unit; 13959648Sakito return(1); 14056873Sakito } 14154008Sfujita 14256873Sakito struct sio_portc * 14356873Sakito sio_port_assign(port, major, unit, intr) 14456873Sakito int port, major, unit; 14556873Sakito int (*intr)(); 14656873Sakito { 14757291Sakito register struct sio_portc *pc; 14854008Sfujita 14957291Sakito pc = &sio_portc[port]; 15057291Sakito 15156873Sakito pc->pc_major = major; 15256873Sakito pc->pc_intr = intr; 15356873Sakito pc->pc_unit = unit; 15454008Sfujita 15556873Sakito return(pc); 15654008Sfujita } 15754008Sfujita 15857291Sakito struct sio_portc * 15957291Sakito sio_port_get(port) 16057291Sakito int port; 16157291Sakito { 16257291Sakito register struct sio_portc *pc; 16356873Sakito 16457291Sakito pc = &sio_portc[port]; 16557291Sakito 16657291Sakito return(pc); 16757291Sakito } 16857291Sakito 16957291Sakito int 17057291Sakito sio_port_info() 17157291Sakito { 17257291Sakito printf("sio_port_info[sio.c]:\t{%d} major = %d, unit = %d, intr = 0x%x\n", 17357291Sakito 0, sio_portc[0].pc_major, sio_portc[0].pc_unit, sio_portc[0].pc_intr); 17457291Sakito printf("sio_port_info[sio.c]:\t{%d} major = %d, unit = %d, intr = 0x%x\n", 17557291Sakito 1, sio_portc[1].pc_major, sio_portc[1].pc_unit, sio_portc[1].pc_intr); 17657291Sakito } 17757291Sakito 17857291Sakito 17956873Sakito /* 18056873Sakito * entry routines 18156873Sakito */ 18256873Sakito 18354008Sfujita /* ARGSUSED */ 18454008Sfujita #ifdef __STDC__ 18554008Sfujita sioopen(dev_t dev, int flag, int mode, struct proc *p) 18654008Sfujita #else 18754008Sfujita sioopen(dev, flag, mode, p) 18854008Sfujita dev_t dev; 18954008Sfujita int flag, mode; 19054008Sfujita struct proc *p; 19154008Sfujita #endif 19254008Sfujita { 19354008Sfujita register struct tty *tp; 19454008Sfujita register int unit; 19554008Sfujita int error = 0; 19654008Sfujita 19754008Sfujita unit = siounit(dev); 19859648Sakito if (unit >= NSIO || (sio_active & (1 << unit)) == 0) 19954008Sfujita return (ENXIO); 20054008Sfujita tp = &sio_tty[unit]; 20154008Sfujita tp->t_oproc = siostart; 20254008Sfujita tp->t_param = sioparam; 20354008Sfujita tp->t_dev = dev; 20454008Sfujita if ((tp->t_state & TS_ISOPEN) == 0) { 20554008Sfujita tp->t_state |= TS_WOPEN; 20654008Sfujita ttychars(tp); 20754008Sfujita if (tp->t_ispeed == 0) { 20854008Sfujita tp->t_iflag = TTYDEF_IFLAG; 20954008Sfujita tp->t_oflag = TTYDEF_OFLAG; 21056873Sakito /* tp->t_cflag = TTYDEF_CFLAG; */ 21154008Sfujita tp->t_cflag = (CREAD | CS8 | HUPCL); 21254008Sfujita tp->t_lflag = TTYDEF_LFLAG; 21354008Sfujita tp->t_ispeed = tp->t_ospeed = siodefaultrate; 21454008Sfujita } 21554008Sfujita sioparam(tp, &tp->t_termios); 21654008Sfujita ttsetwater(tp); 21754008Sfujita } else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0) 21854008Sfujita return (EBUSY); 21956873Sakito (void) siomctl(dev, WR5_DTR | WR5_RTS, DMSET); 22056873Sakito if ((siosoftCAR & (1 << unit)) || (siomctl(dev, 0, DMGET) & RR0_DCD)) 22156873Sakito tp->t_state |= TS_CARR_ON; 22254008Sfujita (void) spltty(); 22354008Sfujita while ((flag&O_NONBLOCK) == 0 && (tp->t_cflag&CLOCAL) == 0 && 22454008Sfujita (tp->t_state & TS_CARR_ON) == 0) { 22554008Sfujita tp->t_state |= TS_WOPEN; 22654008Sfujita if (error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH, 22754008Sfujita ttopen, 0)) 22854008Sfujita break; 22954008Sfujita } 23054008Sfujita (void) spl0(); 23154008Sfujita if (error == 0) 23254008Sfujita error = (*linesw[tp->t_line].l_open)(dev, tp); 23354008Sfujita return (error); 23454008Sfujita } 23556873Sakito 23654008Sfujita /*ARGSUSED*/ 23754008Sfujita sioclose(dev, flag, mode, p) 23854008Sfujita dev_t dev; 23954008Sfujita int flag, mode; 24054008Sfujita struct proc *p; 24154008Sfujita { 24254008Sfujita register struct tty *tp; 24354008Sfujita register int unit; 24454008Sfujita 24554008Sfujita unit = siounit(dev); 24654008Sfujita tp = &sio_tty[unit]; 24754008Sfujita (*linesw[tp->t_line].l_close)(tp, flag); 24856873Sakito (void) siomctl(dev, WR5_BREAK, DMBIS); 24956873Sakito if (tp->t_cflag&HUPCL || tp->t_state&TS_WOPEN || 25056873Sakito (tp->t_state&TS_ISOPEN) == 0) 25156873Sakito (void) siomctl(dev, 0, DMSET); 25254008Sfujita ttyclose(tp); 25354008Sfujita return (0); 25454008Sfujita } 25554008Sfujita 25654008Sfujita sioread(dev, uio, flag) 25754008Sfujita dev_t dev; 25854008Sfujita struct uio *uio; 25954008Sfujita { 26054008Sfujita register struct tty *tp = &sio_tty[siounit(dev)]; 26154008Sfujita 26254008Sfujita return ((*linesw[tp->t_line].l_read)(tp, uio, flag)); 26354008Sfujita } 26454008Sfujita 26554008Sfujita siowrite(dev, uio, flag) 26654008Sfujita dev_t dev; 26754008Sfujita struct uio *uio; 26854008Sfujita { 26957126Sakito register int unit = siounit(dev); 27057126Sakito register struct tty *tp = &sio_tty[unit]; 27154008Sfujita 27257126Sakito if ((unit == sioconsole) && constty && 27357126Sakito (constty->t_state&(TS_CARR_ON|TS_ISOPEN))==(TS_CARR_ON|TS_ISOPEN)) 27457126Sakito tp = constty; 27557126Sakito 27654008Sfujita return ((*linesw[tp->t_line].l_write)(tp, uio, flag)); 27754008Sfujita } 27854008Sfujita 27956873Sakito /* 28056873Sakito * Stop output on a line. 28156873Sakito */ 28256873Sakito /*ARGSUSED*/ 28356873Sakito siostop(tp, flag) 28456873Sakito register struct tty *tp; 28554008Sfujita { 28656873Sakito register int s; 28754008Sfujita 28856873Sakito s = spltty(); 28956873Sakito if (tp->t_state & TS_BUSY) { 29056873Sakito if ((tp->t_state&TS_TTSTOP)==0) 29156873Sakito tp->t_state |= TS_FLUSH; 29254008Sfujita } 29356873Sakito splx(s); 29454008Sfujita } 29554008Sfujita 29654008Sfujita sioioctl(dev, cmd, data, flag, p) 29754008Sfujita dev_t dev; 29854008Sfujita int cmd; 29954008Sfujita caddr_t data; 30054008Sfujita int flag; 30154008Sfujita struct proc *p; 30254008Sfujita { 30354008Sfujita register struct tty *tp; 30454008Sfujita register int unit = siounit(dev); 30554008Sfujita register int error; 30656873Sakito 30754008Sfujita tp = &sio_tty[unit]; 30854008Sfujita error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p); 30954008Sfujita if (error >= 0) 31054008Sfujita return (error); 31154008Sfujita error = ttioctl(tp, cmd, data, flag); 31254008Sfujita if (error >= 0) 31354008Sfujita return (error); 31454008Sfujita 31554008Sfujita switch (cmd) { 31654008Sfujita 31754008Sfujita case TIOCSBRK: 31856873Sakito (void) siomctl(dev, WR5_BREAK, DMBIS); 31956873Sakito break; 32056873Sakito 32154008Sfujita case TIOCCBRK: 32256873Sakito (void) siomctl(dev, WR5_BREAK, DMBIC); 32356873Sakito break; 32456873Sakito 32554008Sfujita case TIOCSDTR: 32656873Sakito (void) siomctl(dev, WR5_DTR | WR5_RTS, DMBIS); 32756873Sakito break; 32856873Sakito 32954008Sfujita case TIOCCDTR: 33056873Sakito (void) siomctl(dev, WR5_DTR | WR5_RTS, DMBIC); 33156873Sakito break; 33256873Sakito 33354008Sfujita case TIOCMSET: 33456873Sakito (void) siomctl(dev, *(int *)data, DMSET); 33556873Sakito break; 33656873Sakito 33754008Sfujita case TIOCMBIS: 33856873Sakito (void) siomctl(dev, *(int *)data, DMBIS); 33956873Sakito break; 34056873Sakito 34154008Sfujita case TIOCMBIC: 34256873Sakito (void) siomctl(dev, *(int *)data, DMBIC); 34356873Sakito break; 34456873Sakito 34554008Sfujita case TIOCMGET: 34656873Sakito *(int *)data = siomctl(dev, 0, DMGET); 34756873Sakito break; 34856873Sakito 34954008Sfujita default: 35054008Sfujita return (ENOTTY); 35154008Sfujita } 35254008Sfujita return (0); 35354008Sfujita } 35454008Sfujita 35554008Sfujita 35656873Sakito /* 35756873Sakito * 35856873Sakito */ 35956873Sakito 36054008Sfujita void 36154008Sfujita siostart(tp) 36254008Sfujita register struct tty *tp; 36354008Sfujita { 36454008Sfujita register struct siodevice *sio; 36556873Sakito register int rr; 36656873Sakito int s, unit, c; 36754008Sfujita 36854008Sfujita unit = siounit(tp->t_dev); 36956873Sakito sio = sio_softc[unit].sc_pc->pc_addr; 37054008Sfujita s = spltty(); 37154008Sfujita if (tp->t_state & (TS_TIMEOUT|TS_TTSTOP)) 37254008Sfujita goto out; 37354008Sfujita if (tp->t_outq.c_cc <= tp->t_lowat) { 37454008Sfujita if (tp->t_state&TS_ASLEEP) { 37554008Sfujita tp->t_state &= ~TS_ASLEEP; 37654008Sfujita wakeup((caddr_t)&tp->t_outq); 37754008Sfujita } 37854008Sfujita selwakeup(&tp->t_wsel); 37954008Sfujita } 38054008Sfujita if (tp->t_outq.c_cc == 0) 38154008Sfujita goto out; 38256873Sakito rr = siogetreg(sio); 38354008Sfujita if (rr & RR_TXRDY) { 38454008Sfujita c = getc(&tp->t_outq); 38554008Sfujita tp->t_state |= TS_BUSY; 38654008Sfujita sio->sio_data = c; 38754008Sfujita } 38854008Sfujita out: 38954008Sfujita splx(s); 39054008Sfujita } 39156873Sakito 39256873Sakito sioparam(tp, t) 39356873Sakito register struct tty *tp; 39456873Sakito register struct termios *t; 39556873Sakito { 39656873Sakito int unit = siounit(tp->t_dev); 39756873Sakito register struct siodevice *sio; 39856873Sakito register cflag = t->c_cflag; 39956873Sakito register u_char wr; 40056873Sakito int ospeed = ttspeedtab(t->c_ospeed, siospeedtab); 40156873Sakito 40256873Sakito sio = sio_softc[unit].sc_pc->pc_addr; 40356873Sakito 40456873Sakito switch (cflag & CSIZE) { 40556873Sakito case CS5: 40656873Sakito case CS6: 40756873Sakito case CS7: 40856873Sakito case CS8: 40956873Sakito break; 41056873Sakito } 41156873Sakito 41256873Sakito wr = ospeed; 41356873Sakito 41456873Sakito if (cflag & PARENB) { 41556873Sakito wr |= WR4_PARENAB; 41656873Sakito if ((cflag&PARODD) == 0) 41756873Sakito wr |= WR4_EPARITY; 41856873Sakito } 41956873Sakito 42056873Sakito if (cflag & CSTOPB) 42156873Sakito wr |= WR4_STOP2; /* 2 stop bit */ 42256873Sakito else 42356873Sakito wr |= WR4_STOP1; /* 1 stop bit */ 42456873Sakito 42556873Sakito (void) sioreg(sio, WR4, wr); 42656873Sakito 42756873Sakito return (0); 42856873Sakito } 42956873Sakito 43056873Sakito siomctl() 43156873Sakito { 43256873Sakito return (0); 43356873Sakito } 43456873Sakito 43556873Sakito 43654008Sfujita /* 43756873Sakito * Interrupt handling 43854008Sfujita */ 43956873Sakito 44056873Sakito void 44156873Sakito _siointr() 44254008Sfujita { 44356873Sakito register int port; 44456873Sakito register struct sio_portc *pc; 44554008Sfujita 44656873Sakito for (port = 0; port < NPORT; port++) { 44756873Sakito pc = &sio_portc[port]; 44856873Sakito 44956873Sakito if (pc->pc_major != -1) 45056873Sakito (pc->pc_intr)(pc->pc_unit); 45154008Sfujita } 45254008Sfujita } 45354008Sfujita 45456873Sakito siointr(unit) 45556873Sakito register int unit; 45656873Sakito { 45756873Sakito register struct siodevice *sio = sio_softc[unit].sc_pc->pc_addr; 45856873Sakito register u_char code; 45956873Sakito register struct tty *tp; 46056873Sakito int s, rr; 46156873Sakito 46256873Sakito tp = &sio_tty[unit]; 46357850Sakito 46457850Sakito start: 46556873Sakito rr = siogetreg(sio); 46657850Sakito if (rr & RR_RXRDY) { 46757850Sakito if (rr & (RR_FRAMING | RR_OVERRUN | RR_PARITY)) { 46857850Sakito sioeint(unit, rr, sio); 46957850Sakito goto start; 47057850Sakito } 47156873Sakito 47256873Sakito code = sio->sio_data; 47356873Sakito if ((tp->t_state & TS_ISOPEN) != 0) 47456873Sakito (*linesw[tp->t_line].l_rint)(code, tp); 475*62579Sakito #ifdef KGDB 476*62579Sakito else { 477*62579Sakito if (code == FRAME_END && 478*62579Sakito kgdb_dev == makedev(siomajor, unit)) 479*62579Sakito kgdb_connect(0); /* trap into kgdb */ 480*62579Sakito } 481*62579Sakito #endif 48257850Sakito while ((rr = siogetreg(sio)) & RR_RXRDY) { 48357850Sakito code = sio->sio_data; 48457850Sakito if ((tp->t_state & TS_ISOPEN) != 0) 48557850Sakito (*linesw[tp->t_line].l_rint)(code, tp); 486*62579Sakito #ifdef KGDB 487*62579Sakito else { 488*62579Sakito if (code == FRAME_END && 489*62579Sakito kgdb_dev == makedev(siomajor, unit)) 490*62579Sakito kgdb_connect(0); /* trap into kgdb */ 491*62579Sakito } 492*62579Sakito #endif 49357850Sakito } 49456873Sakito } 49556873Sakito 49656873Sakito if (rr & RR_TXRDY) { 49756873Sakito sio->sio_cmd = WR0_RSTPEND; 49856873Sakito tp->t_state &= ~(TS_BUSY|TS_FLUSH); 49956873Sakito if (tp->t_line) 50056873Sakito (*linesw[tp->t_line].l_start)(tp); 50156873Sakito else 50256873Sakito siostart(tp); 50356873Sakito } 50456873Sakito } 50556873Sakito 50657850Sakito sioeint(unit, stat, sio) 50757850Sakito register int unit, stat; 50857850Sakito register struct siodevice *sio; 50957850Sakito { 51057850Sakito register struct tty *tp; 51157850Sakito register int code; 51257850Sakito 51357850Sakito tp = &sio_tty[unit]; 51457850Sakito 51557850Sakito code = sio->sio_data; 51657850Sakito 51757850Sakito sio->sio_cmd = WR0_ERRRST; 51857850Sakito 519*62579Sakito if ((tp->t_state & TS_ISOPEN) == 0) { 520*62579Sakito #ifdef KGDB 521*62579Sakito /* we don't care about parity errors */ 522*62579Sakito if (((stat & (RR_FRAMING|RR_PARITY)) == RR_PARITY) && 523*62579Sakito kgdb_dev == makedev(siomajor, unit) && code == FRAME_END) 524*62579Sakito kgdb_connect(0); /* trap into kgdb */ 525*62579Sakito #endif 52657850Sakito return; 527*62579Sakito } 52857850Sakito 52957850Sakito if (stat & RR_FRAMING) 53057850Sakito code |= TTY_FE; 53157850Sakito else if (stat & RR_PARITY) 53257850Sakito code |= TTY_PE; 53357850Sakito 53457850Sakito (*linesw[tp->t_line].l_rint)(code, tp); 53557850Sakito } 53657850Sakito 53754008Sfujita /* 53854008Sfujita * Following are all routines needed for SIO to act as console 53954008Sfujita */ 54057058Sakito #include <luna68k/luna68k/cons.h> 54154008Sfujita 54254008Sfujita siocnprobe(cp) 54356873Sakito register struct consdev *cp; 54454008Sfujita { 54556873Sakito register int unit = 0; 54654008Sfujita 54754008Sfujita /* locate the major number */ 54854008Sfujita for (siomajor = 0; siomajor < nchrdev; siomajor++) 54954008Sfujita if (cdevsw[siomajor].d_open == sioopen) 55054008Sfujita break; 55154008Sfujita 55254008Sfujita /* initialize required fields */ 55354008Sfujita cp->cn_dev = makedev(siomajor, unit); 55456873Sakito cp->cn_tp = &sio_tty[unit]; 55554008Sfujita cp->cn_pri = CN_NORMAL; 55654008Sfujita } 55754008Sfujita 55854008Sfujita siocninit(cp) 55954008Sfujita struct consdev *cp; 56054008Sfujita { 56154008Sfujita int unit = siounit(cp->cn_dev); 56256873Sakito register struct sio_softc *sc = &sio_softc[unit]; 56354008Sfujita 56456873Sakito sioinit((struct siodevice *) SIO_HARDADDR, siodefaultrate); 56556873Sakito 56656873Sakito /* port assign */ 56759648Sakito sc->sc_pc = sio_port_assign(SIO_PORT, siomajor, unit, siointr); 56856873Sakito 56954008Sfujita sioconsole = unit; 57056873Sakito sio_active |= 1 << unit; 57156873Sakito siosoftCAR |= 1 << unit; 57254008Sfujita } 57354008Sfujita 57454008Sfujita siocngetc(dev) 57554008Sfujita dev_t dev; 57654008Sfujita { 57756873Sakito struct sio_softc *sc = &sio_softc[siounit(dev)]; 57856873Sakito struct sio_portc *pc = sc->sc_pc; 57954008Sfujita 58056873Sakito return(sio_imgetc(pc->pc_addr)); 58154008Sfujita } 58254008Sfujita 58354008Sfujita siocnputc(dev, c) 58454008Sfujita dev_t dev; 58554008Sfujita int c; 58654008Sfujita { 58756873Sakito struct sio_softc *sc = &sio_softc[siounit(dev)]; 58856873Sakito struct sio_portc *pc = sc->sc_pc; 58954008Sfujita 59056873Sakito sio_imputc(pc->pc_addr, c); 59156873Sakito } 59254008Sfujita 59354008Sfujita 59456873Sakito /* 59556873Sakito * sio raw-level routines 59656873Sakito */ 59754008Sfujita 59856873Sakito sioinit(sio0, rate) 59956873Sakito register struct siodevice *sio0; 60056873Sakito register int rate; 60156873Sakito { 60256873Sakito register struct siodevice *sio1; 60356873Sakito int s; 60454008Sfujita 60556873Sakito rate = ttspeedtab(rate, siospeedtab); 60654008Sfujita 60756873Sakito if (sio_init_done) 60856873Sakito return; 60954008Sfujita 61056873Sakito sio1 = (struct siodevice *) ((u_long) sio0 + sizeof(struct siodevice)); 61154008Sfujita 61254008Sfujita s = splhigh(); 61354008Sfujita 61456873Sakito sioreg(sio0, WR0, WR0_CHANRST); /* Channel-A Reset */ 61554008Sfujita 61656873Sakito sioreg(sio0, WR2, (WR2_VEC86 | WR2_INTR_1)); /* Set CPU BUS Interface Mode */ 61756873Sakito sioreg(sio1, WR2, 0); /* Set Interrupt Vector */ 61854008Sfujita 61956873Sakito sioreg(sio0, WR0, WR0_RSTINT); /* Reset E/S Interrupt */ 62056873Sakito sioreg(sio0, WR4, (rate | WR4_STOP1 | WR4_NPARITY)); /* Tx/Rx */ 62156873Sakito sioreg(sio0, WR3, (WR3_RX8BIT | WR3_RXENBL)); /* Rx */ 62256873Sakito sioreg(sio0, WR5, (WR5_TX8BIT | WR5_TXENBL)); /* Tx */ 62356873Sakito sioreg(sio0, WR0, WR0_RSTINT); /* Reset E/S Interrupt */ 62456873Sakito sioreg(sio0, WR1, (WR1_RXALLS | WR1_TXENBL)); 62554008Sfujita 62656873Sakito sioreg(sio1, WR0, WR0_CHANRST); /* Channel-B Reset */ 62754008Sfujita 62856873Sakito sioreg(sio1, WR0, WR0_RSTINT); /* Reset E/S Interrupt */ 62956873Sakito sioreg(sio1, WR4, (rate | WR4_STOP1 | WR4_NPARITY)); /* Tx/Rx */ 63056873Sakito sioreg(sio1, WR3, (WR3_RX8BIT | WR3_RXENBL)); /* Rx */ 63156873Sakito sioreg(sio1, WR5, (WR5_TX8BIT | WR5_TXENBL)); /* Tx */ 63256873Sakito sioreg(sio1, WR0, WR0_RSTINT); /* Reset E/S Interrupt */ 63356873Sakito sioreg(sio1, WR1, (WR1_RXALLS | WR1_TXENBL)); 63456873Sakito 63554008Sfujita splx(s); 63656873Sakito 63756873Sakito sio_init_done = 1; 63854008Sfujita } 63954008Sfujita 64056873Sakito sio_imgetc(sio) 64156873Sakito register struct siodevice *sio; 64254008Sfujita { 64356873Sakito register int rr0, rr1; 64456873Sakito int c, s; 64554008Sfujita 64656873Sakito s = splhigh(); 64756873Sakito while (((rr0 = sioreg(sio, RR0, 0)) & RR0_RXAVAIL) == 0) 64856873Sakito ; 64956873Sakito c = sio->sio_data; 65056873Sakito sioreg(sio, WR0, WR0_RSTPEND); 65156873Sakito splx(s); 65256873Sakito return (c); 65354008Sfujita } 65454008Sfujita 65556873Sakito sio_imputc(sio, c) 65656873Sakito register struct siodevice *sio; 65754008Sfujita int c; 65854008Sfujita { 65954008Sfujita register u_char code; 66056873Sakito register int rr; 66156873Sakito int s; 66254008Sfujita 66354008Sfujita s = splhigh(); 66454008Sfujita 66556873Sakito sioreg(sio, WR1, WR1_RXALLS); 66656873Sakito 66754008Sfujita do { 66854008Sfujita DELAY(1); 66956873Sakito rr = siogetreg(sio); 67054008Sfujita } while (!(rr & RR_TXRDY)); 67156873Sakito 67256873Sakito code = (c & 0xFF); 67354008Sfujita sio->sio_data = code; 67454008Sfujita 67554008Sfujita do { 67654008Sfujita DELAY(1); 67756873Sakito rr = siogetreg(sio); 67854008Sfujita } while (!(rr & RR_TXRDY)); 67954008Sfujita 68056873Sakito sioreg(sio, WR1, (WR1_RXALLS | WR1_TXENBL)); 68156873Sakito 68254008Sfujita splx(s); 68354008Sfujita } 68454008Sfujita 68556873Sakito /* 68656873Sakito * uPD7201A register operation 68756873Sakito */ 68854008Sfujita 68954008Sfujita int 69056873Sakito siogetreg(sio) 69156873Sakito register struct siodevice *sio; 69254008Sfujita { 69354008Sfujita register int rr = 0; 69454008Sfujita 69554008Sfujita rr = sio->sio_stat; 69654008Sfujita rr <<= 8; 69754008Sfujita sio->sio_cmd = 1; /* Select RR1 */ 69854008Sfujita rr |= sio->sio_stat; 69954008Sfujita 70054008Sfujita return(rr); 70154008Sfujita } 70254008Sfujita 70354008Sfujita int 70456873Sakito sioreg(sio, reg, val) 70556873Sakito register struct siodevice *sio; 70654008Sfujita register int reg, val; 70754008Sfujita { 70854008Sfujita if (isStatusReg(reg)) { 70956873Sakito if (reg != 0) 71056873Sakito sio->sio_cmd = reg; 71156873Sakito val = sio->sio_stat; 71254008Sfujita } else { 71356873Sakito if (reg != 0) 71456873Sakito sio->sio_cmd = reg; 71556873Sakito sio->sio_cmd = val; 71654008Sfujita } 71756873Sakito 71856873Sakito return(val); 71954008Sfujita } 72054008Sfujita #endif 721