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