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>
33 #include <sys/module.h>
37 #include <sys/condvar.h>
38 #include <sys/callout.h>
39 #include <sys/kernel.h>
40 #include <sys/sysctl.h>
42 #include <machine/bus.h>
45 #include <dev/kbd/kbdreg.h>
46 #include <dev/kbd/kbdtables.h>
47 #include <dev/ofw/openfirm.h>
48 #include <dev/ofw/ofw_bus.h>
55 #define KBD_DRIVER_NAME "akbd"
57 #define AKBD_EMULATE_ATKBD 1
59 static int adb_kbd_probe(device_t dev);
60 static int adb_kbd_attach(device_t dev);
61 static int adb_kbd_detach(device_t dev);
62 static void akbd_repeat(void *xsc);
63 static int adb_fn_keys(SYSCTL_HANDLER_ARGS);
65 static u_int adb_kbd_receive_packet(device_t dev, u_char status,
66 u_char command, u_char reg, int len, u_char *data);
68 struct adb_kbd_softc {
81 #ifdef AKBD_EMULATE_ATKBD
82 uint8_t at_buffered_char[2];
86 struct callout sc_repeater;
88 int sc_repeatcontinue;
92 static device_method_t adb_kbd_methods[] = {
93 /* Device interface */
94 DEVMETHOD(device_probe, adb_kbd_probe),
95 DEVMETHOD(device_attach, adb_kbd_attach),
96 DEVMETHOD(device_detach, adb_kbd_detach),
97 DEVMETHOD(device_shutdown, bus_generic_shutdown),
98 DEVMETHOD(device_suspend, bus_generic_suspend),
99 DEVMETHOD(device_resume, bus_generic_resume),
102 DEVMETHOD(adb_receive_packet, adb_kbd_receive_packet),
107 static driver_t adb_kbd_driver = {
110 sizeof(struct adb_kbd_softc),
113 static devclass_t adb_kbd_devclass;
115 DRIVER_MODULE(akbd, adb, adb_kbd_driver, adb_kbd_devclass, 0, 0);
117 #ifdef AKBD_EMULATE_ATKBD
119 #define SCAN_PRESS 0x000
120 #define SCAN_RELEASE 0x080
121 #define SCAN_PREFIX_E0 0x100
122 #define SCAN_PREFIX_E1 0x200
123 #define SCAN_PREFIX_CTL 0x400
124 #define SCAN_PREFIX_SHIFT 0x800
125 #define SCAN_PREFIX (SCAN_PREFIX_E0 | SCAN_PREFIX_E1 | \
126 SCAN_PREFIX_CTL | SCAN_PREFIX_SHIFT)
128 static const uint8_t adb_to_at_scancode_map[128] = { 30, 31, 32, 33, 35, 34,
129 44, 45, 46, 47, 0, 48, 16, 17, 18, 19, 21, 20, 2, 3, 4, 5, 7, 6, 13,
130 10, 8, 12, 9, 11, 27, 24, 22, 26, 23, 25, 28, 38, 36, 40, 37, 39, 43,
131 51, 53, 49, 50, 52, 15, 57, 41, 14, 0, 1, 29, 0, 42, 58, 56, 97, 98,
132 100, 95, 0, 0, 83, 0, 55, 0, 78, 0, 69, 0, 0, 0, 91, 89, 0, 74, 13, 0,
133 0, 82, 79, 80, 81, 75, 76, 77, 71, 0, 72, 73, 0, 0, 0, 63, 64, 65, 61,
134 66, 67, 0, 87, 0, 105, 0, 70, 0, 68, 0, 88, 0, 107, 102, 94, 96, 103,
135 62, 99, 60, 101, 59, 54, 93, 90, 0, 0 };
138 keycode2scancode(int keycode, int shift, int up)
140 static const int scan[] = {
141 /* KP enter, right ctrl, KP divide */
144 0x37 | SCAN_PREFIX_SHIFT,
145 /* right alt, home, up, page up, left, right, end */
146 0x38, 0x47, 0x48, 0x49, 0x4b, 0x4d, 0x4f,
147 /* down, page down, insert, delete */
148 0x50, 0x51, 0x52, 0x53,
149 /* pause/break (see also below) */
152 * MS: left window, right window, menu
153 * also Sun: left meta, right meta, compose
157 /* help, stop, again, props, undo, front, copy */
158 0x68, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63,
159 /* open, paste, find, cut, audiomute, audiolower, audioraise */
160 0x64, 0x65, 0x66, 0x67, 0x25, 0x1f, 0x1e,
167 if ((keycode >= 89) && (keycode < 89 + nitems(scan)))
168 scancode = scan[keycode - 89] | SCAN_PREFIX_E0;
170 if ((keycode == 104) && !(shift & CTLS))
171 scancode = 0x45 | SCAN_PREFIX_E1 | SCAN_PREFIX_CTL;
173 scancode &= ~SCAN_PREFIX_SHIFT;
174 return (scancode | (up ? SCAN_RELEASE : SCAN_PRESS));
178 /* keyboard driver declaration */
179 static int akbd_configure(int flags);
180 static kbd_probe_t akbd_probe;
181 static kbd_init_t akbd_init;
182 static kbd_term_t akbd_term;
183 static kbd_intr_t akbd_interrupt;
184 static kbd_test_if_t akbd_test_if;
185 static kbd_enable_t akbd_enable;
186 static kbd_disable_t akbd_disable;
187 static kbd_read_t akbd_read;
188 static kbd_check_t akbd_check;
189 static kbd_read_char_t akbd_read_char;
190 static kbd_check_char_t akbd_check_char;
191 static kbd_ioctl_t akbd_ioctl;
192 static kbd_lock_t akbd_lock;
193 static kbd_clear_state_t akbd_clear_state;
194 static kbd_get_state_t akbd_get_state;
195 static kbd_set_state_t akbd_set_state;
196 static kbd_poll_mode_t akbd_poll;
198 keyboard_switch_t akbdsw = {
220 KEYBOARD_DRIVER(akbd, akbdsw, akbd_configure);
223 adb_kbd_probe(device_t dev)
227 type = adb_get_device_type(dev);
229 if (type != ADB_DEVICE_KEYBOARD)
232 switch(adb_get_device_handler(dev)) {
234 device_set_desc(dev,"Apple Standard Keyboard");
237 device_set_desc(dev,"Apple Extended Keyboard");
240 device_set_desc(dev,"Apple ISO Keyboard");
243 device_set_desc(dev,"Apple Extended ISO Keyboard");
246 device_set_desc(dev,"Apple Keyboard II");
249 device_set_desc(dev,"Apple ISO Keyboard II");
252 device_set_desc(dev,"PowerBook Keyboard");
255 device_set_desc(dev,"PowerBook ISO Keyboard");
258 device_set_desc(dev,"PowerBook Extended Keyboard");
261 device_set_desc(dev,"Apple Design Keyboard");
264 device_set_desc(dev,"PowerBook G3 Keyboard");
267 device_set_desc(dev,"iBook Keyboard");
270 device_set_desc(dev,"ADB Keyboard");
287 adb_kbd_attach(device_t dev)
289 struct adb_kbd_softc *sc;
290 keyboard_switch_t *sw;
294 sw = kbd_get_switch(KBD_DRIVER_NAME);
299 sc = device_get_softc(dev);
303 sc->have_led_control = 0;
306 /* Try stepping forward to the extended keyboard protocol */
307 adb_set_device_handler(dev,3);
309 mtx_init(&sc->sc_mutex, KBD_DRIVER_NAME, NULL, MTX_DEF);
310 cv_init(&sc->sc_cv,KBD_DRIVER_NAME);
311 callout_init(&sc->sc_repeater, 0);
313 #ifdef AKBD_EMULATE_ATKBD
314 kbd_init_struct(&sc->sc_kbd, KBD_DRIVER_NAME, KB_101, 0, 0, 0, 0);
315 kbd_set_maps(&sc->sc_kbd, &key_map, &accent_map, fkey_tab,
316 sizeof(fkey_tab) / sizeof(fkey_tab[0]));
318 #error ADB raw mode not implemented
321 KBD_FOUND_DEVICE(&sc->sc_kbd);
322 KBD_PROBE_DONE(&sc->sc_kbd);
323 KBD_INIT_DONE(&sc->sc_kbd);
324 KBD_CONFIG_DONE(&sc->sc_kbd);
326 (*sw->enable)(&sc->sc_kbd);
328 kbd_register(&sc->sc_kbd);
330 #ifdef KBD_INSTALL_CDEV
331 if (kbd_attach(&sc->sc_kbd)) {
337 /* Check if we can read out the LED state from
338 this keyboard by reading the key state register */
339 if (adb_read_register(dev, 2, NULL) == 2)
340 sc->have_led_control = 1;
342 adb_set_autopoll(dev,1);
344 handle = OF_finddevice("mac-io/via-pmu/adb/keyboard");
345 if (handle != -1 && OF_getprop(handle, "AAPL,has-embedded-fn-keys",
346 &fkeys, sizeof(fkeys)) != -1) {
347 static const char *key_names[] = {"F1", "F2", "F3", "F4", "F5",
348 "F6", "F7", "F8", "F9", "F10", "F11", "F12"};
349 struct sysctl_ctx_list *ctx;
350 struct sysctl_oid *tree;
354 device_printf(dev, "Keyboard has embedded Fn keys\n");
356 for (i = 0; i < 12; i++) {
359 if (OF_getprop(handle, key_names[i], &keyval,
365 adb_write_register(dev, 0, 3, buf);
367 adb_write_register(dev, 1, 2, &(uint16_t){0});
369 ctx = device_get_sysctl_ctx(dev);
370 tree = device_get_sysctl_tree(dev);
372 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
373 "fn_keys_function_as_primary", CTLTYPE_INT | CTLFLAG_RW, sc,
375 "Set the Fn keys to be their F-key type as default");
382 adb_kbd_detach(device_t dev)
384 struct adb_kbd_softc *sc;
387 sc = device_get_softc(dev);
389 adb_set_autopoll(dev,0);
390 callout_stop(&sc->sc_repeater);
392 mtx_lock(&sc->sc_mutex);
394 kbd = kbd_get_keyboard(kbd_find_keyboard(KBD_DRIVER_NAME,
395 device_get_unit(dev)));
399 #ifdef KBD_INSTALL_CDEV
405 mtx_unlock(&sc->sc_mutex);
407 mtx_destroy(&sc->sc_mutex);
408 cv_destroy(&sc->sc_cv);
414 adb_kbd_receive_packet(device_t dev, u_char status,
415 u_char command, u_char reg, int len, u_char *data)
417 struct adb_kbd_softc *sc;
419 sc = device_get_softc(dev);
421 if (command != ADB_COMMAND_TALK)
424 if (reg != 0 || len != 2)
427 mtx_lock(&sc->sc_mutex);
428 /* 0x7f is always the power button */
429 if (data[0] == 0x7f) {
430 devctl_notify("PMU", "Button", "pressed", NULL);
431 mtx_unlock(&sc->sc_mutex);
433 } else if (data[0] == 0xff) {
434 mtx_unlock(&sc->sc_mutex);
435 return (0); /* Ignore power button release. */
437 if ((data[0] & 0x7f) == 57 && sc->buffers < 7) {
438 /* Fake the down/up cycle for caps lock */
439 sc->buffer[sc->buffers++] = data[0] & 0x7f;
440 sc->buffer[sc->buffers++] = (data[0] & 0x7f) | (1 << 7);
442 sc->buffer[sc->buffers++] = data[0];
444 if (sc->buffer[sc->buffers-1] < 0xff)
445 sc->last_press = sc->buffer[sc->buffers-1];
447 if ((data[1] & 0x7f) == 57 && sc->buffers < 7) {
448 /* Fake the down/up cycle for caps lock */
449 sc->buffer[sc->buffers++] = data[1] & 0x7f;
450 sc->buffer[sc->buffers++] = (data[1] & 0x7f) | (1 << 7);
452 sc->buffer[sc->buffers++] = data[1];
455 if (sc->buffer[sc->buffers-1] < 0xff)
456 sc->last_press = sc->buffer[sc->buffers-1];
458 /* Stop any existing key repeating */
459 callout_stop(&sc->sc_repeater);
461 /* Schedule a repeat callback on keydown */
462 if (!(sc->last_press & (1 << 7))) {
463 callout_reset(&sc->sc_repeater,
464 ms_to_ticks(sc->sc_kbd.kb_delay1), akbd_repeat, sc);
466 mtx_unlock(&sc->sc_mutex);
468 cv_broadcast(&sc->sc_cv);
470 if (KBD_IS_ACTIVE(&sc->sc_kbd) && KBD_IS_BUSY(&sc->sc_kbd)) {
471 sc->sc_kbd.kb_callback.kc_func(&sc->sc_kbd,
472 KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg);
479 akbd_repeat(void *xsc) {
480 struct adb_kbd_softc *sc = xsc;
483 /* Fake an up/down key repeat so long as we have the
485 mtx_lock(&sc->sc_mutex);
486 if (sc->buffers < 7) {
487 sc->buffer[sc->buffers++] = sc->last_press | (1 << 7);
488 sc->buffer[sc->buffers++] = sc->last_press;
492 mtx_unlock(&sc->sc_mutex);
494 if (notify_kbd && KBD_IS_ACTIVE(&sc->sc_kbd)
495 && KBD_IS_BUSY(&sc->sc_kbd)) {
496 sc->sc_kbd.kb_callback.kc_func(&sc->sc_kbd,
497 KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg);
500 /* Reschedule the callout */
501 callout_reset(&sc->sc_repeater, ms_to_ticks(sc->sc_kbd.kb_delay2),
506 akbd_configure(int flags)
512 akbd_probe(int unit, void *arg, int flags)
518 akbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
524 akbd_term(keyboard_t *kbd)
530 akbd_interrupt(keyboard_t *kbd, void *arg)
536 akbd_test_if(keyboard_t *kbd)
542 akbd_enable(keyboard_t *kbd)
549 akbd_disable(keyboard_t *kbd)
551 struct adb_kbd_softc *sc;
552 sc = (struct adb_kbd_softc *)(kbd);
554 callout_stop(&sc->sc_repeater);
560 akbd_read(keyboard_t *kbd, int wait)
566 akbd_check(keyboard_t *kbd)
568 struct adb_kbd_softc *sc;
570 if (!KBD_IS_ACTIVE(kbd))
573 sc = (struct adb_kbd_softc *)(kbd);
575 mtx_lock(&sc->sc_mutex);
576 #ifdef AKBD_EMULATE_ATKBD
577 if (sc->at_buffered_char[0]) {
578 mtx_unlock(&sc->sc_mutex);
583 if (sc->buffers > 0) {
584 mtx_unlock(&sc->sc_mutex);
587 mtx_unlock(&sc->sc_mutex);
593 akbd_read_char(keyboard_t *kbd, int wait)
595 struct adb_kbd_softc *sc;
600 sc = (struct adb_kbd_softc *)(kbd);
602 mtx_lock(&sc->sc_mutex);
604 #if defined(AKBD_EMULATE_ATKBD)
605 if (sc->sc_mode == K_RAW && sc->at_buffered_char[0]) {
606 key = sc->at_buffered_char[0];
607 if (key & SCAN_PREFIX) {
608 sc->at_buffered_char[0] = key & ~SCAN_PREFIX;
609 key = (key & SCAN_PREFIX_E0) ? 0xe0 : 0xe1;
611 sc->at_buffered_char[0] = sc->at_buffered_char[1];
612 sc->at_buffered_char[1] = 0;
615 mtx_unlock(&sc->sc_mutex);
621 if (!sc->buffers && wait)
622 cv_wait(&sc->sc_cv,&sc->sc_mutex);
625 mtx_unlock(&sc->sc_mutex);
629 adb_code = sc->buffer[0];
631 for (i = 1; i < sc->buffers; i++)
632 sc->buffer[i-1] = sc->buffer[i];
636 #ifdef AKBD_EMULATE_ATKBD
637 key = adb_to_at_scancode_map[adb_code & 0x7f];
638 if (sc->sc_mode == K_CODE) {
639 /* Add the key-release bit */
640 key |= adb_code & 0x80;
641 } else if (sc->sc_mode == K_RAW) {
643 * In the raw case, we have to emulate the gross
644 * variable-length AT keyboard thing. Since this code
645 * is copied from sunkbd, which is the same code
646 * as ukbd, it might be nice to have this centralized.
649 key = keycode2scancode(key,
652 if (key & SCAN_PREFIX) {
653 if (key & SCAN_PREFIX_CTL) {
654 sc->at_buffered_char[0] =
655 0x1d | (key & SCAN_RELEASE);
656 sc->at_buffered_char[1] =
658 } else if (key & SCAN_PREFIX_SHIFT) {
659 sc->at_buffered_char[0] =
660 0x2a | (key & SCAN_RELEASE);
661 sc->at_buffered_char[1] =
662 key & ~SCAN_PREFIX_SHIFT;
664 sc->at_buffered_char[0] =
666 sc->at_buffered_char[1] = 0;
669 key = (key & SCAN_PREFIX_E0) ? 0xe0 : 0xe1;
676 mtx_unlock(&sc->sc_mutex);
682 akbd_check_char(keyboard_t *kbd)
684 if (!KBD_IS_ACTIVE(kbd))
687 return (akbd_check(kbd));
691 set_typematic(keyboard_t *kbd, int code)
693 /* These numbers are in microseconds, so convert to ticks */
695 static int delays[] = { 250, 500, 750, 1000 };
696 static int rates[] = { 34, 38, 42, 46, 50, 55, 59, 63,
697 68, 76, 84, 92, 100, 110, 118, 126,
698 136, 152, 168, 184, 200, 220, 236, 252,
699 272, 304, 336, 368, 400, 440, 472, 504 };
703 kbd->kb_delay1 = delays[(code >> 5) & 3];
704 kbd->kb_delay2 = rates[code & 0x1f];
708 static int akbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t data)
710 struct adb_kbd_softc *sc;
714 sc = (struct adb_kbd_softc *)(kbd);
719 *(int *)data = sc->sc_mode;
722 switch (*(int *)data) {
724 if (sc->sc_mode != K_XLATE) {
725 /* make lock key state and LED state match */
726 sc->sc_state &= ~LOCK_MASK;
727 sc->sc_state |= KBD_LED_VAL(kbd);
732 if (sc->sc_mode != *(int *)data)
733 sc->sc_mode = *(int *)data;
743 *(int *)data = KBD_LED_VAL(kbd);
747 if (*(int *)data & ~LOCK_MASK) {
751 sc->sc_state &= ~LOCK_MASK;
752 sc->sc_state |= *(int *)data;
757 KBD_LED_VAL(kbd) = *(int *)data;
759 if (!sc->have_led_control)
762 r2 = (~0 & 0x04) | 3;
764 if (*(int *)data & NLKED)
766 if (*(int *)data & CLKED)
768 if (*(int *)data & SLKED)
771 adb_send_packet(sc->sc_dev,ADB_COMMAND_LISTEN,2,
772 sizeof(uint16_t),(u_char *)&r2);
777 *(int *)data = sc->sc_state & LOCK_MASK;
781 if (!KBD_HAS_DEVICE(kbd))
783 if (((int *)data)[1] < 0)
785 if (((int *)data)[0] < 0)
787 else if (((int *)data)[0] == 0) /* fastest possible value */
788 kbd->kb_delay1 = 200;
790 kbd->kb_delay1 = ((int *)data)[0];
791 kbd->kb_delay2 = ((int *)data)[1];
796 error = set_typematic(kbd, *(int *)data);
804 return (genkbd_commonioctl(kbd, cmd, data));
810 static int akbd_lock(keyboard_t *kbd, int lock)
815 static void akbd_clear_state(keyboard_t *kbd)
817 struct adb_kbd_softc *sc;
819 sc = (struct adb_kbd_softc *)(kbd);
821 mtx_lock(&sc->sc_mutex);
824 callout_stop(&sc->sc_repeater);
826 #if defined(AKBD_EMULATE_ATKBD)
827 sc->at_buffered_char[0] = 0;
828 sc->at_buffered_char[1] = 0;
830 mtx_unlock(&sc->sc_mutex);
833 static int akbd_get_state(keyboard_t *kbd, void *buf, size_t len)
838 static int akbd_set_state(keyboard_t *kbd, void *buf, size_t len)
843 static int akbd_poll(keyboard_t *kbd, int on)
849 akbd_modevent(module_t mod, int type, void *data)
853 kbd_add_driver(&akbd_kbd_driver);
857 kbd_delete_driver(&akbd_kbd_driver);
868 adb_fn_keys(SYSCTL_HANDLER_ARGS)
870 struct adb_kbd_softc *sc = arg1;
872 uint16_t is_fn_enabled;
873 unsigned int is_fn_enabled_sysctl;
875 adb_read_register(sc->sc_dev, 1, &is_fn_enabled);
877 is_fn_enabled_sysctl = is_fn_enabled;
878 error = sysctl_handle_int(oidp, &is_fn_enabled_sysctl, 0, req);
880 if (error || !req->newptr)
883 is_fn_enabled = is_fn_enabled_sysctl;
884 if (is_fn_enabled != 1 && is_fn_enabled != 0)
887 adb_write_register(sc->sc_dev, 1, 2, &is_fn_enabled);
891 DEV_MODULE(akbd, akbd_modevent, NULL);