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