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