xref: /netbsd-src/sys/arch/zaurus/dev/zkbd.c (revision c7fb772b85b2b5d4cfb282f868f454b4701534fd)
1 /*	$NetBSD: zkbd.c,v 1.22 2021/08/07 16:19:08 thorpej 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.22 2021/08/07 16:19:08 thorpej 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/kmem.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
zkbd_match(device_t parent,cfdata_t cf,void * aux)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
zkbd_attach(device_t parent,device_t self,void * aux)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 = kmem_zalloc(sc->sc_nsense * sc->sc_nstrobe,
287 	    KM_SLEEP);
288 	sc->sc_keystate = kmem_zalloc(sc->sc_nsense * sc->sc_nstrobe,
289 	    KM_SLEEP);
290 
291 	/* set all the strobe bits */
292 	for (i = 0; i < sc->sc_nstrobe; i++) {
293 		pin = sc->sc_strobe_array[i];
294 		if (pin == -1)
295 			continue;
296 		pxa2x0_gpio_set_function(pin, GPIO_SET|GPIO_OUT);
297 	}
298 
299 	/* set all the sense bits */
300 	for (i = 0; i < sc->sc_nsense; i++) {
301 		pin = sc->sc_sense_array[i];
302 		if (pin == -1)
303 			continue;
304 		pxa2x0_gpio_set_function(pin, GPIO_IN);
305 		if (ZAURUS_ISC1000 || ZAURUS_ISC3000) {
306 			pxa2x0_gpio_intr_establish(pin, IST_EDGE_BOTH,
307 			    IPL_TTY, zkbd_irq_c3000, sc);
308 		} else if (ZAURUS_ISC860) {
309 			pxa2x0_gpio_intr_establish(pin, IST_EDGE_RISING,
310 			    IPL_TTY, zkbd_irq_c860, sc);
311 		}
312 	}
313 
314 	if (sc->sc_onkey_pin >= 0)
315 		pxa2x0_gpio_intr_establish(sc->sc_onkey_pin, IST_EDGE_BOTH,
316 		    IPL_TTY, zkbd_on, sc);
317 	if (sc->sc_sync_pin >= 0)
318 		pxa2x0_gpio_intr_establish(sc->sc_sync_pin, IST_EDGE_RISING,
319 		    IPL_TTY, zkbd_sync, sc);
320 	if (sc->sc_swa_pin >= 0)
321 		pxa2x0_gpio_intr_establish(sc->sc_swa_pin, IST_EDGE_BOTH,
322 		    IPL_TTY, zkbd_hinge, sc);
323 	if (sc->sc_swb_pin >= 0)
324 		pxa2x0_gpio_intr_establish(sc->sc_swb_pin, IST_EDGE_BOTH,
325 		    IPL_TTY, zkbd_hinge, sc);
326 
327 	if (glass_console) {
328 		wskbd_cnattach(&zkbd_consops, sc, sc->sc_keymapdata);
329 		a.console = 1;
330 	} else {
331 		a.console = 0;
332 	}
333 	a.keymap = sc->sc_keymapdata;
334 	a.accessops = &zkbd_accessops;
335 	a.accesscookie = sc;
336 
337 	zkbd_hinge(sc);		/* to initialize sc_hinge */
338 
339 	sc->sc_wskbddev = config_found(self, &a, wskbddevprint, CFARGS_NONE);
340 }
341 
342 #ifdef WSDISPLAY_COMPAT_RAWKBD
343 static void
zkbd_rawrepeat(void * v)344 zkbd_rawrepeat(void *v)
345 {
346 	struct zkbd_softc *sc = (struct zkbd_softc *)v;
347 	int s;
348 
349 	s = spltty();
350 	wskbd_rawinput(sc->sc_wskbddev, sc->sc_rep, sc->sc_nrep);
351 	splx(s);
352 	callout_schedule(&sc->sc_rawrepeat_ch, hz * REP_DELAYN / 1000);
353 }
354 #endif
355 
356 /* XXX only deal with keys that can be pressed when display is open? */
357 /* XXX are some not in the array? */
358 /* handle keypress interrupt */
359 static int
zkbd_irq_c3000(void * v)360 zkbd_irq_c3000(void *v)
361 {
362 
363 	zkbd_poll(v);
364 
365 	return 1;
366 }
367 
368 /* Avoid chattering only for SL-C7x0/860 */
369 static int
zkbd_irq_c860(void * v)370 zkbd_irq_c860(void *v)
371 {
372 	struct zkbd_softc *sc = (struct zkbd_softc *)v;
373 
374 	if (!callout_pending(&sc->sc_roll_to)) {
375 		zkbd_poll(v);
376 	}
377 
378 	return 1;
379 }
380 
381 static void
zkbd_poll(void * v)382 zkbd_poll(void *v)
383 {
384 	struct zkbd_softc *sc = (struct zkbd_softc *)v;
385 	int i, j, col, pin, type, keysdown = 0;
386 	int stuck;
387 	int keystate;
388 	int s;
389 #ifdef WSDISPLAY_COMPAT_RAWKBD
390 	int npress = 0, ncbuf = 0, c;
391 	char cbuf[MAXKEYS * 2];
392 #endif
393 
394 	s = spltty();
395 
396 	/* discharge all */
397 	for (i = 0; i < sc->sc_nstrobe; i++) {
398 		pin = sc->sc_strobe_array[i];
399 		if (pin == -1)
400 			continue;
401 		pxa2x0_gpio_clear_bit(pin);
402 		pxa2x0_gpio_set_dir(pin, GPIO_IN);
403 	}
404 
405 	delay(10);
406 	for (col = 0; col < sc->sc_nstrobe; col++) {
407 		pin = sc->sc_strobe_array[col];
408 		if (pin == -1)
409 			continue;
410 
411 		/* activate_col */
412 		pxa2x0_gpio_set_bit(pin);
413 		pxa2x0_gpio_set_dir(pin, GPIO_OUT);
414 
415 		/* wait activate delay */
416 		delay(10);
417 
418 		/* read row */
419 		for (i = 0; i < sc->sc_nsense; i++) {
420 			int bit;
421 
422 			if (sc->sc_sense_array[i] == -1)
423 				continue;
424 			bit = pxa2x0_gpio_get_bit(sc->sc_sense_array[i]);
425 			if (bit && sc->sc_hinge && col < sc->sc_maxkbdcol)
426 				continue;
427 			sc->sc_keystate[i + (col * sc->sc_nsense)] = bit;
428 		}
429 
430 		/* reset_col */
431 		pxa2x0_gpio_set_dir(pin, GPIO_IN);
432 
433 		/* wait discharge delay */
434 		delay(10);
435 	}
436 
437 	/* charge all */
438 	for (i = 0; i < sc->sc_nstrobe; i++) {
439 		pin = sc->sc_strobe_array[i];
440 		if (pin == -1)
441 			continue;
442 		pxa2x0_gpio_set_bit(pin);
443 		pxa2x0_gpio_set_dir(pin, GPIO_OUT);
444 	}
445 
446 	/* force the irqs to clear as we have just played with them. */
447 	for (i = 0; i < sc->sc_nsense; i++) {
448 		pin = sc->sc_sense_array[i];
449 		if (pin == -1)
450 			continue;
451 		pxa2x0_gpio_clear_intr(pin);
452 	}
453 
454 	/* process after resetting interrupt */
455 	zkbd_modstate = (
456 		(sc->sc_keystate[84] ? (1 << 0) : 0) | /* shift */
457 		(sc->sc_keystate[93] ? (1 << 1) : 0) | /* Fn */
458 		(sc->sc_keystate[14] ? (1 << 2) : 0)); /* 'alt' */
459 
460 	for (i = 0; i < sc->sc_nsense * sc->sc_nstrobe; i++) {
461 		stuck = 0;
462 		/* extend  xt_keymap to do this faster. */
463 		/* ignore 'stuck' keys' */
464 		for (j = 0; j < sc->sc_nstuck; j++) {
465 			if (sc->sc_stuck_keys[j] == i) {
466 				stuck = 1;
467 				break;
468 			}
469 		}
470 		if (stuck)
471 			continue;
472 
473 		keystate = sc->sc_keystate[i];
474 		keysdown |= keystate; /* if any keys held */
475 
476 #ifdef WSDISPLAY_COMPAT_RAWKBD
477 		if (sc->sc_polling == 0 && sc->sc_rawkbd) {
478 			if ((keystate) || (sc->sc_okeystate[i] != keystate)) {
479 				c = sc->sc_xt_keymap[i];
480 				if (c & 0x80) {
481 					cbuf[ncbuf++] = 0xe0;
482 				}
483 				cbuf[ncbuf] = c & 0x7f;
484 
485 				if (keystate) {
486 					if (c & 0x80) {
487 						sc->sc_rep[npress++] = 0xe0;
488 					}
489 					sc->sc_rep[npress++] = c & 0x7f;
490 				} else {
491 					cbuf[ncbuf] |= 0x80;
492 				}
493 				ncbuf++;
494 				sc->sc_okeystate[i] = keystate;
495 			}
496 		}
497 #endif
498 
499 		if ((!sc->sc_rawkbd) && (sc->sc_okeystate[i] != keystate)) {
500 			type = keystate ? WSCONS_EVENT_KEY_DOWN :
501 			    WSCONS_EVENT_KEY_UP;
502 
503 			if (sc->sc_polling) {
504 				sc->sc_pollkey = i;
505 				sc->sc_pollUD = type;
506 			} else {
507 				wskbd_input(sc->sc_wskbddev, type, i);
508 			}
509 
510 			sc->sc_okeystate[i] = keystate;
511 		}
512 	}
513 
514 #ifdef WSDISPLAY_COMPAT_RAWKBD
515 	if (sc->sc_polling == 0 && sc->sc_rawkbd) {
516 		wskbd_rawinput(sc->sc_wskbddev, cbuf, ncbuf);
517 		sc->sc_nrep = npress;
518 		if (npress != 0)
519 			callout_schedule(&sc->sc_rawrepeat_ch,
520 			    hz * REP_DELAY1 / 1000);
521 		else
522 			callout_stop(&sc->sc_rawrepeat_ch);
523 	}
524 #endif
525 	if (keysdown)
526 		callout_schedule(&sc->sc_roll_to, hz * REP_DELAYN / 1000 / 2);
527 	else
528 		callout_stop(&sc->sc_roll_to);	/* always cancel? */
529 
530 	splx(s);
531 }
532 
533 #if NAPM > 0
534 extern	int kbd_reset;
535 extern	int apm_suspends;
536 static	int zkbdondown;				/* on key is pressed */
537 static	struct timeval zkbdontv = { 0, 0 };	/* last on key event */
538 const	struct timeval zkbdhalttv = { 3, 0 };	/*  3s for safe shutdown */
539 const	struct timeval zkbdsleeptv = { 0, 250000 };	/* .25s for suspend */
540 extern	int lid_suspend;
541 #endif
542 
543 static int
zkbd_on(void * v)544 zkbd_on(void *v)
545 {
546 #if NAPM > 0
547 	struct zkbd_softc *sc = (struct zkbd_softc *)v;
548 	int down;
549 
550 	if (sc->sc_onkey_pin < 0)
551 		return 1;
552 
553 	down = pxa2x0_gpio_get_bit(sc->sc_onkey_pin) ? 1 : 0;
554 
555 	/*
556 	 * Change run mode depending on how long the key is held down.
557 	 * Ignore the key if it gets pressed while the lid is closed.
558 	 *
559 	 * Keys can bounce and we have to work around missed interrupts.
560 	 * Only the second edge is detected upon exit from sleep mode.
561 	 */
562 	if (down) {
563 		if (sc->sc_hinge == 3) {
564 			zkbdondown = 0;
565 		} else {
566 			microuptime(&zkbdontv);
567 			zkbdondown = 1;
568 		}
569 	} else if (zkbdondown) {
570 		if (ratecheck(&zkbdontv, &zkbdhalttv)) {
571 			if (kbd_reset == 1) {
572 				kbd_reset = 0;
573 				psignal(initproc, SIGUSR1);
574 			}
575 		} else if (ratecheck(&zkbdontv, &zkbdsleeptv)) {
576 			apm_suspends++;
577 		}
578 		zkbdondown = 0;
579 	}
580 #endif
581 	return 1;
582 }
583 
584 static int
zkbd_sync(void * v)585 zkbd_sync(void *v)
586 {
587 
588 	return 1;
589 }
590 
591 static int
zkbd_hinge(void * v)592 zkbd_hinge(void *v)
593 {
594 	struct zkbd_softc *sc = (struct zkbd_softc *)v;
595 	int a, b;
596 
597 	if (sc->sc_swa_pin < 0 || sc->sc_swb_pin < 0)
598 		return 1;
599 
600 	a = pxa2x0_gpio_get_bit(sc->sc_swa_pin) ? 1 : 0;
601 	b = pxa2x0_gpio_get_bit(sc->sc_swb_pin) ? 2 : 0;
602 
603 	sc->sc_hinge = a | b;
604 
605 	if (sc->sc_hinge == 3) {
606 #if NAPM > 0
607 		if (lid_suspend)
608 			apm_suspends++;
609 #endif
610 #if NLCDCTL > 0
611 		lcdctl_blank(true);
612 #endif
613 	} else {
614 #if NLCDCTL > 0
615 		lcdctl_blank(false);
616 #endif
617 	}
618 
619 	return 1;
620 }
621 
622 static int
zkbd_enable(void * v,int on)623 zkbd_enable(void *v, int on)
624 {
625 
626 	return 0;
627 }
628 
629 void
zkbd_set_leds(void * v,int on)630 zkbd_set_leds(void *v, int on)
631 {
632 }
633 
634 static int
zkbd_ioctl(void * v,u_long cmd,void * data,int flag,struct lwp * l)635 zkbd_ioctl(void *v, u_long cmd, void *data, int flag, struct lwp *l)
636 {
637 #ifdef WSDISPLAY_COMPAT_RAWKBD
638 	struct zkbd_softc *sc = (struct zkbd_softc *)v;
639 #endif
640 
641 	switch (cmd) {
642 	case WSKBDIO_GTYPE:
643 		*(int *)data = WSKBD_TYPE_ZAURUS;
644 		return 0;
645 
646 	case WSKBDIO_SETLEDS:
647 		return 0;
648 
649 	case WSKBDIO_GETLEDS:
650 		*(int *)data = 0;
651 		return 0;
652 
653 #ifdef WSDISPLAY_COMPAT_RAWKBD
654 	case WSKBDIO_SETMODE:
655 		sc->sc_rawkbd = *(int *)data == WSKBD_RAW;
656 		callout_stop(&sc->sc_rawrepeat_ch);
657 		return 0;
658 #endif
659 
660 	}
661 	return EPASSTHROUGH;
662 }
663 
664 /* implement polling for zaurus_kbd */
665 static void
zkbd_cngetc(void * v,u_int * type,int * data)666 zkbd_cngetc(void *v, u_int *type, int *data)
667 {
668 	struct zkbd_softc *sc = (struct zkbd_softc *)zkbd_sc;
669 
670 	sc->sc_pollkey = -1;
671 	sc->sc_pollUD = -1;
672 	sc->sc_polling = 1;
673 	while (sc->sc_pollkey == -1) {
674 		zkbd_poll(sc);
675 		DELAY(10000);	/* XXX */
676 	}
677 	sc->sc_polling = 0;
678 	*data = sc->sc_pollkey;
679 	*type = sc->sc_pollUD;
680 }
681 
682 static void
zkbd_cnpollc(void * v,int on)683 zkbd_cnpollc(void *v, int on)
684 {
685 }
686 
687 static bool
zkbd_resume(device_t dv,const pmf_qual_t * qual)688 zkbd_resume(device_t dv, const pmf_qual_t *qual)
689 {
690 	struct zkbd_softc *sc = device_private(dv);
691 
692 	zkbd_hinge(sc);
693 
694 	return true;
695 }
696