Home | History | Annotate | Line # | Download | only in vr
vrkiu.c revision 1.1.1.1.4.1
      1  1.1.1.1.4.1      fvdl /*	$NetBSD: vrkiu.c,v 1.1.1.1.4.1 1999/11/15 00:37:56 fvdl Exp $	*/
      2          1.1  takemura 
      3          1.1  takemura /*-
      4  1.1.1.1.4.1      fvdl  * Copyright (c) 1999 SASAKI Takesi All rights reserved.
      5  1.1.1.1.4.1      fvdl  * Copyright (c) 1999 TAKEMRUA, Shin All rights reserved.
      6          1.1  takemura  * Copyright (c) 1999 PocketBSD Project. All rights reserved.
      7          1.1  takemura  *
      8          1.1  takemura  * Redistribution and use in source and binary forms, with or without
      9          1.1  takemura  * modification, are permitted provided that the following conditions
     10          1.1  takemura  * are met:
     11          1.1  takemura  * 1. Redistributions of source code must retain the above copyright
     12          1.1  takemura  *    notice, this list of conditions and the following disclaimer.
     13          1.1  takemura  * 2. Redistributions in binary form must reproduce the above copyright
     14          1.1  takemura  *    notice, this list of conditions and the following disclaimer in the
     15          1.1  takemura  *    documentation and/or other materials provided with the distribution.
     16          1.1  takemura  * 3. All advertising materials mentioning features or use of this software
     17          1.1  takemura  *    must display the following acknowledgement:
     18          1.1  takemura  *	This product includes software developed by the PocketBSD project
     19          1.1  takemura  *	and its contributors.
     20          1.1  takemura  * 4. Neither the name of the project nor the names of its contributors
     21          1.1  takemura  *    may be used to endorse or promote products derived from this software
     22          1.1  takemura  *    without specific prior written permission.
     23          1.1  takemura  *
     24          1.1  takemura  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     25          1.1  takemura  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     26          1.1  takemura  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     27          1.1  takemura  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     28          1.1  takemura  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     29          1.1  takemura  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     30          1.1  takemura  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     31          1.1  takemura  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     32          1.1  takemura  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     33          1.1  takemura  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     34          1.1  takemura  * SUCH DAMAGE.
     35          1.1  takemura  *
     36          1.1  takemura  */
     37          1.1  takemura 
     38          1.1  takemura #define VRKIUDEBUG
     39          1.1  takemura 
     40          1.1  takemura #include <sys/param.h>
     41          1.1  takemura #include <sys/tty.h>
     42          1.1  takemura #include <sys/systm.h>
     43          1.1  takemura #include <sys/device.h>
     44          1.1  takemura #include <sys/conf.h>
     45          1.1  takemura #include <sys/kernel.h>
     46          1.1  takemura #include <sys/proc.h>
     47          1.1  takemura 
     48          1.1  takemura #include <machine/intr.h>
     49          1.1  takemura #include <machine/cpu.h>
     50          1.1  takemura #include <machine/bus.h>
     51          1.1  takemura #include <machine/platid.h>
     52          1.1  takemura 
     53          1.1  takemura #include <hpcmips/vr/vr.h>
     54          1.1  takemura #include <hpcmips/vr/vripvar.h>
     55          1.1  takemura #include <hpcmips/vr/vrkiuvar.h>
     56          1.1  takemura #include <hpcmips/vr/vrkiureg.h>
     57          1.1  takemura #include <hpcmips/vr/icureg.h>
     58          1.1  takemura 
     59  1.1.1.1.4.1      fvdl #include <dev/wscons/wsconsio.h>
     60  1.1.1.1.4.1      fvdl #include <dev/wscons/wskbdvar.h>
     61  1.1.1.1.4.1      fvdl #include <dev/wscons/wsksymdef.h>
     62  1.1.1.1.4.1      fvdl #include <dev/wscons/wsksymvar.h>
     63  1.1.1.1.4.1      fvdl #include <dev/pckbc/wskbdmap_mfii.h>
     64  1.1.1.1.4.1      fvdl 
     65          1.1  takemura #ifdef VRKIUDEBUG
     66          1.1  takemura int vrkiu_debug = 0;
     67          1.1  takemura #define DPRINTF(arg) if (vrkiu_debug) printf arg;
     68          1.1  takemura #else
     69          1.1  takemura #define	DPRINTF(arg)
     70          1.1  takemura #endif
     71          1.1  takemura 
     72  1.1.1.1.4.1      fvdl /*
     73  1.1.1.1.4.1      fvdl  * structure and data types
     74  1.1.1.1.4.1      fvdl  */
     75  1.1.1.1.4.1      fvdl struct vrkiu_chip {
     76  1.1.1.1.4.1      fvdl 	bus_space_tag_t kc_iot;
     77  1.1.1.1.4.1      fvdl 	bus_space_handle_t kc_ioh;
     78  1.1.1.1.4.1      fvdl 	unsigned short kc_scandata[KIU_NSCANLINE/2];
     79  1.1.1.1.4.1      fvdl 	int kc_polling;
     80  1.1.1.1.4.1      fvdl 	u_int kc_type;
     81  1.1.1.1.4.1      fvdl 	int kc_data;
     82  1.1.1.1.4.1      fvdl 
     83  1.1.1.1.4.1      fvdl 	int kc_sft:1, kc_alt:1, kc_ctrl:1;
     84  1.1.1.1.4.1      fvdl 
     85  1.1.1.1.4.1      fvdl 	struct vrkiu_softc* kc_sc;	/* back link */
     86  1.1.1.1.4.1      fvdl };
     87  1.1.1.1.4.1      fvdl 
     88  1.1.1.1.4.1      fvdl struct vrkiu_softc {
     89  1.1.1.1.4.1      fvdl 	struct device sc_dev;
     90  1.1.1.1.4.1      fvdl 	struct vrkiu_chip *sc_chip;
     91  1.1.1.1.4.1      fvdl 	struct vrkiu_chip sc_chip_body;
     92  1.1.1.1.4.1      fvdl 	int sc_enabled;
     93  1.1.1.1.4.1      fvdl 	struct device *sc_wskbddev;
     94  1.1.1.1.4.1      fvdl 
     95  1.1.1.1.4.1      fvdl 	void *sc_handler;
     96  1.1.1.1.4.1      fvdl #define NKEYBUF 32
     97  1.1.1.1.4.1      fvdl 	unsigned char keybuf[NKEYBUF];
     98  1.1.1.1.4.1      fvdl 	int keybufhead, keybuftail;
     99  1.1.1.1.4.1      fvdl };
    100  1.1.1.1.4.1      fvdl 
    101  1.1.1.1.4.1      fvdl /*
    102  1.1.1.1.4.1      fvdl  * function prototypes
    103  1.1.1.1.4.1      fvdl  */
    104          1.1  takemura static int vrkiumatch __P((struct device *, struct cfdata *, void *));
    105          1.1  takemura static void vrkiuattach __P((struct device *, struct device *, void *));
    106          1.1  takemura 
    107          1.1  takemura int vrkiu_intr __P((void *));
    108          1.1  takemura 
    109  1.1.1.1.4.1      fvdl static int vrkiu_init(struct vrkiu_chip*, bus_space_tag_t, bus_space_handle_t);
    110  1.1.1.1.4.1      fvdl static void vrkiu_write __P((struct vrkiu_chip *, int, unsigned short));
    111  1.1.1.1.4.1      fvdl static unsigned short vrkiu_read __P((struct vrkiu_chip *, int));
    112  1.1.1.1.4.1      fvdl static int vrkiu_is_console(bus_space_tag_t, bus_space_handle_t);
    113  1.1.1.1.4.1      fvdl static void detect_key __P((struct vrkiu_chip *));
    114  1.1.1.1.4.1      fvdl 
    115  1.1.1.1.4.1      fvdl static struct vrkiu_softc *the_vrkiu = NULL; /* XXX: kludge!! */
    116  1.1.1.1.4.1      fvdl 
    117  1.1.1.1.4.1      fvdl /* wskbd accessopts */
    118  1.1.1.1.4.1      fvdl int vrkiu_enable __P((void *, int));
    119  1.1.1.1.4.1      fvdl void vrkiu_set_leds __P((void *, int));
    120  1.1.1.1.4.1      fvdl int vrkiu_ioctl __P((void *, u_long, caddr_t, int, struct proc *));
    121  1.1.1.1.4.1      fvdl 
    122  1.1.1.1.4.1      fvdl /* consopts */
    123  1.1.1.1.4.1      fvdl void vrkiu_cngetc __P((void*, u_int*, int*));
    124  1.1.1.1.4.1      fvdl void vrkiu_cnpollc __P((void *, int));
    125          1.1  takemura 
    126  1.1.1.1.4.1      fvdl /*
    127  1.1.1.1.4.1      fvdl  * global/static data
    128  1.1.1.1.4.1      fvdl  */
    129          1.1  takemura struct cfattach vrkiu_ca = {
    130          1.1  takemura 	sizeof(struct vrkiu_softc), vrkiumatch, vrkiuattach
    131          1.1  takemura };
    132          1.1  takemura 
    133  1.1.1.1.4.1      fvdl const struct wskbd_accessops vrkiu_accessops = {
    134  1.1.1.1.4.1      fvdl 	vrkiu_enable,
    135  1.1.1.1.4.1      fvdl 	vrkiu_set_leds,
    136  1.1.1.1.4.1      fvdl 	vrkiu_ioctl,
    137  1.1.1.1.4.1      fvdl };
    138  1.1.1.1.4.1      fvdl 
    139  1.1.1.1.4.1      fvdl const struct wskbd_consops vrkiu_consops = {
    140  1.1.1.1.4.1      fvdl 	vrkiu_cngetc,
    141  1.1.1.1.4.1      fvdl 	vrkiu_cnpollc,
    142  1.1.1.1.4.1      fvdl };
    143  1.1.1.1.4.1      fvdl 
    144  1.1.1.1.4.1      fvdl const struct wskbd_mapdata vrkiu_keymapdata = {
    145  1.1.1.1.4.1      fvdl 	pckbd_keydesctab,
    146  1.1.1.1.4.1      fvdl 	KB_US,
    147  1.1.1.1.4.1      fvdl };
    148  1.1.1.1.4.1      fvdl 
    149  1.1.1.1.4.1      fvdl struct vrkiu_chip *vrkiu_consdata = NULL;
    150          1.1  takemura 
    151          1.1  takemura /* XXX: This tranlation table may depend on each machine.
    152          1.1  takemura         Should I build it in? */
    153          1.1  takemura static char keytrans[] = {
    154          1.1  takemura 	-1,  28,  25,  52,  21,  48,  44,  57,  /* - enter p . y b z space */
    155          1.1  takemura 	-1,  53,  24,  51,  20,  47,  30,  -1,  /* - / o , t v a - */
    156          1.1  takemura 	-1,  -1,  23,  50,  19,  46,  17,  -1,  /* - - i m r c w - */
    157          1.1  takemura 	13,  -1,  22,  -1,  18,  45,  16,   2,  /* = - u - e x q 1 */
    158          1.1  takemura 	-1,  -1,  11,  38,  40,  34,  15,  59,  /* - - 0 l ' g tab f1 */
    159          1.1  takemura 	-1,  39,  10,  49,   6,  33,   3,  37,  /* - ; 9 n 5 f 2 k */
    160          1.1  takemura 	-1,  27,   9,  36,   5,  32,   7,  -1,  /* - ] 8 j 4 d 6 - */
    161          1.1  takemura 	12,  26,   8,  35,   4,  41,  31,  -1,  /* - [ 7 h 3 ` s - */
    162          1.1  takemura 	58,  -1,  -1,  -1,  14,  -1,  66,  61,  /* caps - - - bs - f8 f3 */
    163          1.1  takemura 	-1,  56,  -1,  -1,  43,  -1,  65,  62,  /* - alt - - \ - f7 f4 */
    164          1.1  takemura 	-1,  -1,  29,  -1,  68,  -1,  64,  60,  /* - - ctrl - f10 - f6 f2 */
    165          1.1  takemura 	-1,  -1,  -1,  42,  -1,  67,  63,   1,  /* - - - shift - f9 f5 esc */
    166          1.1  takemura };
    167          1.1  takemura /* XXX: fill the field of funct. keys, ex. arrow, fnc, nfer... */
    168          1.1  takemura 
    169          1.1  takemura #define	SCROLL		0x0001	/* stop output */
    170          1.1  takemura #define	NUM		0x0002	/* numeric shift  cursors vs. numeric */
    171          1.1  takemura #define	CAPS		0x0004	/* caps shift -- swaps case of letter */
    172          1.1  takemura #define	SHIFT		0x0008	/* keyboard shift */
    173          1.1  takemura #define	CTL		0x0010	/* control shift  -- allows ctl function */
    174          1.1  takemura #define	ASCII		0x0020	/* ascii code for this key */
    175          1.1  takemura #define	ALT		0x0080	/* alternate shift -- alternate chars */
    176          1.1  takemura #define	FUNC		0x0100	/* function key */
    177          1.1  takemura #define	KP		0x0200	/* Keypad keys */
    178          1.1  takemura #define	NONE		0x0400	/* no function */
    179          1.1  takemura 
    180  1.1.1.1.4.1      fvdl /*
    181  1.1.1.1.4.1      fvdl  * utilities
    182  1.1.1.1.4.1      fvdl  */
    183  1.1.1.1.4.1      fvdl static inline void
    184  1.1.1.1.4.1      fvdl vrkiu_write(chip, port, val)
    185  1.1.1.1.4.1      fvdl 	struct vrkiu_chip *chip;
    186  1.1.1.1.4.1      fvdl 	int port;
    187  1.1.1.1.4.1      fvdl 	unsigned short val;
    188  1.1.1.1.4.1      fvdl {
    189  1.1.1.1.4.1      fvdl 	bus_space_write_2(chip->kc_iot, chip->kc_ioh, port, val);
    190  1.1.1.1.4.1      fvdl }
    191          1.1  takemura 
    192  1.1.1.1.4.1      fvdl static inline unsigned short
    193  1.1.1.1.4.1      fvdl vrkiu_read(chip, port)
    194  1.1.1.1.4.1      fvdl 	struct vrkiu_chip *chip;
    195  1.1.1.1.4.1      fvdl 	int port;
    196  1.1.1.1.4.1      fvdl {
    197  1.1.1.1.4.1      fvdl 	return bus_space_read_2(chip->kc_iot, chip->kc_ioh, port);
    198  1.1.1.1.4.1      fvdl }
    199          1.1  takemura 
    200  1.1.1.1.4.1      fvdl static inline int
    201  1.1.1.1.4.1      fvdl vrkiu_is_console(iot, ioh)
    202  1.1.1.1.4.1      fvdl 	bus_space_tag_t iot;
    203  1.1.1.1.4.1      fvdl 	bus_space_handle_t ioh;
    204  1.1.1.1.4.1      fvdl {
    205  1.1.1.1.4.1      fvdl 	if (vrkiu_consdata &&
    206  1.1.1.1.4.1      fvdl 	    vrkiu_consdata->kc_iot == iot &&
    207  1.1.1.1.4.1      fvdl 	    vrkiu_consdata->kc_ioh == ioh) {
    208  1.1.1.1.4.1      fvdl 		return 1;
    209  1.1.1.1.4.1      fvdl 	} else {
    210  1.1.1.1.4.1      fvdl 		return 0;
    211  1.1.1.1.4.1      fvdl 	}
    212  1.1.1.1.4.1      fvdl }
    213          1.1  takemura 
    214  1.1.1.1.4.1      fvdl /*
    215  1.1.1.1.4.1      fvdl  * initialize device
    216  1.1.1.1.4.1      fvdl  */
    217  1.1.1.1.4.1      fvdl static int
    218  1.1.1.1.4.1      fvdl vrkiu_init(chip, iot, ioh)
    219  1.1.1.1.4.1      fvdl 	struct vrkiu_chip* chip;
    220  1.1.1.1.4.1      fvdl 	bus_space_tag_t iot;
    221  1.1.1.1.4.1      fvdl 	bus_space_handle_t ioh;
    222  1.1.1.1.4.1      fvdl {
    223  1.1.1.1.4.1      fvdl 	memset(chip, 0, sizeof(struct vrkiu_chip));
    224  1.1.1.1.4.1      fvdl 	chip->kc_iot = iot;
    225  1.1.1.1.4.1      fvdl 	chip->kc_ioh = ioh;
    226  1.1.1.1.4.1      fvdl 	chip->kc_polling = 0;
    227  1.1.1.1.4.1      fvdl 
    228  1.1.1.1.4.1      fvdl 	/* set KIU */
    229  1.1.1.1.4.1      fvdl 	vrkiu_write(chip, KIURST, 1);   /* reset */
    230  1.1.1.1.4.1      fvdl 	vrkiu_write(chip, KIUSCANLINE, 0); /* 96keys */
    231  1.1.1.1.4.1      fvdl 	vrkiu_write(chip, KIUWKS, 0x18a4); /* XXX: scan timing! */
    232  1.1.1.1.4.1      fvdl 	vrkiu_write(chip, KIUWKI, 450);
    233  1.1.1.1.4.1      fvdl 	vrkiu_write(chip, KIUSCANREP, 0x8023);
    234  1.1.1.1.4.1      fvdl 				/* KEYEN | STPREP = 2 | ATSTP | ATSCAN */
    235  1.1.1.1.4.1      fvdl 	return 0;
    236  1.1.1.1.4.1      fvdl }
    237          1.1  takemura 
    238  1.1.1.1.4.1      fvdl /*
    239  1.1.1.1.4.1      fvdl  * probe
    240  1.1.1.1.4.1      fvdl  */
    241          1.1  takemura static int
    242          1.1  takemura vrkiumatch(parent, cf, aux)
    243          1.1  takemura 	struct device *parent;
    244          1.1  takemura 	struct cfdata *cf;
    245          1.1  takemura 	void *aux;
    246          1.1  takemura {
    247  1.1.1.1.4.1      fvdl 	return 1;
    248          1.1  takemura }
    249          1.1  takemura 
    250  1.1.1.1.4.1      fvdl /*
    251  1.1.1.1.4.1      fvdl  * attach
    252  1.1.1.1.4.1      fvdl  */
    253          1.1  takemura static void
    254          1.1  takemura vrkiuattach(parent, self, aux)
    255          1.1  takemura 	struct device *parent;
    256          1.1  takemura 	struct device *self;
    257          1.1  takemura 	void *aux;
    258          1.1  takemura {
    259          1.1  takemura 	struct vrkiu_softc *sc = (struct vrkiu_softc *)self;
    260          1.1  takemura 	struct vrip_attach_args *va = aux;
    261  1.1.1.1.4.1      fvdl 	struct wskbddev_attach_args wa;
    262  1.1.1.1.4.1      fvdl 	int isconsole;
    263          1.1  takemura 
    264          1.1  takemura 	bus_space_tag_t iot = va->va_iot;
    265          1.1  takemura 	bus_space_handle_t ioh;
    266          1.1  takemura 
    267          1.1  takemura 	if (bus_space_map(iot, va->va_addr, 1, 0, &ioh)) {
    268          1.1  takemura 		printf(": can't map bus space\n");
    269          1.1  takemura 		return;
    270          1.1  takemura 	}
    271          1.1  takemura 
    272  1.1.1.1.4.1      fvdl 	isconsole = vrkiu_is_console(iot, ioh);
    273  1.1.1.1.4.1      fvdl 	if (isconsole) {
    274  1.1.1.1.4.1      fvdl 		sc->sc_chip = vrkiu_consdata;
    275  1.1.1.1.4.1      fvdl 	} else {
    276  1.1.1.1.4.1      fvdl 		sc->sc_chip = &sc->sc_chip_body;
    277  1.1.1.1.4.1      fvdl 		vrkiu_init(sc->sc_chip, iot, ioh);
    278  1.1.1.1.4.1      fvdl 	}
    279  1.1.1.1.4.1      fvdl 	sc->sc_chip->kc_sc = sc;
    280          1.1  takemura 
    281          1.1  takemura 	if (!(sc->sc_handler =
    282          1.1  takemura 	      vrip_intr_establish(va->va_vc, va->va_intr, IPL_TTY,
    283          1.1  takemura 				  vrkiu_intr, sc))) {
    284          1.1  takemura 		printf (": can't map interrupt line.\n");
    285          1.1  takemura 		return;
    286          1.1  takemura 	}
    287          1.1  takemura 	/* Level2 register setting */
    288          1.1  takemura 	vrip_intr_setmask2(va->va_vc, sc->sc_handler, KIUINT_KDATRDY, 1);
    289          1.1  takemura 
    290          1.1  takemura 	printf("\n");
    291  1.1.1.1.4.1      fvdl 
    292  1.1.1.1.4.1      fvdl 	wa.console = isconsole;
    293  1.1.1.1.4.1      fvdl 	wa.keymap = &vrkiu_keymapdata;
    294  1.1.1.1.4.1      fvdl 	wa.accessops = &vrkiu_accessops;
    295  1.1.1.1.4.1      fvdl 	wa.accesscookie = sc;
    296  1.1.1.1.4.1      fvdl 
    297  1.1.1.1.4.1      fvdl 	sc->sc_wskbddev = config_found(self, &wa, wskbddevprint);
    298          1.1  takemura }
    299          1.1  takemura 
    300          1.1  takemura int
    301          1.1  takemura vrkiu_intr(arg)
    302          1.1  takemura 	void *arg;
    303          1.1  takemura {
    304          1.1  takemura         struct vrkiu_softc *sc = arg;
    305          1.1  takemura 
    306  1.1.1.1.4.1      fvdl 	/* When key scan finisshed, this entry is called. */
    307  1.1.1.1.4.1      fvdl 	DPRINTF(("%s(%d): vrkiu_intr: %d\n",
    308  1.1.1.1.4.1      fvdl 		 __FILE__, __LINE__,
    309  1.1.1.1.4.1      fvdl 		 vrkiu_read(sc->sc_chip, KIUINT) & 7));
    310  1.1.1.1.4.1      fvdl 
    311  1.1.1.1.4.1      fvdl 	/*
    312  1.1.1.1.4.1      fvdl 	 * First, we must clear the interrupt register because
    313  1.1.1.1.4.1      fvdl 	 * detect_key() may takes long time if a bitmap screen
    314  1.1.1.1.4.1      fvdl 	 * scrolls up and it makes us to miss some key release
    315  1.1.1.1.4.1      fvdl 	 * event.
    316  1.1.1.1.4.1      fvdl 	 */
    317  1.1.1.1.4.1      fvdl 	vrkiu_write(sc->sc_chip, KIUINT, 0x7); /* Clear all interrupt */
    318  1.1.1.1.4.1      fvdl 	detect_key(sc->sc_chip);
    319          1.1  takemura 
    320          1.1  takemura 	return 0;
    321          1.1  takemura }
    322          1.1  takemura 
    323          1.1  takemura static void
    324  1.1.1.1.4.1      fvdl detect_key(chip)
    325  1.1.1.1.4.1      fvdl 	struct vrkiu_chip* chip;
    326          1.1  takemura {
    327  1.1.1.1.4.1      fvdl 	int i, j, modified, mask;
    328  1.1.1.1.4.1      fvdl 	unsigned short scandata[KIU_NSCANLINE/2];
    329          1.1  takemura 
    330          1.1  takemura 	for (i = 0; i < KIU_NSCANLINE / 2; i++) {
    331  1.1.1.1.4.1      fvdl 		scandata[i] = vrkiu_read(chip, KIUDATP + i * 2);
    332          1.1  takemura 	}
    333          1.1  takemura 
    334  1.1.1.1.4.1      fvdl 	DPRINTF(("%s(%d): detect_key():", __FILE__, __LINE__));
    335          1.1  takemura 
    336  1.1.1.1.4.1      fvdl 	if (chip->kc_polling) {
    337  1.1.1.1.4.1      fvdl 		chip->kc_type = WSCONS_EVENT_ALL_KEYS_UP;
    338  1.1.1.1.4.1      fvdl 	}
    339  1.1.1.1.4.1      fvdl 
    340  1.1.1.1.4.1      fvdl 	for (i = 0; i < KIU_NSCANLINE / 2; i++) {
    341  1.1.1.1.4.1      fvdl 		modified = scandata[i] ^ chip->kc_scandata[i];
    342  1.1.1.1.4.1      fvdl 		mask = 1;
    343  1.1.1.1.4.1      fvdl 		for (j = 0; j < 16; j++, mask <<= 1) {
    344  1.1.1.1.4.1      fvdl 			/* XXX: The order of keys can be a problem.
    345  1.1.1.1.4.1      fvdl 			   If CTRL and normal key are pushed simultaneously,
    346  1.1.1.1.4.1      fvdl 			   normal key can be entered in queue first.
    347  1.1.1.1.4.1      fvdl 			   Same problem would occur in key break. */
    348  1.1.1.1.4.1      fvdl 			if (modified & mask) {
    349  1.1.1.1.4.1      fvdl 				int key, type;
    350  1.1.1.1.4.1      fvdl 				key = i * 16 + j;
    351  1.1.1.1.4.1      fvdl 				if (keytrans[key] < 0) {
    352  1.1.1.1.4.1      fvdl 	                                printf("vrkiu: Unkown scan code 0x%02x\n", key);
    353  1.1.1.1.4.1      fvdl 	                                continue;
    354  1.1.1.1.4.1      fvdl 				}
    355  1.1.1.1.4.1      fvdl 				type = (scandata[i] & mask) ?
    356  1.1.1.1.4.1      fvdl 					WSCONS_EVENT_KEY_DOWN :
    357  1.1.1.1.4.1      fvdl 					WSCONS_EVENT_KEY_UP;
    358  1.1.1.1.4.1      fvdl 				DPRINTF(("(%d,%d)=%s%d ", i, j,
    359  1.1.1.1.4.1      fvdl 					 (scandata[i] & mask) ? "v" : "^",
    360  1.1.1.1.4.1      fvdl 					 keytrans[key]));
    361  1.1.1.1.4.1      fvdl 				if (chip->kc_polling) {
    362  1.1.1.1.4.1      fvdl 					chip->kc_type = type;
    363  1.1.1.1.4.1      fvdl 					chip->kc_data = keytrans[key];
    364  1.1.1.1.4.1      fvdl 				} else {
    365  1.1.1.1.4.1      fvdl 					wskbd_input(chip->kc_sc->sc_wskbddev,
    366  1.1.1.1.4.1      fvdl 						    type,
    367  1.1.1.1.4.1      fvdl 						    keytrans[key]);
    368  1.1.1.1.4.1      fvdl 				}
    369          1.1  takemura 			}
    370          1.1  takemura 		}
    371  1.1.1.1.4.1      fvdl 		chip->kc_scandata[i] = scandata[i];
    372          1.1  takemura 	}
    373  1.1.1.1.4.1      fvdl 	DPRINTF(("\n"));
    374          1.1  takemura }
    375          1.1  takemura 
    376          1.1  takemura /* called from biconsdev.c */
    377          1.1  takemura int
    378          1.1  takemura vrkiu_getc()
    379          1.1  takemura {
    380          1.1  takemura 	int ret;
    381          1.1  takemura 
    382          1.1  takemura 	if (the_vrkiu == NULL) {
    383          1.1  takemura 		return 0;	/* XXX */
    384          1.1  takemura 	}
    385          1.1  takemura 
    386          1.1  takemura 	while (the_vrkiu->keybuftail == the_vrkiu->keybufhead) {
    387  1.1.1.1.4.1      fvdl 		detect_key(vrkiu_consdata);
    388          1.1  takemura 	}
    389          1.1  takemura 	ret = the_vrkiu->keybuf[the_vrkiu->keybuftail++];
    390          1.1  takemura 	if (the_vrkiu->keybuftail >= NKEYBUF) {
    391          1.1  takemura 		the_vrkiu->keybuftail = 0;
    392          1.1  takemura 	}
    393          1.1  takemura 	return ret;
    394          1.1  takemura }
    395          1.1  takemura 
    396  1.1.1.1.4.1      fvdl int
    397  1.1.1.1.4.1      fvdl vrkiu_enable(scx, on)
    398  1.1.1.1.4.1      fvdl 	void *scx;
    399  1.1.1.1.4.1      fvdl 	int on;
    400  1.1.1.1.4.1      fvdl {
    401  1.1.1.1.4.1      fvdl 	struct vrkiu_softc *sc = scx;
    402  1.1.1.1.4.1      fvdl 
    403  1.1.1.1.4.1      fvdl 	if (on) {
    404  1.1.1.1.4.1      fvdl 		if (sc->sc_enabled)
    405  1.1.1.1.4.1      fvdl 			return (EBUSY);
    406  1.1.1.1.4.1      fvdl 		sc->sc_enabled = 1;
    407  1.1.1.1.4.1      fvdl 	} else {
    408  1.1.1.1.4.1      fvdl 		if (sc->sc_chip == vrkiu_consdata)
    409  1.1.1.1.4.1      fvdl 			return (EBUSY);
    410  1.1.1.1.4.1      fvdl 		sc->sc_enabled = 0;
    411  1.1.1.1.4.1      fvdl 	}
    412  1.1.1.1.4.1      fvdl 
    413  1.1.1.1.4.1      fvdl 	return (0);
    414  1.1.1.1.4.1      fvdl }
    415  1.1.1.1.4.1      fvdl 
    416  1.1.1.1.4.1      fvdl void
    417  1.1.1.1.4.1      fvdl vrkiu_set_leds(scx, leds)
    418  1.1.1.1.4.1      fvdl 	void *scx;
    419  1.1.1.1.4.1      fvdl 	int leds;
    420  1.1.1.1.4.1      fvdl {
    421  1.1.1.1.4.1      fvdl 	/*struct pckbd_softc *sc = scx;
    422  1.1.1.1.4.1      fvdl 	 */
    423  1.1.1.1.4.1      fvdl 
    424  1.1.1.1.4.1      fvdl 	DPRINTF(("%s(%d): vrkiu_set_leds() not implemented\n",
    425  1.1.1.1.4.1      fvdl 		 __FILE__, __LINE__));
    426  1.1.1.1.4.1      fvdl }
    427  1.1.1.1.4.1      fvdl 
    428  1.1.1.1.4.1      fvdl int
    429  1.1.1.1.4.1      fvdl vrkiu_ioctl(scx, cmd, data, flag, p)
    430  1.1.1.1.4.1      fvdl 	void *scx;
    431  1.1.1.1.4.1      fvdl 	u_long cmd;
    432  1.1.1.1.4.1      fvdl 	caddr_t data;
    433  1.1.1.1.4.1      fvdl 	int flag;
    434  1.1.1.1.4.1      fvdl 	struct proc *p;
    435  1.1.1.1.4.1      fvdl {
    436  1.1.1.1.4.1      fvdl 	/*struct vrkiu_softc *sc = scx;
    437  1.1.1.1.4.1      fvdl 	 */
    438  1.1.1.1.4.1      fvdl 
    439  1.1.1.1.4.1      fvdl 	switch (cmd) {
    440  1.1.1.1.4.1      fvdl 	case WSKBDIO_GTYPE:
    441  1.1.1.1.4.1      fvdl 		/*
    442  1.1.1.1.4.1      fvdl 		 * XXX, fix me !
    443  1.1.1.1.4.1      fvdl 		 */
    444  1.1.1.1.4.1      fvdl 		*(int *)data = WSKBD_TYPE_PC_XT;
    445  1.1.1.1.4.1      fvdl 		return 0;
    446  1.1.1.1.4.1      fvdl 	case WSKBDIO_SETLEDS:
    447  1.1.1.1.4.1      fvdl 		DPRINTF(("%s(%d): no LED\n", __FILE__, __LINE__));
    448  1.1.1.1.4.1      fvdl 		return 0;
    449  1.1.1.1.4.1      fvdl 	case WSKBDIO_GETLEDS:
    450  1.1.1.1.4.1      fvdl 		DPRINTF(("%s(%d): no LED\n", __FILE__, __LINE__));
    451  1.1.1.1.4.1      fvdl 		*(int *)data = 0;
    452  1.1.1.1.4.1      fvdl 		return (0);
    453  1.1.1.1.4.1      fvdl 	}
    454  1.1.1.1.4.1      fvdl 	return -1;
    455  1.1.1.1.4.1      fvdl }
    456  1.1.1.1.4.1      fvdl 
    457  1.1.1.1.4.1      fvdl /*
    458  1.1.1.1.4.1      fvdl  * console support routines
    459  1.1.1.1.4.1      fvdl  */
    460  1.1.1.1.4.1      fvdl int
    461  1.1.1.1.4.1      fvdl vrkiu_cnattach(iot, iobase)
    462  1.1.1.1.4.1      fvdl 	bus_space_tag_t iot;
    463  1.1.1.1.4.1      fvdl 	int iobase;
    464  1.1.1.1.4.1      fvdl {
    465  1.1.1.1.4.1      fvdl 	static struct vrkiu_chip vrkiu_consdata_body;
    466  1.1.1.1.4.1      fvdl 	bus_space_handle_t ioh;
    467  1.1.1.1.4.1      fvdl 
    468  1.1.1.1.4.1      fvdl 	if (vrkiu_consdata) {
    469  1.1.1.1.4.1      fvdl 		panic("vrkiu is already attached as the console");
    470  1.1.1.1.4.1      fvdl 	}
    471  1.1.1.1.4.1      fvdl 	if (bus_space_map(iot, iobase, 1, 0, &ioh)) {
    472  1.1.1.1.4.1      fvdl 		printf("%s(%d): can't map bus space\n", __FILE__, __LINE__);
    473  1.1.1.1.4.1      fvdl 		return -1;
    474  1.1.1.1.4.1      fvdl 	}
    475  1.1.1.1.4.1      fvdl 
    476  1.1.1.1.4.1      fvdl 	if (vrkiu_init(&vrkiu_consdata_body, iot, ioh) != 0) {
    477  1.1.1.1.4.1      fvdl 		DPRINTF(("%s(%d): vrkiu_init() failed\n", __FILE__, __LINE__));
    478  1.1.1.1.4.1      fvdl 		return -1;
    479  1.1.1.1.4.1      fvdl 	}
    480  1.1.1.1.4.1      fvdl 	vrkiu_consdata = &vrkiu_consdata_body;
    481  1.1.1.1.4.1      fvdl 
    482  1.1.1.1.4.1      fvdl 	wskbd_cnattach(&vrkiu_consops, vrkiu_consdata, &vrkiu_keymapdata);
    483  1.1.1.1.4.1      fvdl 
    484  1.1.1.1.4.1      fvdl 	return (0);
    485  1.1.1.1.4.1      fvdl }
    486  1.1.1.1.4.1      fvdl 
    487  1.1.1.1.4.1      fvdl void
    488  1.1.1.1.4.1      fvdl vrkiu_cngetc(chipx, type, data)
    489  1.1.1.1.4.1      fvdl 	void *chipx;
    490  1.1.1.1.4.1      fvdl 	u_int *type;
    491  1.1.1.1.4.1      fvdl 	int *data;
    492  1.1.1.1.4.1      fvdl {
    493  1.1.1.1.4.1      fvdl 	struct vrkiu_chip* chip = chipx;
    494  1.1.1.1.4.1      fvdl 	int s;
    495  1.1.1.1.4.1      fvdl 
    496  1.1.1.1.4.1      fvdl 	if (!chip->kc_polling) {
    497  1.1.1.1.4.1      fvdl 		printf("%s(%d): kiu is not polled\n", __FILE__, __LINE__);
    498  1.1.1.1.4.1      fvdl 		while (1);
    499  1.1.1.1.4.1      fvdl 	}
    500  1.1.1.1.4.1      fvdl 
    501  1.1.1.1.4.1      fvdl 	s = splimp();
    502  1.1.1.1.4.1      fvdl 	if (chip->kc_type == WSCONS_EVENT_ALL_KEYS_UP) {
    503  1.1.1.1.4.1      fvdl 		detect_key(chip);
    504  1.1.1.1.4.1      fvdl 	}
    505  1.1.1.1.4.1      fvdl 	*type = chip->kc_type;
    506  1.1.1.1.4.1      fvdl 	*data = chip->kc_data;
    507  1.1.1.1.4.1      fvdl 	chip->kc_type = WSCONS_EVENT_ALL_KEYS_UP;
    508  1.1.1.1.4.1      fvdl 	splx(s);
    509  1.1.1.1.4.1      fvdl }
    510  1.1.1.1.4.1      fvdl 
    511  1.1.1.1.4.1      fvdl void
    512  1.1.1.1.4.1      fvdl vrkiu_cnpollc(chipx, on)
    513  1.1.1.1.4.1      fvdl 	void *chipx;
    514  1.1.1.1.4.1      fvdl         int on;
    515  1.1.1.1.4.1      fvdl {
    516  1.1.1.1.4.1      fvdl 	struct vrkiu_chip* chip = chipx;
    517  1.1.1.1.4.1      fvdl 	int s = splimp();
    518  1.1.1.1.4.1      fvdl 
    519  1.1.1.1.4.1      fvdl 	chip->kc_polling = on;
    520  1.1.1.1.4.1      fvdl 
    521  1.1.1.1.4.1      fvdl 	splx(s);
    522  1.1.1.1.4.1      fvdl 
    523  1.1.1.1.4.1      fvdl 	DPRINTF(("%s(%d): vrkiu polling %s\n",
    524  1.1.1.1.4.1      fvdl 		 __FILE__, __LINE__, on ? "ON" : "OFF"));
    525  1.1.1.1.4.1      fvdl }
    526