Home | History | Annotate | Line # | Download | only in dev
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