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