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