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