kbd.c revision 1.45 1 /* $NetBSD: kbd.c,v 1.45 2003/08/07 16:26:42 agc 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.45 2003/08/07 16:26:42 agc 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 TIOCSPGRP:
495 if (*(int *)data != k->k_events.ev_io->p_pgid)
496 return EPERM;
497 return 0;
498
499 default:
500 return ENOTTY;
501 }
502
503 /* We identified the ioctl, but we do not handle it. */
504 return EOPNOTSUPP; /* misuse, but what the heck */
505 }
506
507 int
508 kbdpoll(dev_t dev, int events, struct proc *p)
509 {
510 return ev_poll (&kbd_softc.k_events, events, p);
511 }
512
513 int
514 kbdkqfilter(dev, kn)
515 dev_t dev;
516 struct knote *kn;
517 {
518
519 return (ev_kqfilter(&kbd_softc.k_events, kn));
520 }
521
522 void
523 kbdintr(int mask)
524 {
525 u_char c;
526 #ifdef KBDRESET
527 static int reset_warn;
528 #endif
529
530 /*
531 * now only invoked from generic CIA interrupt handler if there *is*
532 * a keyboard interrupt pending
533 */
534
535 c = ~ciaa.sdr; /* keyboard data is inverted */
536 /* ack */
537 ciaa.cra |= (1 << 6); /* serial line output */
538 #ifdef KBDRESET
539 if (reset_warn && c == 0xf0) {
540 #ifdef DEBUG
541 printf ("kbdintr: !!!! Reset Warning !!!!\n");
542 #endif
543 bootsync();
544 reset_warn = 0;
545 DELAY(30000000);
546 }
547 #endif
548 /* wait 200 microseconds (for bloody Cherry keyboards..) */
549 DELAY(2000); /* fudge delay a bit for some keyboards */
550 ciaa.cra &= ~(1 << 6);
551
552 /* process the character */
553 c = (c >> 1) | (c << 7); /* rotate right once */
554
555 #ifdef KBDRESET
556 if (c == 0x78) {
557 #ifdef DEBUG
558 printf ("kbdintr: Reset Warning started\n");
559 #endif
560 ++reset_warn;
561 return;
562 }
563 #endif
564 kbdstuffchar(c);
565 }
566
567 #ifdef DRACO
568 /* maps MF-II keycodes to Amiga keycodes */
569
570 const u_char drkbdtab[] = {
571 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x50,
572 0x45, 0xff, 0xff, 0xff, 0xff, 0x42, 0x00, 0x51,
573
574 0xff, 0x64, 0x60, 0x30, 0x63, 0x10, 0x01, 0x52,
575 0xff, 0x66, 0x31, 0x21, 0x20, 0x11, 0x02, 0x53,
576
577 0xff, 0x33, 0x32, 0x22, 0x12, 0x04, 0x03, 0x54,
578 0xff, 0x40, 0x34, 0x23, 0x14, 0x13, 0x05, 0x55,
579
580 0xff, 0x36, 0x35, 0x25, 0x24, 0x15, 0x06, 0x56,
581 0xff, 0x67, 0x37, 0x26, 0x16, 0x07, 0x08, 0x57,
582 /* --- */
583 0xff, 0x38, 0x27, 0x17, 0x18, 0x0a, 0x09, 0x58,
584 0xff, 0x39, 0x3a, 0x28, 0x29, 0x19, 0x0b, 0x59,
585
586 0xff, 0xff, 0x2a, 0x2b, 0x1a, 0x0c, 0x4b, 0xff,
587 0x65, 0x61, 0x44, 0x1b, 0xff, 0xff, 0x6f, 0xff,
588
589 0x4d, 0x4f, 0xff, 0x4c, 0x0d, 0xff, 0x41, 0x46,
590 0xff, 0x1d, 0x4e, 0x2d, 0x3d, 0x4a, 0x5f, 0x62,
591
592 0x0f, 0x3c, 0x1e, 0x2e, 0x2f, 0x3e, 0x5a, 0x5b,
593 0xff, 0x43, 0x1f, 0xff, 0x5e, 0x3f, 0x5c, 0xff,
594 /* --- */
595 0xff, 0xff, 0xff, 0xff, 0x5d
596 };
597 #endif
598
599
600 int
601 kbdgetcn(void)
602 {
603 int s;
604 u_char ints, mask, c, in;
605
606 #ifdef DRACO
607 if (is_draco() && kbd_softc.k_mf2) {
608 do {
609 c = 0;
610 s = spltty ();
611 while ((draco_ioct->io_status & DRSTAT_KBDRECV) == 0);
612 in = draco_ioct->io_kbddata;
613 draco_ioct->io_kbdrst = 0;
614 if (in == 0xF0) { /* release prefix */
615 c = 0x80;
616 while ((draco_ioct->io_status &
617 DRSTAT_KBDRECV) == 0);
618 in = draco_ioct->io_kbddata;
619 draco_ioct->io_kbdrst = 0;
620 }
621 splx(s);
622 #ifdef DRACORAWKEYDEBUG
623 printf("<%02x>", in);
624 #endif
625 c |= in>=sizeof(drkbdtab) ? 0xff : drkbdtab[in];
626 } while (c == 0xff);
627 return (c);
628 }
629 #endif
630 s = spltty();
631 for (ints = 0; ! ((mask = ciaa.icr) & CIA_ICR_SP);
632 ints |= mask) ;
633
634 in = ciaa.sdr;
635 c = ~in;
636
637 /* ack */
638 ciaa.cra |= (1 << 6); /* serial line output */
639 ciaa.sdr = 0xff; /* ack */
640 /* wait 200 microseconds */
641 DELAY(2000); /* XXXX only works as long as DELAY doesn't
642 * use a timer and waits.. */
643 ciaa.cra &= ~(1 << 6);
644 ciaa.sdr = in;
645
646 splx (s);
647 c = (c >> 1) | (c << 7);
648
649 /* take care that no CIA-interrupts are lost */
650 if (ints)
651 dispatch_cia_ints (0, ints);
652
653 return c;
654 }
655
656 void
657 kbdstuffchar(u_char c)
658 {
659 struct firm_event *fe;
660 struct kbd_softc *k = &kbd_softc;
661 int put;
662
663 #if NWSKBD>0
664 /*
665 * If we have attached a wskbd and not in polling mode and
666 * nobody has opened us directly, then send the keystroke
667 * to the wskbd.
668 */
669
670 if (kbd_softc.k_pollingmode == 0
671 && kbd_softc.k_wskbddev != NULL
672 && k->k_event_mode == 0) {
673 wskbd_input(kbd_softc.k_wskbddev,
674 KEY_UP(c) ?
675 WSCONS_EVENT_KEY_UP :
676 WSCONS_EVENT_KEY_DOWN,
677 KEY_CODE(c));
678 return;
679 }
680
681 #endif /* NWSKBD */
682
683 /*
684 * If not in event mode, deliver straight to ite to process
685 * key stroke
686 */
687
688 if (! k->k_event_mode) {
689 #if NITE>0
690 ite_filter (c, ITEFILT_TTY);
691 #endif
692 return;
693 }
694
695 /*
696 * Keyboard is generating events. Turn this keystroke into an
697 * event and put it in the queue. If the queue is full, the
698 * keystroke is lost (sorry!).
699 */
700
701 put = k->k_events.ev_put;
702 fe = &k->k_events.ev_q[put];
703 put = (put + 1) % EV_QSIZE;
704 if (put == k->k_events.ev_get) {
705 log(LOG_WARNING, "keyboard event queue overflow\n");
706 /* ??? */
707 return;
708 }
709 fe->id = KEY_CODE(c);
710 fe->value = KEY_UP(c) ? VKEY_UP : VKEY_DOWN;
711 fe->time = time;
712 k->k_events.ev_put = put;
713 EV_WAKEUP(&k->k_events);
714 }
715
716
717 #ifdef DRACO
718 void
719 drkbdintr(void)
720 {
721 u_char in;
722 struct kbd_softc *k = &kbd_softc;
723
724 in = draco_ioct->io_kbddata;
725 draco_ioct->io_kbdrst = 0;
726
727 if (in == 0xF0)
728 k->k_rlprfx = 0x80;
729 else {
730 kbdstuffchar(in>=sizeof(drkbdtab) ? 0xff :
731 drkbdtab[in] | k->k_rlprfx);
732 k->k_rlprfx = 0;
733 }
734 }
735
736 #endif
737
738
739 #if NWSKBD>0
740 /*
741 * These are the callback functions that are passed to wscons.
742 * They really don't do anything worth noting, just call the
743 * other functions above.
744 */
745
746 int
747 kbd_enable(void *c, int on)
748 {
749 /* Wonder what this is supposed to do... */
750 return (0);
751 }
752
753 void
754 kbd_set_leds(void *c, int leds)
755 {
756 }
757
758 int
759 kbd_ioctl(void *c, u_long cmd, caddr_t data, int flag, struct proc *p)
760 {
761 switch (cmd)
762 {
763 case WSKBDIO_COMPLEXBELL:
764 return 0;
765 case WSKBDIO_SETLEDS:
766 return 0;
767 case WSKBDIO_GETLEDS:
768 *(int*)data = 0;
769 return 0;
770 case WSKBDIO_GTYPE:
771 *(u_int*)data = WSKBD_TYPE_AMIGA;
772 return 0;
773 }
774
775 /*
776 * We are supposed to return EPASSTHROUGH to wscons if we didn't
777 * understand.
778 */
779 return (EPASSTHROUGH);
780 }
781
782 void
783 kbd_getc(void *c, u_int *type, int *data)
784 {
785 int key;
786
787 key = kbdgetcn();
788
789 *data = KEY_CODE(key);
790 *type = KEY_UP(key) ? WSCONS_EVENT_KEY_UP : WSCONS_EVENT_KEY_DOWN;
791 }
792
793 void
794 kbd_pollc(void *c, int on)
795 {
796 kbd_softc.k_pollingmode = on;
797 }
798
799 void
800 kbd_bell(void *c, u_int x, u_int y, u_int z)
801 {
802 }
803 #endif /* WSKBD */
804