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