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