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