1/*	$NetBSD: zkbd.c,v 1.15 2012/01/25 16:51:17 tsutsui 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.15 2012/01/25 16:51:17 tsutsui 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
52static const int gpio_sense_pins_c3000[] = {
53	12,
54	17,
55	91,
56	34,
57	36,
58	38,
59	39,
60	-1
61};
62
63static 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
78static const int gpio_sense_pins_c860[] = {
79	58,
80	59,
81	60,
82	61,
83	62,
84	63,
85	64,
86	65
87};
88
89static const int gpio_strobe_pins_c860[] = {
90	66,
91	67,
92	68,
93	69,
94	70,
95	71,
96	72,
97	73,
98	74,
99	75,
100	76,
101	77
102};
103
104static const int stuck_keys[] = {
105	7,
106	15,
107	23,
108	31
109};
110
111#define REP_DELAY1 400
112#define REP_DELAYN 100
113
114struct zkbd_softc {
115	device_t sc_dev;
116
117	const int *sc_sense_array;
118	const int *sc_strobe_array;
119	const int *sc_stuck_keys;
120	int sc_nsense;
121	int sc_nstrobe;
122	int sc_nstuck;
123
124	short sc_onkey_pin;
125	short sc_sync_pin;
126	short sc_swa_pin;
127	short sc_swb_pin;
128	char *sc_okeystate;
129	char *sc_keystate;
130	char sc_hinge;		/* 0=open, 1=nonsense, 2=backwards, 3=closed */
131	char sc_maxkbdcol;
132
133	struct callout sc_roll_to;
134
135	/* console stuff */
136	int sc_polling;
137	int sc_pollUD;
138	int sc_pollkey;
139
140	/* wskbd bits */
141	struct device *sc_wskbddev;
142	struct wskbd_mapdata *sc_keymapdata;
143	int sc_rawkbd;
144#ifdef WSDISPLAY_COMPAT_RAWKBD
145	const char *sc_xt_keymap;
146	struct callout sc_rawrepeat_ch;
147#define MAXKEYS 20
148	char sc_rep[MAXKEYS];
149	int sc_nrep;
150#endif
151};
152
153static struct zkbd_softc *zkbd_sc;
154
155static int	zkbd_match(device_t, cfdata_t, void *);
156static void	zkbd_attach(device_t, device_t, void *);
157
158CFATTACH_DECL_NEW(zkbd, sizeof(struct zkbd_softc),
159	zkbd_match, zkbd_attach, NULL, NULL);
160
161static int	zkbd_irq(void *v);
162static void	zkbd_poll(void *v);
163static int	zkbd_on(void *v);
164static int	zkbd_sync(void *v);
165static int	zkbd_hinge(void *v);
166static bool	zkbd_resume(device_t dv, const pmf_qual_t *);
167
168int zkbd_modstate;
169
170static int	zkbd_enable(void *, int);
171static void	zkbd_set_leds(void *, int);
172static int	zkbd_ioctl(void *, u_long, void *, int, struct lwp *);
173#ifdef WSDISPLAY_COMPAT_RAWKBD
174static void	zkbd_rawrepeat(void *v);
175#endif
176
177static struct wskbd_accessops zkbd_accessops = {
178	zkbd_enable,
179	zkbd_set_leds,
180	zkbd_ioctl,
181};
182
183static void	zkbd_cngetc(void *, u_int *, int *);
184static void	zkbd_cnpollc(void *, int);
185
186static struct wskbd_consops zkbd_consops = {
187	zkbd_cngetc,
188	zkbd_cnpollc,
189};
190
191static struct wskbd_mapdata zkbd_keymapdata = {
192	zkbd_keydesctab,
193	KB_US,
194};
195
196static struct wskbd_mapdata zkbd_keymapdata_c860 = {
197	zkbd_keydesctab_c860,
198	KB_US,
199};
200
201static int
202zkbd_match(device_t parent, cfdata_t cf, void *aux)
203{
204
205	if (zkbd_sc)
206		return 0;
207
208	return 1;
209}
210
211static void
212zkbd_attach(device_t parent, device_t self, void *aux)
213{
214	struct zkbd_softc *sc = device_private(self);
215	struct wskbddev_attach_args a;
216	int pin, i;
217
218	sc->sc_dev = self;
219	zkbd_sc = sc;
220
221	aprint_normal("\n");
222	aprint_naive("\n");
223
224	sc->sc_polling = 0;
225#ifdef WSDISPLAY_COMPAT_RAWKBD
226	sc->sc_rawkbd = 0;
227#endif
228
229	callout_init(&sc->sc_roll_to, 0);
230	callout_setfunc(&sc->sc_roll_to, zkbd_poll, sc);
231#ifdef WSDISPLAY_COMPAT_RAWKBD
232	callout_init(&sc->sc_rawrepeat_ch, 0);
233	callout_setfunc(&sc->sc_rawrepeat_ch, zkbd_rawrepeat, sc);
234#endif
235
236	if (ZAURUS_ISC1000 || ZAURUS_ISC3000) {
237		sc->sc_sense_array = gpio_sense_pins_c3000;
238		sc->sc_strobe_array = gpio_strobe_pins_c3000;
239		sc->sc_nsense = __arraycount(gpio_sense_pins_c3000);
240		sc->sc_nstrobe = __arraycount(gpio_strobe_pins_c3000);
241		sc->sc_stuck_keys = stuck_keys;
242		sc->sc_nstuck = __arraycount(stuck_keys);
243		sc->sc_maxkbdcol = 10;
244		sc->sc_onkey_pin = 95;
245		sc->sc_sync_pin = 16;
246		sc->sc_swa_pin = 97;
247		sc->sc_swb_pin = 96;
248		sc->sc_keymapdata = &zkbd_keymapdata;
249#ifdef WSDISPLAY_COMPAT_RAWKBD
250		sc->sc_xt_keymap = xt_keymap;
251#endif
252	} else if (ZAURUS_ISC860) {
253		sc->sc_sense_array = gpio_sense_pins_c860;
254		sc->sc_strobe_array = gpio_strobe_pins_c860;
255		sc->sc_nsense = __arraycount(gpio_sense_pins_c860);
256		sc->sc_nstrobe = __arraycount(gpio_strobe_pins_c860);
257		sc->sc_stuck_keys = NULL;
258		sc->sc_nstuck = 0;
259		sc->sc_maxkbdcol = 0;
260		sc->sc_onkey_pin = -1;
261		sc->sc_sync_pin = -1;
262		sc->sc_swa_pin = -1;
263		sc->sc_swb_pin = -1;
264		sc->sc_keymapdata = &zkbd_keymapdata_c860;
265#ifdef WSDISPLAY_COMPAT_RAWKBD
266		sc->sc_xt_keymap = xt_keymap_c860;
267#endif
268	} else {
269		/* XXX */
270		return;
271	}
272
273	if (!pmf_device_register(sc->sc_dev, NULL, zkbd_resume))
274		aprint_error_dev(sc->sc_dev,
275		    "couldn't establish power handler\n");
276
277	sc->sc_okeystate = malloc(sc->sc_nsense * sc->sc_nstrobe,
278	    M_DEVBUF, M_NOWAIT);
279	memset(sc->sc_okeystate, 0, sc->sc_nsense * sc->sc_nstrobe);
280
281	sc->sc_keystate = malloc(sc->sc_nsense * sc->sc_nstrobe,
282	    M_DEVBUF, M_NOWAIT);
283	memset(sc->sc_keystate, 0, sc->sc_nsense * sc->sc_nstrobe);
284
285	/* set all the strobe bits */
286	for (i = 0; i < sc->sc_nstrobe; i++) {
287		pin = sc->sc_strobe_array[i];
288		if (pin == -1)
289			continue;
290		pxa2x0_gpio_set_function(pin, GPIO_SET|GPIO_OUT);
291	}
292
293	/* set all the sense bits */
294	for (i = 0; i < sc->sc_nsense; i++) {
295		pin = sc->sc_sense_array[i];
296		if (pin == -1)
297			continue;
298		pxa2x0_gpio_set_function(pin, GPIO_IN);
299		pxa2x0_gpio_intr_establish(pin, IST_EDGE_BOTH, IPL_TTY,
300		    zkbd_irq, sc);
301	}
302
303	if (sc->sc_onkey_pin >= 0)
304		pxa2x0_gpio_intr_establish(sc->sc_onkey_pin, IST_EDGE_BOTH,
305		    IPL_TTY, zkbd_on, sc);
306	if (sc->sc_sync_pin >= 0)
307		pxa2x0_gpio_intr_establish(sc->sc_sync_pin, IST_EDGE_RISING,
308		    IPL_TTY, zkbd_sync, sc);
309	if (sc->sc_swa_pin >= 0)
310		pxa2x0_gpio_intr_establish(sc->sc_swa_pin, IST_EDGE_BOTH,
311		    IPL_TTY, zkbd_hinge, sc);
312	if (sc->sc_swb_pin >= 0)
313		pxa2x0_gpio_intr_establish(sc->sc_swb_pin, IST_EDGE_BOTH,
314		    IPL_TTY, zkbd_hinge, sc);
315
316	if (glass_console) {
317		wskbd_cnattach(&zkbd_consops, sc, sc->sc_keymapdata);
318		a.console = 1;
319	} else {
320		a.console = 0;
321	}
322	a.keymap = sc->sc_keymapdata;
323	a.accessops = &zkbd_accessops;
324	a.accesscookie = sc;
325
326	zkbd_hinge(sc);		/* to initialize sc_hinge */
327
328	sc->sc_wskbddev = config_found(self, &a, wskbddevprint);
329}
330
331#ifdef WSDISPLAY_COMPAT_RAWKBD
332static void
333zkbd_rawrepeat(void *v)
334{
335	struct zkbd_softc *sc = (struct zkbd_softc *)v;
336	int s;
337
338	s = spltty();
339	wskbd_rawinput(sc->sc_wskbddev, sc->sc_rep, sc->sc_nrep);
340	splx(s);
341	callout_schedule(&sc->sc_rawrepeat_ch, hz * REP_DELAYN / 1000);
342}
343#endif
344
345/* XXX only deal with keys that can be pressed when display is open? */
346/* XXX are some not in the array? */
347/* handle keypress interrupt */
348static int
349zkbd_irq(void *v)
350{
351
352	zkbd_poll(v);
353
354	return 1;
355}
356
357static void
358zkbd_poll(void *v)
359{
360	struct zkbd_softc *sc = (struct zkbd_softc *)v;
361	int i, j, col, pin, type, keysdown = 0;
362	int stuck;
363	int keystate;
364	int s;
365#ifdef WSDISPLAY_COMPAT_RAWKBD
366	int npress = 0, ncbuf = 0, c;
367	char cbuf[MAXKEYS * 2];
368#endif
369
370	s = spltty();
371
372	/* discharge all */
373	for (i = 0; i < sc->sc_nstrobe; i++) {
374		pin = sc->sc_strobe_array[i];
375		if (pin == -1)
376			continue;
377		pxa2x0_gpio_clear_bit(pin);
378		pxa2x0_gpio_set_dir(pin, GPIO_IN);
379	}
380
381	delay(10);
382	for (col = 0; col < sc->sc_nstrobe; col++) {
383		pin = sc->sc_strobe_array[col];
384		if (pin == -1)
385			continue;
386
387		/* activate_col */
388		pxa2x0_gpio_set_bit(pin);
389		pxa2x0_gpio_set_dir(pin, GPIO_OUT);
390
391		/* wait activate delay */
392		delay(10);
393
394		/* read row */
395		for (i = 0; i < sc->sc_nsense; i++) {
396			int bit;
397
398			if (sc->sc_sense_array[i] == -1)
399				continue;
400			bit = pxa2x0_gpio_get_bit(sc->sc_sense_array[i]);
401			if (bit && sc->sc_hinge && col < sc->sc_maxkbdcol)
402				continue;
403			sc->sc_keystate[i + (col * sc->sc_nsense)] = bit;
404		}
405
406		/* reset_col */
407		pxa2x0_gpio_set_dir(pin, GPIO_IN);
408
409		/* wait discharge delay */
410		delay(10);
411	}
412
413	/* charge all */
414	for (i = 0; i < sc->sc_nstrobe; i++) {
415		pin = sc->sc_strobe_array[i];
416		if (pin == -1)
417			continue;
418		pxa2x0_gpio_set_bit(pin);
419		pxa2x0_gpio_set_dir(pin, GPIO_OUT);
420	}
421
422	/* force the irqs to clear as we have just played with them. */
423	for (i = 0; i < sc->sc_nsense; i++) {
424		pin = sc->sc_sense_array[i];
425		if (pin == -1)
426			continue;
427		pxa2x0_gpio_clear_intr(pin);
428	}
429
430	/* process after resetting interrupt */
431	zkbd_modstate = (
432		(sc->sc_keystate[84] ? (1 << 0) : 0) | /* shift */
433		(sc->sc_keystate[93] ? (1 << 1) : 0) | /* Fn */
434		(sc->sc_keystate[14] ? (1 << 2) : 0)); /* 'alt' */
435
436	for (i = 0; i < sc->sc_nsense * sc->sc_nstrobe; i++) {
437		stuck = 0;
438		/* extend  xt_keymap to do this faster. */
439		/* ignore 'stuck' keys' */
440		for (j = 0; j < sc->sc_nstuck; j++) {
441			if (sc->sc_stuck_keys[j] == i) {
442				stuck = 1;
443				break;
444			}
445		}
446		if (stuck)
447			continue;
448
449		keystate = sc->sc_keystate[i];
450		keysdown |= keystate; /* if any keys held */
451
452#ifdef WSDISPLAY_COMPAT_RAWKBD
453		if (sc->sc_polling == 0 && sc->sc_rawkbd) {
454			if ((keystate) || (sc->sc_okeystate[i] != keystate)) {
455				c = sc->sc_xt_keymap[i];
456				if (c & 0x80) {
457					cbuf[ncbuf++] = 0xe0;
458				}
459				cbuf[ncbuf] = c & 0x7f;
460
461				if (keystate) {
462					if (c & 0x80) {
463						sc->sc_rep[npress++] = 0xe0;
464					}
465					sc->sc_rep[npress++] = c & 0x7f;
466				} else {
467					cbuf[ncbuf] |= 0x80;
468				}
469				ncbuf++;
470				sc->sc_okeystate[i] = keystate;
471			}
472		}
473#endif
474
475		if ((!sc->sc_rawkbd) && (sc->sc_okeystate[i] != keystate)) {
476			type = keystate ? WSCONS_EVENT_KEY_DOWN :
477			    WSCONS_EVENT_KEY_UP;
478
479			if (sc->sc_polling) {
480				sc->sc_pollkey = i;
481				sc->sc_pollUD = type;
482			} else {
483				wskbd_input(sc->sc_wskbddev, type, i);
484			}
485
486			sc->sc_okeystate[i] = keystate;
487		}
488	}
489
490#ifdef WSDISPLAY_COMPAT_RAWKBD
491	if (sc->sc_polling == 0 && sc->sc_rawkbd) {
492		wskbd_rawinput(sc->sc_wskbddev, cbuf, ncbuf);
493		sc->sc_nrep = npress;
494		if (npress != 0)
495			callout_schedule(&sc->sc_rawrepeat_ch,
496			    hz * REP_DELAY1 / 1000);
497		else
498			callout_stop(&sc->sc_rawrepeat_ch);
499	}
500#endif
501	if (keysdown)
502		callout_schedule(&sc->sc_roll_to, hz * REP_DELAYN / 1000 / 2);
503	else
504		callout_stop(&sc->sc_roll_to);	/* always cancel? */
505
506	splx(s);
507}
508
509#if NAPM > 0
510extern	int kbd_reset;
511extern	int apm_suspends;
512static	int zkbdondown;				/* on key is pressed */
513static	struct timeval zkbdontv = { 0, 0 };	/* last on key event */
514const	struct timeval zkbdhalttv = { 3, 0 };	/*  3s for safe shutdown */
515const	struct timeval zkbdsleeptv = { 0, 250000 };	/* .25s for suspend */
516extern	int lid_suspend;
517#endif
518
519static int
520zkbd_on(void *v)
521{
522#if NAPM > 0
523	struct zkbd_softc *sc = (struct zkbd_softc *)v;
524	int down;
525
526	if (sc->sc_onkey_pin < 0)
527		return 1;
528
529	down = pxa2x0_gpio_get_bit(sc->sc_onkey_pin) ? 1 : 0;
530
531	/*
532	 * Change run mode depending on how long the key is held down.
533	 * Ignore the key if it gets pressed while the lid is closed.
534	 *
535	 * Keys can bounce and we have to work around missed interrupts.
536	 * Only the second edge is detected upon exit from sleep mode.
537	 */
538	if (down) {
539		if (sc->sc_hinge == 3) {
540			zkbdondown = 0;
541		} else {
542			microuptime(&zkbdontv);
543			zkbdondown = 1;
544		}
545	} else if (zkbdondown) {
546		if (ratecheck(&zkbdontv, &zkbdhalttv)) {
547			if (kbd_reset == 1) {
548				kbd_reset = 0;
549				psignal(initproc, SIGUSR1);
550			}
551		} else if (ratecheck(&zkbdontv, &zkbdsleeptv)) {
552			apm_suspends++;
553		}
554		zkbdondown = 0;
555	}
556#endif
557	return 1;
558}
559
560static int
561zkbd_sync(void *v)
562{
563
564	return 1;
565}
566
567static int
568zkbd_hinge(void *v)
569{
570	struct zkbd_softc *sc = (struct zkbd_softc *)v;
571	int a, b;
572
573	if (sc->sc_swa_pin < 0 || sc->sc_swb_pin < 0)
574		return 1;
575
576	a = pxa2x0_gpio_get_bit(sc->sc_swa_pin) ? 1 : 0;
577	b = pxa2x0_gpio_get_bit(sc->sc_swb_pin) ? 2 : 0;
578
579	sc->sc_hinge = a | b;
580
581	if (sc->sc_hinge == 3) {
582#if NAPM > 0
583		if (lid_suspend)
584			apm_suspends++;
585#endif
586#if NLCDCTL > 0
587		lcdctl_blank(true);
588#endif
589	} else {
590#if NLCDCTL > 0
591		lcdctl_blank(false);
592#endif
593	}
594
595	return 1;
596}
597
598static int
599zkbd_enable(void *v, int on)
600{
601
602	return 0;
603}
604
605void
606zkbd_set_leds(void *v, int on)
607{
608}
609
610static int
611zkbd_ioctl(void *v, u_long cmd, void *data, int flag, struct lwp *l)
612{
613#ifdef WSDISPLAY_COMPAT_RAWKBD
614	struct zkbd_softc *sc = (struct zkbd_softc *)v;
615#endif
616
617	switch (cmd) {
618	case WSKBDIO_GTYPE:
619		*(int *)data = WSKBD_TYPE_ZAURUS;
620		return 0;
621
622	case WSKBDIO_SETLEDS:
623		return 0;
624
625	case WSKBDIO_GETLEDS:
626		*(int *)data = 0;
627		return 0;
628
629#ifdef WSDISPLAY_COMPAT_RAWKBD
630	case WSKBDIO_SETMODE:
631		sc->sc_rawkbd = *(int *)data == WSKBD_RAW;
632		callout_stop(&sc->sc_rawrepeat_ch);
633		return 0;
634#endif
635
636	}
637	return EPASSTHROUGH;
638}
639
640/* implement polling for zaurus_kbd */
641static void
642zkbd_cngetc(void *v, u_int *type, int *data)
643{
644	struct zkbd_softc *sc = (struct zkbd_softc *)zkbd_sc;
645
646	sc->sc_pollkey = -1;
647	sc->sc_pollUD = -1;
648	sc->sc_polling = 1;
649	while (sc->sc_pollkey == -1) {
650		zkbd_poll(sc);
651		DELAY(10000);	/* XXX */
652	}
653	sc->sc_polling = 0;
654	*data = sc->sc_pollkey;
655	*type = sc->sc_pollUD;
656}
657
658static void
659zkbd_cnpollc(void *v, int on)
660{
661}
662
663static bool
664zkbd_resume(device_t dv, const pmf_qual_t *qual)
665{
666	struct zkbd_softc *sc = device_private(dv);
667
668	zkbd_hinge(sc);
669
670	return true;
671}
672