Home | History | Annotate | Line # | Download | only in vr
vrkiu.c revision 1.9
      1 /*	$NetBSD: vrkiu.c,v 1.9 1999/12/09 03:14:06 jun 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 PCKBD_LAYOUT
    150 	PCKBD_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 /* NEC MobilePro 750c by "Castor Fu" <castor (at) geocast.com> */
    256 static char mobilepro750c_keytrans[] = {
    257 /*00*/  77,  43,  25,  52,  21,  48,  44,  57, /* right \ p . y b z space */
    258 /*08*/  80,  53,  24,  51,  20,  47,  30, UNK, /* down / o , t v a  - */
    259 /*10*/  75,  28,  23,  50,  19,  46,  17, 221, /* left enter i m r c w Win */
    260 /*18*/  69,  27,  22,  49,  18,  45,  16,  58, /* num ] u n e x q caps */
    261 /*20*/  81,  UNK, 11,  38,   7,  34,  15,   1, /* pgdn - 0 l : g tab esc */
    262 /*28*/ UNK,  39,  10,  37,   6,  33,   3,  41, /* - ; 9 k 5 f 2 ` */
    263 /*30*/  72,  26,   9,  36,   5,  32,   2,  40, /* up [ 8 j 4 d 1 ' */
    264 /*38*/  12,  26,   8,  35,   4,  31,  83, UNK, /* - @ 7 h 3 s del - */
    265 /*40*/  42, UNK, UNK, UNK,  14,  88,  66,  62, /* shift - - - bs f12 f8 f4 */
    266 /*48*/ UNK, 184, UNK, UNK, 125,  87,  65,  61, /* - alt - - | f11 f7 f3 */
    267 /*50*/ UNK, UNK,  29, UNK,  68,  68,  64,  60, /* - - ctrl - f10 f10 f6 f2 */
    268 /*58*/ UNK, UNK, UNK,  42,  13,  67,  63,  59, /* - - - shift del f9 f5 f1 */
    269 };
    270 
    271 /* FUJITSU INTERTOP CX300 */
    272 static char intertop_keytrans[] = {
    273   57,  60,   2,  15,  28,  58,  75,  41,
    274  112,  59,   3,  16, IGN,  30,  56,   1,
    275  210,  17,   4,  31,  83,  43,  80,  45,
    276   44,  18,   5,  32,  68, 125,  77,  46,
    277  115,  19,  39,  33,  67,  26,  13,  47,
    278   53,  20,   6,  34,  66,  25,  12,  48,
    279   52,  21,   7,  35,  65,  38,  11,  49,
    280  IGN,  22,   8,  36,  63,  24,  14,  50,
    281  IGN,  61,   9,  62, IGN,  23,  37,  51,
    282   69,  40,  10,  27,  64, IGN,  72, IGN,
    283  IGN, IGN, IGN, IGN,  42, IGN, IGN,  54,
    284   29, 221, 123, 121, 184, IGN, IGN, IGN,
    285 };
    286 /*
    287 space   a2      1       tab     enter   caps    left    zenkaku
    288 hiraga  a1      2       q       -       a       fnc     esc
    289 ins     w       3       s       del     ]       down    x
    290 z       e       4       d       a10     \       right   c
    291 backsla r       ;       f       a9      @       ^       v
    292 /       t       5       g       a8      p       -       b
    293 .       y       6       h       a7      l       0       n
    294 -       u       7       j       a5      o       bs      m
    295 -       a3      8       a4      -       i       k       ,
    296 num     :       9       [       a6      -       up      -
    297 -       -       -       -       shift_L -       -       shift_R
    298 ctrl    win     muhenka henkan  alt     -       -       -
    299 */
    300 
    301 static char *keytrans = default_keytrans;
    302 
    303 /*
    304  * utilities
    305  */
    306 static inline void
    307 vrkiu_write(chip, port, val)
    308 	struct vrkiu_chip *chip;
    309 	int port;
    310 	unsigned short val;
    311 {
    312 	bus_space_write_2(chip->kc_iot, chip->kc_ioh, port, val);
    313 }
    314 
    315 static inline unsigned short
    316 vrkiu_read(chip, port)
    317 	struct vrkiu_chip *chip;
    318 	int port;
    319 {
    320 	return bus_space_read_2(chip->kc_iot, chip->kc_ioh, port);
    321 }
    322 
    323 static inline int
    324 vrkiu_is_console(iot, ioh)
    325 	bus_space_tag_t iot;
    326 	bus_space_handle_t ioh;
    327 {
    328 	if (vrkiu_consdata &&
    329 	    vrkiu_consdata->kc_iot == iot &&
    330 	    vrkiu_consdata->kc_ioh == ioh) {
    331 		return 1;
    332 	} else {
    333 		return 0;
    334 	}
    335 }
    336 
    337 /*
    338  * initialize device
    339  */
    340 static int
    341 vrkiu_init(chip, iot, ioh)
    342 	struct vrkiu_chip* chip;
    343 	bus_space_tag_t iot;
    344 	bus_space_handle_t ioh;
    345 {
    346 	memset(chip, 0, sizeof(struct vrkiu_chip));
    347 	chip->kc_iot = iot;
    348 	chip->kc_ioh = ioh;
    349 	chip->kc_polling = 0;
    350 
    351 	/* set KIU */
    352 	vrkiu_write(chip, KIURST, 1);   /* reset */
    353 	vrkiu_write(chip, KIUSCANLINE, 0); /* 96keys */
    354 	vrkiu_write(chip, KIUWKS, 0x18a4); /* XXX: scan timing! */
    355 	vrkiu_write(chip, KIUWKI, 450);
    356 	vrkiu_write(chip, KIUSCANREP, 0x8023);
    357 				/* KEYEN | STPREP = 2 | ATSTP | ATSCAN */
    358 	return 0;
    359 }
    360 
    361 /*
    362  * probe
    363  */
    364 static int
    365 vrkiumatch(parent, cf, aux)
    366 	struct device *parent;
    367 	struct cfdata *cf;
    368 	void *aux;
    369 {
    370 	return 1;
    371 }
    372 
    373 /*
    374  * attach
    375  */
    376 static void
    377 vrkiuattach(parent, self, aux)
    378 	struct device *parent;
    379 	struct device *self;
    380 	void *aux;
    381 {
    382 	struct vrkiu_softc *sc = (struct vrkiu_softc *)self;
    383 	struct vrip_attach_args *va = aux;
    384 	struct wskbddev_attach_args wa;
    385 	int isconsole;
    386 
    387 	bus_space_tag_t iot = va->va_iot;
    388 	bus_space_handle_t ioh;
    389 
    390 	if (bus_space_map(iot, va->va_addr, 1, 0, &ioh)) {
    391 		printf(": can't map bus space\n");
    392 		return;
    393 	}
    394 
    395 	isconsole = vrkiu_is_console(iot, ioh);
    396 	if (isconsole) {
    397 		sc->sc_chip = vrkiu_consdata;
    398 	} else {
    399 		sc->sc_chip = &sc->sc_chip_body;
    400 		vrkiu_init(sc->sc_chip, iot, ioh);
    401 	}
    402 	sc->sc_chip->kc_sc = sc;
    403 
    404 	if (!(sc->sc_handler =
    405 	      vrip_intr_establish(va->va_vc, va->va_intr, IPL_TTY,
    406 				  vrkiu_intr, sc))) {
    407 		printf (": can't map interrupt line.\n");
    408 		return;
    409 	}
    410 	/* Level2 register setting */
    411 	vrip_intr_setmask2(va->va_vc, sc->sc_handler, KIUINT_KDATRDY, 1);
    412 
    413 	printf("\n");
    414 
    415 	if (platid_match(&platid, &platid_mask_MACH_NEC_MCR_520A)) {
    416 		keytrans = mobilepro_keytrans;
    417 #if !defined(PCKBD_LAYOUT)
    418 		vrkiu_keymapdata.layout = KB_US;
    419 #endif
    420 	} else if (platid_match(&platid, &platid_mask_MACH_NEC_MCR_500A)) {
    421 		keytrans = mobilepro750c_keytrans;
    422 #if !defined(PCKBD_LAYOUT)
    423 		vrkiu_keymapdata.layout = KB_US;
    424 #endif
    425 	} else if (platid_match(&platid, &platid_mask_MACH_NEC_MCR_700A)) {
    426 		keytrans = mobilepro_keytrans;
    427 #if !defined(PCKBD_LAYOUT)
    428 		vrkiu_keymapdata.layout = KB_US;
    429 #endif
    430 	} else if (platid_match(&platid, &platid_mask_MACH_NEC_MCR)) {
    431 		keytrans = mcr_jp_keytrans;
    432 #if !defined(PCKBD_LAYOUT)
    433 		vrkiu_keymapdata.layout = KB_JP;
    434 #endif
    435 	} else if (platid_match(&platid, &platid_mask_MACH_IBM_WORKPAD_Z50)) {
    436 		keytrans = z50_keytrans;
    437 #if !defined(PCKBD_LAYOUT)
    438 		vrkiu_keymapdata.layout = KB_US;
    439 #endif
    440 	} else if (platid_match(&platid, &platid_mask_MACH_SHARP_TRIPAD)) {
    441 		keytrans = tripad_keytrans;
    442 #if !defined(PCKBD_LAYOUT)
    443 		vrkiu_keymapdata.layout = KB_JP;
    444 #endif
    445 	} else if (platid_match(&platid, &platid_mask_MACH_NEC_MCCS)) {
    446 		keytrans = mccs_keytrans;
    447 #if !defined(PCKBD_LAYOUT)
    448 		vrkiu_keymapdata.layout = KB_JP;
    449 #endif
    450 	} else if (platid_match(&platid, &platid_mask_MACH_FUJITSU_INTERTOP)) {
    451 		keytrans = intertop_keytrans;
    452 #if !defined(PCKBD_LAYOUT)
    453 		vrkiu_keymapdata.layout = KB_JP;
    454 #endif
    455 	}
    456 	wa.console = isconsole;
    457 	wa.keymap = &vrkiu_keymapdata;
    458 	wa.accessops = &vrkiu_accessops;
    459 	wa.accesscookie = sc;
    460 
    461 	sc->sc_wskbddev = config_found(self, &wa, wskbddevprint);
    462 }
    463 
    464 int
    465 vrkiu_intr(arg)
    466 	void *arg;
    467 {
    468         struct vrkiu_softc *sc = arg;
    469 
    470 	/* When key scan finisshed, this entry is called. */
    471 	DPRINTF(("%s(%d): vrkiu_intr: %d\n",
    472 		 __FILE__, __LINE__,
    473 		 vrkiu_read(sc->sc_chip, KIUINT) & 7));
    474 
    475 	/*
    476 	 * First, we must clear the interrupt register because
    477 	 * detect_key() may takes long time if a bitmap screen
    478 	 * scrolls up and it makes us to miss some key release
    479 	 * event.
    480 	 */
    481 	vrkiu_write(sc->sc_chip, KIUINT, 0x7); /* Clear all interrupt */
    482 	detect_key(sc->sc_chip);
    483 
    484 	return 0;
    485 }
    486 
    487 static void
    488 detect_key(chip)
    489 	struct vrkiu_chip* chip;
    490 {
    491 	int i, j, modified, mask;
    492 	unsigned short scandata[KIU_NSCANLINE/2];
    493 
    494 	for (i = 0; i < KIU_NSCANLINE / 2; i++) {
    495 		scandata[i] = vrkiu_read(chip, KIUDATP + i * 2);
    496 	}
    497 
    498 	DPRINTF(("%s(%d): detect_key():", __FILE__, __LINE__));
    499 
    500 	if (chip->kc_polling) {
    501 		chip->kc_type = WSCONS_EVENT_ALL_KEYS_UP;
    502 	}
    503 
    504 	for (i = 0; i < KIU_NSCANLINE / 2; i++) {
    505 		modified = scandata[i] ^ chip->kc_scandata[i];
    506 		mask = 1;
    507 		for (j = 0; j < 16; j++, mask <<= 1) {
    508 			/* XXX: The order of keys can be a problem.
    509 			   If CTRL and normal key are pushed simultaneously,
    510 			   normal key can be entered in queue first.
    511 			   Same problem would occur in key break. */
    512 			if (modified & mask) {
    513 				int key, type;
    514 				key = i * 16 + j;
    515 				if (keytrans[key] == UNK) {
    516 	                                printf("vrkiu: Unknown scan code 0x%02x\n", key);
    517 	                                continue;
    518 				} else if (keytrans[key] == IGN) {
    519 					continue;
    520 				}
    521 				type = (scandata[i] & mask) ?
    522 					WSCONS_EVENT_KEY_DOWN :
    523 					WSCONS_EVENT_KEY_UP;
    524 				DPRINTF(("(%d,%d)=%s%d ", i, j,
    525 					 (scandata[i] & mask) ? "v" : "^",
    526 					 keytrans[key]));
    527 				if (chip->kc_polling) {
    528 					chip->kc_type = type;
    529 					chip->kc_data = keytrans[key];
    530 				} else {
    531 					wskbd_input(chip->kc_sc->sc_wskbddev,
    532 						    type,
    533 						    keytrans[key]);
    534 				}
    535 			}
    536 		}
    537 		chip->kc_scandata[i] = scandata[i];
    538 	}
    539 	DPRINTF(("\n"));
    540 }
    541 
    542 /* called from biconsdev.c */
    543 int
    544 vrkiu_getc()
    545 {
    546 	int ret;
    547 
    548 	if (the_vrkiu == NULL) {
    549 		return 0;	/* XXX */
    550 	}
    551 
    552 	while (the_vrkiu->keybuftail == the_vrkiu->keybufhead) {
    553 		detect_key(vrkiu_consdata);
    554 	}
    555 	ret = the_vrkiu->keybuf[the_vrkiu->keybuftail++];
    556 	if (the_vrkiu->keybuftail >= NKEYBUF) {
    557 		the_vrkiu->keybuftail = 0;
    558 	}
    559 	return ret;
    560 }
    561 
    562 int
    563 vrkiu_enable(scx, on)
    564 	void *scx;
    565 	int on;
    566 {
    567 	struct vrkiu_softc *sc = scx;
    568 
    569 	if (on) {
    570 		if (sc->sc_enabled)
    571 			return (EBUSY);
    572 		sc->sc_enabled = 1;
    573 	} else {
    574 		if (sc->sc_chip == vrkiu_consdata)
    575 			return (EBUSY);
    576 		sc->sc_enabled = 0;
    577 	}
    578 
    579 	return (0);
    580 }
    581 
    582 void
    583 vrkiu_set_leds(scx, leds)
    584 	void *scx;
    585 	int leds;
    586 {
    587 	/*struct pckbd_softc *sc = scx;
    588 	 */
    589 
    590 	DPRINTF(("%s(%d): vrkiu_set_leds() not implemented\n",
    591 		 __FILE__, __LINE__));
    592 }
    593 
    594 int
    595 vrkiu_ioctl(scx, cmd, data, flag, p)
    596 	void *scx;
    597 	u_long cmd;
    598 	caddr_t data;
    599 	int flag;
    600 	struct proc *p;
    601 {
    602 	/*struct vrkiu_softc *sc = scx;
    603 	 */
    604 
    605 	switch (cmd) {
    606 	case WSKBDIO_GTYPE:
    607 		/*
    608 		 * XXX, fix me !
    609 		 */
    610 		*(int *)data = WSKBD_TYPE_PC_XT;
    611 		return 0;
    612 	case WSKBDIO_SETLEDS:
    613 		DPRINTF(("%s(%d): no LED\n", __FILE__, __LINE__));
    614 		return 0;
    615 	case WSKBDIO_GETLEDS:
    616 		DPRINTF(("%s(%d): no LED\n", __FILE__, __LINE__));
    617 		*(int *)data = 0;
    618 		return (0);
    619 	}
    620 	return -1;
    621 }
    622 
    623 /*
    624  * console support routines
    625  */
    626 int
    627 vrkiu_cnattach(iot, iobase)
    628 	bus_space_tag_t iot;
    629 	int iobase;
    630 {
    631 	static struct vrkiu_chip vrkiu_consdata_body;
    632 	bus_space_handle_t ioh;
    633 
    634 	if (vrkiu_consdata) {
    635 		panic("vrkiu is already attached as the console");
    636 	}
    637 	if (bus_space_map(iot, iobase, 1, 0, &ioh)) {
    638 		printf("%s(%d): can't map bus space\n", __FILE__, __LINE__);
    639 		return -1;
    640 	}
    641 
    642 	if (vrkiu_init(&vrkiu_consdata_body, iot, ioh) != 0) {
    643 		DPRINTF(("%s(%d): vrkiu_init() failed\n", __FILE__, __LINE__));
    644 		return -1;
    645 	}
    646 	vrkiu_consdata = &vrkiu_consdata_body;
    647 
    648 	wskbd_cnattach(&vrkiu_consops, vrkiu_consdata, &vrkiu_keymapdata);
    649 
    650 	return (0);
    651 }
    652 
    653 void
    654 vrkiu_cngetc(chipx, type, data)
    655 	void *chipx;
    656 	u_int *type;
    657 	int *data;
    658 {
    659 	struct vrkiu_chip* chip = chipx;
    660 	int s;
    661 
    662 	if (!chip->kc_polling) {
    663 		printf("%s(%d): kiu is not polled\n", __FILE__, __LINE__);
    664 		while (1);
    665 	}
    666 
    667 	s = splimp();
    668 	if (chip->kc_type == WSCONS_EVENT_ALL_KEYS_UP) {
    669 		detect_key(chip);
    670 	}
    671 	*type = chip->kc_type;
    672 	*data = chip->kc_data;
    673 	chip->kc_type = WSCONS_EVENT_ALL_KEYS_UP;
    674 	splx(s);
    675 }
    676 
    677 void
    678 vrkiu_cnpollc(chipx, on)
    679 	void *chipx;
    680         int on;
    681 {
    682 	struct vrkiu_chip* chip = chipx;
    683 	int s = splimp();
    684 
    685 	chip->kc_polling = on;
    686 
    687 	splx(s);
    688 
    689 	DPRINTF(("%s(%d): vrkiu polling %s\n",
    690 		 __FILE__, __LINE__, on ? "ON" : "OFF"));
    691 }
    692