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