Home | History | Annotate | Line # | Download | only in vr
vrkiu.c revision 1.11
      1 /*	$NetBSD: vrkiu.c,v 1.11 2000/01/17 12:22:37 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 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, IGN, /* 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,  IGN, 11,  38,   7,  34,  15,   1, /* pgdn - 0 l : g tab esc */
    262 /*28*/ IGN,  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, IGN, /* - @ 7 h 3 s del - */
    265 /*40*/  42, IGN, IGN, IGN,  14,  88,  66,  62, /* shift - - - bs f12 f8 f4 */
    266 /*48*/ IGN,  56, IGN, IGN, 125,  87,  65,  61, /* - alt - - | f11 f7 f3 */
    267 /*50*/ IGN, IGN,  29, IGN,  68,  68,  64,  60, /* - - ctrl - f10 f10 f6 f2 */
    268 /*58*/ IGN, IGN, IGN,  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 static void
    338 vrkiu_initkeymap(void)
    339 {
    340 	if (platid_match(&platid, &platid_mask_MACH_NEC_MCR_520A)) {
    341 		keytrans = mobilepro_keytrans;
    342 #if !defined(PCKBD_LAYOUT)
    343 		vrkiu_keymapdata.layout = KB_US;
    344 #endif
    345 	} else if (platid_match(&platid, &platid_mask_MACH_NEC_MCR_500A)) {
    346 		keytrans = mobilepro750c_keytrans;
    347 #if !defined(PCKBD_LAYOUT)
    348 		vrkiu_keymapdata.layout = KB_US;
    349 #endif
    350 	} else if (platid_match(&platid, &platid_mask_MACH_NEC_MCR_700A)) {
    351 		keytrans = mobilepro_keytrans;
    352 #if !defined(PCKBD_LAYOUT)
    353 		vrkiu_keymapdata.layout = KB_US;
    354 #endif
    355 	} else if (platid_match(&platid, &platid_mask_MACH_NEC_MCR)) {
    356 		keytrans = mcr_jp_keytrans;
    357 #if !defined(PCKBD_LAYOUT)
    358 		vrkiu_keymapdata.layout = KB_JP;
    359 #endif
    360 	} else if (platid_match(&platid, &platid_mask_MACH_IBM_WORKPAD_Z50)) {
    361 		keytrans = z50_keytrans;
    362 #if !defined(PCKBD_LAYOUT)
    363 		vrkiu_keymapdata.layout = KB_US;
    364 #endif
    365 	} else if (platid_match(&platid, &platid_mask_MACH_SHARP_TRIPAD)) {
    366 		keytrans = tripad_keytrans;
    367 #if !defined(PCKBD_LAYOUT)
    368 		vrkiu_keymapdata.layout = KB_JP;
    369 #endif
    370 	} else if (platid_match(&platid, &platid_mask_MACH_NEC_MCCS)) {
    371 		keytrans = mccs_keytrans;
    372 #if !defined(PCKBD_LAYOUT)
    373 		vrkiu_keymapdata.layout = KB_JP;
    374 #endif
    375 	} else if (platid_match(&platid, &platid_mask_MACH_FUJITSU_INTERTOP)) {
    376 		keytrans = intertop_keytrans;
    377 #if !defined(PCKBD_LAYOUT)
    378 		vrkiu_keymapdata.layout = KB_JP;
    379 #endif
    380 	}
    381 }
    382 
    383 /*
    384  * initialize device
    385  */
    386 static int
    387 vrkiu_init(chip, iot, ioh)
    388 	struct vrkiu_chip* chip;
    389 	bus_space_tag_t iot;
    390 	bus_space_handle_t ioh;
    391 {
    392 	memset(chip, 0, sizeof(struct vrkiu_chip));
    393 	chip->kc_iot = iot;
    394 	chip->kc_ioh = ioh;
    395 	chip->kc_polling = 0;
    396 
    397 	/* set KIU */
    398 	vrkiu_write(chip, KIURST, 1);   /* reset */
    399 	vrkiu_write(chip, KIUSCANLINE, 0); /* 96keys */
    400 	vrkiu_write(chip, KIUWKS, 0x18a4); /* XXX: scan timing! */
    401 	vrkiu_write(chip, KIUWKI, 450);
    402 	vrkiu_write(chip, KIUSCANREP, 0x8023);
    403 				/* KEYEN | STPREP = 2 | ATSTP | ATSCAN */
    404 	vrkiu_initkeymap();
    405 	return 0;
    406 }
    407 
    408 /*
    409  * probe
    410  */
    411 static int
    412 vrkiumatch(parent, cf, aux)
    413 	struct device *parent;
    414 	struct cfdata *cf;
    415 	void *aux;
    416 {
    417 	return 1;
    418 }
    419 
    420 /*
    421  * attach
    422  */
    423 static void
    424 vrkiuattach(parent, self, aux)
    425 	struct device *parent;
    426 	struct device *self;
    427 	void *aux;
    428 {
    429 	struct vrkiu_softc *sc = (struct vrkiu_softc *)self;
    430 	struct vrip_attach_args *va = aux;
    431 	struct wskbddev_attach_args wa;
    432 	int isconsole;
    433 
    434 	bus_space_tag_t iot = va->va_iot;
    435 	bus_space_handle_t ioh;
    436 
    437 	if (bus_space_map(iot, va->va_addr, 1, 0, &ioh)) {
    438 		printf(": can't map bus space\n");
    439 		return;
    440 	}
    441 
    442 	isconsole = vrkiu_is_console(iot, ioh);
    443 	if (isconsole) {
    444 		sc->sc_chip = vrkiu_consdata;
    445 	} else {
    446 		sc->sc_chip = &sc->sc_chip_body;
    447 		vrkiu_init(sc->sc_chip, iot, ioh);
    448 	}
    449 	sc->sc_chip->kc_sc = sc;
    450 
    451 	if (!(sc->sc_handler =
    452 	      vrip_intr_establish(va->va_vc, va->va_intr, IPL_TTY,
    453 				  vrkiu_intr, sc))) {
    454 		printf (": can't map interrupt line.\n");
    455 		return;
    456 	}
    457 	/* Level2 register setting */
    458 	vrip_intr_setmask2(va->va_vc, sc->sc_handler, KIUINT_KDATRDY, 1);
    459 
    460 	printf("\n");
    461 
    462 	wa.console = isconsole;
    463 	wa.keymap = &vrkiu_keymapdata;
    464 	wa.accessops = &vrkiu_accessops;
    465 	wa.accesscookie = sc;
    466 
    467 	sc->sc_wskbddev = config_found(self, &wa, wskbddevprint);
    468 }
    469 
    470 int
    471 vrkiu_intr(arg)
    472 	void *arg;
    473 {
    474         struct vrkiu_softc *sc = arg;
    475 
    476 	/* When key scan finisshed, this entry is called. */
    477 	DPRINTF(("%s(%d): vrkiu_intr: %d\n",
    478 		 __FILE__, __LINE__,
    479 		 vrkiu_read(sc->sc_chip, KIUINT) & 7));
    480 
    481 	/*
    482 	 * First, we must clear the interrupt register because
    483 	 * detect_key() may takes long time if a bitmap screen
    484 	 * scrolls up and it makes us to miss some key release
    485 	 * event.
    486 	 */
    487 	vrkiu_write(sc->sc_chip, KIUINT, 0x7); /* Clear all interrupt */
    488 	detect_key(sc->sc_chip);
    489 
    490 	return 0;
    491 }
    492 
    493 static void
    494 detect_key(chip)
    495 	struct vrkiu_chip* chip;
    496 {
    497 	int i, j, modified, mask;
    498 	unsigned short scandata[KIU_NSCANLINE/2];
    499 
    500 	for (i = 0; i < KIU_NSCANLINE / 2; i++) {
    501 		scandata[i] = vrkiu_read(chip, KIUDATP + i * 2);
    502 	}
    503 
    504 	DPRINTF(("%s(%d): detect_key():", __FILE__, __LINE__));
    505 
    506 	if (chip->kc_polling) {
    507 		chip->kc_type = WSCONS_EVENT_ALL_KEYS_UP;
    508 	}
    509 
    510 	for (i = 0; i < KIU_NSCANLINE / 2; i++) {
    511 		modified = scandata[i] ^ chip->kc_scandata[i];
    512 		mask = 1;
    513 		for (j = 0; j < 16; j++, mask <<= 1) {
    514 			/* XXX: The order of keys can be a problem.
    515 			   If CTRL and normal key are pushed simultaneously,
    516 			   normal key can be entered in queue first.
    517 			   Same problem would occur in key break. */
    518 			if (modified & mask) {
    519 				int key, type;
    520 				key = i * 16 + j;
    521 				if (keytrans[key] == UNK) {
    522 	                                printf("vrkiu: Unknown scan code 0x%02x\n", key);
    523 	                                continue;
    524 				} else if (keytrans[key] == IGN) {
    525 					continue;
    526 				}
    527 				type = (scandata[i] & mask) ?
    528 					WSCONS_EVENT_KEY_DOWN :
    529 					WSCONS_EVENT_KEY_UP;
    530 				DPRINTF(("(%d,%d)=%s%d ", i, j,
    531 					 (scandata[i] & mask) ? "v" : "^",
    532 					 keytrans[key]));
    533 				if (chip->kc_polling) {
    534 					chip->kc_type = type;
    535 					chip->kc_data = keytrans[key];
    536 				} else {
    537 					wskbd_input(chip->kc_sc->sc_wskbddev,
    538 						    type,
    539 						    keytrans[key]);
    540 				}
    541 			}
    542 		}
    543 		chip->kc_scandata[i] = scandata[i];
    544 	}
    545 	DPRINTF(("\n"));
    546 }
    547 
    548 /* called from biconsdev.c */
    549 int
    550 vrkiu_getc()
    551 {
    552 	int ret;
    553 
    554 	if (the_vrkiu == NULL) {
    555 		return 0;	/* XXX */
    556 	}
    557 
    558 	while (the_vrkiu->keybuftail == the_vrkiu->keybufhead) {
    559 		detect_key(vrkiu_consdata);
    560 	}
    561 	ret = the_vrkiu->keybuf[the_vrkiu->keybuftail++];
    562 	if (the_vrkiu->keybuftail >= NKEYBUF) {
    563 		the_vrkiu->keybuftail = 0;
    564 	}
    565 	return ret;
    566 }
    567 
    568 int
    569 vrkiu_enable(scx, on)
    570 	void *scx;
    571 	int on;
    572 {
    573 	struct vrkiu_softc *sc = scx;
    574 
    575 	if (on) {
    576 		if (sc->sc_enabled)
    577 			return (EBUSY);
    578 		sc->sc_enabled = 1;
    579 	} else {
    580 		if (sc->sc_chip == vrkiu_consdata)
    581 			return (EBUSY);
    582 		sc->sc_enabled = 0;
    583 	}
    584 
    585 	return (0);
    586 }
    587 
    588 void
    589 vrkiu_set_leds(scx, leds)
    590 	void *scx;
    591 	int leds;
    592 {
    593 	/*struct pckbd_softc *sc = scx;
    594 	 */
    595 
    596 	DPRINTF(("%s(%d): vrkiu_set_leds() not implemented\n",
    597 		 __FILE__, __LINE__));
    598 }
    599 
    600 int
    601 vrkiu_ioctl(scx, cmd, data, flag, p)
    602 	void *scx;
    603 	u_long cmd;
    604 	caddr_t data;
    605 	int flag;
    606 	struct proc *p;
    607 {
    608 	/*struct vrkiu_softc *sc = scx;
    609 	 */
    610 
    611 	switch (cmd) {
    612 	case WSKBDIO_GTYPE:
    613 		/*
    614 		 * XXX, fix me !
    615 		 */
    616 		*(int *)data = WSKBD_TYPE_PC_XT;
    617 		return 0;
    618 	case WSKBDIO_SETLEDS:
    619 		DPRINTF(("%s(%d): no LED\n", __FILE__, __LINE__));
    620 		return 0;
    621 	case WSKBDIO_GETLEDS:
    622 		DPRINTF(("%s(%d): no LED\n", __FILE__, __LINE__));
    623 		*(int *)data = 0;
    624 		return (0);
    625 	}
    626 	return -1;
    627 }
    628 
    629 /*
    630  * console support routines
    631  */
    632 int
    633 vrkiu_cnattach(iot, iobase)
    634 	bus_space_tag_t iot;
    635 	int iobase;
    636 {
    637 	static struct vrkiu_chip vrkiu_consdata_body;
    638 	bus_space_handle_t ioh;
    639 
    640 	if (vrkiu_consdata) {
    641 		panic("vrkiu is already attached as the console");
    642 	}
    643 	if (bus_space_map(iot, iobase, 1, 0, &ioh)) {
    644 		printf("%s(%d): can't map bus space\n", __FILE__, __LINE__);
    645 		return -1;
    646 	}
    647 
    648 	if (vrkiu_init(&vrkiu_consdata_body, iot, ioh) != 0) {
    649 		DPRINTF(("%s(%d): vrkiu_init() failed\n", __FILE__, __LINE__));
    650 		return -1;
    651 	}
    652 	vrkiu_consdata = &vrkiu_consdata_body;
    653 
    654 	wskbd_cnattach(&vrkiu_consops, vrkiu_consdata, &vrkiu_keymapdata);
    655 
    656 	return (0);
    657 }
    658 
    659 void
    660 vrkiu_cngetc(chipx, type, data)
    661 	void *chipx;
    662 	u_int *type;
    663 	int *data;
    664 {
    665 	struct vrkiu_chip* chip = chipx;
    666 	int s;
    667 
    668 	if (!chip->kc_polling) {
    669 		printf("%s(%d): kiu is not polled\n", __FILE__, __LINE__);
    670 		while (1);
    671 	}
    672 
    673 	s = splimp();
    674 	if (chip->kc_type == WSCONS_EVENT_ALL_KEYS_UP) {
    675 		detect_key(chip);
    676 	}
    677 	*type = chip->kc_type;
    678 	*data = chip->kc_data;
    679 	chip->kc_type = WSCONS_EVENT_ALL_KEYS_UP;
    680 	splx(s);
    681 }
    682 
    683 void
    684 vrkiu_cnpollc(chipx, on)
    685 	void *chipx;
    686         int on;
    687 {
    688 	struct vrkiu_chip* chip = chipx;
    689 	int s = splimp();
    690 
    691 	chip->kc_polling = on;
    692 
    693 	splx(s);
    694 
    695 	DPRINTF(("%s(%d): vrkiu polling %s\n",
    696 		 __FILE__, __LINE__, on ? "ON" : "OFF"));
    697 }
    698