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