xref: /csrg-svn/sys/luna68k/dev/kbd.c (revision 65037)
156877Sakito /*
256877Sakito  * Copyright (c) 1992 OMRON Corporation.
363192Sbostic  * Copyright (c) 1992, 1993
463192Sbostic  *	The Regents of the University of California.  All rights reserved.
556877Sakito  *
656877Sakito  * This code is derived from software contributed to Berkeley by
756877Sakito  * OMRON Corporation.
856877Sakito  *
956877Sakito  * %sccs.include.redist.c%
1056877Sakito  *
11*65037Sakito  *	@(#)kbd.c	8.2 (Berkeley) 12/06/93
1256877Sakito  */
1356877Sakito 
1456877Sakito /*
1557293Sakito  * kbd.c -- keyboard device driver
1657293Sakito  *	remade by A.Fujita, DEC-21-1992
1756877Sakito  */
1856877Sakito 
1957293Sakito #define NKBD	2
2056877Sakito 
2157060Sakito #include <sys/param.h>
2257293Sakito #include <sys/systm.h>
2357293Sakito #include <sys/ioctl.h>
2457293Sakito #include <sys/proc.h>
2557293Sakito #include <sys/tty.h>
2657293Sakito #include <sys/conf.h>
2757293Sakito #include <sys/file.h>
2857293Sakito #include <sys/uio.h>
2957293Sakito #include <sys/kernel.h>
3057293Sakito #include <sys/syslog.h>
3156877Sakito 
3257293Sakito #include <luna68k/dev/device.h>
3357293Sakito #include <luna68k/dev/sioreg.h>
3457293Sakito #include <luna68k/dev/siovar.h>
3557293Sakito #include <luna68k/dev/kbio.h>
3656877Sakito 
3757293Sakito extern	struct sio_portc *sio_port_assign();
3857293Sakito extern	struct sio_portc *sio_port_get();
3956877Sakito 
4057293Sakito struct	sio_softc kbd_softc[NKBD];
4157293Sakito struct	sio_portc kbd_sport;
4257293Sakito struct	sio_portc *kbd_pc;
4356877Sakito 
4457293Sakito int     kbdopen();
4557293Sakito void    kbdstart();
4657293Sakito int     kbdparam();
4757293Sakito int     kbdintr();
4857293Sakito 
4957293Sakito struct	tty kbd_tty[NKBD];
5057293Sakito 
5157293Sakito int	kbddefaultrate = B9600;				/* speed of console line is fixed */
5257293Sakito int	kbdmajor = 14;
5357293Sakito int	kbd_state = 0;
5457293Sakito 
5557293Sakito #define	kbdunit(x)		minor(x)
5657293Sakito 
5757293Sakito /*
5857293Sakito  *  entry routines
5957293Sakito  */
6057293Sakito 
6157293Sakito /* ARGSUSED */
6257293Sakito #ifdef __STDC__
kbdopen(dev_t dev,int flag,int mode,struct proc * p)6357293Sakito kbdopen(dev_t dev, int flag, int mode, struct proc *p)
6457293Sakito #else
6557293Sakito kbdopen(dev, flag, mode, p)
6657293Sakito 	dev_t dev;
6757293Sakito 	int flag, mode;
6857293Sakito 	struct proc *p;
6957293Sakito #endif
7056877Sakito {
7157293Sakito 	register struct tty *tp;
7257293Sakito 	register int unit, s;
7357293Sakito 	register struct sio_portc *pc;
7457293Sakito 	int error = 0;
7556877Sakito 
7657293Sakito 	unit = kbdunit(dev);
7756877Sakito 
7857293Sakito 	if (unit != 0)
7957293Sakito 		return (ENXIO);
8056877Sakito 
8157293Sakito 	if (kbd_state == 0) {
8257293Sakito 		s = splhigh();
8357293Sakito 		pc = sio_port_get(1);
8457293Sakito 		kbd_sport = *pc;
8557293Sakito 		kbd_pc = sio_port_assign(1, kbdmajor, unit, kbdintr);
8657293Sakito 		splx(s);
8757293Sakito 	}
8857293Sakito 	kbd_softc[unit].sc_pc = kbd_pc;
8957293Sakito 	kbd_state |= 1 << unit;
9056877Sakito 
9157293Sakito 	tp = &kbd_tty[unit];
9257293Sakito 	tp->t_oproc = kbdstart;
9357293Sakito 	tp->t_param = kbdparam;
9457293Sakito 	tp->t_dev = dev;
9557293Sakito 	if ((tp->t_state & TS_ISOPEN) == 0) {
9657293Sakito 		tp->t_state |= TS_WOPEN;
9757293Sakito 		ttychars(tp);
9857293Sakito 		if (tp->t_ispeed == 0) {
9957293Sakito /*
10057293Sakito 			tp->t_iflag = TTYDEF_IFLAG;
10157293Sakito 			tp->t_oflag = TTYDEF_OFLAG;
10257293Sakito 			tp->t_cflag = TTYDEF_CFLAG;
10357293Sakito 			tp->t_lflag = TTYDEF_LFLAG;
10457293Sakito  */
10557293Sakito 			tp->t_iflag = 0;
10657293Sakito 			tp->t_oflag = 0;
10757293Sakito 			tp->t_cflag = (CREAD | CS8 | HUPCL);
10857293Sakito 			tp->t_lflag = 0;
10956877Sakito 
11057293Sakito 			tp->t_ispeed = tp->t_ospeed = kbddefaultrate;
11157293Sakito 		}
11257293Sakito 		ttsetwater(tp);
11357293Sakito 	} else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0)
11457293Sakito 		return (EBUSY);
11556877Sakito 
11657293Sakito 	tp->t_state |= TS_CARR_ON;
11756877Sakito 
11857293Sakito 	if (error == 0)
11957293Sakito 		error = (*linesw[tp->t_line].l_open)(dev, tp);
12056877Sakito 
12157293Sakito 	return (error);
12257293Sakito }
12357293Sakito 
12457293Sakito /*ARGSUSED*/
kbdclose(dev,flag,mode,p)12557293Sakito kbdclose(dev, flag, mode, p)
12657293Sakito 	dev_t dev;
12757293Sakito 	int flag, mode;
12857293Sakito 	struct proc *p;
12957293Sakito {
13057774Sakito 	register struct siodevice *sio = kbd_pc->pc_addr;
13157293Sakito 	register struct	sio_portc *pc;
13257293Sakito 	register struct tty *tp;
13357293Sakito 	register int unit, s;
13457774Sakito 	int  code, rr;
13557293Sakito 
13657293Sakito 	unit = kbdunit(dev);
13757293Sakito 
13857293Sakito 	tp = &kbd_tty[unit];
13957293Sakito 	(*linesw[tp->t_line].l_close)(tp, flag);
14057293Sakito 	ttyclose(tp);
14157293Sakito 
14257293Sakito 	kbd_state &= ~(1 << unit);
14357293Sakito 
14457293Sakito 	if (kbd_state == 0) {
14557293Sakito 		s = splhigh();
14657774Sakito 
14757774Sakito 		while((rr = siogetreg(sio)) & RR_RXRDY) {
14857774Sakito 			code = sio->sio_data;
14957774Sakito 			DELAY(100);
15057774Sakito 		}
15157774Sakito 
15257293Sakito 		pc = &kbd_sport;
15357293Sakito 		(void) sio_port_assign(1, pc->pc_major, pc->pc_unit, pc->pc_intr);
15457293Sakito 		splx(s);
15557293Sakito 	}
15657293Sakito 
15757293Sakito 	return (0);
15857293Sakito }
15957293Sakito 
kbdread(dev,uio,flag)16057293Sakito kbdread(dev, uio, flag)
16157293Sakito 	dev_t dev;
16257293Sakito 	struct uio *uio;
16357293Sakito {
16457293Sakito 	register struct tty *tp = &kbd_tty[kbdunit(dev)];
16557293Sakito 
16657293Sakito 	return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
16757293Sakito }
16857293Sakito 
16957293Sakito int
kbdparam(tp,t)17057293Sakito kbdparam(tp, t)
17157293Sakito 	register struct tty *tp;
17257293Sakito 	register struct termios *t;
17357293Sakito {
17457293Sakito 	int unit = kbdunit(tp->t_dev);
17557293Sakito 	register struct sio_softc *sc = &kbd_softc[unit];
17657293Sakito 	register int cflag = t->c_cflag;
17757293Sakito 
17857293Sakito         /* and copy to tty */
17957293Sakito         tp->t_ispeed = t->c_ispeed;
18057293Sakito         tp->t_ospeed = t->c_ospeed;
18157293Sakito         tp->t_cflag = cflag;
18257293Sakito 
18357293Sakito 	/*
18457293Sakito 	 * change line speed
18557293Sakito 	 */
18657293Sakito 
18757293Sakito 	/*
18857293Sakito 	 * parity
18957293Sakito 	 */
19057293Sakito 
19157293Sakito 	/*
19257293Sakito 	 * stop bit
19357293Sakito 	 */
19457293Sakito 
19557293Sakito 	return (0);
19657293Sakito }
19757293Sakito 
kbdioctl(dev,cmd,data,flag,p)19857293Sakito kbdioctl(dev, cmd, data, flag, p)
19957293Sakito 	dev_t dev;
20057293Sakito 	int cmd;
20157293Sakito 	caddr_t data;
20257293Sakito 	int flag;
20357293Sakito 	struct proc *p;
20457293Sakito {
20557293Sakito 	register struct siodevice *sio = kbd_pc->pc_addr;
20657293Sakito 	register struct tty *tp;
20757293Sakito 	register int unit = kbdunit(dev);
20857293Sakito 	register int error;
20957774Sakito 	int code, rr, s;
21057293Sakito 
21157293Sakito 	tp = &kbd_tty[unit];
21257293Sakito 	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
21357293Sakito 	if (error >= 0)
21457293Sakito 		return (error);
21557293Sakito 	error = ttioctl(tp, cmd, data, flag);
21657293Sakito 	if (error >= 0)
21757293Sakito 		return (error);
21857293Sakito 
21957293Sakito 	switch (cmd) {
22057293Sakito 
22157293Sakito 	case KIOCMOUSE:
22257293Sakito 		if (*((int *) data)) {
22357293Sakito 			sio->sio_data = 0x60;	/* enable  mouse tracking */
22457293Sakito 		} else {
22557774Sakito 			s = splhigh();
22657293Sakito 			sio->sio_data = 0x20;	/* disable mouse tracking */
22757774Sakito 			while((rr = siogetreg(sio)) & RR_RXRDY) {
22857774Sakito 				code = sio->sio_data;
22957774Sakito 				DELAY(100);
23057774Sakito 			}
23157774Sakito 			splx(s);
23256877Sakito 		}
23356877Sakito 		break;
23456877Sakito 
23556877Sakito 	default:
23657293Sakito 		return (ENOTTY);
23756877Sakito 	}
23857293Sakito 	return (0);
23957293Sakito }
24056877Sakito 
24157293Sakito /*
24257293Sakito  *
24357293Sakito  */
24457293Sakito void
kbdstart(tp)24557293Sakito kbdstart(tp)
24657293Sakito 	register struct tty *tp;
24757293Sakito {
24857293Sakito 	register int unit;
24957293Sakito 	register struct siodevice *sio = kbd_pc->pc_addr;
25057293Sakito 	register int rr;
25157293Sakito 	int s, c;
25257293Sakito 
25357293Sakito 	s = spltty();
25456877Sakito 
25557293Sakito 	if (tp->t_state & (TS_TIMEOUT|TS_TTSTOP))
25657293Sakito 		goto out;
25757293Sakito 
25857293Sakito 	if (tp->t_outq.c_cc <= tp->t_lowat) {
25957293Sakito 		if (tp->t_state&TS_ASLEEP) {
26057293Sakito 			tp->t_state &= ~TS_ASLEEP;
26157293Sakito 			wakeup((caddr_t)&tp->t_outq);
26257293Sakito 		}
26357293Sakito 		selwakeup(&tp->t_wsel);
26456877Sakito 	}
26556877Sakito 
26657293Sakito 	if (tp->t_outq.c_cc != 0)
26757293Sakito 		c = getc(&tp->t_outq);
26857293Sakito 
26957293Sakito out:
27057293Sakito 	splx(s);
27156877Sakito }
27257293Sakito 
27357293Sakito /*
27457293Sakito  *  interrupt handling
27557293Sakito  */
27657293Sakito 
kbdintr(unit)27757293Sakito kbdintr(unit)
27857293Sakito 	register int unit;
27957293Sakito {
28057293Sakito 	register struct siodevice *sio = kbd_pc->pc_addr;
28157293Sakito 	register struct tty *tp;
28257293Sakito 	register u_char code;
28357293Sakito 	int s, rr;
28457293Sakito 
28557851Sakito 	tp = &kbd_tty[0];		/* Keyboard */
28657293Sakito 	rr = siogetreg(sio);
28757293Sakito 
28857293Sakito 	if (rr & RR_RXRDY) {
28957293Sakito 		code = sio->sio_data;
29057293Sakito 		if ((tp->t_state & TS_ISOPEN) != 0)
29157293Sakito 			(*linesw[tp->t_line].l_rint)(code, tp);
29257851Sakito 
29357851Sakito 		while ((rr = siogetreg(sio)) & RR_RXRDY) {
29457851Sakito 			code = sio->sio_data;
29557851Sakito 			if ((tp->t_state & TS_ISOPEN) != 0)
29657851Sakito 				(*linesw[tp->t_line].l_rint)(code, tp);
29757851Sakito 		}
29857293Sakito 	}
29957293Sakito 
30057293Sakito 	if (rr & RR_TXRDY) {
30157293Sakito 		sio->sio_cmd = WR0_RSTPEND;
30257293Sakito 	}
30357293Sakito }
304