Home | History | Annotate | Line # | Download | only in vr
vrkiu.c revision 1.5
      1 /*	$NetBSD: vrkiu.c,v 1.5 1999/11/21 12:53:57 shin Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 1999 SASAKI Takesi All rights reserved.
      5  * Copyright (c) 1999 TAKEMRUA, Shin All rights reserved.
      6  * Copyright (c) 1999 PocketBSD Project. All rights reserved.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  * 1. Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  * 2. Redistributions in binary form must reproduce the above copyright
     14  *    notice, this list of conditions and the following disclaimer in the
     15  *    documentation and/or other materials provided with the distribution.
     16  * 3. All advertising materials mentioning features or use of this software
     17  *    must display the following acknowledgement:
     18  *	This product includes software developed by the PocketBSD project
     19  *	and its contributors.
     20  * 4. Neither the name of the project nor the names of its contributors
     21  *    may be used to endorse or promote products derived from this software
     22  *    without specific prior written permission.
     23  *
     24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     34  * SUCH DAMAGE.
     35  *
     36  */
     37 
     38 #define VRKIUDEBUG
     39 
     40 #include <sys/param.h>
     41 #include <sys/tty.h>
     42 #include <sys/systm.h>
     43 #include <sys/device.h>
     44 #include <sys/conf.h>
     45 #include <sys/kernel.h>
     46 #include <sys/proc.h>
     47 
     48 #include <machine/intr.h>
     49 #include <machine/cpu.h>
     50 #include <machine/bus.h>
     51 #include <machine/platid.h>
     52 #include <machine/platid_mask.h>
     53 
     54 #include <hpcmips/vr/vr.h>
     55 #include <hpcmips/vr/vripvar.h>
     56 #include <hpcmips/vr/vrkiuvar.h>
     57 #include <hpcmips/vr/vrkiureg.h>
     58 #include <hpcmips/vr/icureg.h>
     59 
     60 #include <dev/wscons/wsconsio.h>
     61 #include <dev/wscons/wskbdvar.h>
     62 #include <dev/wscons/wsksymdef.h>
     63 #include <dev/wscons/wsksymvar.h>
     64 #include <dev/pckbc/wskbdmap_mfii.h>
     65 
     66 #include "opt_pckbd_layout.h"
     67 
     68 #ifdef VRKIUDEBUG
     69 int vrkiu_debug = 0;
     70 #define DPRINTF(arg) if (vrkiu_debug) printf arg;
     71 #else
     72 #define	DPRINTF(arg)
     73 #endif
     74 
     75 /*
     76  * structure and data types
     77  */
     78 struct vrkiu_chip {
     79 	bus_space_tag_t kc_iot;
     80 	bus_space_handle_t kc_ioh;
     81 	unsigned short kc_scandata[KIU_NSCANLINE/2];
     82 	int kc_polling;
     83 	u_int kc_type;
     84 	int kc_data;
     85 
     86 	int kc_sft:1, kc_alt:1, kc_ctrl:1;
     87 
     88 	struct vrkiu_softc* kc_sc;	/* back link */
     89 };
     90 
     91 struct vrkiu_softc {
     92 	struct device sc_dev;
     93 	struct vrkiu_chip *sc_chip;
     94 	struct vrkiu_chip sc_chip_body;
     95 	int sc_enabled;
     96 	struct device *sc_wskbddev;
     97 
     98 	void *sc_handler;
     99 #define NKEYBUF 32
    100 	unsigned char keybuf[NKEYBUF];
    101 	int keybufhead, keybuftail;
    102 };
    103 
    104 /*
    105  * function prototypes
    106  */
    107 static int vrkiumatch __P((struct device *, struct cfdata *, void *));
    108 static void vrkiuattach __P((struct device *, struct device *, void *));
    109 
    110 int vrkiu_intr __P((void *));
    111 
    112 static int vrkiu_init(struct vrkiu_chip*, bus_space_tag_t, bus_space_handle_t);
    113 static void vrkiu_write __P((struct vrkiu_chip *, int, unsigned short));
    114 static unsigned short vrkiu_read __P((struct vrkiu_chip *, int));
    115 static int vrkiu_is_console(bus_space_tag_t, bus_space_handle_t);
    116 static void detect_key __P((struct vrkiu_chip *));
    117 
    118 static struct vrkiu_softc *the_vrkiu = NULL; /* XXX: kludge!! */
    119 
    120 /* wskbd accessopts */
    121 int vrkiu_enable __P((void *, int));
    122 void vrkiu_set_leds __P((void *, int));
    123 int vrkiu_ioctl __P((void *, u_long, caddr_t, int, struct proc *));
    124 
    125 /* consopts */
    126 void vrkiu_cngetc __P((void*, u_int*, int*));
    127 void vrkiu_cnpollc __P((void *, int));
    128 
    129 /*
    130  * global/static data
    131  */
    132 struct cfattach vrkiu_ca = {
    133 	sizeof(struct vrkiu_softc), vrkiumatch, vrkiuattach
    134 };
    135 
    136 const struct wskbd_accessops vrkiu_accessops = {
    137 	vrkiu_enable,
    138 	vrkiu_set_leds,
    139 	vrkiu_ioctl,
    140 };
    141 
    142 const struct wskbd_consops vrkiu_consops = {
    143 	vrkiu_cngetc,
    144 	vrkiu_cnpollc,
    145 };
    146 
    147 struct wskbd_mapdata vrkiu_keymapdata = {
    148 	pckbd_keydesctab,
    149 #ifdef VRKIU_LAYOUT
    150 	VRKIU_LAYOUT,
    151 #else
    152 	KB_US,
    153 #endif
    154 };
    155 
    156 struct vrkiu_chip *vrkiu_consdata = NULL;
    157 
    158 #define UNK	-1	/* unknown */
    159 #define IGN	-2	/* ignore */
    160 
    161 static char default_keytrans[] = {
    162 /*00*/ UNK,  UNK,  UNK,  UNK,  UNK,  UNK,  UNK,  UNK,	/* - - - - - - - - */
    163 /*08*/ UNK,  UNK,  UNK,  UNK,  UNK,  UNK,  UNK,  UNK,	/* - - - - - - - - */
    164 /*10*/ UNK,  UNK,  UNK,  UNK,  UNK,  UNK,  UNK,  UNK,	/* - - - - - - - - */
    165 /*18*/ UNK,  UNK,  UNK,  UNK,  UNK,  UNK,  UNK,  UNK,	/* - - - - - - - - */
    166 /*20*/ UNK,  UNK,  UNK,  UNK,  UNK,  UNK,  UNK,  UNK,	/* - - - - - - - - */
    167 /*28*/ UNK,  UNK,  UNK,  UNK,  UNK,  UNK,  UNK,  UNK,	/* - - - - - - - - */
    168 /*30*/ UNK,  UNK,  UNK,  UNK,  UNK,  UNK,  UNK,  UNK,	/* - - - - - - - - */
    169 /*38*/ UNK,  UNK,  UNK,  UNK,  UNK,  UNK,  UNK,  UNK,	/* - - - - - - - - */
    170 /*40*/ UNK,  UNK,  UNK,  UNK,  UNK,  UNK,  UNK,  UNK,	/* - - - - - - - - */
    171 /*48*/ UNK,  UNK,  UNK,  UNK,  UNK,  UNK,  UNK,  UNK,	/* - - - - - - - - */
    172 /*50*/ UNK,  UNK,  UNK,  UNK,  UNK,  UNK,  UNK,  UNK,	/* - - - - - - - - */
    173 /*58*/ UNK,  UNK,  UNK,  UNK,  UNK,  UNK,  UNK,  UNK,	/* - - - - - - - - */
    174 };
    175 
    176 /* NEC MobileGearII MCR series (Japan) */
    177 static char mcr_jp_keytrans[] = {
    178 /*00*/  77,  28,  25,  52,  21,  48,  44,  57, /* right ent p . y b z space */
    179 /*08*/  80,  53,  24,  51,  20,  47,  30, 123, /* down / o , t v a nfer */
    180 /*10*/  75, 115,  23,  50,  19,  46,  17, 221, /* left \ i m r c w menu */
    181 /*18*/  13, IGN,  22, IGN,  18,  45,  16,   2, /* ^ - u - e x q 1 */
    182 /*20*/  81,  41,  11,  38,  40,  34,  15,  59, /* pgdn h/z 0 l : g tab f1 */
    183 /*28*/ 121,  39,  10,  49,   6,  33,   3,  37, /* xfer ; 9 n 5 f 2 k */
    184 /*30*/  72,  27,   9,  36,   5,  32,   7, IGN, /* up [ 8 j 4 d 6 - */
    185 /*38*/  12,  26,   8,  35,   4,  43,  31, IGN, /* - @ 7 h 3 ] s - */
    186 /*40*/  58, IGN, IGN, IGN,  14, IGN,  66,  61, /* caps - - - bs - f8 f3 */
    187 /*48*/ IGN,  56, IGN, IGN, 125, 112,  65,  62, /* - alt - - | k/h f7 f4 */
    188 /*50*/ IGN, IGN,  29, IGN,  68,  73,  64,  60, /* - - ctrl - f10 pgup f6 f2 */
    189 /*58*/ IGN, IGN, IGN,  42,  14,  67,  63,   1, /* - - - shift del f9 f5 esc */
    190 };
    191 
    192 /* IBM WorkPad z50 */
    193 static char z50_keytrans[] = {
    194 /*00*/  59,  61,  63,  65,  67, IGN, IGN,  87,	/* f1 f3 f5 f7 f9 - - f11 */
    195 /*08*/  60,  62,  64,  66,  68, IGN, IGN,  88,	/* f2 f4 f6 f8 f10 - - f12 */
    196 /*10*/  40,  26,  12,  11,  25,  39,  72,  53,	/* ' [ - 0 p ; up / */
    197 /*18*/ IGN, IGN, IGN,  10,  24,  38,  52, IGN,	/* - - - 9 o l . - */
    198 /*20*/  75,  27,  13,   9,  23,  37,  51, IGN,	/* left ] = 8 i k , - */
    199 /*28*/  35,  21,   7,   8,  22,  36,  50,  49,	/* h y 6 7 u j m n */
    200 /*30*/ IGN,  14,  69,  14, IGN,  43,  28,  57,	/* - bs num del - \ ent sp */
    201 /*38*/  34,  20,   6,   5,  19,  33,  47,  48,	/* g t 5 4 r f v b */
    202 /*40*/ IGN, IGN, IGN,   4,  18,  32,  46,  77,	/* - - - 3 e d c right */
    203 /*48*/ IGN, IGN, IGN,   3,  17,  31,  45,  80,	/* - - - 2 w s x down */
    204 /*50*/   1,  29,  41,   2,  16,  30,  44, IGN,	/* esc tab ~ 1 q a z - */
    205 /*58*/ 221,  42,  29,  29,  56,  56,  54, IGN,	/* menu Ls Lc Rc La Ra Rs - */
    206 };
    207 
    208 /* Sharp Tripad PV6000 */
    209 static char tripad_keytrans[] = {
    210 /*00*/  42,  15,  41,  16,   1,   2, 104, 221,	/* lsh tab ` q esc 1 WIN - */
    211 /*08*/  58,  44,  45,  30,  31,  17,  18,   3,	/* ctrl z x a s w e 2 */
    212 /*10*/  56,  57,  46,  47,  32,  33,  19,   4,	/* lalt sp c v d f r 3 */
    213 /*18*/  48,  49,  34,  35,  20,  21,   5,   6,	/* b n g h t y 4 5 */
    214 /*20*/  50,  51,  36,  37,  22,  23,   7,   8,	/* m , j k u i 6 7 */
    215 /*28*/ 105,  29,  38,  24,  25,   9,  10,  11,	/* Fn caps l o p 8 9 0 */
    216 /*30*/  26,  27, 102,  52,  53,  39,  12,  13,	/* [ ] dar , / ; \- = */
    217 /*38*/  54, 103, 100, 102,  39,  28,  43,  14,	/* rsh - - uar - ; ent \ del */
    218 /*40*/ IGN, IGN, IGN, IGN, IGN, IGN, IGN, IGN,	/* - - - - - - - - */
    219 /*48*/ IGN, IGN, IGN, IGN, IGN, IGN, IGN, IGN,	/* - - - - - - - - */
    220 /*50*/ IGN, IGN, IGN, IGN, IGN, IGN, IGN, IGN,	/* - - - - - - - - */
    221 /*58*/ IGN, IGN, IGN, IGN, IGN, IGN, IGN, IGN,	/* - - - - - - - - */
    222 };
    223 
    224 /* NEC Mobile Gear MCCS series */
    225 static char mccs_keytrans[] = {
    226 /*00*/  58,  28, 102,  25,  52,  21,  48,  44,  /* caps cr rar p . y b z */
    227 /*08*/  56,  27, 103,  24,  51,  20,  47,  30,  /* alt [ dar o , t v a */
    228 /*10*/  41,  26, 101,  23,  50,  19,  46,  17,  /* zen @ lar i m r c w */
    229 /*18*/  29,  39, 100,  22,  49,  18,  45,  16,  /* lctrl ; uar u n e x q */
    230 /*20*/  42,  14, 115,  11,  38,   7,  34,  15,  /* lshft bs \ 0 l 6 g tab */
    231 /*28*/ 123, 125,  53,  10,  37,   6,  33,   3,  /* nconv | / 9 k 5 f 2 */
    232 /*30*/ 121,  13,  43,   9,  36,   5,  32,   2,  /* conv = ] 8 j 4 d 1 */
    233 /*38*/ 112,  12,  40,   8,  35,   4,  31,   1,  /* hira - ' 7 h 3 s esc */
    234 /*40*/ IGN,  57, IGN, IGN, IGN, IGN, IGN, IGN,  /* - sp - - - - - - */
    235 /*48*/ IGN, IGN, IGN, IGN, IGN, IGN, IGN, IGN,  /* - - - - - - - - */
    236 /*50*/ IGN, IGN, IGN, IGN, IGN, IGN, IGN, IGN,  /* - - - - - - - - */
    237 /*58*/ IGN, IGN, IGN, IGN, IGN, IGN, IGN, IGN,  /* - - - - - - - - */
    238 };
    239 
    240 static char mobilepro_keytrans[] = {
    241 /*00*/  57,  27,  43,  53,  75,  80,  28,  38,  /* space ] \ / - - enter l */
    242 /*08*/ IGN,  26,  40,  39,  77,  72,  52,  24,  /* - [ ' ; - - . o */
    243 /*10*/ IGN, IGN, IGN, 221,  47,  46,  45,  44,  /* - - - Windows v c x z */
    244 /*18*/ IGN,  13,  12,  41,  33,  32,  31,  30,  /* - = \- ` f d s a */
    245 /*20*/   9,   8,   7,   6,  19,  18,  17,  16,  /* 8 7 6 5 r e w q */
    246 /*28*/  51,  50,  49,  48, IGN, IGN,  11,  10,  /* , m n b - - 0 9 */
    247 /*30*/  37,  36,  35,  34,   5,   4,   3,   2,  /* k j h g 4 3 2 1 */
    248 /*38*/  23,  22,  21,  20, IGN,  58,  14,   1,  /* i u y t - caps del esc */
    249 /*40*/ 184, IGN, IGN, IGN,  14,  25,  15, IGN,  /* alt_R - - - BS p TAB Fn */
    250 /*48*/ IGN,  56, IGN, IGN,  88,  87,  68,  67,  /* - alt_L - - f12 f11 f10 f9*/
    251 /*50*/ IGN, IGN,  29, IGN,  66,  65,  64,  63,  /* - - ctrl - f8 f7 f6 f5 */
    252 /*58*/ IGN, IGN, IGN,  42,  62,  61,  60,  59,  /* - - - shift f4 f3 f2 f1 */
    253 };
    254 
    255 /* FUJITSU INTERTOP CX300 */
    256 static char intertop_keytrans[] = {
    257   57,  60,   2,  15,  28,  58,  75,  41,
    258  112,  59,   3,  16, IGN,  30,  56,   1,
    259  210,  17,   4,  31,  83,  43,  80,  45,
    260   44,  18,   5,  32,  68, 125,  77,  46,
    261  115,  19,  39,  33,  67,  26,  13,  47,
    262   53,  20,   6,  34,  66,  25,  12,  48,
    263   52,  21,   7,  35,  65,  38,  11,  49,
    264  IGN,  22,   8,  36,  63,  24,  14,  50,
    265  IGN,  61,   9,  62, IGN,  23,  37,  51,
    266   69,  40,  10,  27,  64, IGN,  72, IGN,
    267  IGN, IGN, IGN, IGN,  42, IGN, IGN,  54,
    268  157, 221, 123, 121, 184, IGN, IGN, IGN,
    269 };
    270 /*
    271 space   a2      1       tab     enter   caps    left    zenkaku
    272 hiraga  a1      2       q       -       a       fnc     esc
    273 ins     w       3       s       del     ]       down    x
    274 z       e       4       d       a10     \       right   c
    275 backsla r       ;       f       a9      @       ^       v
    276 /       t       5       g       a8      p       -       b
    277 .       y       6       h       a7      l       0       n
    278 -       u       7       j       a5      o       bs      m
    279 -       a3      8       a4      -       i       k       ,
    280 num     :       9       [       a6      -       up      -
    281 -       -       -       -       shift_L -       -       shift_R
    282 ctrl    win     muhenka henkan  alt     -       -       -
    283 */
    284 
    285 static char *keytrans = default_keytrans;
    286 
    287 /*
    288  * utilities
    289  */
    290 static inline void
    291 vrkiu_write(chip, port, val)
    292 	struct vrkiu_chip *chip;
    293 	int port;
    294 	unsigned short val;
    295 {
    296 	bus_space_write_2(chip->kc_iot, chip->kc_ioh, port, val);
    297 }
    298 
    299 static inline unsigned short
    300 vrkiu_read(chip, port)
    301 	struct vrkiu_chip *chip;
    302 	int port;
    303 {
    304 	return bus_space_read_2(chip->kc_iot, chip->kc_ioh, port);
    305 }
    306 
    307 static inline int
    308 vrkiu_is_console(iot, ioh)
    309 	bus_space_tag_t iot;
    310 	bus_space_handle_t ioh;
    311 {
    312 	if (vrkiu_consdata &&
    313 	    vrkiu_consdata->kc_iot == iot &&
    314 	    vrkiu_consdata->kc_ioh == ioh) {
    315 		return 1;
    316 	} else {
    317 		return 0;
    318 	}
    319 }
    320 
    321 /*
    322  * initialize device
    323  */
    324 static int
    325 vrkiu_init(chip, iot, ioh)
    326 	struct vrkiu_chip* chip;
    327 	bus_space_tag_t iot;
    328 	bus_space_handle_t ioh;
    329 {
    330 	memset(chip, 0, sizeof(struct vrkiu_chip));
    331 	chip->kc_iot = iot;
    332 	chip->kc_ioh = ioh;
    333 	chip->kc_polling = 0;
    334 
    335 	/* set KIU */
    336 	vrkiu_write(chip, KIURST, 1);   /* reset */
    337 	vrkiu_write(chip, KIUSCANLINE, 0); /* 96keys */
    338 	vrkiu_write(chip, KIUWKS, 0x18a4); /* XXX: scan timing! */
    339 	vrkiu_write(chip, KIUWKI, 450);
    340 	vrkiu_write(chip, KIUSCANREP, 0x8023);
    341 				/* KEYEN | STPREP = 2 | ATSTP | ATSCAN */
    342 	return 0;
    343 }
    344 
    345 /*
    346  * probe
    347  */
    348 static int
    349 vrkiumatch(parent, cf, aux)
    350 	struct device *parent;
    351 	struct cfdata *cf;
    352 	void *aux;
    353 {
    354 	return 1;
    355 }
    356 
    357 /*
    358  * attach
    359  */
    360 static void
    361 vrkiuattach(parent, self, aux)
    362 	struct device *parent;
    363 	struct device *self;
    364 	void *aux;
    365 {
    366 	struct vrkiu_softc *sc = (struct vrkiu_softc *)self;
    367 	struct vrip_attach_args *va = aux;
    368 	struct wskbddev_attach_args wa;
    369 	int isconsole;
    370 
    371 	bus_space_tag_t iot = va->va_iot;
    372 	bus_space_handle_t ioh;
    373 
    374 	if (bus_space_map(iot, va->va_addr, 1, 0, &ioh)) {
    375 		printf(": can't map bus space\n");
    376 		return;
    377 	}
    378 
    379 	isconsole = vrkiu_is_console(iot, ioh);
    380 	if (isconsole) {
    381 		sc->sc_chip = vrkiu_consdata;
    382 	} else {
    383 		sc->sc_chip = &sc->sc_chip_body;
    384 		vrkiu_init(sc->sc_chip, iot, ioh);
    385 	}
    386 	sc->sc_chip->kc_sc = sc;
    387 
    388 	if (!(sc->sc_handler =
    389 	      vrip_intr_establish(va->va_vc, va->va_intr, IPL_TTY,
    390 				  vrkiu_intr, sc))) {
    391 		printf (": can't map interrupt line.\n");
    392 		return;
    393 	}
    394 	/* Level2 register setting */
    395 	vrip_intr_setmask2(va->va_vc, sc->sc_handler, KIUINT_KDATRDY, 1);
    396 
    397 	printf("\n");
    398 
    399 	if (platid_match(&platid, &platid_mask_MACH_NEC_MCR_520A)) {
    400 		keytrans = mobilepro_keytrans;
    401 #if !defined(VRKIU_LAYOUT)
    402 		vrkiu_keymapdata.layout = KB_US;
    403 #endif
    404 	} else if (platid_match(&platid, &platid_mask_MACH_NEC_MCR_700A)) {
    405 		keytrans = mobilepro_keytrans;
    406 #if !defined(VRKIU_LAYOUT)
    407 		vrkiu_keymapdata.layout = KB_US;
    408 #endif
    409 	} else if (platid_match(&platid, &platid_mask_MACH_NEC_MCR)) {
    410 		keytrans = mcr_jp_keytrans;
    411 #if !defined(VRKIU_LAYOUT)
    412 		vrkiu_keymapdata.layout = KB_JP;
    413 #endif
    414 	} else if (platid_match(&platid, &platid_mask_MACH_IBM_WORKPAD_Z50)) {
    415 		keytrans = z50_keytrans;
    416 #if !defined(VRKIU_LAYOUT)
    417 		vrkiu_keymapdata.layout = KB_US;
    418 #endif
    419 	} else if (platid_match(&platid, &platid_mask_MACH_SHARP_TRIPAD)) {
    420 		keytrans = tripad_keytrans;
    421 #if !defined(VRKIU_LAYOUT)
    422 		vrkiu_keymapdata.layout = KB_JP;
    423 #endif
    424 	} else if (platid_match(&platid, &platid_mask_MACH_NEC_MCCS)) {
    425 		keytrans = mccs_keytrans;
    426 #if !defined(VRKIU_LAYOUT)
    427 		vrkiu_keymapdata.layout = KB_JP;
    428 #endif
    429 	} else if (platid_match(&platid, &platid_mask_MACH_FUJITSU_INTERTOP)) {
    430 		keytrans = intertop_keytrans;
    431 #if !defined(VRKIU_LAYOUT)
    432 		vrkiu_keymapdata.layout = KB_JP;
    433 #endif
    434 	}
    435 	wa.console = isconsole;
    436 	wa.keymap = &vrkiu_keymapdata;
    437 	wa.accessops = &vrkiu_accessops;
    438 	wa.accesscookie = sc;
    439 
    440 	sc->sc_wskbddev = config_found(self, &wa, wskbddevprint);
    441 }
    442 
    443 int
    444 vrkiu_intr(arg)
    445 	void *arg;
    446 {
    447         struct vrkiu_softc *sc = arg;
    448 
    449 	/* When key scan finisshed, this entry is called. */
    450 	DPRINTF(("%s(%d): vrkiu_intr: %d\n",
    451 		 __FILE__, __LINE__,
    452 		 vrkiu_read(sc->sc_chip, KIUINT) & 7));
    453 
    454 	/*
    455 	 * First, we must clear the interrupt register because
    456 	 * detect_key() may takes long time if a bitmap screen
    457 	 * scrolls up and it makes us to miss some key release
    458 	 * event.
    459 	 */
    460 	vrkiu_write(sc->sc_chip, KIUINT, 0x7); /* Clear all interrupt */
    461 	detect_key(sc->sc_chip);
    462 
    463 	return 0;
    464 }
    465 
    466 static void
    467 detect_key(chip)
    468 	struct vrkiu_chip* chip;
    469 {
    470 	int i, j, modified, mask;
    471 	unsigned short scandata[KIU_NSCANLINE/2];
    472 
    473 	for (i = 0; i < KIU_NSCANLINE / 2; i++) {
    474 		scandata[i] = vrkiu_read(chip, KIUDATP + i * 2);
    475 	}
    476 
    477 	DPRINTF(("%s(%d): detect_key():", __FILE__, __LINE__));
    478 
    479 	if (chip->kc_polling) {
    480 		chip->kc_type = WSCONS_EVENT_ALL_KEYS_UP;
    481 	}
    482 
    483 	for (i = 0; i < KIU_NSCANLINE / 2; i++) {
    484 		modified = scandata[i] ^ chip->kc_scandata[i];
    485 		mask = 1;
    486 		for (j = 0; j < 16; j++, mask <<= 1) {
    487 			/* XXX: The order of keys can be a problem.
    488 			   If CTRL and normal key are pushed simultaneously,
    489 			   normal key can be entered in queue first.
    490 			   Same problem would occur in key break. */
    491 			if (modified & mask) {
    492 				int key, type;
    493 				key = i * 16 + j;
    494 				if (keytrans[key] == UNK) {
    495 	                                printf("vrkiu: Unknown scan code 0x%02x\n", key);
    496 	                                continue;
    497 				} else if (keytrans[key] == IGN) {
    498 					continue;
    499 				}
    500 				type = (scandata[i] & mask) ?
    501 					WSCONS_EVENT_KEY_DOWN :
    502 					WSCONS_EVENT_KEY_UP;
    503 				DPRINTF(("(%d,%d)=%s%d ", i, j,
    504 					 (scandata[i] & mask) ? "v" : "^",
    505 					 keytrans[key]));
    506 				if (chip->kc_polling) {
    507 					chip->kc_type = type;
    508 					chip->kc_data = keytrans[key];
    509 				} else {
    510 					wskbd_input(chip->kc_sc->sc_wskbddev,
    511 						    type,
    512 						    keytrans[key]);
    513 				}
    514 			}
    515 		}
    516 		chip->kc_scandata[i] = scandata[i];
    517 	}
    518 	DPRINTF(("\n"));
    519 }
    520 
    521 /* called from biconsdev.c */
    522 int
    523 vrkiu_getc()
    524 {
    525 	int ret;
    526 
    527 	if (the_vrkiu == NULL) {
    528 		return 0;	/* XXX */
    529 	}
    530 
    531 	while (the_vrkiu->keybuftail == the_vrkiu->keybufhead) {
    532 		detect_key(vrkiu_consdata);
    533 	}
    534 	ret = the_vrkiu->keybuf[the_vrkiu->keybuftail++];
    535 	if (the_vrkiu->keybuftail >= NKEYBUF) {
    536 		the_vrkiu->keybuftail = 0;
    537 	}
    538 	return ret;
    539 }
    540 
    541 int
    542 vrkiu_enable(scx, on)
    543 	void *scx;
    544 	int on;
    545 {
    546 	struct vrkiu_softc *sc = scx;
    547 
    548 	if (on) {
    549 		if (sc->sc_enabled)
    550 			return (EBUSY);
    551 		sc->sc_enabled = 1;
    552 	} else {
    553 		if (sc->sc_chip == vrkiu_consdata)
    554 			return (EBUSY);
    555 		sc->sc_enabled = 0;
    556 	}
    557 
    558 	return (0);
    559 }
    560 
    561 void
    562 vrkiu_set_leds(scx, leds)
    563 	void *scx;
    564 	int leds;
    565 {
    566 	/*struct pckbd_softc *sc = scx;
    567 	 */
    568 
    569 	DPRINTF(("%s(%d): vrkiu_set_leds() not implemented\n",
    570 		 __FILE__, __LINE__));
    571 }
    572 
    573 int
    574 vrkiu_ioctl(scx, cmd, data, flag, p)
    575 	void *scx;
    576 	u_long cmd;
    577 	caddr_t data;
    578 	int flag;
    579 	struct proc *p;
    580 {
    581 	/*struct vrkiu_softc *sc = scx;
    582 	 */
    583 
    584 	switch (cmd) {
    585 	case WSKBDIO_GTYPE:
    586 		/*
    587 		 * XXX, fix me !
    588 		 */
    589 		*(int *)data = WSKBD_TYPE_PC_XT;
    590 		return 0;
    591 	case WSKBDIO_SETLEDS:
    592 		DPRINTF(("%s(%d): no LED\n", __FILE__, __LINE__));
    593 		return 0;
    594 	case WSKBDIO_GETLEDS:
    595 		DPRINTF(("%s(%d): no LED\n", __FILE__, __LINE__));
    596 		*(int *)data = 0;
    597 		return (0);
    598 	}
    599 	return -1;
    600 }
    601 
    602 /*
    603  * console support routines
    604  */
    605 int
    606 vrkiu_cnattach(iot, iobase)
    607 	bus_space_tag_t iot;
    608 	int iobase;
    609 {
    610 	static struct vrkiu_chip vrkiu_consdata_body;
    611 	bus_space_handle_t ioh;
    612 
    613 	if (vrkiu_consdata) {
    614 		panic("vrkiu is already attached as the console");
    615 	}
    616 	if (bus_space_map(iot, iobase, 1, 0, &ioh)) {
    617 		printf("%s(%d): can't map bus space\n", __FILE__, __LINE__);
    618 		return -1;
    619 	}
    620 
    621 	if (vrkiu_init(&vrkiu_consdata_body, iot, ioh) != 0) {
    622 		DPRINTF(("%s(%d): vrkiu_init() failed\n", __FILE__, __LINE__));
    623 		return -1;
    624 	}
    625 	vrkiu_consdata = &vrkiu_consdata_body;
    626 
    627 	wskbd_cnattach(&vrkiu_consops, vrkiu_consdata, &vrkiu_keymapdata);
    628 
    629 	return (0);
    630 }
    631 
    632 void
    633 vrkiu_cngetc(chipx, type, data)
    634 	void *chipx;
    635 	u_int *type;
    636 	int *data;
    637 {
    638 	struct vrkiu_chip* chip = chipx;
    639 	int s;
    640 
    641 	if (!chip->kc_polling) {
    642 		printf("%s(%d): kiu is not polled\n", __FILE__, __LINE__);
    643 		while (1);
    644 	}
    645 
    646 	s = splimp();
    647 	if (chip->kc_type == WSCONS_EVENT_ALL_KEYS_UP) {
    648 		detect_key(chip);
    649 	}
    650 	*type = chip->kc_type;
    651 	*data = chip->kc_data;
    652 	chip->kc_type = WSCONS_EVENT_ALL_KEYS_UP;
    653 	splx(s);
    654 }
    655 
    656 void
    657 vrkiu_cnpollc(chipx, on)
    658 	void *chipx;
    659         int on;
    660 {
    661 	struct vrkiu_chip* chip = chipx;
    662 	int s = splimp();
    663 
    664 	chip->kc_polling = on;
    665 
    666 	splx(s);
    667 
    668 	DPRINTF(("%s(%d): vrkiu polling %s\n",
    669 		 __FILE__, __LINE__, on ? "ON" : "OFF"));
    670 }
    671