adb_kbd.c revision 224126
1145510Sdarrenr/*-
2145510Sdarrenr * Copyright (C) 2008 Nathan Whitehorn
3145510Sdarrenr * All rights reserved.
4145510Sdarrenr *
5145510Sdarrenr * Redistribution and use in source and binary forms, with or without
6145510Sdarrenr * modification, are permitted provided that the following conditions
7145510Sdarrenr * are met:
8145510Sdarrenr * 1. Redistributions of source code must retain the above copyright
9145510Sdarrenr *    notice, this list of conditions and the following disclaimer.
10145510Sdarrenr * 2. Redistributions in binary form must reproduce the above copyright
11145510Sdarrenr *    notice, this list of conditions and the following disclaimer in the
12145510Sdarrenr *    documentation and/or other materials provided with the distribution.
13145510Sdarrenr *
14145510Sdarrenr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15145510Sdarrenr * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16145510Sdarrenr * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17145510Sdarrenr * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
18145510Sdarrenr * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19145510Sdarrenr * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
20145510Sdarrenr * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
21145510Sdarrenr * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
22145510Sdarrenr * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
23145510Sdarrenr * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24145510Sdarrenr *
25145510Sdarrenr * $FreeBSD: head/sys/dev/adb/adb_kbd.c 224126 2011-07-17 08:19:19Z ed $
26145510Sdarrenr */
27145510Sdarrenr
28145510Sdarrenr#include <sys/cdefs.h>
29145510Sdarrenr#include <sys/param.h>
30145510Sdarrenr#include <sys/systm.h>
31145510Sdarrenr#include <sys/module.h>
32145510Sdarrenr#include <sys/bus.h>
33145510Sdarrenr#include <sys/conf.h>
34145510Sdarrenr#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
54static int adb_kbd_probe(device_t dev);
55static int adb_kbd_attach(device_t dev);
56static int adb_kbd_detach(device_t dev);
57static void akbd_repeat(void *xsc);
58
59static 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
62struct 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
86static 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
101static driver_t adb_kbd_driver = {
102	"akbd",
103	adb_kbd_methods,
104	sizeof(struct adb_kbd_softc),
105};
106
107static devclass_t adb_kbd_devclass;
108
109DRIVER_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
122static 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
131static int
132keycode2scancode(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 */
173static int              akbd_configure(int flags);
174static kbd_probe_t      akbd_probe;
175static kbd_init_t       akbd_init;
176static kbd_term_t       akbd_term;
177static kbd_intr_t       akbd_interrupt;
178static kbd_test_if_t    akbd_test_if;
179static kbd_enable_t     akbd_enable;
180static kbd_disable_t    akbd_disable;
181static kbd_read_t       akbd_read;
182static kbd_check_t      akbd_check;
183static kbd_read_char_t  akbd_read_char;
184static kbd_check_char_t akbd_check_char;
185static kbd_ioctl_t      akbd_ioctl;
186static kbd_lock_t       akbd_lock;
187static kbd_clear_state_t akbd_clear_state;
188static kbd_get_state_t  akbd_get_state;
189static kbd_set_state_t  akbd_set_state;
190static kbd_poll_mode_t  akbd_poll;
191
192keyboard_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
214KEYBOARD_DRIVER(akbd, akbdsw, akbd_configure);
215
216static int
217adb_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
271static int
272ms_to_ticks(int ms)
273{
274	if (hz > 1000)
275		return ms*(hz/1000);
276
277	return ms/(1000/hz);
278}
279
280static int
281adb_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
339static int
340adb_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
371static u_int
372adb_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
428static void
429akbd_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
455static int
456akbd_configure(int flags)
457{
458	return 0;
459}
460
461static int
462akbd_probe(int unit, void *arg, int flags)
463{
464	return 0;
465}
466
467static int
468akbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
469{
470	return 0;
471}
472
473static int
474akbd_term(keyboard_t *kbd)
475{
476	return 0;
477}
478
479static int
480akbd_interrupt(keyboard_t *kbd, void *arg)
481{
482	return 0;
483}
484
485static int
486akbd_test_if(keyboard_t *kbd)
487{
488	return 0;
489}
490
491static int
492akbd_enable(keyboard_t *kbd)
493{
494	KBD_ACTIVATE(kbd);
495	return (0);
496}
497
498static int
499akbd_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
509static int
510akbd_read(keyboard_t *kbd, int wait)
511{
512	return (0);
513}
514
515static int
516akbd_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
542static u_int
543akbd_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
631static int
632akbd_check_char(keyboard_t *kbd)
633{
634	if (!KBD_IS_ACTIVE(kbd))
635		return (FALSE);
636
637	return (akbd_check(kbd));
638}
639
640static int
641set_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
658static 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 OPIO_KEYMAP:
751	case PIO_KEYMAPENT:
752	case PIO_DEADKEYMAP:
753	default:
754		return (genkbd_commonioctl(kbd, cmd, data));
755	}
756
757	return (error);
758}
759
760static int akbd_lock(keyboard_t *kbd, int lock)
761{
762	return (0);
763}
764
765static void akbd_clear_state(keyboard_t *kbd)
766{
767	struct adb_kbd_softc *sc;
768
769	sc = (struct adb_kbd_softc *)(kbd);
770
771	mtx_lock(&sc->sc_mutex);
772
773	sc->buffers = 0;
774	callout_stop(&sc->sc_repeater);
775
776#if defined(AKBD_EMULATE_ATKBD)
777	sc->at_buffered_char[0] = 0;
778	sc->at_buffered_char[1] = 0;
779#endif
780	mtx_unlock(&sc->sc_mutex);
781}
782
783static int akbd_get_state(keyboard_t *kbd, void *buf, size_t len)
784{
785	return (0);
786}
787
788static int akbd_set_state(keyboard_t *kbd, void *buf, size_t len)
789{
790	return (0);
791}
792
793static int akbd_poll(keyboard_t *kbd, int on)
794{
795	return (0);
796}
797
798static int
799akbd_modevent(module_t mod, int type, void *data)
800{
801	switch (type) {
802	case MOD_LOAD:
803		kbd_add_driver(&akbd_kbd_driver);
804		break;
805
806	case MOD_UNLOAD:
807		kbd_delete_driver(&akbd_kbd_driver);
808		break;
809
810	default:
811		return (EOPNOTSUPP);
812	}
813
814	return (0);
815}
816
817DEV_MODULE(akbd, akbd_modevent, NULL);
818
819