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