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