]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/adb/adb_kbd.c
MFV r354378,r354379,r354386: 10499 Multi-modifier protection (MMP)
[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         akbd_probe,
202         akbd_init,
203         akbd_term,
204         akbd_interrupt,
205         akbd_test_if,
206         akbd_enable,
207         akbd_disable,
208         akbd_read,
209         akbd_check,
210         akbd_read_char,
211         akbd_check_char,
212         akbd_ioctl,
213         akbd_lock,
214         akbd_clear_state,
215         akbd_get_state,
216         akbd_set_state,
217         genkbd_get_fkeystr,
218         akbd_poll,
219         genkbd_diag,
220 };
221
222 KEYBOARD_DRIVER(akbd, akbdsw, akbd_configure);
223
224 static int 
225 adb_kbd_probe(device_t dev) 
226 {
227         uint8_t type;
228
229         type = adb_get_device_type(dev);
230
231         if (type != ADB_DEVICE_KEYBOARD)
232                 return (ENXIO);
233
234         switch(adb_get_device_handler(dev)) {
235         case 1:
236                 device_set_desc(dev,"Apple Standard Keyboard");
237                 break;
238         case 2:
239                 device_set_desc(dev,"Apple Extended Keyboard");
240                 break;
241         case 4:
242                 device_set_desc(dev,"Apple ISO Keyboard");
243                 break;
244         case 5:
245                 device_set_desc(dev,"Apple Extended ISO Keyboard");
246                 break;
247         case 8:
248                 device_set_desc(dev,"Apple Keyboard II");
249                 break;
250         case 9:
251                 device_set_desc(dev,"Apple ISO Keyboard II");
252                 break;
253         case 12:
254                 device_set_desc(dev,"PowerBook Keyboard");
255                 break;
256         case 13:
257                 device_set_desc(dev,"PowerBook ISO Keyboard");
258                 break;
259         case 24:
260                 device_set_desc(dev,"PowerBook Extended Keyboard");
261                 break;
262         case 27:
263                 device_set_desc(dev,"Apple Design Keyboard");
264                 break;
265         case 195:
266                 device_set_desc(dev,"PowerBook G3 Keyboard");
267                 break;
268         case 196:
269                 device_set_desc(dev,"iBook Keyboard");
270                 break;
271         default:
272                 device_set_desc(dev,"ADB Keyboard");
273                 break;
274         }
275
276         return (0);
277 }
278
279 static int
280 ms_to_ticks(int ms)
281 {
282         if (hz > 1000)
283                 return ms*(hz/1000);
284
285         return ms/(1000/hz);
286 }
287         
288 static int 
289 adb_kbd_attach(device_t dev) 
290 {
291         struct adb_kbd_softc *sc;
292         keyboard_switch_t *sw;
293         uint32_t fkeys;
294         phandle_t handle;
295
296         sw = kbd_get_switch(KBD_DRIVER_NAME);
297         if (sw == NULL) {
298                 return ENXIO;
299         }
300
301         sc = device_get_softc(dev);
302         sc->sc_dev = dev;
303         sc->sc_mode = K_RAW;
304         sc->sc_state = 0;
305         sc->have_led_control = 0;
306         sc->buffers = 0;
307
308         /* Try stepping forward to the extended keyboard protocol */
309         adb_set_device_handler(dev,3);
310
311         mtx_init(&sc->sc_mutex, KBD_DRIVER_NAME, NULL, MTX_DEF);
312         cv_init(&sc->sc_cv,KBD_DRIVER_NAME);
313         callout_init(&sc->sc_repeater, 0);
314
315 #ifdef AKBD_EMULATE_ATKBD
316         kbd_init_struct(&sc->sc_kbd, KBD_DRIVER_NAME, KB_101, 0, 0, 0, 0);
317         kbd_set_maps(&sc->sc_kbd, &key_map, &accent_map, fkey_tab,
318             sizeof(fkey_tab) / sizeof(fkey_tab[0]));
319 #else
320         #error ADB raw mode not implemented
321 #endif
322
323         KBD_FOUND_DEVICE(&sc->sc_kbd);
324         KBD_PROBE_DONE(&sc->sc_kbd);
325         KBD_INIT_DONE(&sc->sc_kbd);
326         KBD_CONFIG_DONE(&sc->sc_kbd);
327
328         (*sw->enable)(&sc->sc_kbd);
329
330         kbd_register(&sc->sc_kbd);
331
332 #ifdef KBD_INSTALL_CDEV
333         if (kbd_attach(&sc->sc_kbd)) {
334                 adb_kbd_detach(dev);
335                 return ENXIO;
336         }
337 #endif
338
339         /* Check if we can read out the LED state from 
340            this keyboard by reading the key state register */
341         if (adb_read_register(dev, 2, NULL) == 2)
342                 sc->have_led_control = 1;
343
344         adb_set_autopoll(dev,1);
345
346         handle = OF_finddevice("mac-io/via-pmu/adb/keyboard");
347         if (handle != -1 && OF_getprop(handle, "AAPL,has-embedded-fn-keys",
348             &fkeys, sizeof(fkeys)) != -1) {
349                 static const char *key_names[] = {"F1", "F2", "F3", "F4", "F5",
350                     "F6", "F7", "F8", "F9", "F10", "F11", "F12"};
351                 struct sysctl_ctx_list *ctx;
352                 struct sysctl_oid *tree;
353                 int i;
354
355                 if (bootverbose)
356                         device_printf(dev, "Keyboard has embedded Fn keys\n");
357
358                 for (i = 0; i < 12; i++) {
359                         uint32_t keyval;
360                         char buf[3];
361                         if (OF_getprop(handle, key_names[i], &keyval,
362                             sizeof(keyval)) < 0)
363                                 continue;
364                         buf[0] = 1;
365                         buf[1] = i+1;
366                         buf[2] = keyval;
367                         adb_write_register(dev, 0, 3, buf);
368                 }
369                 adb_write_register(dev, 1, 2, &(uint16_t){0});
370
371                 ctx = device_get_sysctl_ctx(dev);
372                 tree = device_get_sysctl_tree(dev);
373
374                 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
375                     "fn_keys_function_as_primary", CTLTYPE_INT | CTLFLAG_RW, sc,
376                     0, adb_fn_keys, "I",
377                     "Set the Fn keys to be their F-key type as default");
378         }
379
380         return (0);
381 }
382
383 static int 
384 adb_kbd_detach(device_t dev) 
385 {
386         struct adb_kbd_softc *sc;
387         keyboard_t *kbd;
388
389         sc = device_get_softc(dev);
390
391         adb_set_autopoll(dev,0);
392         callout_stop(&sc->sc_repeater);
393
394         mtx_lock(&sc->sc_mutex);
395
396         kbd = kbd_get_keyboard(kbd_find_keyboard(KBD_DRIVER_NAME,
397                   device_get_unit(dev)));
398
399         kbdd_disable(kbd);
400
401 #ifdef KBD_INSTALL_CDEV
402         kbd_detach(kbd);
403 #endif
404
405         kbdd_term(kbd);
406
407         mtx_unlock(&sc->sc_mutex);
408
409         mtx_destroy(&sc->sc_mutex);
410         cv_destroy(&sc->sc_cv);
411
412         return (0);
413 }
414
415 static u_int 
416 adb_kbd_receive_packet(device_t dev, u_char status, 
417     u_char command, u_char reg, int len, u_char *data)
418 {
419         struct adb_kbd_softc *sc;
420
421         sc = device_get_softc(dev);
422
423         if (command != ADB_COMMAND_TALK)
424                 return 0;
425
426         if (reg != 0 || len != 2)
427                 return (0);
428
429         mtx_lock(&sc->sc_mutex);
430                 /* 0x7f is always the power button */
431                 if (data[0] == 0x7f) {
432                         devctl_notify("PMU", "Button", "pressed", NULL);
433                         mtx_unlock(&sc->sc_mutex);
434                         return (0);
435                 } else if (data[0] == 0xff) {
436                         mtx_unlock(&sc->sc_mutex);
437                         return (0);     /* Ignore power button release. */
438                 }
439                 if ((data[0] & 0x7f) == 57 && sc->buffers < 7) {
440                         /* Fake the down/up cycle for caps lock */
441                         sc->buffer[sc->buffers++] = data[0] & 0x7f;
442                         sc->buffer[sc->buffers++] = (data[0] & 0x7f) | (1 << 7);
443                 } else {
444                         sc->buffer[sc->buffers++] = data[0];
445                 }
446                 if (sc->buffer[sc->buffers-1] < 0xff)
447                         sc->last_press = sc->buffer[sc->buffers-1];
448
449                 if ((data[1] & 0x7f) == 57 && sc->buffers < 7) {
450                         /* Fake the down/up cycle for caps lock */
451                         sc->buffer[sc->buffers++] = data[1] & 0x7f;
452                         sc->buffer[sc->buffers++] = (data[1] & 0x7f) | (1 << 7);
453                 } else {
454                         sc->buffer[sc->buffers++] = data[1];
455                 }
456
457                 if (sc->buffer[sc->buffers-1] < 0xff)
458                         sc->last_press = sc->buffer[sc->buffers-1];
459
460                 /* Stop any existing key repeating */
461                 callout_stop(&sc->sc_repeater);
462
463                 /* Schedule a repeat callback on keydown */
464                 if (!(sc->last_press & (1 << 7))) {
465                         callout_reset(&sc->sc_repeater, 
466                             ms_to_ticks(sc->sc_kbd.kb_delay1), akbd_repeat, sc);
467                 }
468         mtx_unlock(&sc->sc_mutex);
469
470         cv_broadcast(&sc->sc_cv);
471
472         if (KBD_IS_ACTIVE(&sc->sc_kbd) && KBD_IS_BUSY(&sc->sc_kbd)) {
473                 sc->sc_kbd.kb_callback.kc_func(&sc->sc_kbd,
474                          KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg);
475         }
476
477         return (0);
478 }
479
480 static void
481 akbd_repeat(void *xsc) {
482         struct adb_kbd_softc *sc = xsc;
483         int notify_kbd = 0;
484
485         /* Fake an up/down key repeat so long as we have the
486            free buffers */
487         mtx_lock(&sc->sc_mutex);
488                 if (sc->buffers < 7) {
489                         sc->buffer[sc->buffers++] = sc->last_press | (1 << 7);
490                         sc->buffer[sc->buffers++] = sc->last_press;
491
492                         notify_kbd = 1;
493                 }
494         mtx_unlock(&sc->sc_mutex);
495
496         if (notify_kbd && KBD_IS_ACTIVE(&sc->sc_kbd) 
497             && KBD_IS_BUSY(&sc->sc_kbd)) {
498                 sc->sc_kbd.kb_callback.kc_func(&sc->sc_kbd,
499                     KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg);
500         }
501
502         /* Reschedule the callout */
503         callout_reset(&sc->sc_repeater, ms_to_ticks(sc->sc_kbd.kb_delay2),
504             akbd_repeat, sc);
505 }
506         
507 static int 
508 akbd_configure(int flags) 
509 {
510         return 0;
511 }
512
513 static int 
514 akbd_probe(int unit, void *arg, int flags) 
515 {
516         return 0;
517 }
518
519 static int 
520 akbd_init(int unit, keyboard_t **kbdp, void *arg, int flags) 
521 {
522         return 0;
523 }
524
525 static int 
526 akbd_term(keyboard_t *kbd) 
527 {
528         return 0;
529 }
530
531 static int 
532 akbd_interrupt(keyboard_t *kbd, void *arg) 
533 {
534         return 0;
535 }
536
537 static int 
538 akbd_test_if(keyboard_t *kbd) 
539 {
540         return 0;
541 }
542
543 static int 
544 akbd_enable(keyboard_t *kbd) 
545 {
546         KBD_ACTIVATE(kbd);
547         return (0);
548 }
549
550 static int 
551 akbd_disable(keyboard_t *kbd) 
552 {
553         struct adb_kbd_softc *sc;
554         sc = (struct adb_kbd_softc *)(kbd);
555
556         callout_stop(&sc->sc_repeater);
557         KBD_DEACTIVATE(kbd);
558         return (0);
559 }
560
561 static int 
562 akbd_read(keyboard_t *kbd, int wait) 
563 {
564         return (0);
565 }
566
567 static int 
568 akbd_check(keyboard_t *kbd) 
569 {
570         struct adb_kbd_softc *sc;
571
572         if (!KBD_IS_ACTIVE(kbd))
573                 return (FALSE);
574
575         sc = (struct adb_kbd_softc *)(kbd);
576
577         mtx_lock(&sc->sc_mutex);
578 #ifdef AKBD_EMULATE_ATKBD
579                 if (sc->at_buffered_char[0]) {
580                         mtx_unlock(&sc->sc_mutex);
581                         return (TRUE);
582                 }
583 #endif
584
585                 if (sc->buffers > 0) {
586                         mtx_unlock(&sc->sc_mutex);
587                         return (TRUE); 
588                 }
589         mtx_unlock(&sc->sc_mutex);
590
591         return (FALSE);
592 }
593
594 static u_int 
595 akbd_read_char(keyboard_t *kbd, int wait) 
596 {
597         struct adb_kbd_softc *sc;
598         uint16_t key;
599         uint8_t adb_code;
600         int i;
601
602         sc = (struct adb_kbd_softc *)(kbd);
603
604         mtx_lock(&sc->sc_mutex);
605
606 #if defined(AKBD_EMULATE_ATKBD)
607         if (sc->sc_mode == K_RAW && sc->at_buffered_char[0]) {
608                 key = sc->at_buffered_char[0];
609                 if (key & SCAN_PREFIX) {
610                         sc->at_buffered_char[0] = key & ~SCAN_PREFIX;
611                         key = (key & SCAN_PREFIX_E0) ? 0xe0 : 0xe1;
612                 } else {
613                         sc->at_buffered_char[0] = sc->at_buffered_char[1];
614                         sc->at_buffered_char[1] = 0;
615                 }
616
617                 mtx_unlock(&sc->sc_mutex);
618
619                 return (key);
620         }
621 #endif
622
623         if (!sc->buffers && wait)
624                 cv_wait(&sc->sc_cv,&sc->sc_mutex);
625
626         if (!sc->buffers) {
627                 mtx_unlock(&sc->sc_mutex);
628                 return (NOKEY);
629         }
630
631         adb_code = sc->buffer[0];
632
633         for (i = 1; i < sc->buffers; i++)
634                 sc->buffer[i-1] = sc->buffer[i];
635
636         sc->buffers--;
637
638         #ifdef AKBD_EMULATE_ATKBD
639                 key = adb_to_at_scancode_map[adb_code & 0x7f];
640                 if (sc->sc_mode == K_CODE) {
641                         /* Add the key-release bit */
642                         key |= adb_code & 0x80;
643                 } else if (sc->sc_mode == K_RAW) {
644                         /*
645                          * In the raw case, we have to emulate the gross
646                          * variable-length AT keyboard thing. Since this code
647                          * is copied from sunkbd, which is the same code
648                          * as ukbd, it might be nice to have this centralized.
649                          */
650
651                         key = keycode2scancode(key, 
652                             0, adb_code & 0x80);
653
654                         if (key & SCAN_PREFIX) {
655                                 if (key & SCAN_PREFIX_CTL) {
656                                         sc->at_buffered_char[0] =
657                                             0x1d | (key & SCAN_RELEASE);
658                                         sc->at_buffered_char[1] =
659                                             key & ~SCAN_PREFIX;
660                                 } else if (key & SCAN_PREFIX_SHIFT) {
661                                         sc->at_buffered_char[0] =
662                                             0x2a | (key & SCAN_RELEASE);
663                                         sc->at_buffered_char[1] =
664                                             key & ~SCAN_PREFIX_SHIFT;
665                                 } else {
666                                         sc->at_buffered_char[0] =
667                                             key & ~SCAN_PREFIX;
668                                         sc->at_buffered_char[1] = 0;
669                                 }
670         
671                                 key = (key & SCAN_PREFIX_E0) ? 0xe0 : 0xe1;
672                         }
673                 }
674         #else
675                 key = adb_code;
676         #endif
677
678         mtx_unlock(&sc->sc_mutex);
679
680         return (key);
681 }
682
683 static int 
684 akbd_check_char(keyboard_t *kbd) 
685 {
686         if (!KBD_IS_ACTIVE(kbd))
687                 return (FALSE);
688
689         return (akbd_check(kbd));
690 }
691
692 static int
693 set_typematic(keyboard_t *kbd, int code)
694 {
695         /* These numbers are in microseconds, so convert to ticks */
696
697         static int delays[] = { 250, 500, 750, 1000 };
698         static int rates[] = {  34,  38,  42,  46,  50,  55,  59,  63,
699                                 68,  76,  84,  92, 100, 110, 118, 126,
700                                 136, 152, 168, 184, 200, 220, 236, 252,
701                                 272, 304, 336, 368, 400, 440, 472, 504 };
702                 
703         if (code & ~0x7f)
704                 return EINVAL;
705         kbd->kb_delay1 = delays[(code >> 5) & 3];
706         kbd->kb_delay2 = rates[code & 0x1f];
707         return 0;
708 }
709
710 static int akbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t data)
711 {
712         struct adb_kbd_softc *sc;
713         uint16_t r2;
714         int error;
715
716         sc = (struct adb_kbd_softc *)(kbd);
717         error = 0;
718
719         switch (cmd) {
720         case KDGKBMODE:
721                 *(int *)data = sc->sc_mode;
722                 break;
723         case KDSKBMODE:
724                 switch (*(int *)data) {
725                 case K_XLATE:
726                         if (sc->sc_mode != K_XLATE) {
727                                 /* make lock key state and LED state match */
728                                 sc->sc_state &= ~LOCK_MASK;
729                                 sc->sc_state |= KBD_LED_VAL(kbd);
730                         }
731                         /* FALLTHROUGH */
732                 case K_RAW:
733                 case K_CODE:
734                         if (sc->sc_mode != *(int *)data) 
735                                 sc->sc_mode = *(int *)data;
736                         break;
737                 default:
738                         error = EINVAL;
739                         break;
740                 }
741
742                 break;
743
744         case KDGETLED:
745                 *(int *)data = KBD_LED_VAL(kbd);
746                 break;
747
748         case KDSKBSTATE:
749                 if (*(int *)data & ~LOCK_MASK) {
750                         error = EINVAL;
751                         break;
752                 }
753                 sc->sc_state &= ~LOCK_MASK;
754                 sc->sc_state |= *(int *)data;
755
756                 /* FALLTHROUGH */
757
758         case KDSETLED:
759                 KBD_LED_VAL(kbd) = *(int *)data;
760         
761                 if (!sc->have_led_control)
762                         break;
763
764                 r2 = (~0 & 0x04) | 3;
765
766                 if (*(int *)data & NLKED)
767                         r2 &= ~1;
768                 if (*(int *)data & CLKED)
769                         r2 &= ~2;
770                 if (*(int *)data & SLKED)
771                         r2 &= ~4;
772
773                 adb_send_packet(sc->sc_dev,ADB_COMMAND_LISTEN,2,
774                         sizeof(uint16_t),(u_char *)&r2);
775                 
776                 break;
777
778         case KDGKBSTATE:
779                 *(int *)data = sc->sc_state & LOCK_MASK;
780                 break;
781
782         case KDSETREPEAT:
783                 if (!KBD_HAS_DEVICE(kbd))
784                         return 0;
785                 if (((int *)data)[1] < 0)
786                         return EINVAL;
787                 if (((int *)data)[0] < 0)
788                         return EINVAL;
789                 else if (((int *)data)[0] == 0)  /* fastest possible value */
790                         kbd->kb_delay1 = 200;
791                 else
792                         kbd->kb_delay1 = ((int *)data)[0];
793                 kbd->kb_delay2 = ((int *)data)[1];
794
795                 break;
796
797         case KDSETRAD:
798                 error = set_typematic(kbd, *(int *)data);
799                 break;
800
801         case PIO_KEYMAP:
802         case OPIO_KEYMAP:
803         case PIO_KEYMAPENT:
804         case PIO_DEADKEYMAP:
805         default:
806                 return (genkbd_commonioctl(kbd, cmd, data));
807         }
808
809         return (error);
810 }
811
812 static int akbd_lock(keyboard_t *kbd, int lock)
813 {
814         return (0);
815 }
816
817 static void akbd_clear_state(keyboard_t *kbd)
818 {
819         struct adb_kbd_softc *sc;
820
821         sc = (struct adb_kbd_softc *)(kbd);
822
823         mtx_lock(&sc->sc_mutex);
824
825         sc->buffers = 0;
826         callout_stop(&sc->sc_repeater);
827
828 #if defined(AKBD_EMULATE_ATKBD) 
829         sc->at_buffered_char[0] = 0;
830         sc->at_buffered_char[1] = 0;
831 #endif
832         mtx_unlock(&sc->sc_mutex);
833 }
834
835 static int akbd_get_state(keyboard_t *kbd, void *buf, size_t len)
836 {
837         return (0);
838 }
839
840 static int akbd_set_state(keyboard_t *kbd, void *buf, size_t len)
841 {
842         return (0);
843 }
844
845 static int akbd_poll(keyboard_t *kbd, int on) 
846 {
847         return (0);
848 }
849
850 static int
851 akbd_modevent(module_t mod, int type, void *data)
852 {
853         switch (type) {
854         case MOD_LOAD:
855                 kbd_add_driver(&akbd_kbd_driver);
856                 break;
857
858         case MOD_UNLOAD:
859                 kbd_delete_driver(&akbd_kbd_driver);
860                 break;
861
862         default:
863                 return (EOPNOTSUPP);
864         }
865
866         return (0);
867 }
868
869 static int
870 adb_fn_keys(SYSCTL_HANDLER_ARGS)
871 {
872         struct adb_kbd_softc *sc = arg1;
873         int error;
874         uint16_t is_fn_enabled;
875         unsigned int is_fn_enabled_sysctl;
876
877         adb_read_register(sc->sc_dev, 1, &is_fn_enabled);
878         is_fn_enabled &= 1;
879         is_fn_enabled_sysctl = is_fn_enabled;
880         error = sysctl_handle_int(oidp, &is_fn_enabled_sysctl, 0, req);
881
882         if (error || !req->newptr)
883                 return (error);
884
885         is_fn_enabled = is_fn_enabled_sysctl;
886         if (is_fn_enabled != 1 && is_fn_enabled != 0)
887                 return (EINVAL);
888
889         adb_write_register(sc->sc_dev, 1, 2, &is_fn_enabled);
890         return (0);
891 }
892
893 DEV_MODULE(akbd, akbd_modevent, NULL);
894