xref: /csrg-svn/sys/luna68k/dev/kbd.c (revision 57293)
156877Sakito /*
256877Sakito  * Copyright (c) 1992 OMRON Corporation.
356877Sakito  * Copyright (c) 1992 The Regents of the University of California.
456877Sakito  * 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*57293Sakito  *	@(#)kbd.c	7.3 (Berkeley) 12/25/92
1256877Sakito  */
1356877Sakito 
1456877Sakito /*
15*57293Sakito  * kbd.c -- keyboard device driver
16*57293Sakito  *	remade by A.Fujita, DEC-21-1992
1756877Sakito  */
1856877Sakito 
19*57293Sakito #define NKBD	2
2056877Sakito 
2157060Sakito #include <sys/param.h>
22*57293Sakito #include <sys/systm.h>
23*57293Sakito #include <sys/ioctl.h>
24*57293Sakito #include <sys/proc.h>
25*57293Sakito #include <sys/tty.h>
26*57293Sakito #include <sys/conf.h>
27*57293Sakito #include <sys/file.h>
28*57293Sakito #include <sys/uio.h>
29*57293Sakito #include <sys/kernel.h>
30*57293Sakito #include <sys/syslog.h>
3156877Sakito 
32*57293Sakito #include <luna68k/dev/device.h>
33*57293Sakito #include <luna68k/dev/sioreg.h>
34*57293Sakito #include <luna68k/dev/siovar.h>
35*57293Sakito #include <luna68k/dev/kbio.h>
3656877Sakito 
37*57293Sakito extern	struct sio_portc *sio_port_assign();
38*57293Sakito extern	struct sio_portc *sio_port_get();
3956877Sakito 
40*57293Sakito struct	sio_softc kbd_softc[NKBD];
41*57293Sakito struct	sio_portc kbd_sport;
42*57293Sakito struct	sio_portc *kbd_pc;
4356877Sakito 
44*57293Sakito int     kbdopen();
45*57293Sakito void    kbdstart();
46*57293Sakito int     kbdparam();
47*57293Sakito int     kbdintr();
48*57293Sakito 
49*57293Sakito struct	tty kbd_tty[NKBD];
50*57293Sakito 
51*57293Sakito int	kbddefaultrate = B9600;				/* speed of console line is fixed */
52*57293Sakito int	kbdmajor = 14;
53*57293Sakito int	kbd_state = 0;
54*57293Sakito 
55*57293Sakito #define	kbdunit(x)		minor(x)
56*57293Sakito 
57*57293Sakito /*
58*57293Sakito  *  entry routines
59*57293Sakito  */
60*57293Sakito 
61*57293Sakito /* ARGSUSED */
62*57293Sakito #ifdef __STDC__
63*57293Sakito kbdopen(dev_t dev, int flag, int mode, struct proc *p)
64*57293Sakito #else
65*57293Sakito kbdopen(dev, flag, mode, p)
66*57293Sakito 	dev_t dev;
67*57293Sakito 	int flag, mode;
68*57293Sakito 	struct proc *p;
69*57293Sakito #endif
7056877Sakito {
71*57293Sakito 	register struct tty *tp;
72*57293Sakito 	register int unit, s;
73*57293Sakito 	register struct sio_portc *pc;
74*57293Sakito 	int error = 0;
7556877Sakito 
76*57293Sakito 	unit = kbdunit(dev);
7756877Sakito 
78*57293Sakito 	if (unit != 0)
79*57293Sakito 		return (ENXIO);
8056877Sakito 
81*57293Sakito 	if (kbd_state == 0) {
82*57293Sakito 		s = splhigh();
83*57293Sakito 		pc = sio_port_get(1);
84*57293Sakito 		kbd_sport = *pc;
85*57293Sakito 		kbd_pc = sio_port_assign(1, kbdmajor, unit, kbdintr);
86*57293Sakito 		splx(s);
87*57293Sakito 	}
88*57293Sakito 	kbd_softc[unit].sc_pc = kbd_pc;
89*57293Sakito 	kbd_state |= 1 << unit;
9056877Sakito 
91*57293Sakito 	tp = &kbd_tty[unit];
92*57293Sakito 	tp->t_oproc = kbdstart;
93*57293Sakito 	tp->t_param = kbdparam;
94*57293Sakito 	tp->t_dev = dev;
95*57293Sakito 	if ((tp->t_state & TS_ISOPEN) == 0) {
96*57293Sakito 		tp->t_state |= TS_WOPEN;
97*57293Sakito 		ttychars(tp);
98*57293Sakito 		if (tp->t_ispeed == 0) {
99*57293Sakito /*
100*57293Sakito 			tp->t_iflag = TTYDEF_IFLAG;
101*57293Sakito 			tp->t_oflag = TTYDEF_OFLAG;
102*57293Sakito 			tp->t_cflag = TTYDEF_CFLAG;
103*57293Sakito 			tp->t_lflag = TTYDEF_LFLAG;
104*57293Sakito  */
105*57293Sakito 			tp->t_iflag = 0;
106*57293Sakito 			tp->t_oflag = 0;
107*57293Sakito 			tp->t_cflag = (CREAD | CS8 | HUPCL);
108*57293Sakito 			tp->t_lflag = 0;
10956877Sakito 
110*57293Sakito 			tp->t_ispeed = tp->t_ospeed = kbddefaultrate;
111*57293Sakito 		}
112*57293Sakito 		ttsetwater(tp);
113*57293Sakito 	} else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0)
114*57293Sakito 		return (EBUSY);
11556877Sakito 
116*57293Sakito 	tp->t_state |= TS_CARR_ON;
11756877Sakito 
118*57293Sakito 	if (error == 0)
119*57293Sakito 		error = (*linesw[tp->t_line].l_open)(dev, tp);
12056877Sakito 
121*57293Sakito 	return (error);
122*57293Sakito }
123*57293Sakito 
124*57293Sakito /*ARGSUSED*/
125*57293Sakito kbdclose(dev, flag, mode, p)
126*57293Sakito 	dev_t dev;
127*57293Sakito 	int flag, mode;
128*57293Sakito 	struct proc *p;
129*57293Sakito {
130*57293Sakito 	register struct	sio_portc *pc;
131*57293Sakito 	register struct tty *tp;
132*57293Sakito 	register int unit, s;
133*57293Sakito 
134*57293Sakito 	unit = kbdunit(dev);
135*57293Sakito 
136*57293Sakito 	tp = &kbd_tty[unit];
137*57293Sakito 	(*linesw[tp->t_line].l_close)(tp, flag);
138*57293Sakito 	ttyclose(tp);
139*57293Sakito 
140*57293Sakito 	kbd_state &= ~(1 << unit);
141*57293Sakito 
142*57293Sakito 	if (kbd_state == 0) {
143*57293Sakito 		s = splhigh();
144*57293Sakito 		pc = &kbd_sport;
145*57293Sakito 		(void) sio_port_assign(1, pc->pc_major, pc->pc_unit, pc->pc_intr);
146*57293Sakito 		splx(s);
147*57293Sakito 	}
148*57293Sakito 
149*57293Sakito 	return (0);
150*57293Sakito }
151*57293Sakito 
152*57293Sakito kbdread(dev, uio, flag)
153*57293Sakito 	dev_t dev;
154*57293Sakito 	struct uio *uio;
155*57293Sakito {
156*57293Sakito 	register struct tty *tp = &kbd_tty[kbdunit(dev)];
157*57293Sakito 
158*57293Sakito 	return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
159*57293Sakito }
160*57293Sakito 
161*57293Sakito int
162*57293Sakito kbdparam(tp, t)
163*57293Sakito 	register struct tty *tp;
164*57293Sakito 	register struct termios *t;
165*57293Sakito {
166*57293Sakito 	int unit = kbdunit(tp->t_dev);
167*57293Sakito 	register struct sio_softc *sc = &kbd_softc[unit];
168*57293Sakito 	register int cflag = t->c_cflag;
169*57293Sakito 
170*57293Sakito         /* and copy to tty */
171*57293Sakito         tp->t_ispeed = t->c_ispeed;
172*57293Sakito         tp->t_ospeed = t->c_ospeed;
173*57293Sakito         tp->t_cflag = cflag;
174*57293Sakito 
175*57293Sakito 	/*
176*57293Sakito 	 * change line speed
177*57293Sakito 	 */
178*57293Sakito 
179*57293Sakito 	/*
180*57293Sakito 	 * parity
181*57293Sakito 	 */
182*57293Sakito 
183*57293Sakito 	/*
184*57293Sakito 	 * stop bit
185*57293Sakito 	 */
186*57293Sakito 
187*57293Sakito 	return (0);
188*57293Sakito }
189*57293Sakito 
190*57293Sakito kbdioctl(dev, cmd, data, flag, p)
191*57293Sakito 	dev_t dev;
192*57293Sakito 	int cmd;
193*57293Sakito 	caddr_t data;
194*57293Sakito 	int flag;
195*57293Sakito 	struct proc *p;
196*57293Sakito {
197*57293Sakito 	register struct siodevice *sio = kbd_pc->pc_addr;
198*57293Sakito 	register struct tty *tp;
199*57293Sakito 	register int unit = kbdunit(dev);
200*57293Sakito 	register int error;
201*57293Sakito 
202*57293Sakito 	tp = &kbd_tty[unit];
203*57293Sakito 	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
204*57293Sakito 	if (error >= 0)
205*57293Sakito 		return (error);
206*57293Sakito 	error = ttioctl(tp, cmd, data, flag);
207*57293Sakito 	if (error >= 0)
208*57293Sakito 		return (error);
209*57293Sakito 
210*57293Sakito 	switch (cmd) {
211*57293Sakito 
212*57293Sakito 	case KIOCMOUSE:
213*57293Sakito 		if (*((int *) data)) {
214*57293Sakito 			sio->sio_data = 0x60;	/* enable  mouse tracking */
215*57293Sakito 		} else {
216*57293Sakito 			sio->sio_data = 0x20;	/* disable mouse tracking */
21756877Sakito 		}
21856877Sakito 		break;
21956877Sakito 
22056877Sakito 	default:
221*57293Sakito 		return (ENOTTY);
22256877Sakito 	}
223*57293Sakito 	return (0);
224*57293Sakito }
22556877Sakito 
226*57293Sakito /*
227*57293Sakito  *
228*57293Sakito  */
229*57293Sakito void
230*57293Sakito kbdstart(tp)
231*57293Sakito 	register struct tty *tp;
232*57293Sakito {
233*57293Sakito 	register int unit;
234*57293Sakito 	register struct siodevice *sio = kbd_pc->pc_addr;
235*57293Sakito 	register int rr;
236*57293Sakito 	int s, c;
237*57293Sakito 
238*57293Sakito 	s = spltty();
23956877Sakito 
240*57293Sakito 	if (tp->t_state & (TS_TIMEOUT|TS_TTSTOP))
241*57293Sakito 		goto out;
242*57293Sakito 
243*57293Sakito 	if (tp->t_outq.c_cc <= tp->t_lowat) {
244*57293Sakito 		if (tp->t_state&TS_ASLEEP) {
245*57293Sakito 			tp->t_state &= ~TS_ASLEEP;
246*57293Sakito 			wakeup((caddr_t)&tp->t_outq);
247*57293Sakito 		}
248*57293Sakito 		selwakeup(&tp->t_wsel);
24956877Sakito 	}
25056877Sakito 
251*57293Sakito 	if (tp->t_outq.c_cc != 0)
252*57293Sakito 		c = getc(&tp->t_outq);
253*57293Sakito 
254*57293Sakito out:
255*57293Sakito 	splx(s);
25656877Sakito }
257*57293Sakito 
258*57293Sakito /*
259*57293Sakito  *  interrupt handling
260*57293Sakito  */
261*57293Sakito 
262*57293Sakito kbdintr(unit)
263*57293Sakito 	register int unit;
264*57293Sakito {
265*57293Sakito 	register struct siodevice *sio = kbd_pc->pc_addr;
266*57293Sakito 	register struct tty *tp;
267*57293Sakito 	register u_char code;
268*57293Sakito 	int s, rr;
269*57293Sakito 
270*57293Sakito 	rr = siogetreg(sio);
271*57293Sakito 
272*57293Sakito 	if (rr & RR_RXRDY) {
273*57293Sakito 		code = sio->sio_data;
274*57293Sakito 		tp = &kbd_tty[0];		/* Keyboard */
275*57293Sakito 		if ((tp->t_state & TS_ISOPEN) != 0)
276*57293Sakito 			(*linesw[tp->t_line].l_rint)(code, tp);
277*57293Sakito 	}
278*57293Sakito 
279*57293Sakito 	if (rr & RR_TXRDY) {
280*57293Sakito 		sio->sio_cmd = WR0_RSTPEND;
281*57293Sakito 		tp->t_state &= ~(TS_BUSY|TS_FLUSH);
282*57293Sakito 		if (tp->t_line)
283*57293Sakito 			(*linesw[tp->t_line].l_start)(tp);
284*57293Sakito 		else
285*57293Sakito 			kbdstart(tp);
286*57293Sakito 	}
287*57293Sakito }
288*57293Sakito 
289*57293Sakito kbdselect(dev, rw, p)
290*57293Sakito 	dev_t dev;
291*57293Sakito 	int rw;
292*57293Sakito 	struct proc *p;
293*57293Sakito {
294*57293Sakito 	register int unit = kbdunit(dev);
295*57293Sakito 	register struct tty *tp;
296*57293Sakito 	int nread;
297*57293Sakito 	int s = spltty();
298*57293Sakito 
299*57293Sakito 	tp = &kbd_tty[unit];
300*57293Sakito 
301*57293Sakito 	switch (rw) {
302*57293Sakito 
303*57293Sakito 	case FREAD:
304*57293Sakito 		nread = ttnread(tp);
305*57293Sakito 		if (nread > 0 || ((tp->t_cflag&CLOCAL) == 0 && (tp->t_state&TS_CARR_ON) == 0))
306*57293Sakito 			goto win;
307*57293Sakito 
308*57293Sakito 		selrecord(p, &tp->t_rsel);
309*57293Sakito 		break;
310*57293Sakito 
311*57293Sakito 	case FWRITE:
312*57293Sakito 		if (tp->t_outq.c_cc <= tp->t_lowat)
313*57293Sakito 			goto win;
314*57293Sakito 		selrecord(p, &tp->t_wsel);
315*57293Sakito 		break;
316*57293Sakito 	}
317*57293Sakito 	splx(s);
318*57293Sakito 	return (0);
319*57293Sakito win:
320*57293Sakito 	splx(s);
321*57293Sakito 	return (1);
322*57293Sakito }
323