xref: /netbsd-src/sys/arch/zaurus/dev/zkbd.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 /*	$NetBSD: zkbd.c,v 1.18 2013/03/30 08:35:06 nonaka Exp $	*/
2 /* $OpenBSD: zaurus_kbd.c,v 1.28 2005/12/21 20:36:03 deraadt Exp $ */
3 
4 /*
5  * Copyright (c) 2005 Dale Rahn <drahn@openbsd.org>
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include <sys/cdefs.h>
21 __KERNEL_RCSID(0, "$NetBSD: zkbd.c,v 1.18 2013/03/30 08:35:06 nonaka Exp $");
22 
23 #include "opt_wsdisplay_compat.h"
24 #if 0	/* XXX */
25 #include "apm.h"
26 #endif
27 #include "lcdctl.h"
28 
29 #include <sys/param.h>
30 #include <sys/systm.h>
31 #include <sys/device.h>
32 #include <sys/malloc.h>
33 #include <sys/kernel.h>
34 #include <sys/proc.h>
35 #include <sys/signalvar.h>
36 #include <sys/callout.h>
37 
38 #include <arm/xscale/pxa2x0reg.h>
39 #include <arm/xscale/pxa2x0_gpio.h>
40 
41 #include <dev/wscons/wsconsio.h>
42 #include <dev/wscons/wskbdvar.h>
43 #include <dev/wscons/wsksymdef.h>
44 #include <dev/wscons/wsksymvar.h>
45 
46 #include <zaurus/zaurus/zaurus_var.h>
47 #include <zaurus/dev/zkbdmap.h>
48 #if NLCDCTL > 0
49 #include <zaurus/dev/lcdctlvar.h>
50 #endif
51 
52 static const int gpio_sense_pins_c3000[] = {
53 	12,
54 	17,
55 	91,
56 	34,
57 	36,
58 	38,
59 	39,
60 	-1
61 };
62 
63 static const int gpio_strobe_pins_c3000[] = {
64 	88,
65 	23,
66 	24,
67 	25,
68 	26,
69 	27,
70 	52,
71 	103,
72 	107,
73 	-1,
74 	108,
75 	114
76 };
77 
78 static const int stuck_keys_c3000[] = {
79 	1,  7,  15, 22, 23, 31, 39, 47,
80 	53, 55, 60, 63, 66, 67, 69, 71,
81 	72, 73, 74, 75, 76, 77, 78, 79,
82 	82, 85, 86, 87, 90, 91, 92, 94,
83 	95
84 };
85 
86 static const int gpio_sense_pins_c860[] = {
87 	58,
88 	59,
89 	60,
90 	61,
91 	62,
92 	63,
93 	64,
94 	65
95 };
96 
97 static const int gpio_strobe_pins_c860[] = {
98 	66,
99 	67,
100 	68,
101 	69,
102 	70,
103 	71,
104 	72,
105 	73,
106 	74,
107 	75,
108 	76,
109 	77
110 };
111 
112 static const int stuck_keys_c860[] = {
113 	0,  1,  47, 53, 55, 60, 63, 66,
114 	67, 69, 71, 72, 73, 74, 76, 77,
115 	78, 79, 80, 81, 82, 83, 85, 86,
116 	87, 88, 89, 90, 91, 92, 94, 95
117 };
118 
119 #define REP_DELAY1 400
120 #define REP_DELAYN 100
121 
122 struct zkbd_softc {
123 	device_t sc_dev;
124 
125 	const int *sc_sense_array;
126 	const int *sc_strobe_array;
127 	const int *sc_stuck_keys;
128 	int sc_nsense;
129 	int sc_nstrobe;
130 	int sc_nstuck;
131 
132 	short sc_onkey_pin;
133 	short sc_sync_pin;
134 	short sc_swa_pin;
135 	short sc_swb_pin;
136 	char *sc_okeystate;
137 	char *sc_keystate;
138 	char sc_hinge;		/* 0=open, 1=nonsense, 2=backwards, 3=closed */
139 	char sc_maxkbdcol;
140 
141 	struct callout sc_roll_to;
142 
143 	/* console stuff */
144 	int sc_polling;
145 	int sc_pollUD;
146 	int sc_pollkey;
147 
148 	/* wskbd bits */
149 	device_t sc_wskbddev;
150 	struct wskbd_mapdata *sc_keymapdata;
151 	int sc_rawkbd;
152 #ifdef WSDISPLAY_COMPAT_RAWKBD
153 	const char *sc_xt_keymap;
154 	struct callout sc_rawrepeat_ch;
155 #define MAXKEYS 20
156 	char sc_rep[MAXKEYS];
157 	int sc_nrep;
158 #endif
159 };
160 
161 static struct zkbd_softc *zkbd_sc;
162 
163 static int	zkbd_match(device_t, cfdata_t, void *);
164 static void	zkbd_attach(device_t, device_t, void *);
165 
166 CFATTACH_DECL_NEW(zkbd, sizeof(struct zkbd_softc),
167 	zkbd_match, zkbd_attach, NULL, NULL);
168 
169 static int	zkbd_irq_c3000(void *v);
170 static int	zkbd_irq_c860(void *v);
171 static void	zkbd_poll(void *v);
172 static int	zkbd_on(void *v);
173 static int	zkbd_sync(void *v);
174 static int	zkbd_hinge(void *v);
175 static bool	zkbd_resume(device_t dv, const pmf_qual_t *);
176 
177 int zkbd_modstate;
178 
179 static int	zkbd_enable(void *, int);
180 static void	zkbd_set_leds(void *, int);
181 static int	zkbd_ioctl(void *, u_long, void *, int, struct lwp *);
182 #ifdef WSDISPLAY_COMPAT_RAWKBD
183 static void	zkbd_rawrepeat(void *v);
184 #endif
185 
186 static struct wskbd_accessops zkbd_accessops = {
187 	zkbd_enable,
188 	zkbd_set_leds,
189 	zkbd_ioctl,
190 };
191 
192 static void	zkbd_cngetc(void *, u_int *, int *);
193 static void	zkbd_cnpollc(void *, int);
194 
195 static struct wskbd_consops zkbd_consops = {
196 	zkbd_cngetc,
197 	zkbd_cnpollc,
198 };
199 
200 static struct wskbd_mapdata zkbd_keymapdata = {
201 	zkbd_keydesctab,
202 	KB_US,
203 };
204 
205 static struct wskbd_mapdata zkbd_keymapdata_c860 = {
206 	zkbd_keydesctab_c860,
207 	KB_US,
208 };
209 
210 static int
211 zkbd_match(device_t parent, cfdata_t cf, void *aux)
212 {
213 
214 	if (zkbd_sc)
215 		return 0;
216 
217 	return 1;
218 }
219 
220 static void
221 zkbd_attach(device_t parent, device_t self, void *aux)
222 {
223 	struct zkbd_softc *sc = device_private(self);
224 	struct wskbddev_attach_args a;
225 	int pin, i;
226 
227 	sc->sc_dev = self;
228 	zkbd_sc = sc;
229 
230 	aprint_normal("\n");
231 	aprint_naive("\n");
232 
233 	sc->sc_polling = 0;
234 #ifdef WSDISPLAY_COMPAT_RAWKBD
235 	sc->sc_rawkbd = 0;
236 #endif
237 
238 	callout_init(&sc->sc_roll_to, 0);
239 	callout_setfunc(&sc->sc_roll_to, zkbd_poll, sc);
240 #ifdef WSDISPLAY_COMPAT_RAWKBD
241 	callout_init(&sc->sc_rawrepeat_ch, 0);
242 	callout_setfunc(&sc->sc_rawrepeat_ch, zkbd_rawrepeat, sc);
243 #endif
244 
245 	if (ZAURUS_ISC1000 || ZAURUS_ISC3000) {
246 		sc->sc_sense_array = gpio_sense_pins_c3000;
247 		sc->sc_strobe_array = gpio_strobe_pins_c3000;
248 		sc->sc_nsense = __arraycount(gpio_sense_pins_c3000);
249 		sc->sc_nstrobe = __arraycount(gpio_strobe_pins_c3000);
250 		sc->sc_stuck_keys = stuck_keys_c3000;
251 		sc->sc_nstuck = __arraycount(stuck_keys_c3000);
252 		sc->sc_maxkbdcol = 10;
253 		sc->sc_onkey_pin = 95;
254 		sc->sc_sync_pin = 16;
255 		sc->sc_swa_pin = 97;
256 		sc->sc_swb_pin = 96;
257 		sc->sc_keymapdata = &zkbd_keymapdata;
258 #ifdef WSDISPLAY_COMPAT_RAWKBD
259 		sc->sc_xt_keymap = xt_keymap;
260 #endif
261 	} else if (ZAURUS_ISC860) {
262 		sc->sc_sense_array = gpio_sense_pins_c860;
263 		sc->sc_strobe_array = gpio_strobe_pins_c860;
264 		sc->sc_nsense = __arraycount(gpio_sense_pins_c860);
265 		sc->sc_nstrobe = __arraycount(gpio_strobe_pins_c860);
266 		sc->sc_stuck_keys = stuck_keys_c860;
267 		sc->sc_nstuck = __arraycount(stuck_keys_c860);
268 		sc->sc_maxkbdcol = 0;
269 		sc->sc_onkey_pin = -1;
270 		sc->sc_sync_pin = -1;
271 		sc->sc_swa_pin = -1;
272 		sc->sc_swb_pin = -1;
273 		sc->sc_keymapdata = &zkbd_keymapdata_c860;
274 #ifdef WSDISPLAY_COMPAT_RAWKBD
275 		sc->sc_xt_keymap = xt_keymap_c860;
276 #endif
277 	} else {
278 		/* XXX */
279 		return;
280 	}
281 
282 	if (!pmf_device_register(sc->sc_dev, NULL, zkbd_resume))
283 		aprint_error_dev(sc->sc_dev,
284 		    "couldn't establish power handler\n");
285 
286 	sc->sc_okeystate = malloc(sc->sc_nsense * sc->sc_nstrobe,
287 	    M_DEVBUF, M_NOWAIT);
288 	memset(sc->sc_okeystate, 0, sc->sc_nsense * sc->sc_nstrobe);
289 
290 	sc->sc_keystate = malloc(sc->sc_nsense * sc->sc_nstrobe,
291 	    M_DEVBUF, M_NOWAIT);
292 	memset(sc->sc_keystate, 0, sc->sc_nsense * sc->sc_nstrobe);
293 
294 	/* set all the strobe bits */
295 	for (i = 0; i < sc->sc_nstrobe; i++) {
296 		pin = sc->sc_strobe_array[i];
297 		if (pin == -1)
298 			continue;
299 		pxa2x0_gpio_set_function(pin, GPIO_SET|GPIO_OUT);
300 	}
301 
302 	/* set all the sense bits */
303 	for (i = 0; i < sc->sc_nsense; i++) {
304 		pin = sc->sc_sense_array[i];
305 		if (pin == -1)
306 			continue;
307 		pxa2x0_gpio_set_function(pin, GPIO_IN);
308 		if (ZAURUS_ISC1000 || ZAURUS_ISC3000) {
309 			pxa2x0_gpio_intr_establish(pin, IST_EDGE_BOTH,
310 			    IPL_TTY, zkbd_irq_c3000, sc);
311 		} else if (ZAURUS_ISC860) {
312 			pxa2x0_gpio_intr_establish(pin, IST_EDGE_RISING,
313 			    IPL_TTY, zkbd_irq_c860, sc);
314 		}
315 	}
316 
317 	if (sc->sc_onkey_pin >= 0)
318 		pxa2x0_gpio_intr_establish(sc->sc_onkey_pin, IST_EDGE_BOTH,
319 		    IPL_TTY, zkbd_on, sc);
320 	if (sc->sc_sync_pin >= 0)
321 		pxa2x0_gpio_intr_establish(sc->sc_sync_pin, IST_EDGE_RISING,
322 		    IPL_TTY, zkbd_sync, sc);
323 	if (sc->sc_swa_pin >= 0)
324 		pxa2x0_gpio_intr_establish(sc->sc_swa_pin, IST_EDGE_BOTH,
325 		    IPL_TTY, zkbd_hinge, sc);
326 	if (sc->sc_swb_pin >= 0)
327 		pxa2x0_gpio_intr_establish(sc->sc_swb_pin, IST_EDGE_BOTH,
328 		    IPL_TTY, zkbd_hinge, sc);
329 
330 	if (glass_console) {
331 		wskbd_cnattach(&zkbd_consops, sc, sc->sc_keymapdata);
332 		a.console = 1;
333 	} else {
334 		a.console = 0;
335 	}
336 	a.keymap = sc->sc_keymapdata;
337 	a.accessops = &zkbd_accessops;
338 	a.accesscookie = sc;
339 
340 	zkbd_hinge(sc);		/* to initialize sc_hinge */
341 
342 	sc->sc_wskbddev = config_found(self, &a, wskbddevprint);
343 }
344 
345 #ifdef WSDISPLAY_COMPAT_RAWKBD
346 static void
347 zkbd_rawrepeat(void *v)
348 {
349 	struct zkbd_softc *sc = (struct zkbd_softc *)v;
350 	int s;
351 
352 	s = spltty();
353 	wskbd_rawinput(sc->sc_wskbddev, sc->sc_rep, sc->sc_nrep);
354 	splx(s);
355 	callout_schedule(&sc->sc_rawrepeat_ch, hz * REP_DELAYN / 1000);
356 }
357 #endif
358 
359 /* XXX only deal with keys that can be pressed when display is open? */
360 /* XXX are some not in the array? */
361 /* handle keypress interrupt */
362 static int
363 zkbd_irq_c3000(void *v)
364 {
365 
366 	zkbd_poll(v);
367 
368 	return 1;
369 }
370 
371 /* Avoid chattering only for SL-C7x0/860 */
372 static int
373 zkbd_irq_c860(void *v)
374 {
375 	struct zkbd_softc *sc = (struct zkbd_softc *)v;
376 
377 	if (!callout_pending(&sc->sc_roll_to)) {
378 		zkbd_poll(v);
379 	}
380 
381 	return 1;
382 }
383 
384 static void
385 zkbd_poll(void *v)
386 {
387 	struct zkbd_softc *sc = (struct zkbd_softc *)v;
388 	int i, j, col, pin, type, keysdown = 0;
389 	int stuck;
390 	int keystate;
391 	int s;
392 #ifdef WSDISPLAY_COMPAT_RAWKBD
393 	int npress = 0, ncbuf = 0, c;
394 	char cbuf[MAXKEYS * 2];
395 #endif
396 
397 	s = spltty();
398 
399 	/* discharge all */
400 	for (i = 0; i < sc->sc_nstrobe; i++) {
401 		pin = sc->sc_strobe_array[i];
402 		if (pin == -1)
403 			continue;
404 		pxa2x0_gpio_clear_bit(pin);
405 		pxa2x0_gpio_set_dir(pin, GPIO_IN);
406 	}
407 
408 	delay(10);
409 	for (col = 0; col < sc->sc_nstrobe; col++) {
410 		pin = sc->sc_strobe_array[col];
411 		if (pin == -1)
412 			continue;
413 
414 		/* activate_col */
415 		pxa2x0_gpio_set_bit(pin);
416 		pxa2x0_gpio_set_dir(pin, GPIO_OUT);
417 
418 		/* wait activate delay */
419 		delay(10);
420 
421 		/* read row */
422 		for (i = 0; i < sc->sc_nsense; i++) {
423 			int bit;
424 
425 			if (sc->sc_sense_array[i] == -1)
426 				continue;
427 			bit = pxa2x0_gpio_get_bit(sc->sc_sense_array[i]);
428 			if (bit && sc->sc_hinge && col < sc->sc_maxkbdcol)
429 				continue;
430 			sc->sc_keystate[i + (col * sc->sc_nsense)] = bit;
431 		}
432 
433 		/* reset_col */
434 		pxa2x0_gpio_set_dir(pin, GPIO_IN);
435 
436 		/* wait discharge delay */
437 		delay(10);
438 	}
439 
440 	/* charge all */
441 	for (i = 0; i < sc->sc_nstrobe; i++) {
442 		pin = sc->sc_strobe_array[i];
443 		if (pin == -1)
444 			continue;
445 		pxa2x0_gpio_set_bit(pin);
446 		pxa2x0_gpio_set_dir(pin, GPIO_OUT);
447 	}
448 
449 	/* force the irqs to clear as we have just played with them. */
450 	for (i = 0; i < sc->sc_nsense; i++) {
451 		pin = sc->sc_sense_array[i];
452 		if (pin == -1)
453 			continue;
454 		pxa2x0_gpio_clear_intr(pin);
455 	}
456 
457 	/* process after resetting interrupt */
458 	zkbd_modstate = (
459 		(sc->sc_keystate[84] ? (1 << 0) : 0) | /* shift */
460 		(sc->sc_keystate[93] ? (1 << 1) : 0) | /* Fn */
461 		(sc->sc_keystate[14] ? (1 << 2) : 0)); /* 'alt' */
462 
463 	for (i = 0; i < sc->sc_nsense * sc->sc_nstrobe; i++) {
464 		stuck = 0;
465 		/* extend  xt_keymap to do this faster. */
466 		/* ignore 'stuck' keys' */
467 		for (j = 0; j < sc->sc_nstuck; j++) {
468 			if (sc->sc_stuck_keys[j] == i) {
469 				stuck = 1;
470 				break;
471 			}
472 		}
473 		if (stuck)
474 			continue;
475 
476 		keystate = sc->sc_keystate[i];
477 		keysdown |= keystate; /* if any keys held */
478 
479 #ifdef WSDISPLAY_COMPAT_RAWKBD
480 		if (sc->sc_polling == 0 && sc->sc_rawkbd) {
481 			if ((keystate) || (sc->sc_okeystate[i] != keystate)) {
482 				c = sc->sc_xt_keymap[i];
483 				if (c & 0x80) {
484 					cbuf[ncbuf++] = 0xe0;
485 				}
486 				cbuf[ncbuf] = c & 0x7f;
487 
488 				if (keystate) {
489 					if (c & 0x80) {
490 						sc->sc_rep[npress++] = 0xe0;
491 					}
492 					sc->sc_rep[npress++] = c & 0x7f;
493 				} else {
494 					cbuf[ncbuf] |= 0x80;
495 				}
496 				ncbuf++;
497 				sc->sc_okeystate[i] = keystate;
498 			}
499 		}
500 #endif
501 
502 		if ((!sc->sc_rawkbd) && (sc->sc_okeystate[i] != keystate)) {
503 			type = keystate ? WSCONS_EVENT_KEY_DOWN :
504 			    WSCONS_EVENT_KEY_UP;
505 
506 			if (sc->sc_polling) {
507 				sc->sc_pollkey = i;
508 				sc->sc_pollUD = type;
509 			} else {
510 				wskbd_input(sc->sc_wskbddev, type, i);
511 			}
512 
513 			sc->sc_okeystate[i] = keystate;
514 		}
515 	}
516 
517 #ifdef WSDISPLAY_COMPAT_RAWKBD
518 	if (sc->sc_polling == 0 && sc->sc_rawkbd) {
519 		wskbd_rawinput(sc->sc_wskbddev, cbuf, ncbuf);
520 		sc->sc_nrep = npress;
521 		if (npress != 0)
522 			callout_schedule(&sc->sc_rawrepeat_ch,
523 			    hz * REP_DELAY1 / 1000);
524 		else
525 			callout_stop(&sc->sc_rawrepeat_ch);
526 	}
527 #endif
528 	if (keysdown)
529 		callout_schedule(&sc->sc_roll_to, hz * REP_DELAYN / 1000 / 2);
530 	else
531 		callout_stop(&sc->sc_roll_to);	/* always cancel? */
532 
533 	splx(s);
534 }
535 
536 #if NAPM > 0
537 extern	int kbd_reset;
538 extern	int apm_suspends;
539 static	int zkbdondown;				/* on key is pressed */
540 static	struct timeval zkbdontv = { 0, 0 };	/* last on key event */
541 const	struct timeval zkbdhalttv = { 3, 0 };	/*  3s for safe shutdown */
542 const	struct timeval zkbdsleeptv = { 0, 250000 };	/* .25s for suspend */
543 extern	int lid_suspend;
544 #endif
545 
546 static int
547 zkbd_on(void *v)
548 {
549 #if NAPM > 0
550 	struct zkbd_softc *sc = (struct zkbd_softc *)v;
551 	int down;
552 
553 	if (sc->sc_onkey_pin < 0)
554 		return 1;
555 
556 	down = pxa2x0_gpio_get_bit(sc->sc_onkey_pin) ? 1 : 0;
557 
558 	/*
559 	 * Change run mode depending on how long the key is held down.
560 	 * Ignore the key if it gets pressed while the lid is closed.
561 	 *
562 	 * Keys can bounce and we have to work around missed interrupts.
563 	 * Only the second edge is detected upon exit from sleep mode.
564 	 */
565 	if (down) {
566 		if (sc->sc_hinge == 3) {
567 			zkbdondown = 0;
568 		} else {
569 			microuptime(&zkbdontv);
570 			zkbdondown = 1;
571 		}
572 	} else if (zkbdondown) {
573 		if (ratecheck(&zkbdontv, &zkbdhalttv)) {
574 			if (kbd_reset == 1) {
575 				kbd_reset = 0;
576 				psignal(initproc, SIGUSR1);
577 			}
578 		} else if (ratecheck(&zkbdontv, &zkbdsleeptv)) {
579 			apm_suspends++;
580 		}
581 		zkbdondown = 0;
582 	}
583 #endif
584 	return 1;
585 }
586 
587 static int
588 zkbd_sync(void *v)
589 {
590 
591 	return 1;
592 }
593 
594 static int
595 zkbd_hinge(void *v)
596 {
597 	struct zkbd_softc *sc = (struct zkbd_softc *)v;
598 	int a, b;
599 
600 	if (sc->sc_swa_pin < 0 || sc->sc_swb_pin < 0)
601 		return 1;
602 
603 	a = pxa2x0_gpio_get_bit(sc->sc_swa_pin) ? 1 : 0;
604 	b = pxa2x0_gpio_get_bit(sc->sc_swb_pin) ? 2 : 0;
605 
606 	sc->sc_hinge = a | b;
607 
608 	if (sc->sc_hinge == 3) {
609 #if NAPM > 0
610 		if (lid_suspend)
611 			apm_suspends++;
612 #endif
613 #if NLCDCTL > 0
614 		lcdctl_blank(true);
615 #endif
616 	} else {
617 #if NLCDCTL > 0
618 		lcdctl_blank(false);
619 #endif
620 	}
621 
622 	return 1;
623 }
624 
625 static int
626 zkbd_enable(void *v, int on)
627 {
628 
629 	return 0;
630 }
631 
632 void
633 zkbd_set_leds(void *v, int on)
634 {
635 }
636 
637 static int
638 zkbd_ioctl(void *v, u_long cmd, void *data, int flag, struct lwp *l)
639 {
640 #ifdef WSDISPLAY_COMPAT_RAWKBD
641 	struct zkbd_softc *sc = (struct zkbd_softc *)v;
642 #endif
643 
644 	switch (cmd) {
645 	case WSKBDIO_GTYPE:
646 		*(int *)data = WSKBD_TYPE_ZAURUS;
647 		return 0;
648 
649 	case WSKBDIO_SETLEDS:
650 		return 0;
651 
652 	case WSKBDIO_GETLEDS:
653 		*(int *)data = 0;
654 		return 0;
655 
656 #ifdef WSDISPLAY_COMPAT_RAWKBD
657 	case WSKBDIO_SETMODE:
658 		sc->sc_rawkbd = *(int *)data == WSKBD_RAW;
659 		callout_stop(&sc->sc_rawrepeat_ch);
660 		return 0;
661 #endif
662 
663 	}
664 	return EPASSTHROUGH;
665 }
666 
667 /* implement polling for zaurus_kbd */
668 static void
669 zkbd_cngetc(void *v, u_int *type, int *data)
670 {
671 	struct zkbd_softc *sc = (struct zkbd_softc *)zkbd_sc;
672 
673 	sc->sc_pollkey = -1;
674 	sc->sc_pollUD = -1;
675 	sc->sc_polling = 1;
676 	while (sc->sc_pollkey == -1) {
677 		zkbd_poll(sc);
678 		DELAY(10000);	/* XXX */
679 	}
680 	sc->sc_polling = 0;
681 	*data = sc->sc_pollkey;
682 	*type = sc->sc_pollUD;
683 }
684 
685 static void
686 zkbd_cnpollc(void *v, int on)
687 {
688 }
689 
690 static bool
691 zkbd_resume(device_t dv, const pmf_qual_t *qual)
692 {
693 	struct zkbd_softc *sc = device_private(dv);
694 
695 	zkbd_hinge(sc);
696 
697 	return true;
698 }
699