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