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