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