]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - sys/dev/adb/adb_kbd.c
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / sys / dev / adb / adb_kbd.c
1 /*-
2  * Copyright (C) 2008 Nathan Whitehorn
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
18  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
20  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
21  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
22  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
23  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  * $FreeBSD$
26  */
27
28 #include <sys/cdefs.h>
29 #include <sys/param.h>
30 #include <sys/systm.h>
31 #include <sys/module.h>
32 #include <sys/bus.h>
33 #include <sys/conf.h>
34 #include <sys/kbio.h>
35 #include <sys/condvar.h>
36 #include <sys/callout.h>
37 #include <sys/kernel.h>
38
39 #include <machine/bus.h>
40
41 #include "opt_kbd.h"
42 #include <dev/kbd/kbdreg.h>
43 #include <dev/kbd/kbdtables.h>
44
45 #include <vm/vm.h>
46 #include <vm/pmap.h>
47
48 #include "adb.h"
49
50 #define KBD_DRIVER_NAME "akbd"
51
52 #define AKBD_EMULATE_ATKBD 1
53
54 static int adb_kbd_probe(device_t dev);
55 static int adb_kbd_attach(device_t dev);
56 static int adb_kbd_detach(device_t dev);
57 static void akbd_repeat(void *xsc);
58
59 static u_int adb_kbd_receive_packet(device_t dev, u_char status, 
60         u_char command, u_char reg, int len, u_char *data);
61
62 struct adb_kbd_softc {
63         keyboard_t sc_kbd;
64
65         device_t sc_dev;
66         struct mtx sc_mutex;
67         struct cv  sc_cv;
68
69         int sc_mode;
70         int sc_state;
71
72         int have_led_control;
73
74         uint8_t buffer[8];
75 #ifdef AKBD_EMULATE_ATKBD
76         uint8_t at_buffered_char[2];
77 #endif
78         volatile int buffers;
79
80         struct callout sc_repeater;
81         int sc_repeatstart;
82         int sc_repeatcontinue;
83         uint8_t last_press;
84 };
85
86 static device_method_t adb_kbd_methods[] = {
87         /* Device interface */
88         DEVMETHOD(device_probe,         adb_kbd_probe),
89         DEVMETHOD(device_attach,        adb_kbd_attach),
90         DEVMETHOD(device_detach,        adb_kbd_detach),
91         DEVMETHOD(device_shutdown,      bus_generic_shutdown),
92         DEVMETHOD(device_suspend,       bus_generic_suspend),
93         DEVMETHOD(device_resume,        bus_generic_resume),
94
95         /* ADB interface */
96         DEVMETHOD(adb_receive_packet,   adb_kbd_receive_packet),
97
98         { 0, 0 }
99 };
100
101 static driver_t adb_kbd_driver = {
102         "akbd",
103         adb_kbd_methods,
104         sizeof(struct adb_kbd_softc),
105 };
106
107 static devclass_t adb_kbd_devclass;
108
109 DRIVER_MODULE(akbd, adb, adb_kbd_driver, adb_kbd_devclass, 0, 0);
110
111 #ifdef AKBD_EMULATE_ATKBD
112
113 #define SCAN_PRESS              0x000
114 #define SCAN_RELEASE            0x080
115 #define SCAN_PREFIX_E0          0x100
116 #define SCAN_PREFIX_E1          0x200
117 #define SCAN_PREFIX_CTL         0x400
118 #define SCAN_PREFIX_SHIFT       0x800
119 #define SCAN_PREFIX             (SCAN_PREFIX_E0 | SCAN_PREFIX_E1 |      \
120                                 SCAN_PREFIX_CTL | SCAN_PREFIX_SHIFT)
121
122 static const uint8_t adb_to_at_scancode_map[128] = { 30, 31, 32, 33, 35, 34, 
123         44, 45, 46, 47, 0, 48, 16, 17, 18, 19, 21, 20, 2, 3, 4, 5, 7, 6, 13, 
124         10, 8, 12, 9, 11, 27, 24, 22, 26, 23, 25, 28, 38, 36, 40, 37, 39, 43, 
125         51, 53, 49, 50, 52, 15, 57, 41, 14, 0, 1, 29, 0, 42, 58, 56, 97, 98, 
126         100, 95, 0, 0, 83, 0, 55, 0, 78, 0, 69, 0, 0, 0, 91, 89, 0, 74, 13, 0, 
127         0, 82, 79, 80, 81, 75, 76, 77, 71, 0, 72, 73, 0, 0, 0, 63, 64, 65, 61, 
128         66, 67, 0, 87, 0, 105, 0, 70, 0, 68, 0, 88, 0, 107, 102, 94, 96, 103, 
129         62, 99, 60, 101, 59, 54, 93, 90, 0, 0 };
130
131 static int
132 keycode2scancode(int keycode, int shift, int up)
133 {
134         static const int scan[] = {
135                 /* KP enter, right ctrl, KP divide */
136                 0x1c , 0x1d , 0x35 ,
137                 /* print screen */
138                 0x37 | SCAN_PREFIX_SHIFT,
139                 /* right alt, home, up, page up, left, right, end */
140                 0x38, 0x47, 0x48, 0x49, 0x4b, 0x4d, 0x4f,
141                 /* down, page down, insert, delete */
142                 0x50, 0x51, 0x52, 0x53,
143                 /* pause/break (see also below) */
144                 0x46,
145                 /*
146                  * MS: left window, right window, menu
147                  * also Sun: left meta, right meta, compose
148                  */
149                 0x5b, 0x5c, 0x5d,
150                 /* Sun type 6 USB */
151                 /* help, stop, again, props, undo, front, copy */
152                 0x68, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63,
153                 /* open, paste, find, cut, audiomute, audiolower, audioraise */
154                 0x64, 0x65, 0x66, 0x67, 0x25, 0x1f, 0x1e,
155                 /* power */
156                 0x20
157         };
158         int scancode;
159
160         scancode = keycode;
161         if ((keycode >= 89) && (keycode < 89 + sizeof(scan) / sizeof(scan[0])))
162         scancode = scan[keycode - 89] | SCAN_PREFIX_E0;
163         /* pause/break */
164         if ((keycode == 104) && !(shift & CTLS))
165                 scancode = 0x45 | SCAN_PREFIX_E1 | SCAN_PREFIX_CTL;
166         if (shift & SHIFTS)
167                 scancode &= ~SCAN_PREFIX_SHIFT;
168         return (scancode | (up ? SCAN_RELEASE : SCAN_PRESS));
169 }
170 #endif
171
172 /* keyboard driver declaration */
173 static int              akbd_configure(int flags);
174 static kbd_probe_t      akbd_probe;
175 static kbd_init_t       akbd_init;
176 static kbd_term_t       akbd_term;
177 static kbd_intr_t       akbd_interrupt;
178 static kbd_test_if_t    akbd_test_if;
179 static kbd_enable_t     akbd_enable;
180 static kbd_disable_t    akbd_disable;
181 static kbd_read_t       akbd_read;
182 static kbd_check_t      akbd_check;
183 static kbd_read_char_t  akbd_read_char;
184 static kbd_check_char_t akbd_check_char;
185 static kbd_ioctl_t      akbd_ioctl;
186 static kbd_lock_t       akbd_lock;
187 static kbd_clear_state_t akbd_clear_state;
188 static kbd_get_state_t  akbd_get_state;
189 static kbd_set_state_t  akbd_set_state;
190 static kbd_poll_mode_t  akbd_poll;
191
192 keyboard_switch_t akbdsw = {
193         akbd_probe,
194         akbd_init,
195         akbd_term,
196         akbd_interrupt,
197         akbd_test_if,
198         akbd_enable,
199         akbd_disable,
200         akbd_read,
201         akbd_check,
202         akbd_read_char,
203         akbd_check_char,
204         akbd_ioctl,
205         akbd_lock,
206         akbd_clear_state,
207         akbd_get_state,
208         akbd_set_state,
209         genkbd_get_fkeystr,
210         akbd_poll,
211         genkbd_diag,
212 };
213
214 KEYBOARD_DRIVER(akbd, akbdsw, akbd_configure);
215
216 static int 
217 adb_kbd_probe(device_t dev) 
218 {
219         uint8_t type;
220
221         type = adb_get_device_type(dev);
222
223         if (type != ADB_DEVICE_KEYBOARD)
224                 return (ENXIO);
225
226         switch(adb_get_device_handler(dev)) {
227         case 1:
228                 device_set_desc(dev,"Apple Standard Keyboard");
229                 break;
230         case 2:
231                 device_set_desc(dev,"Apple Extended Keyboard");
232                 break;
233         case 4:
234                 device_set_desc(dev,"Apple ISO Keyboard");
235                 break;
236         case 5:
237                 device_set_desc(dev,"Apple Extended ISO Keyboard");
238                 break;
239         case 8:
240                 device_set_desc(dev,"Apple Keyboard II");
241                 break;
242         case 9:
243                 device_set_desc(dev,"Apple ISO Keyboard II");
244                 break;
245         case 12:
246                 device_set_desc(dev,"PowerBook Keyboard");
247                 break;
248         case 13:
249                 device_set_desc(dev,"PowerBook ISO Keyboard");
250                 break;
251         case 24:
252                 device_set_desc(dev,"PowerBook Extended Keyboard");
253                 break;
254         case 27:
255                 device_set_desc(dev,"Apple Design Keyboard");
256                 break;
257         case 195:
258                 device_set_desc(dev,"PowerBook G3 Keyboard");
259                 break;
260         case 196:
261                 device_set_desc(dev,"iBook Keyboard");
262                 break;
263         default:
264                 device_set_desc(dev,"ADB Keyboard");
265                 break;
266         }
267
268         return (0);
269 }
270
271 static int
272 ms_to_ticks(int ms)
273 {
274         if (hz > 1000)
275                 return ms*(hz/1000);
276
277         return ms/(1000/hz);
278 }
279         
280 static int 
281 adb_kbd_attach(device_t dev) 
282 {
283         struct adb_kbd_softc *sc;
284         keyboard_switch_t *sw;
285
286         sw = kbd_get_switch(KBD_DRIVER_NAME);
287         if (sw == NULL) {
288                 return ENXIO;
289         }
290
291         sc = device_get_softc(dev);
292         sc->sc_dev = dev;
293         sc->sc_mode = K_RAW;
294         sc->sc_state = 0;
295         sc->have_led_control = 0;
296         sc->buffers = 0;
297
298         /* Try stepping forward to the extended keyboard protocol */
299         adb_set_device_handler(dev,3);
300
301         mtx_init(&sc->sc_mutex,KBD_DRIVER_NAME,MTX_DEF,0);
302         cv_init(&sc->sc_cv,KBD_DRIVER_NAME);
303         callout_init(&sc->sc_repeater, 0);
304
305 #ifdef AKBD_EMULATE_ATKBD
306         kbd_init_struct(&sc->sc_kbd, KBD_DRIVER_NAME, KB_101, 0, 0, 0, 0);
307         kbd_set_maps(&sc->sc_kbd, &key_map, &accent_map, fkey_tab,
308             sizeof(fkey_tab) / sizeof(fkey_tab[0]));
309 #else
310         #error ADB raw mode not implemented
311 #endif
312
313         KBD_FOUND_DEVICE(&sc->sc_kbd);
314         KBD_PROBE_DONE(&sc->sc_kbd);
315         KBD_INIT_DONE(&sc->sc_kbd);
316         KBD_CONFIG_DONE(&sc->sc_kbd);
317
318         (*sw->enable)(&sc->sc_kbd);
319
320         kbd_register(&sc->sc_kbd);
321
322 #ifdef KBD_INSTALL_CDEV
323         if (kbd_attach(&sc->sc_kbd)) {
324                 adb_kbd_detach(dev);
325                 return ENXIO;
326         }
327 #endif
328
329         /* Check if we can read out the LED state from 
330            this keyboard by reading the key state register */
331         if (adb_read_register(dev, 2, NULL) == 2)
332                 sc->have_led_control = 1;
333
334         adb_set_autopoll(dev,1);
335
336         return (0);
337 }
338
339 static int 
340 adb_kbd_detach(device_t dev) 
341 {
342         struct adb_kbd_softc *sc;
343         keyboard_t *kbd;
344
345         sc = device_get_softc(dev);
346
347         adb_set_autopoll(dev,0);
348         callout_stop(&sc->sc_repeater);
349
350         mtx_lock(&sc->sc_mutex);
351
352         kbd = kbd_get_keyboard(kbd_find_keyboard(KBD_DRIVER_NAME,
353                   device_get_unit(dev)));
354
355         kbdd_disable(kbd);
356
357 #ifdef KBD_INSTALL_CDEV
358         kbd_detach(kbd);
359 #endif
360
361         kbdd_term(kbd);
362
363         mtx_unlock(&sc->sc_mutex);
364
365         mtx_destroy(&sc->sc_mutex);
366         cv_destroy(&sc->sc_cv);
367
368         return (0);
369 }
370
371 static u_int 
372 adb_kbd_receive_packet(device_t dev, u_char status, 
373     u_char command, u_char reg, int len, u_char *data)
374 {
375         struct adb_kbd_softc *sc;
376
377         sc = device_get_softc(dev);
378
379         if (command != ADB_COMMAND_TALK)
380                 return 0;
381
382         if (reg != 0 || len != 2)
383                 return (0);
384
385         mtx_lock(&sc->sc_mutex);
386                 if ((data[0] & 0x7f) == 57 && sc->buffers < 7) {
387                         /* Fake the down/up cycle for caps lock */
388                         sc->buffer[sc->buffers++] = data[0] & 0x7f;
389                         sc->buffer[sc->buffers++] = (data[0] & 0x7f) | (1 << 7);
390                 } else {
391                         sc->buffer[sc->buffers++] = data[0];
392                 }
393
394                 if (sc->buffer[sc->buffers-1] < 0xff)
395                         sc->last_press = sc->buffer[sc->buffers-1];
396
397                 if ((data[1] & 0x7f) == 57 && sc->buffers < 7) {
398                         /* Fake the down/up cycle for caps lock */
399                         sc->buffer[sc->buffers++] = data[1] & 0x7f;
400                         sc->buffer[sc->buffers++] = (data[1] & 0x7f) | (1 << 7);
401                 } else {
402                         sc->buffer[sc->buffers++] = data[1];
403                 }
404
405                 if (sc->buffer[sc->buffers-1] < 0xff)
406                         sc->last_press = sc->buffer[sc->buffers-1];
407
408                 /* Stop any existing key repeating */
409                 callout_stop(&sc->sc_repeater);
410
411                 /* Schedule a repeat callback on keydown */
412                 if (!(sc->last_press & (1 << 7))) {
413                         callout_reset(&sc->sc_repeater, 
414                             ms_to_ticks(sc->sc_kbd.kb_delay1), akbd_repeat, sc);
415                 }
416         mtx_unlock(&sc->sc_mutex);
417
418         cv_broadcast(&sc->sc_cv);
419
420         if (KBD_IS_ACTIVE(&sc->sc_kbd) && KBD_IS_BUSY(&sc->sc_kbd)) {
421                 sc->sc_kbd.kb_callback.kc_func(&sc->sc_kbd,
422                          KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg);
423         }
424
425         return (0);
426 }
427
428 static void
429 akbd_repeat(void *xsc) {
430         struct adb_kbd_softc *sc = xsc;
431         int notify_kbd = 0;
432
433         /* Fake an up/down key repeat so long as we have the
434            free buffers */
435         mtx_lock(&sc->sc_mutex);
436                 if (sc->buffers < 7) {
437                         sc->buffer[sc->buffers++] = sc->last_press | (1 << 7);
438                         sc->buffer[sc->buffers++] = sc->last_press;
439
440                         notify_kbd = 1;
441                 }
442         mtx_unlock(&sc->sc_mutex);
443
444         if (notify_kbd && KBD_IS_ACTIVE(&sc->sc_kbd) 
445             && KBD_IS_BUSY(&sc->sc_kbd)) {
446                 sc->sc_kbd.kb_callback.kc_func(&sc->sc_kbd,
447                     KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg);
448         }
449
450         /* Reschedule the callout */
451         callout_reset(&sc->sc_repeater, ms_to_ticks(sc->sc_kbd.kb_delay2),
452             akbd_repeat, sc);
453 }
454         
455 static int 
456 akbd_configure(int flags) 
457 {
458         return 0;
459 }
460
461 static int 
462 akbd_probe(int unit, void *arg, int flags) 
463 {
464         return 0;
465 }
466
467 static int 
468 akbd_init(int unit, keyboard_t **kbdp, void *arg, int flags) 
469 {
470         return 0;
471 }
472
473 static int 
474 akbd_term(keyboard_t *kbd) 
475 {
476         return 0;
477 }
478
479 static int 
480 akbd_interrupt(keyboard_t *kbd, void *arg) 
481 {
482         return 0;
483 }
484
485 static int 
486 akbd_test_if(keyboard_t *kbd) 
487 {
488         return 0;
489 }
490
491 static int 
492 akbd_enable(keyboard_t *kbd) 
493 {
494         KBD_ACTIVATE(kbd);
495         return (0);
496 }
497
498 static int 
499 akbd_disable(keyboard_t *kbd) 
500 {
501         struct adb_kbd_softc *sc;
502         sc = (struct adb_kbd_softc *)(kbd);
503
504         callout_stop(&sc->sc_repeater);
505         KBD_DEACTIVATE(kbd);
506         return (0);
507 }
508
509 static int 
510 akbd_read(keyboard_t *kbd, int wait) 
511 {
512         return (0);
513 }
514
515 static int 
516 akbd_check(keyboard_t *kbd) 
517 {
518         struct adb_kbd_softc *sc;
519
520         if (!KBD_IS_ACTIVE(kbd))
521                 return (FALSE);
522
523         sc = (struct adb_kbd_softc *)(kbd);
524
525         mtx_lock(&sc->sc_mutex);
526 #ifdef AKBD_EMULATE_ATKBD
527                 if (sc->at_buffered_char[0]) {
528                         mtx_unlock(&sc->sc_mutex);
529                         return (TRUE);
530                 }
531 #endif
532
533                 if (sc->buffers > 0) {
534                         mtx_unlock(&sc->sc_mutex);
535                         return (TRUE); 
536                 }
537         mtx_unlock(&sc->sc_mutex);
538
539         return (FALSE);
540 }
541
542 static u_int 
543 akbd_read_char(keyboard_t *kbd, int wait) 
544 {
545         struct adb_kbd_softc *sc;
546         uint16_t key;
547         uint8_t adb_code;
548         int i;
549
550         sc = (struct adb_kbd_softc *)(kbd);
551
552         mtx_lock(&sc->sc_mutex);
553
554 #if defined(AKBD_EMULATE_ATKBD)
555         if (sc->sc_mode == K_RAW && sc->at_buffered_char[0]) {
556                 key = sc->at_buffered_char[0];
557                 if (key & SCAN_PREFIX) {
558                         sc->at_buffered_char[0] = key & ~SCAN_PREFIX;
559                         key = (key & SCAN_PREFIX_E0) ? 0xe0 : 0xe1;
560                 } else {
561                         sc->at_buffered_char[0] = sc->at_buffered_char[1];
562                         sc->at_buffered_char[1] = 0;
563                 }
564
565                 mtx_unlock(&sc->sc_mutex);
566
567                 return (key);
568         }
569 #endif
570
571         if (!sc->buffers && wait)
572                 cv_wait(&sc->sc_cv,&sc->sc_mutex);
573
574         if (!sc->buffers) {
575                 mtx_unlock(&sc->sc_mutex);
576                 return (0);
577         }
578
579         adb_code = sc->buffer[0];
580
581         for (i = 1; i < sc->buffers; i++)
582                 sc->buffer[i-1] = sc->buffer[i];
583
584         sc->buffers--;
585
586         #ifdef AKBD_EMULATE_ATKBD
587                 key = adb_to_at_scancode_map[adb_code & 0x7f];
588                 if (sc->sc_mode == K_CODE) {
589                         /* Add the key-release bit */
590                         key |= adb_code & 0x80;
591                 } else if (sc->sc_mode == K_RAW) {
592                         /*
593                          * In the raw case, we have to emulate the gross
594                          * variable-length AT keyboard thing. Since this code
595                          * is copied from sunkbd, which is the same code
596                          * as ukbd, it might be nice to have this centralized.
597                          */
598
599                         key = keycode2scancode(key, 
600                             0, adb_code & 0x80);
601
602                         if (key & SCAN_PREFIX) {
603                                 if (key & SCAN_PREFIX_CTL) {
604                                         sc->at_buffered_char[0] =
605                                             0x1d | (key & SCAN_RELEASE);
606                                         sc->at_buffered_char[1] =
607                                             key & ~SCAN_PREFIX;
608                                 } else if (key & SCAN_PREFIX_SHIFT) {
609                                         sc->at_buffered_char[0] =
610                                             0x2a | (key & SCAN_RELEASE);
611                                         sc->at_buffered_char[1] =
612                                             key & ~SCAN_PREFIX_SHIFT;
613                                 } else {
614                                         sc->at_buffered_char[0] =
615                                             key & ~SCAN_PREFIX;
616                                         sc->at_buffered_char[1] = 0;
617                                 }
618         
619                                 key = (key & SCAN_PREFIX_E0) ? 0xe0 : 0xe1;
620                         }
621                 }
622         #else
623                 key = adb_code;
624         #endif
625
626         mtx_unlock(&sc->sc_mutex);
627
628         return (key);
629 }
630
631 static int 
632 akbd_check_char(keyboard_t *kbd) 
633 {
634         if (!KBD_IS_ACTIVE(kbd))
635                 return (FALSE);
636
637         return (akbd_check(kbd));
638 }
639
640 static int
641 set_typematic(keyboard_t *kbd, int code)
642 {
643         /* These numbers are in microseconds, so convert to ticks */
644
645         static int delays[] = { 250, 500, 750, 1000 };
646         static int rates[] = {  34,  38,  42,  46,  50,  55,  59,  63,
647                                 68,  76,  84,  92, 100, 110, 118, 126,
648                                 136, 152, 168, 184, 200, 220, 236, 252,
649                                 272, 304, 336, 368, 400, 440, 472, 504 };
650                 
651         if (code & ~0x7f)
652                 return EINVAL;
653         kbd->kb_delay1 = delays[(code >> 5) & 3];
654         kbd->kb_delay2 = rates[code & 0x1f];
655         return 0;
656 }
657
658 static int akbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t data)
659 {
660         struct adb_kbd_softc *sc;
661         uint16_t r2;
662         int error;
663
664         sc = (struct adb_kbd_softc *)(kbd);
665         error = 0;
666
667         switch (cmd) {
668         case KDGKBMODE:
669                 *(int *)data = sc->sc_mode;
670                 break;
671         case KDSKBMODE:
672                 switch (*(int *)data) {
673                 case K_XLATE:
674                         if (sc->sc_mode != K_XLATE) {
675                                 /* make lock key state and LED state match */
676                                 sc->sc_state &= ~LOCK_MASK;
677                                 sc->sc_state |= KBD_LED_VAL(kbd);
678                         }
679                         /* FALLTHROUGH */
680                 case K_RAW:
681                 case K_CODE:
682                         if (sc->sc_mode != *(int *)data) 
683                                 sc->sc_mode = *(int *)data;
684                         break;
685                 default:
686                         error = EINVAL;
687                         break;
688                 }
689
690                 break;
691
692         case KDGETLED:
693                 *(int *)data = KBD_LED_VAL(kbd);
694                 break;
695
696         case KDSKBSTATE:
697                 if (*(int *)data & ~LOCK_MASK) {
698                         error = EINVAL;
699                         break;
700                 }
701                 sc->sc_state &= ~LOCK_MASK;
702                 sc->sc_state |= *(int *)data;
703
704                 /* FALLTHROUGH */
705
706         case KDSETLED:
707                 KBD_LED_VAL(kbd) = *(int *)data;
708         
709                 if (!sc->have_led_control)
710                         break;
711
712                 r2 = (~0 & 0x04) | 3;
713
714                 if (*(int *)data & NLKED)
715                         r2 &= ~1;
716                 if (*(int *)data & CLKED)
717                         r2 &= ~2;
718                 if (*(int *)data & SLKED)
719                         r2 &= ~4;
720
721                 adb_send_packet(sc->sc_dev,ADB_COMMAND_LISTEN,2,
722                         sizeof(uint16_t),(u_char *)&r2);
723                 
724                 break;
725
726         case KDGKBSTATE:
727                 *(int *)data = sc->sc_state & LOCK_MASK;
728                 break;
729
730         case KDSETREPEAT:
731                 if (!KBD_HAS_DEVICE(kbd))
732                         return 0;
733                 if (((int *)data)[1] < 0)
734                         return EINVAL;
735                 if (((int *)data)[0] < 0)
736                         return EINVAL;
737                 else if (((int *)data)[0] == 0)  /* fastest possible value */
738                         kbd->kb_delay1 = 200;
739                 else
740                         kbd->kb_delay1 = ((int *)data)[0];
741                 kbd->kb_delay2 = ((int *)data)[1];
742
743                 break;
744
745         case KDSETRAD:
746                 error = set_typematic(kbd, *(int *)data);
747                 break;
748
749         case PIO_KEYMAP:
750         case PIO_KEYMAPENT:
751         case PIO_DEADKEYMAP:
752         default:
753                 return (genkbd_commonioctl(kbd, cmd, data));
754         }
755
756         return (error);
757 }
758
759 static int akbd_lock(keyboard_t *kbd, int lock)
760 {
761         return (0);
762 }
763
764 static void akbd_clear_state(keyboard_t *kbd)
765 {
766         struct adb_kbd_softc *sc;
767
768         sc = (struct adb_kbd_softc *)(kbd);
769
770         mtx_lock(&sc->sc_mutex);
771
772         sc->buffers = 0;
773         callout_stop(&sc->sc_repeater);
774
775 #if defined(AKBD_EMULATE_ATKBD) 
776         sc->at_buffered_char[0] = 0;
777         sc->at_buffered_char[1] = 0;
778 #endif
779         mtx_unlock(&sc->sc_mutex);
780 }
781
782 static int akbd_get_state(keyboard_t *kbd, void *buf, size_t len)
783 {
784         return (0);
785 }
786
787 static int akbd_set_state(keyboard_t *kbd, void *buf, size_t len)
788 {
789         return (0);
790 }
791
792 static int akbd_poll(keyboard_t *kbd, int on) 
793 {
794         return (0);
795 }
796
797 static int
798 akbd_modevent(module_t mod, int type, void *data)
799 {
800         switch (type) {
801         case MOD_LOAD:
802                 kbd_add_driver(&akbd_kbd_driver);
803                 break;
804
805         case MOD_UNLOAD:
806                 kbd_delete_driver(&akbd_kbd_driver);
807                 break;
808
809         default:
810                 return (EOPNOTSUPP);
811         }
812
813         return (0);
814 }
815
816 DEV_MODULE(akbd, akbd_modevent, NULL);
817