mkbd.c revision 1.1 1 /* $NetBSD: mkbd.c,v 1.1 2001/01/16 00:33:01 marcus Exp $ */
2
3 /*
4 * Copyright (c) 2001 Marcus Comstedt
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Colin Wood.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #include <sys/param.h>
34 #include <sys/device.h>
35 #include <sys/fcntl.h>
36 #include <sys/poll.h>
37 #include <sys/select.h>
38 #include <sys/proc.h>
39 #include <sys/signalvar.h>
40 #include <sys/systm.h>
41
42 #include "wskbd.h"
43
44 #include <dev/wscons/wsconsio.h>
45 #include <dev/wscons/wskbdvar.h>
46 #include <dev/wscons/wsksymdef.h>
47 #include <dev/wscons/wsksymvar.h>
48
49 #include <machine/cpu.h>
50 #include <machine/bus.h>
51
52 #include <dreamcast/dev/maple/maple.h>
53 #include <dreamcast/dev/maple/mapleconf.h>
54 #include <dreamcast/dev/maple/mkbdvar.h>
55 #include <dreamcast/dev/maple/mkbdmap.h>
56
57
58 /*
59 * Function declarations.
60 */
61 static int mkbdmatch __P((struct device *, struct cfdata *, void *));
62 static void mkbdattach __P((struct device *, struct device *, void *));
63
64 int mkbd_enable __P((void *, int));
65 void mkbd_set_leds __P((void *, int));
66 int mkbd_ioctl __P((void *, u_long, caddr_t, int, struct proc *));
67
68 struct wskbd_accessops mkbd_accessops = {
69 mkbd_enable,
70 mkbd_set_leds,
71 mkbd_ioctl,
72 };
73
74 static void mkbd_intr __P((struct mkbd_softc *, struct mkbd_condition *, int));
75
76 void mkbd_cngetc __P((void *, u_int *, int *));
77 void mkbd_cnpollc __P((void *, int));
78 int mkbd_cnattach __P((void));
79
80 struct wskbd_consops mkbd_consops = {
81 mkbd_cngetc,
82 mkbd_cnpollc,
83 };
84
85 struct wskbd_mapdata mkbd_keymapdata = {
86 mkbd_keydesctab,
87 KB_JP,
88 };
89
90 static struct mkbd_softc *mkbd_console_softc = NULL;
91
92 /* Driver definition. */
93 struct cfattach mkbd_ca = {
94 sizeof(struct mkbd_softc), mkbdmatch, mkbdattach
95 };
96
97 static int
98 mkbdmatch(parent, cf, aux)
99 struct device *parent;
100 struct cfdata *cf;
101 void *aux;
102 {
103 struct maple_attach_args *ma = aux;
104
105 return (ma->ma_devinfo->di_func & MAPLE_FUNC_KEYBOARD) != 0;
106 }
107
108 static void
109 mkbdattach(parent, self, aux)
110 struct device *parent, *self;
111 void *aux;
112 {
113 struct mkbd_softc *sc = (struct mkbd_softc *)self;
114 struct maple_attach_args *ma = aux;
115 #if NWSKBD > 0
116 struct wskbddev_attach_args a;
117 static int mkbd_console_initted = 0;
118 #endif
119
120 sc->sc_parent = parent;
121 sc->sc_port = ma->ma_port;
122 sc->sc_subunit = ma->ma_subunit;
123
124 switch(maple_get_function_data(ma->ma_devinfo,
125 MAPLE_FUNC_KEYBOARD)>>24) {
126 case 1: printf(" (Japanese keyboard)"); break;
127 case 3: printf(" (European keyboard)"); break;
128 default: printf(" (Unknown keyboard)");
129 }
130 printf("\n");
131
132 #if NWSKBD > 0
133 a.console = (++mkbd_console_initted == 1);
134 a.keymap = &mkbd_keymapdata;
135 a.accessops = &mkbd_accessops;
136 a.accesscookie = sc;
137 if (a.console)
138 mkbd_console_softc = sc;
139 sc->sc_wskbddev = config_found(self, &a, wskbddevprint);
140 #endif
141
142 maple_set_condition_callback(parent, sc->sc_port, sc->sc_subunit,
143 MAPLE_FUNC_KEYBOARD,
144 (void (*)(void *, void *, int))mkbd_intr,
145 sc);
146 }
147
148
149
150 int
151 mkbd_enable(v, on)
152 void *v;
153 int on;
154 {
155 return 0;
156 }
157
158 void
159 mkbd_set_leds(v, on)
160 void *v;
161 int on;
162 {
163 }
164
165 int
166 mkbd_ioctl(v, cmd, data, flag, p)
167 void *v;
168 u_long cmd;
169 caddr_t data;
170 int flag;
171 struct proc *p;
172 {
173 switch (cmd) {
174
175 case WSKBDIO_GTYPE:
176 *(int *)data = 0; /* XXX */
177 return 0;
178 case WSKBDIO_SETLEDS:
179 return 0;
180 case WSKBDIO_GETLEDS:
181 *(int *)data = 0;
182 return 0;
183 case WSKBDIO_BELL:
184 case WSKBDIO_COMPLEXBELL:
185 return 0;
186 }
187
188 return -1;
189 }
190
191
192 int
193 mkbd_cnattach()
194 {
195 wskbd_cnattach(&mkbd_consops, NULL, &mkbd_keymapdata);
196
197 return 0;
198 }
199
200 static int polledkey;
201 extern int maple_polling;
202
203 #define SHIFT_KEYCODE_BASE 0x100
204 #define UP_KEYCODE_FLAG 0x1000
205
206 #define KEY_UP(n) \
207 if (maple_polling) \
208 polledkey = (n)|UP_KEYCODE_FLAG; \
209 else \
210 wskbd_input(sc->sc_wskbddev, WSCONS_EVENT_KEY_UP, (n))
211
212 #define KEY_DOWN(n) \
213 if (maple_polling) \
214 polledkey = (n); \
215 else \
216 wskbd_input(sc->sc_wskbddev, WSCONS_EVENT_KEY_DOWN, (n))
217
218 #define SHIFT_UP(n) KEY_UP((n)|SHIFT_KEYCODE_BASE)
219 #define SHIFT_DOWN(n) KEY_DOWN((n)|SHIFT_KEYCODE_BASE)
220
221 static void
222 mkbd_intr(sc, kbddata, sz)
223 struct mkbd_softc *sc;
224 struct mkbd_condition *kbddata;
225 int sz;
226 {
227 if (sz >= sizeof(struct mkbd_condition)) {
228 int i, j, v;
229
230 v = sc->sc_condition.shift & ~kbddata->shift;
231 if (v)
232 for (i=0; i<8; i++)
233 if (v & (1<<i))
234 SHIFT_UP(i);
235
236 v = kbddata->shift & ~sc->sc_condition.shift;
237 if (v)
238 for (i=0; i<8; i++)
239 if (v & (1<<i))
240 SHIFT_DOWN(i);
241
242 for (i=0, j=0; i<6; i++)
243 if (sc->sc_condition.key[i] < 4)
244 break;
245 else if(sc->sc_condition.key[i] == kbddata->key[i])
246 j++;
247 else
248 KEY_UP(sc->sc_condition.key[i]);
249
250 for (; j<6; j++)
251 if (kbddata->key[j] < 4)
252 break;
253 else
254 KEY_DOWN(kbddata->key[j]);
255
256 bcopy(kbddata, &sc->sc_condition, sizeof(struct mkbd_condition));
257 }
258 }
259
260 void
261 mkbd_cngetc(v, type, data)
262 void *v;
263 u_int *type;
264 int *data;
265 {
266 int key;
267
268 polledkey = -1;
269 maple_polling = 1;
270 while (polledkey == -1) {
271 if (mkbd_console_softc != NULL ||
272 mkbd_console_softc->sc_parent != NULL)
273 maple_run_polling(mkbd_console_softc->sc_parent);
274 }
275 maple_polling = 0;
276 key = polledkey;
277
278 *data = key & ~UP_KEYCODE_FLAG;
279 *type = (key & UP_KEYCODE_FLAG)?
280 WSCONS_EVENT_KEY_UP : WSCONS_EVENT_KEY_DOWN;
281 }
282
283 void
284 mkbd_cnpollc(v, on)
285 void *v;
286 int on;
287 {
288 }
289