adb_kbd.c revision 185724
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: head/sys/dev/adb/adb_kbd.c 185724 2008-12-06 23:26:02Z nwhitehorn $
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
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	volatile int buffers;
76
77	struct callout sc_repeater;
78	int sc_repeatstart;
79	int sc_repeatcontinue;
80	uint8_t last_press;
81};
82
83static device_method_t adb_kbd_methods[] = {
84	/* Device interface */
85	DEVMETHOD(device_probe,         adb_kbd_probe),
86        DEVMETHOD(device_attach,        adb_kbd_attach),
87        DEVMETHOD(device_detach,        adb_kbd_detach),
88        DEVMETHOD(device_shutdown,      bus_generic_shutdown),
89        DEVMETHOD(device_suspend,       bus_generic_suspend),
90        DEVMETHOD(device_resume,        bus_generic_resume),
91
92	/* ADB interface */
93	DEVMETHOD(adb_receive_packet,	adb_kbd_receive_packet),
94
95	{ 0, 0 }
96};
97
98static driver_t adb_kbd_driver = {
99	"akbd",
100	adb_kbd_methods,
101	sizeof(struct adb_kbd_softc),
102};
103
104static devclass_t adb_kbd_devclass;
105
106DRIVER_MODULE(akbd, adb, adb_kbd_driver, adb_kbd_devclass, 0, 0);
107
108static const uint8_t adb_to_at_scancode_map[128] = { 30, 31, 32, 33, 35, 34,
109	44, 45, 46, 47, 0, 48, 16, 17, 18, 19, 21, 20, 2, 3, 4, 5, 7, 6, 13,
110	10, 8, 12, 9, 11, 27, 24, 22, 26, 23, 25, 28, 38, 36, 40, 37, 39, 43,
111	51, 53, 49, 50, 52, 15, 57, 41, 14, 0, 1, 29, 0, 42, 58, 56, 97, 98,
112	100, 95, 0, 0, 83, 0, 55, 0, 78, 0, 69, 0, 0, 0, 91, 89, 0, 74, 13, 0,
113	0, 82, 79, 80, 81, 75, 76, 77, 71, 0, 72, 73, 0, 0, 0, 63, 64, 65, 61,
114	66, 67, 0, 87, 0, 105, 0, 70, 0, 68, 0, 88, 0, 107, 102, 94, 96, 103,
115	62, 99, 60, 101, 59, 54, 93, 90, 0, 0 };
116
117/* keyboard driver declaration */
118static int              akbd_configure(int flags);
119static kbd_probe_t      akbd_probe;
120static kbd_init_t       akbd_init;
121static kbd_term_t       akbd_term;
122static kbd_intr_t       akbd_interrupt;
123static kbd_test_if_t    akbd_test_if;
124static kbd_enable_t     akbd_enable;
125static kbd_disable_t    akbd_disable;
126static kbd_read_t       akbd_read;
127static kbd_check_t      akbd_check;
128static kbd_read_char_t  akbd_read_char;
129static kbd_check_char_t akbd_check_char;
130static kbd_ioctl_t      akbd_ioctl;
131static kbd_lock_t       akbd_lock;
132static kbd_clear_state_t akbd_clear_state;
133static kbd_get_state_t  akbd_get_state;
134static kbd_set_state_t  akbd_set_state;
135static kbd_poll_mode_t  akbd_poll;
136
137keyboard_switch_t akbdsw = {
138        akbd_probe,
139        akbd_init,
140        akbd_term,
141        akbd_interrupt,
142        akbd_test_if,
143        akbd_enable,
144        akbd_disable,
145        akbd_read,
146        akbd_check,
147        akbd_read_char,
148        akbd_check_char,
149        akbd_ioctl,
150        akbd_lock,
151        akbd_clear_state,
152        akbd_get_state,
153        akbd_set_state,
154        genkbd_get_fkeystr,
155        akbd_poll,
156        genkbd_diag,
157};
158
159KEYBOARD_DRIVER(akbd, akbdsw, akbd_configure);
160
161static int
162adb_kbd_probe(device_t dev)
163{
164	uint8_t type;
165
166	type = adb_get_device_type(dev);
167
168	if (type != ADB_DEVICE_KEYBOARD)
169		return (ENXIO);
170
171	switch(adb_get_device_handler(dev)) {
172	case 1:
173		device_set_desc(dev,"Apple Standard Keyboard");
174		break;
175	case 2:
176		device_set_desc(dev,"Apple Extended Keyboard");
177		break;
178	case 4:
179		device_set_desc(dev,"Apple ISO Keyboard");
180		break;
181	case 5:
182		device_set_desc(dev,"Apple Extended ISO Keyboard");
183		break;
184	case 8:
185		device_set_desc(dev,"Apple Keyboard II");
186		break;
187	case 9:
188		device_set_desc(dev,"Apple ISO Keyboard II");
189		break;
190	case 12:
191		device_set_desc(dev,"PowerBook Keyboard");
192		break;
193	case 13:
194		device_set_desc(dev,"PowerBook ISO Keyboard");
195		break;
196	case 24:
197		device_set_desc(dev,"PowerBook Extended Keyboard");
198		break;
199	case 27:
200		device_set_desc(dev,"Apple Design Keyboard");
201		break;
202	case 195:
203		device_set_desc(dev,"PowerBook G3 Keyboard");
204		break;
205	case 196:
206		device_set_desc(dev,"iBook Keyboard");
207		break;
208	default:
209		device_set_desc(dev,"ADB Keyboard");
210		break;
211	}
212
213	return (0);
214}
215
216static int
217ms_to_ticks(int ms)
218{
219	if (hz > 1000)
220		return ms*(hz/1000);
221
222	return ms/(1000/hz);
223}
224
225static int
226adb_kbd_attach(device_t dev)
227{
228	struct adb_kbd_softc *sc;
229	keyboard_switch_t *sw;
230
231	sw = kbd_get_switch(KBD_DRIVER_NAME);
232	if (sw == NULL) {
233		return ENXIO;
234	}
235
236	sc = device_get_softc(dev);
237	sc->sc_dev = dev;
238	sc->sc_mode = K_RAW;
239	sc->sc_state = 0;
240	sc->have_led_control = 0;
241	sc->buffers = 0;
242
243	/* Try stepping forward to the extended keyboard protocol */
244	adb_set_device_handler(dev,3);
245
246	mtx_init(&sc->sc_mutex,KBD_DRIVER_NAME,MTX_DEF,0);
247	cv_init(&sc->sc_cv,KBD_DRIVER_NAME);
248	callout_init(&sc->sc_repeater, 0);
249
250#ifdef AKBD_EMULATE_ATKBD
251	kbd_init_struct(&sc->sc_kbd, KBD_DRIVER_NAME, KB_101, 0, 0, 0, 0);
252	kbd_set_maps(&sc->sc_kbd, &key_map, &accent_map, fkey_tab,
253            sizeof(fkey_tab) / sizeof(fkey_tab[0]));
254#else
255	#error ADB raw mode not implemented
256#endif
257
258	KBD_FOUND_DEVICE(&sc->sc_kbd);
259	KBD_PROBE_DONE(&sc->sc_kbd);
260	KBD_INIT_DONE(&sc->sc_kbd);
261	KBD_CONFIG_DONE(&sc->sc_kbd);
262
263	(*sw->enable)(&sc->sc_kbd);
264
265	kbd_register(&sc->sc_kbd);
266
267#ifdef KBD_INSTALL_CDEV
268	if (kbd_attach(&sc->sc_kbd)) {
269		adb_kbd_detach(dev);
270		return ENXIO;
271	}
272#endif
273
274	/* Check if we can read out the LED state from
275	   this keyboard by reading the key state register */
276	if (adb_read_register(dev, 2, NULL) == 2)
277		sc->have_led_control = 1;
278
279	adb_set_autopoll(dev,1);
280
281	return (0);
282}
283
284static int
285adb_kbd_detach(device_t dev)
286{
287	struct adb_kbd_softc *sc;
288	keyboard_t *kbd;
289
290	sc = device_get_softc(dev);
291
292	adb_set_autopoll(dev,0);
293	callout_stop(&sc->sc_repeater);
294
295	mtx_lock(&sc->sc_mutex);
296
297	kbd = kbd_get_keyboard(kbd_find_keyboard(KBD_DRIVER_NAME,
298	          device_get_unit(dev)));
299
300	kbdd_disable(kbd);
301
302#ifdef KBD_INSTALL_CDEV
303	kbd_detach(kbd);
304#endif
305
306	kbdd_term(kbd);
307
308	mtx_unlock(&sc->sc_mutex);
309
310	mtx_destroy(&sc->sc_mutex);
311	cv_destroy(&sc->sc_cv);
312
313	return (0);
314}
315
316static u_int
317adb_kbd_receive_packet(device_t dev, u_char status,
318    u_char command, u_char reg, int len, u_char *data)
319{
320	struct adb_kbd_softc *sc;
321
322	sc = device_get_softc(dev);
323
324	if (command != ADB_COMMAND_TALK)
325		return 0;
326
327	if (reg != 0 || len != 2)
328		return (0);
329
330	mtx_lock(&sc->sc_mutex);
331		if ((data[0] & 0x7f) == 57 && sc->buffers < 7) {
332			/* Fake the down/up cycle for caps lock */
333			sc->buffer[sc->buffers++] = data[0] & 0x7f;
334			sc->buffer[sc->buffers++] = (data[0] & 0x7f) | (1 << 7);
335		} else {
336			sc->buffer[sc->buffers++] = data[0];
337		}
338
339		if (sc->buffer[sc->buffers-1] < 0xff)
340			sc->last_press = sc->buffer[sc->buffers-1];
341
342		if ((data[1] & 0x7f) == 57 && sc->buffers < 7) {
343			/* Fake the down/up cycle for caps lock */
344			sc->buffer[sc->buffers++] = data[1] & 0x7f;
345			sc->buffer[sc->buffers++] = (data[1] & 0x7f) | (1 << 7);
346		} else {
347			sc->buffer[sc->buffers++] = data[1];
348		}
349
350		if (sc->buffer[sc->buffers-1] < 0xff)
351			sc->last_press = sc->buffer[sc->buffers-1];
352
353		/* Stop any existing key repeating */
354		callout_stop(&sc->sc_repeater);
355
356		/* Schedule a repeat callback on keydown */
357		if (!(sc->last_press & (1 << 7))) {
358			callout_reset(&sc->sc_repeater,
359			    ms_to_ticks(sc->sc_kbd.kb_delay1), akbd_repeat, sc);
360		}
361	mtx_unlock(&sc->sc_mutex);
362
363	cv_broadcast(&sc->sc_cv);
364
365	if (KBD_IS_ACTIVE(&sc->sc_kbd) && KBD_IS_BUSY(&sc->sc_kbd)) {
366		sc->sc_kbd.kb_callback.kc_func(&sc->sc_kbd,
367			 KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg);
368	}
369
370	return (0);
371}
372
373static void
374akbd_repeat(void *xsc) {
375	struct adb_kbd_softc *sc = xsc;
376	int notify_kbd = 0;
377
378	/* Fake an up/down key repeat so long as we have the
379	   free buffers */
380	mtx_lock(&sc->sc_mutex);
381		if (sc->buffers < 7) {
382			sc->buffer[sc->buffers++] = sc->last_press | (1 << 7);
383			sc->buffer[sc->buffers++] = sc->last_press;
384
385			notify_kbd = 1;
386		}
387	mtx_unlock(&sc->sc_mutex);
388
389	if (notify_kbd && KBD_IS_ACTIVE(&sc->sc_kbd)
390	    && KBD_IS_BUSY(&sc->sc_kbd)) {
391		sc->sc_kbd.kb_callback.kc_func(&sc->sc_kbd,
392		    KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg);
393	}
394
395	/* Reschedule the callout */
396	callout_reset(&sc->sc_repeater, ms_to_ticks(sc->sc_kbd.kb_delay2),
397	    akbd_repeat, sc);
398}
399
400static int
401akbd_configure(int flags)
402{
403	return 0;
404}
405
406static int
407akbd_probe(int unit, void *arg, int flags)
408{
409	return 0;
410}
411
412static int
413akbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
414{
415	return 0;
416}
417
418static int
419akbd_term(keyboard_t *kbd)
420{
421	return 0;
422}
423
424static int
425akbd_interrupt(keyboard_t *kbd, void *arg)
426{
427	return 0;
428}
429
430static int
431akbd_test_if(keyboard_t *kbd)
432{
433	return 0;
434}
435
436static int
437akbd_enable(keyboard_t *kbd)
438{
439	KBD_ACTIVATE(kbd);
440	return (0);
441}
442
443static int
444akbd_disable(keyboard_t *kbd)
445{
446	struct adb_kbd_softc *sc;
447	sc = (struct adb_kbd_softc *)(kbd);
448
449	callout_stop(&sc->sc_repeater);
450	KBD_DEACTIVATE(kbd);
451	return (0);
452}
453
454static int
455akbd_read(keyboard_t *kbd, int wait)
456{
457	return (0);
458}
459
460static int
461akbd_check(keyboard_t *kbd)
462{
463	struct adb_kbd_softc *sc;
464
465	if (!KBD_IS_ACTIVE(kbd))
466		return (FALSE);
467
468	sc = (struct adb_kbd_softc *)(kbd);
469
470	mtx_lock(&sc->sc_mutex);
471		if (sc->buffers > 0) {
472			mtx_unlock(&sc->sc_mutex);
473			return (TRUE);
474		}
475	mtx_unlock(&sc->sc_mutex);
476
477	return (FALSE);
478}
479
480static u_int
481akbd_read_char(keyboard_t *kbd, int wait)
482{
483	struct adb_kbd_softc *sc;
484	uint8_t adb_code, final_scancode;
485	int i;
486
487	sc = (struct adb_kbd_softc *)(kbd);
488
489	mtx_lock(&sc->sc_mutex);
490		if (!sc->buffers && wait)
491			cv_wait(&sc->sc_cv,&sc->sc_mutex);
492
493		if (!sc->buffers) {
494			mtx_unlock(&sc->sc_mutex);
495			return (0);
496		}
497
498		adb_code = sc->buffer[0];
499
500		for (i = 1; i < sc->buffers; i++)
501			sc->buffer[i-1] = sc->buffer[i];
502
503		sc->buffers--;
504	mtx_unlock(&sc->sc_mutex);
505
506	#ifdef AKBD_EMULATE_ATKBD
507		final_scancode = adb_to_at_scancode_map[adb_code & 0x7f];
508		final_scancode |= adb_code & 0x80;
509	#else
510		final_scancode = adb_code;
511	#endif
512
513	return (final_scancode);
514}
515
516static int
517akbd_check_char(keyboard_t *kbd)
518{
519	if (!KBD_IS_ACTIVE(kbd))
520		return (FALSE);
521
522	return (akbd_check(kbd));
523}
524
525static int
526set_typematic(keyboard_t *kbd, int code)
527{
528	/* These numbers are in microseconds, so convert to ticks */
529
530	static int delays[] = { 250, 500, 750, 1000 };
531	static int rates[] = {  34,  38,  42,  46,  50,  55,  59,  63,
532				68,  76,  84,  92, 100, 110, 118, 126,
533				136, 152, 168, 184, 200, 220, 236, 252,
534				272, 304, 336, 368, 400, 440, 472, 504 };
535
536	if (code & ~0x7f)
537		return EINVAL;
538	kbd->kb_delay1 = delays[(code >> 5) & 3];
539	kbd->kb_delay2 = rates[code & 0x1f];
540	return 0;
541}
542
543static int akbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t data)
544{
545	struct adb_kbd_softc *sc;
546	uint16_t r2;
547	int error;
548
549	sc = (struct adb_kbd_softc *)(kbd);
550	error = 0;
551
552	switch (cmd) {
553	case KDGKBMODE:
554		*(int *)data = sc->sc_mode;
555		break;
556	case KDSKBMODE:
557		switch (*(int *)data) {
558		case K_XLATE:
559			if (sc->sc_mode != K_XLATE) {
560				/* make lock key state and LED state match */
561				sc->sc_state &= ~LOCK_MASK;
562				sc->sc_state |= KBD_LED_VAL(kbd);
563			}
564			/* FALLTHROUGH */
565		case K_RAW:
566		case K_CODE:
567			if (sc->sc_mode != *(int *)data)
568				sc->sc_mode = *(int *)data;
569			break;
570		default:
571			error = EINVAL;
572			break;
573		}
574
575		break;
576
577	case KDGETLED:
578		*(int *)data = KBD_LED_VAL(kbd);
579		break;
580
581	case KDSKBSTATE:
582		if (*(int *)data & ~LOCK_MASK) {
583			error = EINVAL;
584			break;
585		}
586		sc->sc_state &= ~LOCK_MASK;
587		sc->sc_state |= *(int *)data;
588
589		/* FALLTHROUGH */
590
591	case KDSETLED:
592		KBD_LED_VAL(kbd) = *(int *)data;
593
594		if (!sc->have_led_control)
595			break;
596
597		r2 = (~0 & 0x04) | 3;
598
599		if (*(int *)data & NLKED)
600			r2 &= ~1;
601		if (*(int *)data & CLKED)
602			r2 &= ~2;
603		if (*(int *)data & SLKED)
604			r2 &= ~4;
605
606		adb_send_packet(sc->sc_dev,ADB_COMMAND_LISTEN,2,
607			sizeof(uint16_t),(u_char *)&r2);
608
609		break;
610
611	case KDGKBSTATE:
612		*(int *)data = sc->sc_state & LOCK_MASK;
613		break;
614
615	case KDSETREPEAT:
616		if (!KBD_HAS_DEVICE(kbd))
617			return 0;
618		if (((int *)data)[1] < 0)
619			return EINVAL;
620		if (((int *)data)[0] < 0)
621			return EINVAL;
622		else if (((int *)data)[0] == 0)  /* fastest possible value */
623			kbd->kb_delay1 = 200;
624		else
625			kbd->kb_delay1 = ((int *)data)[0];
626		kbd->kb_delay2 = ((int *)data)[1];
627
628		break;
629
630	case KDSETRAD:
631		error = set_typematic(kbd, *(int *)data);
632		break;
633
634	case PIO_KEYMAP:
635	case PIO_KEYMAPENT:
636	case PIO_DEADKEYMAP:
637	default:
638		return (genkbd_commonioctl(kbd, cmd, data));
639	}
640
641	return (error);
642}
643
644static int akbd_lock(keyboard_t *kbd, int lock)
645{
646	return (0);
647}
648
649static void akbd_clear_state(keyboard_t *kbd)
650{
651}
652
653static int akbd_get_state(keyboard_t *kbd, void *buf, size_t len)
654{
655	return (0);
656}
657
658static int akbd_set_state(keyboard_t *kbd, void *buf, size_t len)
659{
660	return (0);
661}
662
663static int akbd_poll(keyboard_t *kbd, int on)
664{
665	return (0);
666}
667
668static int
669akbd_modevent(module_t mod, int type, void *data)
670{
671	switch (type) {
672	case MOD_LOAD:
673		kbd_add_driver(&akbd_kbd_driver);
674		break;
675
676	case MOD_UNLOAD:
677		kbd_delete_driver(&akbd_kbd_driver);
678		break;
679
680	default:
681		return (EOPNOTSUPP);
682	}
683
684	return (0);
685}
686
687DEV_MODULE(akbd, akbd_modevent, NULL);
688
689