2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (C) 2008 Nathan Whitehorn
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
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.
30 #include <sys/cdefs.h>
31 #include <sys/param.h>
32 #include <sys/systm.h>
34 #include <sys/module.h>
35 #include <sys/mutex.h>
39 #include <sys/condvar.h>
40 #include <sys/callout.h>
41 #include <sys/kernel.h>
42 #include <sys/sysctl.h>
44 #include <machine/bus.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>
57 #define KBD_DRIVER_NAME "akbd"
59 #define AKBD_EMULATE_ATKBD 1
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);
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);
70 struct adb_kbd_softc {
83 #ifdef AKBD_EMULATE_ATKBD
84 uint8_t at_buffered_char[2];
88 struct callout sc_repeater;
90 int sc_repeatcontinue;
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),
104 DEVMETHOD(adb_receive_packet, adb_kbd_receive_packet),
109 static driver_t adb_kbd_driver = {
112 sizeof(struct adb_kbd_softc),
115 static devclass_t adb_kbd_devclass;
117 DRIVER_MODULE(akbd, adb, adb_kbd_driver, adb_kbd_devclass, 0, 0);
119 #ifdef AKBD_EMULATE_ATKBD
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)
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 };
140 keycode2scancode(int keycode, int shift, int up)
142 static const int scan[] = {
143 /* KP enter, right ctrl, KP divide */
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) */
154 * MS: left window, right window, menu
155 * also Sun: left meta, right meta, compose
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,
169 if ((keycode >= 89) && (keycode < 89 + nitems(scan)))
170 scancode = scan[keycode - 89] | SCAN_PREFIX_E0;
172 if ((keycode == 104) && !(shift & CTLS))
173 scancode = 0x45 | SCAN_PREFIX_E1 | SCAN_PREFIX_CTL;
175 scancode &= ~SCAN_PREFIX_SHIFT;
176 return (scancode | (up ? SCAN_RELEASE : SCAN_PRESS));
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;
200 keyboard_switch_t akbdsw = {
222 KEYBOARD_DRIVER(akbd, akbdsw, akbd_configure);
225 adb_kbd_probe(device_t dev)
229 type = adb_get_device_type(dev);
231 if (type != ADB_DEVICE_KEYBOARD)
234 switch(adb_get_device_handler(dev)) {
236 device_set_desc(dev,"Apple Standard Keyboard");
239 device_set_desc(dev,"Apple Extended Keyboard");
242 device_set_desc(dev,"Apple ISO Keyboard");
245 device_set_desc(dev,"Apple Extended ISO Keyboard");
248 device_set_desc(dev,"Apple Keyboard II");
251 device_set_desc(dev,"Apple ISO Keyboard II");
254 device_set_desc(dev,"PowerBook Keyboard");
257 device_set_desc(dev,"PowerBook ISO Keyboard");
260 device_set_desc(dev,"PowerBook Extended Keyboard");
263 device_set_desc(dev,"Apple Design Keyboard");
266 device_set_desc(dev,"PowerBook G3 Keyboard");
269 device_set_desc(dev,"iBook Keyboard");
272 device_set_desc(dev,"ADB Keyboard");
289 adb_kbd_attach(device_t dev)
291 struct adb_kbd_softc *sc;
292 keyboard_switch_t *sw;
296 sw = kbd_get_switch(KBD_DRIVER_NAME);
301 sc = device_get_softc(dev);
305 sc->have_led_control = 0;
308 /* Try stepping forward to the extended keyboard protocol */
309 adb_set_device_handler(dev,3);
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);
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]));
320 #error ADB raw mode not implemented
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);
328 (*sw->enable)(&sc->sc_kbd);
330 kbd_register(&sc->sc_kbd);
332 #ifdef KBD_INSTALL_CDEV
333 if (kbd_attach(&sc->sc_kbd)) {
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;
344 adb_set_autopoll(dev,1);
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;
356 device_printf(dev, "Keyboard has embedded Fn keys\n");
358 for (i = 0; i < 12; i++) {
361 if (OF_getprop(handle, key_names[i], &keyval,
367 adb_write_register(dev, 0, 3, buf);
369 adb_write_register(dev, 1, 2, &(uint16_t){0});
371 ctx = device_get_sysctl_ctx(dev);
372 tree = device_get_sysctl_tree(dev);
374 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
375 "fn_keys_function_as_primary", CTLTYPE_INT | CTLFLAG_RW, sc,
377 "Set the Fn keys to be their F-key type as default");
384 adb_kbd_detach(device_t dev)
386 struct adb_kbd_softc *sc;
389 sc = device_get_softc(dev);
391 adb_set_autopoll(dev,0);
392 callout_stop(&sc->sc_repeater);
394 mtx_lock(&sc->sc_mutex);
396 kbd = kbd_get_keyboard(kbd_find_keyboard(KBD_DRIVER_NAME,
397 device_get_unit(dev)));
401 #ifdef KBD_INSTALL_CDEV
407 mtx_unlock(&sc->sc_mutex);
409 mtx_destroy(&sc->sc_mutex);
410 cv_destroy(&sc->sc_cv);
416 adb_kbd_receive_packet(device_t dev, u_char status,
417 u_char command, u_char reg, int len, u_char *data)
419 struct adb_kbd_softc *sc;
421 sc = device_get_softc(dev);
423 if (command != ADB_COMMAND_TALK)
426 if (reg != 0 || len != 2)
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);
435 } else if (data[0] == 0xff) {
436 mtx_unlock(&sc->sc_mutex);
437 return (0); /* Ignore power button release. */
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);
444 sc->buffer[sc->buffers++] = data[0];
446 if (sc->buffer[sc->buffers-1] < 0xff)
447 sc->last_press = sc->buffer[sc->buffers-1];
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);
454 sc->buffer[sc->buffers++] = data[1];
457 if (sc->buffer[sc->buffers-1] < 0xff)
458 sc->last_press = sc->buffer[sc->buffers-1];
460 /* Stop any existing key repeating */
461 callout_stop(&sc->sc_repeater);
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);
468 mtx_unlock(&sc->sc_mutex);
470 cv_broadcast(&sc->sc_cv);
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);
481 akbd_repeat(void *xsc) {
482 struct adb_kbd_softc *sc = xsc;
485 /* Fake an up/down key repeat so long as we have the
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;
494 mtx_unlock(&sc->sc_mutex);
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);
502 /* Reschedule the callout */
503 callout_reset(&sc->sc_repeater, ms_to_ticks(sc->sc_kbd.kb_delay2),
508 akbd_configure(int flags)
514 akbd_probe(int unit, void *arg, int flags)
520 akbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
526 akbd_term(keyboard_t *kbd)
532 akbd_interrupt(keyboard_t *kbd, void *arg)
538 akbd_test_if(keyboard_t *kbd)
544 akbd_enable(keyboard_t *kbd)
551 akbd_disable(keyboard_t *kbd)
553 struct adb_kbd_softc *sc;
554 sc = (struct adb_kbd_softc *)(kbd);
556 callout_stop(&sc->sc_repeater);
562 akbd_read(keyboard_t *kbd, int wait)
568 akbd_check(keyboard_t *kbd)
570 struct adb_kbd_softc *sc;
572 if (!KBD_IS_ACTIVE(kbd))
575 sc = (struct adb_kbd_softc *)(kbd);
577 mtx_lock(&sc->sc_mutex);
578 #ifdef AKBD_EMULATE_ATKBD
579 if (sc->at_buffered_char[0]) {
580 mtx_unlock(&sc->sc_mutex);
585 if (sc->buffers > 0) {
586 mtx_unlock(&sc->sc_mutex);
589 mtx_unlock(&sc->sc_mutex);
595 akbd_read_char(keyboard_t *kbd, int wait)
597 struct adb_kbd_softc *sc;
602 sc = (struct adb_kbd_softc *)(kbd);
604 mtx_lock(&sc->sc_mutex);
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;
613 sc->at_buffered_char[0] = sc->at_buffered_char[1];
614 sc->at_buffered_char[1] = 0;
617 mtx_unlock(&sc->sc_mutex);
623 if (!sc->buffers && wait)
624 cv_wait(&sc->sc_cv,&sc->sc_mutex);
627 mtx_unlock(&sc->sc_mutex);
631 adb_code = sc->buffer[0];
633 for (i = 1; i < sc->buffers; i++)
634 sc->buffer[i-1] = sc->buffer[i];
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) {
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.
651 key = keycode2scancode(key,
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] =
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;
666 sc->at_buffered_char[0] =
668 sc->at_buffered_char[1] = 0;
671 key = (key & SCAN_PREFIX_E0) ? 0xe0 : 0xe1;
678 mtx_unlock(&sc->sc_mutex);
684 akbd_check_char(keyboard_t *kbd)
686 if (!KBD_IS_ACTIVE(kbd))
689 return (akbd_check(kbd));
693 set_typematic(keyboard_t *kbd, int code)
695 /* These numbers are in microseconds, so convert to ticks */
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 };
705 kbd->kb_delay1 = delays[(code >> 5) & 3];
706 kbd->kb_delay2 = rates[code & 0x1f];
710 static int akbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t data)
712 struct adb_kbd_softc *sc;
716 sc = (struct adb_kbd_softc *)(kbd);
721 *(int *)data = sc->sc_mode;
724 switch (*(int *)data) {
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);
734 if (sc->sc_mode != *(int *)data)
735 sc->sc_mode = *(int *)data;
745 *(int *)data = KBD_LED_VAL(kbd);
749 if (*(int *)data & ~LOCK_MASK) {
753 sc->sc_state &= ~LOCK_MASK;
754 sc->sc_state |= *(int *)data;
759 KBD_LED_VAL(kbd) = *(int *)data;
761 if (!sc->have_led_control)
764 r2 = (~0 & 0x04) | 3;
766 if (*(int *)data & NLKED)
768 if (*(int *)data & CLKED)
770 if (*(int *)data & SLKED)
773 adb_send_packet(sc->sc_dev,ADB_COMMAND_LISTEN,2,
774 sizeof(uint16_t),(u_char *)&r2);
779 *(int *)data = sc->sc_state & LOCK_MASK;
783 if (!KBD_HAS_DEVICE(kbd))
785 if (((int *)data)[1] < 0)
787 if (((int *)data)[0] < 0)
789 else if (((int *)data)[0] == 0) /* fastest possible value */
790 kbd->kb_delay1 = 200;
792 kbd->kb_delay1 = ((int *)data)[0];
793 kbd->kb_delay2 = ((int *)data)[1];
798 error = set_typematic(kbd, *(int *)data);
806 return (genkbd_commonioctl(kbd, cmd, data));
812 static int akbd_lock(keyboard_t *kbd, int lock)
817 static void akbd_clear_state(keyboard_t *kbd)
819 struct adb_kbd_softc *sc;
821 sc = (struct adb_kbd_softc *)(kbd);
823 mtx_lock(&sc->sc_mutex);
826 callout_stop(&sc->sc_repeater);
828 #if defined(AKBD_EMULATE_ATKBD)
829 sc->at_buffered_char[0] = 0;
830 sc->at_buffered_char[1] = 0;
832 mtx_unlock(&sc->sc_mutex);
835 static int akbd_get_state(keyboard_t *kbd, void *buf, size_t len)
840 static int akbd_set_state(keyboard_t *kbd, void *buf, size_t len)
845 static int akbd_poll(keyboard_t *kbd, int on)
851 akbd_modevent(module_t mod, int type, void *data)
855 kbd_add_driver(&akbd_kbd_driver);
859 kbd_delete_driver(&akbd_kbd_driver);
870 adb_fn_keys(SYSCTL_HANDLER_ARGS)
872 struct adb_kbd_softc *sc = arg1;
874 uint16_t is_fn_enabled;
875 unsigned int is_fn_enabled_sysctl;
877 adb_read_register(sc->sc_dev, 1, &is_fn_enabled);
879 is_fn_enabled_sysctl = is_fn_enabled;
880 error = sysctl_handle_int(oidp, &is_fn_enabled_sysctl, 0, req);
882 if (error || !req->newptr)
885 is_fn_enabled = is_fn_enabled_sysctl;
886 if (is_fn_enabled != 1 && is_fn_enabled != 0)
889 adb_write_register(sc->sc_dev, 1, 2, &is_fn_enabled);
893 DEV_MODULE(akbd, akbd_modevent, NULL);