lunaws.c revision 1.1 1 /* $NetBSD: lunaws.c,v 1.1 2000/01/05 08:48:56 nisimura Exp $ */
2
3 /*-
4 * Copyright (c) 2000 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Tohru Nishimura.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the NetBSD
21 * Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 * contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39 #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
40
41 __KERNEL_RCSID(0, "$NetBSD: lunaws.c,v 1.1 2000/01/05 08:48:56 nisimura Exp $");
42
43 #include "wsmouse.h"
44
45 #include <sys/param.h>
46 #include <sys/systm.h>
47 #include <sys/conf.h>
48 #include <sys/device.h>
49
50 #include <dev/wscons/wsconsio.h>
51 #include <dev/wscons/wskbdvar.h>
52 #include <dev/wscons/wsksymdef.h>
53 #include <dev/wscons/wsksymvar.h>
54 #include <dev/wscons/wsmousevar.h>
55
56 #include <luna68k/dev/sioreg.h>
57 #include <luna68k/dev/siovar.h>
58
59 static const u_int8_t ch1_regs[6] = {
60 WR0_RSTINT, /* Reset E/S Interrupt */
61 WR1_RXALLS, /* Rx per char, No Tx */
62 0, /* */
63 WR3_RX8BIT | WR3_RXENBL, /* Rx */
64 WR4_BAUD96 | WR4_STOP1 | WR4_NPARITY, /* Tx/Rx */
65 WR5_TX8BIT | WR5_TXENBL, /* Tx */
66 };
67
68 struct ws_softc {
69 struct device sc_dv;
70 struct device *sc_wskbddev;
71 struct device *sc_wsmousedev;
72 struct sioreg *sc_ctl;
73 u_int8_t sc_wr[6];
74 };
75
76 static void omkbd_input __P((void *, int));
77 static int omkbd_decode __P((void *, int, u_int *, int *));
78 static int omkbd_enable __P((void *, int));
79 static void omkbd_set_leds __P((void *, int));
80 static int omkbd_ioctl __P((void *, u_long, caddr_t, int, struct proc *));
81
82 struct wscons_keydesc omkbd_keydesctab[];
83
84 static const struct wskbd_mapdata omkbd_keymapdata = {
85 omkbd_keydesctab,
86 KB_JP,
87 };
88 static const struct wskbd_accessops omkbd_accessops = {
89 omkbd_enable,
90 omkbd_set_leds,
91 omkbd_ioctl,
92 };
93
94 void ws_cnattach __P((void));
95 static void ws_cngetc __P((void *, u_int *, int *));
96 static void ws_cnpollc __P((void *, int));
97 static const struct wskbd_consops ws_consops = {
98 ws_cngetc,
99 ws_cnpollc,
100 };
101
102 #if NWSMOUSE > 0
103 static int omms_enable __P((void *));
104 static int omms_ioctl __P((void *, u_long, caddr_t, int, struct proc *));
105 static void omms_disable __P((void *));
106
107 static const struct wsmouse_accessops omms_accessops = {
108 omms_enable,
109 omms_ioctl,
110 omms_disable,
111 };
112 #endif
113
114 static void wsintr __P((int));
115
116 static int wsmatch __P((struct device *, struct cfdata *, void *));
117 static void wsattach __P((struct device *, struct device *, void *));
118
119 const struct cfattach ws_ca = {
120 sizeof(struct ws_softc), wsmatch, wsattach
121 };
122 extern struct cfdriver ws_cd;
123
124 extern int syscngetc __P((dev_t));
125 extern void syscnputc __P((dev_t, int));
126
127 static int
128 wsmatch(parent, match, aux)
129 struct device *parent;
130 struct cfdata *match;
131 void *aux;
132 {
133 struct sio_attach_args *args = aux;
134
135 if (args->channel != 1)
136 return 0;
137 return 1;
138 }
139
140 static void
141 wsattach(parent, self, aux)
142 struct device *parent;
143 struct device *self;
144 void *aux;
145 {
146 struct ws_softc *sc = (struct ws_softc *)self;
147 struct sio_softc *scp = (struct sio_softc *)parent;
148 struct sio_attach_args *args = aux;
149 struct wskbddev_attach_args a;
150
151 sc->sc_ctl = (struct sioreg *)scp->scp_ctl + 1;
152 bcopy(ch1_regs, sc->sc_wr, sizeof(ch1_regs));
153 scp->scp_intr[1] = wsintr;
154
155 setsioreg(sc->sc_ctl, WR0, sc->sc_wr[WR0]);
156 setsioreg(sc->sc_ctl, WR4, sc->sc_wr[WR4]);
157 setsioreg(sc->sc_ctl, WR3, sc->sc_wr[WR3]);
158 setsioreg(sc->sc_ctl, WR5, sc->sc_wr[WR5]);
159 setsioreg(sc->sc_ctl, WR0, sc->sc_wr[WR0]);
160 setsioreg(sc->sc_ctl, WR1, sc->sc_wr[WR1]);
161
162 syscnputc((dev_t)1, 0x20); /* keep quiet mouse */
163
164 printf("\n");
165
166 a.console = (args->hwflags == 1);
167 a.keymap = &omkbd_keymapdata;
168 a.accessops = &omkbd_accessops;
169 a.accesscookie = (void *)sc;
170 sc->sc_wskbddev = config_found(self, &a, wskbddevprint);
171
172 #if NWSMOUSE > 0
173 {
174 struct wsmousedev_attach_args b;
175 b.accessops = &omms_accessops;
176 b.accesscookie = (void *)sc;
177 sc->sc_wsmousedev = config_found(self, &b, wsmousedevprint);
178 }
179 #endif
180 }
181
182 /*ARGSUSED*/
183 static void
184 wsintr(chan)
185 int chan;
186 {
187 struct ws_softc *sc = ws_cd.cd_devs[0];
188 struct sioreg *sio = sc->sc_ctl;
189 u_int code;
190 int rr;
191 extern int getsiocsr __P((struct sioreg *));
192
193 rr = getsiocsr(sio);
194 if (rr & RR_RXRDY) {
195 do {
196 code = sio->sio_data;
197 if (rr & (RR_FRAMING | RR_OVERRUN | RR_PARITY)) {
198 sio->sio_cmd = WR0_ERRRST;
199 #if 0
200 if (sio->sio_stat & RR_FRAMING)
201 code |= TTY_FE;
202 else if (sio->sio_stat & RR_PARITY)
203 code |= TTY_PE;
204 #endif
205 continue;
206 }
207 #if 0
208 /*
209 * if (code >= 0x80 || code <= 0x87), then
210 * it's the first byte of 3 byte long mouse report
211 * code[0] & 07 -> LMR button condition
212 * code[1], [2] -> x,y delta
213 */
214 #endif
215 omkbd_input(sc, code & 0xff);
216 } while ((rr = getsiocsr(sio)) & RR_RXRDY);
217 }
218 if (rr && RR_TXRDY)
219 sio->sio_cmd = WR0_RSTPEND;
220 /* not capable of transmit, yet */
221 }
222
223 static void
224 omkbd_input(v, data)
225 void *v;
226 int data;
227 {
228 struct ws_softc *sc = v;
229 u_int type;
230 int key;
231
232 if (omkbd_decode(v, data, &type, &key))
233 wskbd_input(sc->sc_wskbddev, type, key);
234 }
235
236 static int
237 omkbd_decode(v, datain, type, dataout)
238 void *v;
239 int datain;
240 u_int *type;
241 int *dataout;
242 {
243 *type = (datain & 0x80) ? WSCONS_EVENT_KEY_UP : WSCONS_EVENT_KEY_DOWN;
244 *dataout = datain & 0x7f;
245 return 1;
246 }
247
248 #define KC(n) KS_KEYCODE(n)
249
250 static const keysym_t omkbd_keydesc_1[] = {
251 /* pos command normal shifted */
252 KC(0x9), KS_Tab,
253 KC(0xa), KS_Control_L,
254 KC(0xb), KS_Mode_switch, /* Kana */
255 KC(0xc), KS_Shift_R,
256 KC(0xd), KS_Shift_L,
257 KC(0xe), KS_Caps_Lock,
258 KC(0xf), KS_Meta_L, /* Zenmen */
259 KC(0x10), KS_Escape,
260 KC(0x11), KS_BackSpace,
261 KC(0x12), KS_Return,
262 KC(0x14), KS_space,
263 KC(0x15), KS_Delete,
264 KC(0x16), KS_Alt_L, /* Henkan */
265 KC(0x17), KS_Alt_R, /* Kakutei */
266 KC(0x18), KS_f11, /* Shokyo */
267 KC(0x19), KS_f12, /* Yobidashi */
268 KC(0x1a), KS_f13, /* Bunsetsu L */
269 KC(0x1b), KS_f14, /* Bunsetsu R */
270 KC(0x1c), KS_KP_Up,
271 KC(0x1d), KS_KP_Left,
272 KC(0x1e), KS_KP_Right,
273 KC(0x1f), KS_KP_Down,
274 /* KC(0x20), KS_f11, */
275 /* KC(0x21), KS_f12, */
276 KC(0x22), KS_1, KS_exclam,
277 KC(0x23), KS_2, KS_quotedbl,
278 KC(0x24), KS_3, KS_numbersign,
279 KC(0x25), KS_4, KS_dollar,
280 KC(0x26), KS_5, KS_percent,
281 KC(0x27), KS_6, KS_ampersand,
282 KC(0x28), KS_7, KS_apostrophe,
283 KC(0x29), KS_8, KS_parenleft,
284 KC(0x2a), KS_9, KS_parenright,
285 KC(0x2b), KS_0,
286 KC(0x2c), KS_minus, KS_equal,
287 KC(0x2d), KS_asciicircum, KS_asciitilde,
288 KC(0x2e), KS_backslash, KS_bar,
289 /* KC(0x30), KS_f13, */
290 /* KC(0x31), KS_f14, */
291 KC(0x32), KS_q,
292 KC(0x33), KS_w,
293 KC(0x34), KS_e,
294 KC(0x35), KS_r,
295 KC(0x36), KS_t,
296 KC(0x37), KS_y,
297 KC(0x38), KS_u,
298 KC(0x39), KS_i,
299 KC(0x3a), KS_o,
300 KC(0x3b), KS_p,
301 KC(0x3c), KS_at, KS_grave,
302 KC(0x3d), KS_bracketleft, KS_braceleft,
303 KC(0x42), KS_a,
304 KC(0x43), KS_s,
305 KC(0x44), KS_d,
306 KC(0x45), KS_f,
307 KC(0x46), KS_g,
308 KC(0x47), KS_h,
309 KC(0x48), KS_j,
310 KC(0x49), KS_k,
311 KC(0x4a), KS_l,
312 KC(0x4b), KS_semicolon, KS_plus,
313 KC(0x4c), KS_colon, KS_asterisk,
314 KC(0x4d), KS_bracketright, KS_braceright,
315 KC(0x52), KS_z,
316 KC(0x53), KS_x,
317 KC(0x54), KS_c,
318 KC(0x55), KS_v,
319 KC(0x56), KS_b,
320 KC(0x57), KS_n,
321 KC(0x58), KS_m,
322 KC(0x59), KS_comma, KS_less,
323 KC(0x5a), KS_period, KS_greater,
324 KC(0x5b), KS_slash, KS_question,
325 KC(0x5c), KS_underscore,
326 KC(0x60), KS_KP_Delete,
327 KC(0x61), KS_KP_Add,
328 KC(0x62), KS_KP_Subtract,
329 KC(0x63), KS_KP_7,
330 KC(0x64), KS_KP_8,
331 KC(0x65), KS_KP_9,
332 KC(0x66), KS_KP_4,
333 KC(0x67), KS_KP_5,
334 KC(0x68), KS_KP_6,
335 KC(0x69), KS_KP_1,
336 KC(0x6a), KS_KP_2,
337 KC(0x6b), KS_KP_3,
338 KC(0x6c), KS_KP_0,
339 KC(0x6d), KS_KP_Decimal,
340 KC(0x6e), KS_KP_Enter,
341 KC(0x72), KS_f1,
342 KC(0x73), KS_f2,
343 KC(0x74), KS_f3,
344 KC(0x75), KS_f4,
345 KC(0x76), KS_f5,
346 KC(0x77), KS_f6,
347 KC(0x78), KS_f7,
348 KC(0x79), KS_f8,
349 KC(0x7a), KS_f9,
350 KC(0x7b), KS_f10,
351 KC(0x7c), KS_KP_Multiply,
352 KC(0x7d), KS_KP_Divide,
353 KC(0x7e), KS_KP_Equal,
354 KC(0x7f), KS_KP_Separator,
355 };
356
357 #define SIZE(map) (sizeof(map)/sizeof(keysym_t))
358
359 struct wscons_keydesc omkbd_keydesctab[] = {
360 { KB_JP, 0, SIZE(omkbd_keydesc_1), omkbd_keydesc_1, },
361 { 0, 0, 0, 0 },
362 };
363
364 static void
365 ws_cngetc(v, type, data)
366 void *v;
367 u_int *type;
368 int *data;
369 {
370 int code;
371
372 do {
373 code = syscngetc((dev_t)1);
374 } while (!omkbd_decode(v, code, type, data));
375 }
376
377 static void
378 ws_cnpollc(v, on)
379 void *v;
380 int on;
381 {
382 }
383
384 /* EXPORT */ void
385 ws_cnattach()
386 {
387 static int voidfill;
388
389 wskbd_cnattach(&ws_consops, &voidfill, &omkbd_keymapdata);
390 }
391
392 static int
393 omkbd_enable(v, on)
394 void *v;
395 int on;
396 {
397 return 0;
398 }
399
400 static void
401 omkbd_set_leds(v, leds)
402 void *v;
403 int leds;
404 {
405 #if 0
406 syscnputc((dev_t)1, 0x10); /* kana LED on */
407 syscnputc((dev_t)1, 0x00); /* kana LED off */
408 syscnputc((dev_t)1, 0x11); /* caps LED off */
409 syscnputc((dev_t)1, 0x01); /* caps LED off */
410 #endif
411 }
412
413 static int
414 omkbd_ioctl(v, cmd, data, flag, p)
415 void *v;
416 u_long cmd;
417 caddr_t data;
418 int flag;
419 struct proc *p;
420 {
421 switch (cmd) {
422 case WSKBDIO_GTYPE:
423 *(int *)data = 0x19991005 /* XXX */;
424 return 0;
425 case WSKBDIO_SETLEDS:
426 case WSKBDIO_GETLEDS:
427 case WSKBDIO_COMPLEXBELL:
428 return 0;
429 }
430 return -1;
431 }
432
433 #if NWSMOUSE > 0
434
435 static int
436 omms_enable(v)
437 void *v;
438 {
439 syscnputc((dev_t)1, 0x60); /* enable 3 byte long mouse reporting */
440 return 0;
441 }
442
443 /*ARGUSED*/
444 static int
445 omms_ioctl(v, cmd, data, flag, p)
446 void *v;
447 u_long cmd;
448 caddr_t data;
449 int flag;
450 struct proc *p;
451 {
452 if (cmd == WSMOUSEIO_GTYPE) {
453 *(u_int *)data = 0x19991005; /* XXX */
454 return 0;
455 }
456 return ENOTTY;
457 }
458
459 static void
460 omms_disable(v)
461 void *v;
462 {
463 syscnputc((dev_t)1, 0x20); /* quiet mouse */
464 }
465 #endif
466