xref: /csrg-svn/sys/luna68k/dev/sio.c (revision 57058)
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