Home | History | Annotate | Line # | Download | only in dev
zkbd.c revision 1.18
      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 (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.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