xref: /freebsd/sys/dev/adb/adb_kbd.c (revision 2008043f386721d58158e37e0d7e50df8095942d)
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/cdefs.h>
29 #include <sys/param.h>
30 #include <sys/systm.h>
31 #include <sys/lock.h>
32 #include <sys/module.h>
33 #include <sys/mutex.h>
34 #include <sys/bus.h>
35 #include <sys/conf.h>
36 #include <sys/kbio.h>
37 #include <sys/condvar.h>
38 #include <sys/callout.h>
39 #include <sys/kernel.h>
40 #include <sys/sysctl.h>
41 
42 #include <machine/bus.h>
43 
44 #include "opt_kbd.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>
49 
50 #include <vm/vm.h>
51 #include <vm/pmap.h>
52 
53 #include "adb.h"
54 
55 #define KBD_DRIVER_NAME "akbd"
56 
57 #define AKBD_EMULATE_ATKBD 1
58 
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);
64 
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);
67 
68 struct adb_kbd_softc {
69 	keyboard_t sc_kbd;
70 
71 	device_t sc_dev;
72 	struct mtx sc_mutex;
73 	struct cv  sc_cv;
74 
75 	int sc_mode;
76 	int sc_state;
77 
78 	int have_led_control;
79 
80 	uint8_t buffer[8];
81 #ifdef AKBD_EMULATE_ATKBD
82 	uint8_t at_buffered_char[2];
83 #endif
84 	volatile int buffers;
85 
86 	struct callout sc_repeater;
87 	int sc_repeatstart;
88 	int sc_repeatcontinue;
89 	uint8_t last_press;
90 };
91 
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),
100 
101 	/* ADB interface */
102 	DEVMETHOD(adb_receive_packet,	adb_kbd_receive_packet),
103 	{ 0, 0 }
104 };
105 
106 static driver_t adb_kbd_driver = {
107 	"akbd",
108 	adb_kbd_methods,
109 	sizeof(struct adb_kbd_softc),
110 };
111 
112 DRIVER_MODULE(akbd, adb, adb_kbd_driver, 0, 0);
113 
114 #ifdef AKBD_EMULATE_ATKBD
115 
116 #define	SCAN_PRESS		0x000
117 #define	SCAN_RELEASE		0x080
118 #define	SCAN_PREFIX_E0		0x100
119 #define	SCAN_PREFIX_E1		0x200
120 #define	SCAN_PREFIX_CTL		0x400
121 #define	SCAN_PREFIX_SHIFT	0x800
122 #define	SCAN_PREFIX		(SCAN_PREFIX_E0 | SCAN_PREFIX_E1 |	\
123 				SCAN_PREFIX_CTL | SCAN_PREFIX_SHIFT)
124 
125 static const uint8_t adb_to_at_scancode_map[128] = { 30, 31, 32, 33, 35, 34,
126 	44, 45, 46, 47, 0, 48, 16, 17, 18, 19, 21, 20, 2, 3, 4, 5, 7, 6, 13,
127 	10, 8, 12, 9, 11, 27, 24, 22, 26, 23, 25, 28, 38, 36, 40, 37, 39, 43,
128 	51, 53, 49, 50, 52, 15, 57, 41, 14, 0, 1, 29, 0, 42, 58, 56, 97, 98,
129 	100, 95, 0, 0, 83, 0, 55, 0, 78, 0, 69, 0, 0, 0, 91, 89, 0, 74, 13, 0,
130 	0, 82, 79, 80, 81, 75, 76, 77, 71, 0, 72, 73, 0, 0, 0, 63, 64, 65, 61,
131 	66, 67, 0, 87, 0, 105, 0, 70, 0, 68, 0, 88, 0, 107, 102, 94, 96, 103,
132 	62, 99, 60, 101, 59, 54, 93, 90, 0, 0 };
133 
134 static int
135 keycode2scancode(int keycode, int shift, int up)
136 {
137 	static const int scan[] = {
138 		/* KP enter, right ctrl, KP divide */
139 		0x1c , 0x1d , 0x35 ,
140 		/* print screen */
141 		0x37 | SCAN_PREFIX_SHIFT,
142 		/* right alt, home, up, page up, left, right, end */
143 		0x38, 0x47, 0x48, 0x49, 0x4b, 0x4d, 0x4f,
144 		/* down, page down, insert, delete */
145 		0x50, 0x51, 0x52, 0x53,
146 		/* pause/break (see also below) */
147 		0x46,
148 		/*
149 		 * MS: left window, right window, menu
150 		 * also Sun: left meta, right meta, compose
151 		 */
152 		0x5b, 0x5c, 0x5d,
153 		/* Sun type 6 USB */
154 		/* help, stop, again, props, undo, front, copy */
155 		0x68, 0x5e, 0x5f, 0x60,	0x61, 0x62, 0x63,
156 		/* open, paste, find, cut, audiomute, audiolower, audioraise */
157 		0x64, 0x65, 0x66, 0x67, 0x25, 0x1f, 0x1e,
158 		/* power */
159 		0x20
160 	};
161 	int scancode;
162 
163 	scancode = keycode;
164 	if ((keycode >= 89) && (keycode < 89 + nitems(scan)))
165 	scancode = scan[keycode - 89] | SCAN_PREFIX_E0;
166 	/* pause/break */
167 	if ((keycode == 104) && !(shift & CTLS))
168 		scancode = 0x45 | SCAN_PREFIX_E1 | SCAN_PREFIX_CTL;
169 	if (shift & SHIFTS)
170 		scancode &= ~SCAN_PREFIX_SHIFT;
171 	return (scancode | (up ? SCAN_RELEASE : SCAN_PRESS));
172 }
173 #endif
174 
175 /* keyboard driver declaration */
176 static int              akbd_configure(int flags);
177 static kbd_probe_t      akbd_probe;
178 static kbd_init_t       akbd_init;
179 static kbd_term_t       akbd_term;
180 static kbd_intr_t       akbd_interrupt;
181 static kbd_test_if_t    akbd_test_if;
182 static kbd_enable_t     akbd_enable;
183 static kbd_disable_t    akbd_disable;
184 static kbd_read_t       akbd_read;
185 static kbd_check_t      akbd_check;
186 static kbd_read_char_t  akbd_read_char;
187 static kbd_check_char_t akbd_check_char;
188 static kbd_ioctl_t      akbd_ioctl;
189 static kbd_lock_t       akbd_lock;
190 static kbd_clear_state_t akbd_clear_state;
191 static kbd_get_state_t  akbd_get_state;
192 static kbd_set_state_t  akbd_set_state;
193 static kbd_poll_mode_t  akbd_poll;
194 
195 keyboard_switch_t akbdsw = {
196         .probe =	akbd_probe,
197         .init =		akbd_init,
198         .term =		akbd_term,
199         .intr =		akbd_interrupt,
200         .test_if =	akbd_test_if,
201         .enable =	akbd_enable,
202         .disable =	akbd_disable,
203         .read =		akbd_read,
204         .check =	akbd_check,
205         .read_char =	akbd_read_char,
206         .check_char =	akbd_check_char,
207         .ioctl =	akbd_ioctl,
208         .lock =		akbd_lock,
209         .clear_state =	akbd_clear_state,
210         .get_state =	akbd_get_state,
211         .set_state =	akbd_set_state,
212         .poll =		akbd_poll,
213 };
214 
215 KEYBOARD_DRIVER(akbd, akbdsw, akbd_configure);
216 
217 static int
218 adb_kbd_probe(device_t dev)
219 {
220 	uint8_t type;
221 
222 	type = adb_get_device_type(dev);
223 
224 	if (type != ADB_DEVICE_KEYBOARD)
225 		return (ENXIO);
226 
227 	switch(adb_get_device_handler(dev)) {
228 	case 1:
229 		device_set_desc(dev,"Apple Standard Keyboard");
230 		break;
231 	case 2:
232 		device_set_desc(dev,"Apple Extended Keyboard");
233 		break;
234 	case 4:
235 		device_set_desc(dev,"Apple ISO Keyboard");
236 		break;
237 	case 5:
238 		device_set_desc(dev,"Apple Extended ISO Keyboard");
239 		break;
240 	case 8:
241 		device_set_desc(dev,"Apple Keyboard II");
242 		break;
243 	case 9:
244 		device_set_desc(dev,"Apple ISO Keyboard II");
245 		break;
246 	case 12:
247 		device_set_desc(dev,"PowerBook Keyboard");
248 		break;
249 	case 13:
250 		device_set_desc(dev,"PowerBook ISO Keyboard");
251 		break;
252 	case 24:
253 		device_set_desc(dev,"PowerBook Extended Keyboard");
254 		break;
255 	case 27:
256 		device_set_desc(dev,"Apple Design Keyboard");
257 		break;
258 	case 195:
259 		device_set_desc(dev,"PowerBook G3 Keyboard");
260 		break;
261 	case 196:
262 		device_set_desc(dev,"iBook Keyboard");
263 		break;
264 	default:
265 		device_set_desc(dev,"ADB Keyboard");
266 		break;
267 	}
268 
269 	return (0);
270 }
271 
272 static int
273 ms_to_ticks(int ms)
274 {
275 	if (hz > 1000)
276 		return ms*(hz/1000);
277 
278 	return ms/(1000/hz);
279 }
280 
281 static int
282 adb_kbd_attach(device_t dev)
283 {
284 	struct adb_kbd_softc *sc;
285 	keyboard_switch_t *sw;
286 	uint32_t fkeys;
287 	phandle_t handle;
288 
289 	sw = kbd_get_switch(KBD_DRIVER_NAME);
290 	if (sw == NULL) {
291 		return ENXIO;
292 	}
293 
294 	sc = device_get_softc(dev);
295 	sc->sc_dev = dev;
296 	sc->sc_mode = K_RAW;
297 	sc->sc_state = 0;
298 	sc->have_led_control = 0;
299 	sc->buffers = 0;
300 
301 	/* Try stepping forward to the extended keyboard protocol */
302 	adb_set_device_handler(dev,3);
303 
304 	mtx_init(&sc->sc_mutex, KBD_DRIVER_NAME, NULL, MTX_DEF);
305 	cv_init(&sc->sc_cv,KBD_DRIVER_NAME);
306 	callout_init(&sc->sc_repeater, 0);
307 
308 #ifdef AKBD_EMULATE_ATKBD
309 	kbd_init_struct(&sc->sc_kbd, KBD_DRIVER_NAME, KB_101, 0, 0, 0, 0);
310 	kbd_set_maps(&sc->sc_kbd, &key_map, &accent_map, fkey_tab,
311             sizeof(fkey_tab) / sizeof(fkey_tab[0]));
312 #else
313 	#error ADB raw mode not implemented
314 #endif
315 
316 	KBD_FOUND_DEVICE(&sc->sc_kbd);
317 	KBD_PROBE_DONE(&sc->sc_kbd);
318 	KBD_INIT_DONE(&sc->sc_kbd);
319 	KBD_CONFIG_DONE(&sc->sc_kbd);
320 
321 	(*sw->enable)(&sc->sc_kbd);
322 
323 	kbd_register(&sc->sc_kbd);
324 
325 #ifdef KBD_INSTALL_CDEV
326 	if (kbd_attach(&sc->sc_kbd)) {
327 		adb_kbd_detach(dev);
328 		return ENXIO;
329 	}
330 #endif
331 
332 	/* Check if we can read out the LED state from
333 	   this keyboard by reading the key state register */
334 	if (adb_read_register(dev, 2, NULL) == 2)
335 		sc->have_led_control = 1;
336 
337 	adb_set_autopoll(dev,1);
338 
339 	handle = OF_finddevice("mac-io/via-pmu/adb/keyboard");
340 	if (handle != -1 && OF_getprop(handle, "AAPL,has-embedded-fn-keys",
341 	    &fkeys, sizeof(fkeys)) != -1) {
342 		static const char *key_names[] = {"F1", "F2", "F3", "F4", "F5",
343 		    "F6", "F7", "F8", "F9", "F10", "F11", "F12"};
344 		struct sysctl_ctx_list *ctx;
345 		struct sysctl_oid *tree;
346 		int i;
347 
348 		if (bootverbose)
349 			device_printf(dev, "Keyboard has embedded Fn keys\n");
350 
351 		for (i = 0; i < 12; i++) {
352 			uint32_t keyval;
353 			char buf[3];
354 			if (OF_getprop(handle, key_names[i], &keyval,
355 			    sizeof(keyval)) < 0)
356 				continue;
357 			buf[0] = 1;
358 			buf[1] = i+1;
359 			buf[2] = keyval;
360 			adb_write_register(dev, 0, 3, buf);
361 		}
362 		adb_write_register(dev, 1, 2, &(uint16_t){0});
363 
364 		ctx = device_get_sysctl_ctx(dev);
365 		tree = device_get_sysctl_tree(dev);
366 
367 		SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
368 		    "fn_keys_function_as_primary",
369 		    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, 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 	if (code & ~0x7f)
690 		return EINVAL;
691 	kbd->kb_delay1 = kbdelays[(code >> 5) & 3];
692 	kbd->kb_delay2 = kbrates[code & 0x1f];
693 	return 0;
694 }
695 
696 static int akbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t data)
697 {
698 	struct adb_kbd_softc *sc;
699 	uint16_t r2;
700 	int error;
701 
702 	sc = (struct adb_kbd_softc *)(kbd);
703 	error = 0;
704 
705 	switch (cmd) {
706 	case KDGKBMODE:
707 		*(int *)data = sc->sc_mode;
708 		break;
709 	case KDSKBMODE:
710 		switch (*(int *)data) {
711 		case K_XLATE:
712 			if (sc->sc_mode != K_XLATE) {
713 				/* make lock key state and LED state match */
714 				sc->sc_state &= ~LOCK_MASK;
715 				sc->sc_state |= KBD_LED_VAL(kbd);
716 			}
717 			/* FALLTHROUGH */
718 		case K_RAW:
719 		case K_CODE:
720 			if (sc->sc_mode != *(int *)data)
721 				sc->sc_mode = *(int *)data;
722 			break;
723 		default:
724 			error = EINVAL;
725 			break;
726 		}
727 
728 		break;
729 
730 	case KDGETLED:
731 		*(int *)data = KBD_LED_VAL(kbd);
732 		break;
733 
734 	case KDSKBSTATE:
735 		if (*(int *)data & ~LOCK_MASK) {
736 			error = EINVAL;
737 			break;
738 		}
739 		sc->sc_state &= ~LOCK_MASK;
740 		sc->sc_state |= *(int *)data;
741 
742 		/* FALLTHROUGH */
743 
744 	case KDSETLED:
745 		KBD_LED_VAL(kbd) = *(int *)data;
746 
747 		if (!sc->have_led_control)
748 			break;
749 
750 		r2 = (~0 & 0x04) | 3;
751 
752 		if (*(int *)data & NLKED)
753 			r2 &= ~1;
754 		if (*(int *)data & CLKED)
755 			r2 &= ~2;
756 		if (*(int *)data & SLKED)
757 			r2 &= ~4;
758 
759 		adb_send_packet(sc->sc_dev,ADB_COMMAND_LISTEN,2,
760 			sizeof(uint16_t),(u_char *)&r2);
761 
762 		break;
763 
764 	case KDGKBSTATE:
765 		*(int *)data = sc->sc_state & LOCK_MASK;
766 		break;
767 
768 	case KDSETREPEAT:
769 		if (!KBD_HAS_DEVICE(kbd))
770 			return 0;
771 		if (((int *)data)[1] < 0)
772 			return EINVAL;
773 		if (((int *)data)[0] < 0)
774 			return EINVAL;
775 		else if (((int *)data)[0] == 0)  /* fastest possible value */
776 			kbd->kb_delay1 = 200;
777 		else
778 			kbd->kb_delay1 = ((int *)data)[0];
779 		kbd->kb_delay2 = ((int *)data)[1];
780 
781 		break;
782 
783 	case KDSETRAD:
784 		error = set_typematic(kbd, *(int *)data);
785 		break;
786 
787 	case PIO_KEYMAP:
788 	case PIO_KEYMAPENT:
789 	case PIO_DEADKEYMAP:
790 #ifdef COMPAT_FREEBSD13
791 	case OPIO_KEYMAP:
792 	case OPIO_DEADKEYMAP:
793 #endif /* COMPAT_FREEBSD13 */
794 	default:
795 		return (genkbd_commonioctl(kbd, cmd, data));
796 	}
797 
798 	return (error);
799 }
800 
801 static int akbd_lock(keyboard_t *kbd, int lock)
802 {
803 	return (0);
804 }
805 
806 static void akbd_clear_state(keyboard_t *kbd)
807 {
808 	struct adb_kbd_softc *sc;
809 
810 	sc = (struct adb_kbd_softc *)(kbd);
811 
812 	mtx_lock(&sc->sc_mutex);
813 
814 	sc->buffers = 0;
815 	callout_stop(&sc->sc_repeater);
816 
817 #if defined(AKBD_EMULATE_ATKBD)
818 	sc->at_buffered_char[0] = 0;
819 	sc->at_buffered_char[1] = 0;
820 #endif
821 	mtx_unlock(&sc->sc_mutex);
822 }
823 
824 static int akbd_get_state(keyboard_t *kbd, void *buf, size_t len)
825 {
826 	return (0);
827 }
828 
829 static int akbd_set_state(keyboard_t *kbd, void *buf, size_t len)
830 {
831 	return (0);
832 }
833 
834 static int akbd_poll(keyboard_t *kbd, int on)
835 {
836 	return (0);
837 }
838 
839 static int
840 akbd_modevent(module_t mod, int type, void *data)
841 {
842 	switch (type) {
843 	case MOD_LOAD:
844 		kbd_add_driver(&akbd_kbd_driver);
845 		break;
846 
847 	case MOD_UNLOAD:
848 		kbd_delete_driver(&akbd_kbd_driver);
849 		break;
850 
851 	default:
852 		return (EOPNOTSUPP);
853 	}
854 
855 	return (0);
856 }
857 
858 static int
859 adb_fn_keys(SYSCTL_HANDLER_ARGS)
860 {
861 	struct adb_kbd_softc *sc = arg1;
862 	int error;
863 	uint16_t is_fn_enabled;
864 	unsigned int is_fn_enabled_sysctl;
865 
866 	adb_read_register(sc->sc_dev, 1, &is_fn_enabled);
867 	is_fn_enabled &= 1;
868 	is_fn_enabled_sysctl = is_fn_enabled;
869 	error = sysctl_handle_int(oidp, &is_fn_enabled_sysctl, 0, req);
870 
871 	if (error || !req->newptr)
872 		return (error);
873 
874 	is_fn_enabled = is_fn_enabled_sysctl;
875 	if (is_fn_enabled != 1 && is_fn_enabled != 0)
876 		return (EINVAL);
877 
878 	adb_write_register(sc->sc_dev, 1, 2, &is_fn_enabled);
879 	return (0);
880 }
881 
882 DEV_MODULE(akbd, akbd_modevent, NULL);
883