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*57774Sakito * @(#)kbd.c 7.5 (Berkeley) 02/02/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__ 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*/ 12557293Sakito kbdclose(dev, flag, mode, p) 12657293Sakito dev_t dev; 12757293Sakito int flag, mode; 12857293Sakito struct proc *p; 12957293Sakito { 130*57774Sakito register struct siodevice *sio = kbd_pc->pc_addr; 13157293Sakito register struct sio_portc *pc; 13257293Sakito register struct tty *tp; 13357293Sakito register int unit, s; 134*57774Sakito 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(); 146*57774Sakito 147*57774Sakito while((rr = siogetreg(sio)) & RR_RXRDY) { 148*57774Sakito code = sio->sio_data; 149*57774Sakito DELAY(100); 150*57774Sakito } 151*57774Sakito 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 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 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 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; 209*57774Sakito 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 { 225*57774Sakito s = splhigh(); 22657293Sakito sio->sio_data = 0x20; /* disable mouse tracking */ 227*57774Sakito while((rr = siogetreg(sio)) & RR_RXRDY) { 228*57774Sakito code = sio->sio_data; 229*57774Sakito DELAY(100); 230*57774Sakito } 231*57774Sakito splx(s); 23256877Sakito } 23356877Sakito break; 23456877Sakito 23556877Sakito default: 23657293Sakito return (ENOTTY); 23756877Sakito } 23857293Sakito return (0); 23957293Sakito } 24056877Sakito 24157293Sakito /* 24257293Sakito * 24357293Sakito */ 24457293Sakito void 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 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 28557293Sakito rr = siogetreg(sio); 28657293Sakito 28757293Sakito if (rr & RR_RXRDY) { 28857293Sakito code = sio->sio_data; 28957293Sakito tp = &kbd_tty[0]; /* Keyboard */ 29057293Sakito if ((tp->t_state & TS_ISOPEN) != 0) 29157293Sakito (*linesw[tp->t_line].l_rint)(code, tp); 29257293Sakito } 29357293Sakito 29457293Sakito if (rr & RR_TXRDY) { 29557293Sakito sio->sio_cmd = WR0_RSTPEND; 29657293Sakito } 29757293Sakito } 29857293Sakito 29957293Sakito kbdselect(dev, rw, p) 30057293Sakito dev_t dev; 30157293Sakito int rw; 30257293Sakito struct proc *p; 30357293Sakito { 30457293Sakito register int unit = kbdunit(dev); 30557293Sakito register struct tty *tp; 30657293Sakito int nread; 30757293Sakito int s = spltty(); 30857293Sakito 30957293Sakito tp = &kbd_tty[unit]; 31057293Sakito 31157293Sakito switch (rw) { 31257293Sakito 31357293Sakito case FREAD: 31457293Sakito nread = ttnread(tp); 31557293Sakito if (nread > 0 || ((tp->t_cflag&CLOCAL) == 0 && (tp->t_state&TS_CARR_ON) == 0)) 31657293Sakito goto win; 31757293Sakito 31857293Sakito selrecord(p, &tp->t_rsel); 31957293Sakito break; 32057293Sakito 32157293Sakito case FWRITE: 32257293Sakito if (tp->t_outq.c_cc <= tp->t_lowat) 32357293Sakito goto win; 32457293Sakito selrecord(p, &tp->t_wsel); 32557293Sakito break; 32657293Sakito } 32757293Sakito splx(s); 32857293Sakito return (0); 32957293Sakito win: 33057293Sakito splx(s); 33157293Sakito return (1); 33257293Sakito } 333