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