Home | History | Annotate | Line # | Download | only in dev
kbd.c revision 1.46
      1 /*	$NetBSD: kbd.c,v 1.46 2003/09/21 19:16:48 jdolecek Exp $ */
      2 
      3 /*
      4  * Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  * 3. Neither the name of the University nor the names of its contributors
     16  *    may be used to endorse or promote products derived from this software
     17  *    without specific prior written permission.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     29  * SUCH DAMAGE.
     30  *
     31  *	kbd.c
     32  */
     33 
     34 #include <sys/cdefs.h>
     35 __KERNEL_RCSID(0, "$NetBSD: kbd.c,v 1.46 2003/09/21 19:16:48 jdolecek Exp $");
     36 
     37 #include <sys/param.h>
     38 #include <sys/systm.h>
     39 #include <sys/device.h>
     40 #include <sys/ioctl.h>
     41 #include <sys/tty.h>
     42 #include <sys/proc.h>
     43 #include <sys/file.h>
     44 #include <sys/kernel.h>
     45 #include <sys/syslog.h>
     46 #include <sys/signalvar.h>
     47 #include <sys/conf.h>
     48 #include <dev/cons.h>
     49 #include <machine/cpu.h>
     50 #include <amiga/amiga/device.h>
     51 #include <amiga/amiga/custom.h>
     52 #ifdef DRACO
     53 #include <m68k/asm_single.h>
     54 #include <amiga/amiga/drcustom.h>
     55 #endif
     56 #include <amiga/amiga/cia.h>
     57 #include <amiga/dev/itevar.h>
     58 #include <amiga/dev/kbdreg.h>
     59 #include <amiga/dev/kbdmap.h>
     60 #include <amiga/dev/event_var.h>
     61 #include <amiga/dev/vuid_event.h>
     62 
     63 #include "kbd.h"
     64 #include "ite.h"
     65 
     66 /* WSKBD */
     67 
     68 /*
     69  * If NWSKBD>0 we try to attach an wskbd device to us. What follows
     70  * is definitions of callback functions and structures that are passed
     71  * to wscons when initializing.
     72  */
     73 
     74 /*
     75  * Now with wscons this driver exhibits some weird behaviour.
     76  * It may act both as a driver of its own and the md part of the
     77  * wskbd driver. Therefore it can be accessed through /dev/kbd
     78  * and /dev/wskbd0 both.
     79  *
     80  * The data from they keyboard may end up in at least four different
     81  * places:
     82  * - If this driver has been opened (/dev/kbd) and the
     83  *   direct mode (TIOCDIRECT) has been set, data goes to
     84  *   the process who opened the device. Data will transmit itself
     85  *   as described by the firm_event structure.
     86  * - If wskbd support is compiled in and a wskbd driver has been
     87  *   attached then the data is sent to it. Wskbd in turn may
     88  *   - Send the data in the wscons_event form to a process that
     89  *     has opened /dev/wskbd0
     90  *   - Feed the data to a virtual terminal.
     91  * - If an ite is present the data may be fed to it.
     92  */
     93 
     94 #include "wskbd.h"
     95 
     96 #if NWSKBD>0
     97 #include <dev/wscons/wsconsio.h>
     98 #include <dev/wscons/wskbdvar.h>
     99 #include <dev/wscons/wsksymdef.h>
    100 #include <dev/wscons/wsksymvar.h>
    101 #include <amiga/dev/wskbdmap_amiga.h>
    102 
    103 /* accessops */
    104 int     kbd_enable(void *, int);
    105 void    kbd_set_leds(void *, int);
    106 int     kbd_ioctl(void *, u_long, caddr_t, int, struct proc *);
    107 
    108 /* console ops */
    109 void    kbd_getc(void *, u_int *, int *);
    110 void    kbd_pollc(void *, int);
    111 void    kbd_bell(void *, u_int, u_int, u_int);
    112 
    113 static struct wskbd_accessops kbd_accessops = {
    114 	kbd_enable,
    115 	kbd_set_leds,
    116 	kbd_ioctl
    117 };
    118 
    119 static struct wskbd_consops kbd_consops = {
    120 	kbd_getc,
    121 	kbd_pollc,
    122 	kbd_bell
    123 };
    124 
    125 /*
    126  * Pointer to keymaps. They are defined in wskbdmap_amiga.c.
    127  */
    128 static struct wskbd_mapdata kbd_mapdata = {
    129 	amigakbd_keydesctab,
    130 	KB_US
    131 };
    132 
    133 #endif /* WSKBD */
    134 
    135 struct kbd_softc {
    136 	int k_event_mode;	/* if true, collect events, else pass to ite */
    137 	struct evvar k_events;	/* event queue state */
    138 #ifdef DRACO
    139 	u_char k_rlprfx;	/* MF-II rel. prefix has been seen */
    140 	u_char k_mf2;
    141 #endif
    142 
    143 #if NWSKBD>0
    144 	struct device *k_wskbddev; /* pointer to wskbd for sending strokes */
    145 	int k_pollingmode;         /* polling mode on? whatever it isss... */
    146 #endif
    147 };
    148 struct kbd_softc kbd_softc;
    149 
    150 int kbdmatch(struct device *, struct cfdata *, void *);
    151 void kbdattach(struct device *, struct device *, void *);
    152 void kbdintr(int);
    153 void kbdstuffchar(u_char);
    154 
    155 int drkbdgetc(void);
    156 int drkbdrputc(u_int8_t);
    157 int drkbdputc(u_int8_t);
    158 int drkbdputc2(u_int8_t, u_int8_t);
    159 int drkbdwaitfor(int);
    160 
    161 CFATTACH_DECL(kbd, sizeof(struct device),
    162     kbdmatch, kbdattach, NULL, NULL);
    163 
    164 dev_type_open(kbdopen);
    165 dev_type_close(kbdclose);
    166 dev_type_read(kbdread);
    167 dev_type_ioctl(kbdioctl);
    168 dev_type_poll(kbdpoll);
    169 dev_type_kqfilter(kbdkqfilter);
    170 
    171 const struct cdevsw kbd_cdevsw = {
    172 	kbdopen, kbdclose, kbdread, nowrite, kbdioctl,
    173 	nostop, notty, kbdpoll, nommap, kbdkqfilter,
    174 };
    175 
    176 /*ARGSUSED*/
    177 int
    178 kbdmatch(struct device *pdp, struct cfdata *cfp, void *auxp)
    179 {
    180 
    181 	if (matchname((char *)auxp, "kbd"))
    182 		return(1);
    183 	return(0);
    184 }
    185 
    186 /*ARGSUSED*/
    187 void
    188 kbdattach(struct device *pdp, struct device *dp, void *auxp)
    189 {
    190 #ifdef DRACO
    191 	kbdenable();
    192 	if (kbd_softc.k_mf2)
    193 		printf(": QuickLogic type MF-II\n");
    194 	else
    195 		printf(": CIA A type Amiga\n");
    196 #else
    197 	printf(": CIA A type Amiga\n");
    198 #endif
    199 
    200 #if NWSKBD>0
    201 	if (dp != NULL) {
    202 		/*
    203 		 * Try to attach the wskbd.
    204 		 */
    205 		struct wskbddev_attach_args waa;
    206 
    207 		/* Maybe should be done before this?... */
    208 		wskbd_cnattach(&kbd_consops, NULL, &kbd_mapdata);
    209 
    210 		waa.console = 1;
    211 		waa.keymap = &kbd_mapdata;
    212 		waa.accessops = &kbd_accessops;
    213 		waa.accesscookie = NULL;
    214 		kbd_softc.k_wskbddev = config_found(dp, &waa, wskbddevprint);
    215 
    216 		kbd_softc.k_pollingmode = 0;
    217 	}
    218 	kbdenable();
    219 #endif /* WSKBD */
    220 }
    221 
    222 /* definitions for amiga keyboard encoding. */
    223 #define KEY_CODE(c)  ((c) & 0x7f)
    224 #define KEY_UP(c)    ((c) & 0x80)
    225 
    226 #define DATLO single_inst_bclr_b(draco_ioct->io_control, DRCNTRL_KBDDATOUT)
    227 #define DATHI single_inst_bset_b(draco_ioct->io_control, DRCNTRL_KBDDATOUT)
    228 
    229 #define CLKLO single_inst_bclr_b(draco_ioct->io_control, DRCNTRL_KBDCLKOUT)
    230 #define CLKHI single_inst_bset_b(draco_ioct->io_control, DRCNTRL_KBDCLKOUT)
    231 
    232 void
    233 kbdenable(void)
    234 {
    235 	static int kbd_inited = 0;
    236 
    237 	int s;
    238 
    239 #ifdef DRACO
    240 	int id;
    241 #endif
    242 	/*
    243 	 * collides with external ints from SCSI, watch out for this when
    244 	 * enabling/disabling interrupts there !!
    245 	 */
    246 	s = splhigh();	/* don't lower; might be called from early ddb */
    247 	if (kbd_inited) {
    248 		splx(s);
    249 		return;
    250 	}
    251 	kbd_inited = 1;
    252 #ifdef DRACO
    253 	if (is_draco()) {
    254 
    255 		CLKLO;
    256 		delay(5000);
    257 		draco_ioct->io_kbdrst = 0;
    258 
    259 		if (drkbdputc(0xf2))
    260 			goto LnoMFII;
    261 
    262 		id = drkbdgetc() << 8;
    263 		id |= drkbdgetc();
    264 
    265 		if (id != 0xab83)
    266 			goto LnoMFII;
    267 
    268 		if (drkbdputc2(0xf0, 3))	/* mode 3 */
    269 			goto LnoMFII;
    270 
    271 		if (drkbdputc(0xf8))		/* make/break, no typematic */
    272 			goto LnoMFII;
    273 
    274 		if (drkbdputc(0xf4))		/* enable */
    275 			goto LnoMFII;
    276 		kbd_softc.k_mf2 = 1;
    277 		single_inst_bclr_b(draco_ioct->io_control, DRCNTRL_KBDINTENA);
    278 
    279 		ciaa.icr = CIA_ICR_SP;  /* CIA SP interrupt disable */
    280 		ciaa.cra &= ~(1<<6);	/* serial line == input */
    281 		splx(s);
    282 		return;
    283 
    284 	LnoMFII:
    285 		kbd_softc.k_mf2 = 0;
    286 		single_inst_bset_b(*draco_intena, DRIRQ_INT2);
    287 		ciaa.icr = CIA_ICR_IR_SC | CIA_ICR_SP;
    288 					/* SP interrupt enable */
    289 		ciaa.cra &= ~(1<<6);	/* serial line == input */
    290 		splx(s);
    291 		return;
    292 
    293 	} else {
    294 #endif
    295 	custom.intena = INTF_SETCLR | INTF_PORTS;
    296 	ciaa.icr = CIA_ICR_IR_SC | CIA_ICR_SP;  /* SP interrupt enable */
    297 	ciaa.cra &= ~(1<<6);		/* serial line == input */
    298 #ifdef DRACO
    299 	}
    300 #endif
    301 	kbd_softc.k_event_mode = 0;
    302 	kbd_softc.k_events.ev_io = 0;
    303 	splx(s);
    304 }
    305 
    306 #ifdef DRACO
    307 /*
    308  * call this with kbd interrupt blocked
    309  */
    310 
    311 int
    312 drkbdgetc(void)
    313 {
    314 	u_int8_t in;
    315 
    316 	while ((draco_ioct->io_status & DRSTAT_KBDRECV) == 0);
    317 	in = draco_ioct->io_kbddata;
    318 	draco_ioct->io_kbdrst = 0;
    319 
    320 	return in;
    321 }
    322 
    323 #define WAIT0 if (drkbdwaitfor(0)) goto Ltimeout
    324 #define WAIT1 if (drkbdwaitfor(DRSTAT_KBDCLKIN)) goto Ltimeout
    325 
    326 int
    327 drkbdwaitfor(int bit)
    328 {
    329 	int i;
    330 
    331 
    332 
    333 	i = 60000;	/* about 50 ms max */
    334 
    335 	do {
    336 		if ((draco_ioct->io_status & DRSTAT_KBDCLKIN) == bit)
    337 			return 0;
    338 
    339 	} while (--i >= 0);
    340 
    341 	return 1;
    342 }
    343 
    344 /*
    345  * Output a raw byte to the keyboard (+ parity and stop bit).
    346  * return 0 on success, 1 on timeout.
    347  */
    348 int
    349 drkbdrputc(u_int8_t c)
    350 {
    351 	u_int8_t parity;
    352 	int bitcnt;
    353 
    354 	DATLO; CLKHI; WAIT1;
    355 	parity = 0;
    356 
    357 	for (bitcnt=7; bitcnt >= 0; bitcnt--) {
    358 		WAIT0;
    359 		if (c & 1) {
    360 			DATHI;
    361 		} else {
    362 			++parity;
    363 			DATLO;
    364 		}
    365 		c >>= 1;
    366 		WAIT1;
    367 	}
    368 	WAIT0;
    369 	/* parity bit */
    370 	if (parity & 1) {
    371 		DATLO;
    372 	} else {
    373 		DATHI;
    374 	}
    375 	WAIT1;
    376 	/* stop bit */
    377 	WAIT0; DATHI; WAIT1;
    378 
    379 	WAIT0; /* XXX should check the ack bit here... */
    380 	WAIT1;
    381 	draco_ioct->io_kbdrst = 0;
    382 	return 0;
    383 
    384 Ltimeout:
    385 	DATHI;
    386 	draco_ioct->io_kbdrst = 0;
    387 	return 1;
    388 }
    389 
    390 /*
    391  * Output one cooked byte to the keyboard, with wait for ACK or RESEND,
    392  * and retry if necessary. 0 == success, 1 == timeout
    393  */
    394 int
    395 drkbdputc(u_int8_t c)
    396 {
    397 	int rc;
    398 
    399 	do {
    400 		if (drkbdrputc(c))
    401 			return(-1);
    402 
    403 		rc = drkbdgetc();
    404 	} while (rc == 0xfe);
    405 	return (!(rc == 0xfa));
    406 }
    407 
    408 /*
    409  * same for twobyte sequence
    410  */
    411 
    412 int
    413 drkbdputc2(u_int8_t c1, u_int8_t c2)
    414 {
    415 	int rc;
    416 
    417 	do {
    418 		do {
    419 			if (drkbdrputc(c1))
    420 				return(-1);
    421 
    422 			rc = drkbdgetc();
    423 		} while (rc == 0xfe);
    424 		if (rc != 0xfa)
    425 			return (-1);
    426 
    427 		if (drkbdrputc(c2))
    428 			return(-1);
    429 
    430 		rc = drkbdgetc();
    431 	} while (rc == 0xfe);
    432 	return (!(rc == 0xfa));
    433 }
    434 #endif
    435 
    436 int
    437 kbdopen(dev_t dev, int flags, int mode, struct proc *p)
    438 {
    439 
    440 	kbdenable();
    441 	if (kbd_softc.k_events.ev_io)
    442 		return EBUSY;
    443 
    444 	kbd_softc.k_events.ev_io = p;
    445 	ev_init(&kbd_softc.k_events);
    446 	return (0);
    447 }
    448 
    449 int
    450 kbdclose(dev_t dev, int flags, int mode, struct proc *p)
    451 {
    452 
    453 	/* Turn off event mode, dump the queue */
    454 	kbd_softc.k_event_mode = 0;
    455 	ev_fini(&kbd_softc.k_events);
    456 	kbd_softc.k_events.ev_io = NULL;
    457 	return (0);
    458 }
    459 
    460 int
    461 kbdread(dev_t dev, struct uio *uio, int flags)
    462 {
    463 	return ev_read (&kbd_softc.k_events, uio, flags);
    464 }
    465 
    466 int
    467 kbdioctl(dev_t dev, u_long cmd, register caddr_t data, int flag,
    468          struct proc *p)
    469 {
    470 	register struct kbd_softc *k = &kbd_softc;
    471 
    472 	switch (cmd) {
    473 		case KIOCTRANS:
    474 			if (*(int *)data == TR_UNTRANS_EVENT)
    475 				return 0;
    476 			break;
    477 
    478 		case KIOCGTRANS:
    479 			/* Get translation mode */
    480 			*(int *)data = TR_UNTRANS_EVENT;
    481 			return 0;
    482 
    483 		case KIOCSDIRECT:
    484 			k->k_event_mode = *(int *)data;
    485 			return 0;
    486 
    487 		case FIONBIO:	/* we will remove this someday (soon???) */
    488 			return 0;
    489 
    490 		case FIOASYNC:
    491 			k->k_events.ev_async = *(int *)data != 0;
    492 			return 0;
    493 
    494 		case FIOSETOWN:
    495 			if (-*(int *)data != k->k_events.ev_io->p_pgid
    496 			    && *(int *)data != k->k_events.ev_io->p_pid)
    497 				return EPERM;
    498 			return 0;
    499 
    500 		case TIOCSPGRP:
    501 			if (*(int *)data != k->k_events.ev_io->p_pgid)
    502 				return EPERM;
    503 			return 0;
    504 
    505 		default:
    506 			return ENOTTY;
    507 	}
    508 
    509 	/* We identified the ioctl, but we do not handle it. */
    510 	return EOPNOTSUPP;	/* misuse, but what the heck */
    511 }
    512 
    513 int
    514 kbdpoll(dev_t dev, int events, struct proc *p)
    515 {
    516 	return ev_poll (&kbd_softc.k_events, events, p);
    517 }
    518 
    519 int
    520 kbdkqfilter(dev, kn)
    521 	dev_t dev;
    522 	struct knote *kn;
    523 {
    524 
    525 	return (ev_kqfilter(&kbd_softc.k_events, kn));
    526 }
    527 
    528 void
    529 kbdintr(int mask)
    530 {
    531 	u_char c;
    532 #ifdef KBDRESET
    533 	static int reset_warn;
    534 #endif
    535 
    536 	/*
    537 	 * now only invoked from generic CIA interrupt handler if there *is*
    538 	 * a keyboard interrupt pending
    539 	 */
    540 
    541 	c = ~ciaa.sdr;	/* keyboard data is inverted */
    542 	/* ack */
    543 	ciaa.cra |= (1 << 6);	/* serial line output */
    544 #ifdef KBDRESET
    545 	if (reset_warn && c == 0xf0) {
    546 #ifdef DEBUG
    547 		printf ("kbdintr: !!!! Reset Warning !!!!\n");
    548 #endif
    549 		bootsync();
    550 		reset_warn = 0;
    551 		DELAY(30000000);
    552 	}
    553 #endif
    554 	/* wait 200 microseconds (for bloody Cherry keyboards..) */
    555 	DELAY(2000);			/* fudge delay a bit for some keyboards */
    556 	ciaa.cra &= ~(1 << 6);
    557 
    558 	/* process the character */
    559 	c = (c >> 1) | (c << 7);	/* rotate right once */
    560 
    561 #ifdef KBDRESET
    562 	if (c == 0x78) {
    563 #ifdef DEBUG
    564 		printf ("kbdintr: Reset Warning started\n");
    565 #endif
    566 		++reset_warn;
    567 		return;
    568 	}
    569 #endif
    570 	kbdstuffchar(c);
    571 }
    572 
    573 #ifdef DRACO
    574 /* maps MF-II keycodes to Amiga keycodes */
    575 
    576 const u_char drkbdtab[] = {
    577 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x50,
    578 	0x45, 0xff, 0xff, 0xff, 0xff, 0x42, 0x00, 0x51,
    579 
    580 	0xff, 0x64, 0x60, 0x30, 0x63, 0x10, 0x01, 0x52,
    581 	0xff, 0x66, 0x31, 0x21, 0x20, 0x11, 0x02, 0x53,
    582 
    583 	0xff, 0x33, 0x32, 0x22, 0x12, 0x04, 0x03, 0x54,
    584 	0xff, 0x40, 0x34, 0x23, 0x14, 0x13, 0x05, 0x55,
    585 
    586 	0xff, 0x36, 0x35, 0x25, 0x24, 0x15, 0x06, 0x56,
    587 	0xff, 0x67, 0x37, 0x26, 0x16, 0x07, 0x08, 0x57,
    588 	/* --- */
    589 	0xff, 0x38, 0x27, 0x17, 0x18, 0x0a, 0x09, 0x58,
    590 	0xff, 0x39, 0x3a, 0x28, 0x29, 0x19, 0x0b, 0x59,
    591 
    592 	0xff, 0xff, 0x2a, 0x2b, 0x1a, 0x0c, 0x4b, 0xff,
    593 	0x65, 0x61, 0x44, 0x1b, 0xff, 0xff, 0x6f, 0xff,
    594 
    595 	0x4d, 0x4f, 0xff, 0x4c, 0x0d, 0xff, 0x41, 0x46,
    596 	0xff, 0x1d, 0x4e, 0x2d, 0x3d, 0x4a, 0x5f, 0x62,
    597 
    598 	0x0f, 0x3c, 0x1e, 0x2e, 0x2f, 0x3e, 0x5a, 0x5b,
    599 	0xff, 0x43, 0x1f, 0xff, 0x5e, 0x3f, 0x5c, 0xff,
    600 	/* --- */
    601 	0xff, 0xff, 0xff, 0xff, 0x5d
    602 };
    603 #endif
    604 
    605 
    606 int
    607 kbdgetcn(void)
    608 {
    609 	int s;
    610 	u_char ints, mask, c, in;
    611 
    612 #ifdef DRACO
    613 	if (is_draco() && kbd_softc.k_mf2) {
    614 		do {
    615 			c = 0;
    616 			s = spltty ();
    617 			while ((draco_ioct->io_status & DRSTAT_KBDRECV) == 0);
    618 			in = draco_ioct->io_kbddata;
    619 			draco_ioct->io_kbdrst = 0;
    620 			if (in == 0xF0) { /* release prefix */
    621 				c = 0x80;
    622 				while ((draco_ioct->io_status &
    623 				    DRSTAT_KBDRECV) == 0);
    624 				in = draco_ioct->io_kbddata;
    625 				draco_ioct->io_kbdrst = 0;
    626 			}
    627 			splx(s);
    628 #ifdef DRACORAWKEYDEBUG
    629 			printf("<%02x>", in);
    630 #endif
    631 			c |= in>=sizeof(drkbdtab) ? 0xff : drkbdtab[in];
    632 		} while (c == 0xff);
    633 		return (c);
    634 	}
    635 #endif
    636 	s = spltty();
    637 	for (ints = 0; ! ((mask = ciaa.icr) & CIA_ICR_SP);
    638 	    ints |= mask) ;
    639 
    640 	in = ciaa.sdr;
    641 	c = ~in;
    642 
    643 	/* ack */
    644 	ciaa.cra |= (1 << 6);	/* serial line output */
    645 	ciaa.sdr = 0xff;	/* ack */
    646 	/* wait 200 microseconds */
    647 	DELAY(2000);	/* XXXX only works as long as DELAY doesn't
    648 			 * use a timer and waits.. */
    649 	ciaa.cra &= ~(1 << 6);
    650 	ciaa.sdr = in;
    651 
    652 	splx (s);
    653 	c = (c >> 1) | (c << 7);
    654 
    655 	/* take care that no CIA-interrupts are lost */
    656 	if (ints)
    657 		dispatch_cia_ints (0, ints);
    658 
    659 	return c;
    660 }
    661 
    662 void
    663 kbdstuffchar(u_char c)
    664 {
    665 	struct firm_event *fe;
    666 	struct kbd_softc *k = &kbd_softc;
    667 	int put;
    668 
    669 #if NWSKBD>0
    670 	/*
    671 	 * If we have attached a wskbd and not in polling mode and
    672 	 * nobody has opened us directly, then send the keystroke
    673 	 * to the wskbd.
    674 	 */
    675 
    676 	if (kbd_softc.k_pollingmode == 0
    677 	    && kbd_softc.k_wskbddev != NULL
    678 	    && k->k_event_mode == 0) {
    679 		wskbd_input(kbd_softc.k_wskbddev,
    680 			    KEY_UP(c) ?
    681 			    WSCONS_EVENT_KEY_UP :
    682 			    WSCONS_EVENT_KEY_DOWN,
    683 			    KEY_CODE(c));
    684 		return;
    685 	}
    686 
    687 #endif /* NWSKBD */
    688 
    689 	/*
    690 	 * If not in event mode, deliver straight to ite to process
    691 	 * key stroke
    692 	 */
    693 
    694 	if (! k->k_event_mode) {
    695 #if NITE>0
    696 		ite_filter (c, ITEFILT_TTY);
    697 #endif
    698 		return;
    699 	}
    700 
    701 	/*
    702 	 * Keyboard is generating events. Turn this keystroke into an
    703 	 * event and put it in the queue. If the queue is full, the
    704 	 * keystroke is lost (sorry!).
    705 	 */
    706 
    707 	put = k->k_events.ev_put;
    708 	fe = &k->k_events.ev_q[put];
    709 	put = (put + 1) % EV_QSIZE;
    710 	if (put == k->k_events.ev_get) {
    711 		log(LOG_WARNING, "keyboard event queue overflow\n");
    712 			/* ??? */
    713 		return;
    714 	}
    715 	fe->id = KEY_CODE(c);
    716 	fe->value = KEY_UP(c) ? VKEY_UP : VKEY_DOWN;
    717 	fe->time = time;
    718 	k->k_events.ev_put = put;
    719 	EV_WAKEUP(&k->k_events);
    720 }
    721 
    722 
    723 #ifdef DRACO
    724 void
    725 drkbdintr(void)
    726 {
    727 	u_char in;
    728 	struct kbd_softc *k = &kbd_softc;
    729 
    730 	in = draco_ioct->io_kbddata;
    731 	draco_ioct->io_kbdrst = 0;
    732 
    733 	if (in == 0xF0)
    734 		k->k_rlprfx = 0x80;
    735 	else {
    736 		kbdstuffchar(in>=sizeof(drkbdtab) ? 0xff :
    737 		    drkbdtab[in] | k->k_rlprfx);
    738 		k->k_rlprfx = 0;
    739 	}
    740 }
    741 
    742 #endif
    743 
    744 
    745 #if NWSKBD>0
    746 /*
    747  * These are the callback functions that are passed to wscons.
    748  * They really don't do anything worth noting, just call the
    749  * other functions above.
    750  */
    751 
    752 int
    753 kbd_enable(void *c, int on)
    754 {
    755 	/* Wonder what this is supposed to do... */
    756 	return (0);
    757 }
    758 
    759 void
    760 kbd_set_leds(void *c, int leds)
    761 {
    762 }
    763 
    764 int
    765 kbd_ioctl(void *c, u_long cmd, caddr_t data, int flag, struct proc *p)
    766 {
    767 	switch (cmd)
    768 	{
    769 	case WSKBDIO_COMPLEXBELL:
    770 		return 0;
    771 	case WSKBDIO_SETLEDS:
    772 		return 0;
    773 	case WSKBDIO_GETLEDS:
    774 		*(int*)data = 0;
    775 		return 0;
    776 	case WSKBDIO_GTYPE:
    777 		*(u_int*)data = WSKBD_TYPE_AMIGA;
    778 		return 0;
    779 	}
    780 
    781 	/*
    782 	 * We are supposed to return EPASSTHROUGH to wscons if we didn't
    783 	 * understand.
    784 	 */
    785 	return (EPASSTHROUGH);
    786 }
    787 
    788 void
    789 kbd_getc(void *c, u_int *type, int *data)
    790 {
    791 	int key;
    792 
    793 	key = kbdgetcn();
    794 
    795 	*data = KEY_CODE(key);
    796 	*type = KEY_UP(key) ? WSCONS_EVENT_KEY_UP : WSCONS_EVENT_KEY_DOWN;
    797 }
    798 
    799 void
    800 kbd_pollc(void *c, int on)
    801 {
    802 	kbd_softc.k_pollingmode = on;
    803 }
    804 
    805 void
    806 kbd_bell(void *c, u_int x, u_int y, u_int z)
    807 {
    808 }
    809 #endif /* WSKBD */
    810