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