1 /* $NetBSD: lunaws.c,v 1.19 2009/03/18 17:06:45 cegger Exp $ */
4 * Copyright (c) 2000 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
34 __KERNEL_RCSID(0, "$NetBSD: lunaws.c,v 1.19 2009/03/18 17:06:45 cegger Exp $");
38 #include <sys/param.h>
39 #include <sys/systm.h>
41 #include <sys/device.h>
43 #include <dev/wscons/wsconsio.h>
44 #include <dev/wscons/wskbdvar.h>
45 #include <dev/wscons/wsksymdef.h>
46 #include <dev/wscons/wsksymvar.h>
47 #include <dev/wscons/wsmousevar.h>
49 #include <luna68k/dev/sioreg.h>
50 #include <luna68k/dev/siovar.h>
52 static const u_int8_t ch1_regs
[6] = {
53 WR0_RSTINT
, /* Reset E/S Interrupt */
54 WR1_RXALLS
, /* Rx per char, No Tx */
56 WR3_RX8BIT
| WR3_RXENBL
, /* Rx */
57 WR4_BAUD96
| WR4_STOP1
| WR4_NPARITY
, /* Tx/Rx */
58 WR5_TX8BIT
| WR5_TXENBL
, /* Tx */
63 struct sioreg
*sc_ctl
;
65 struct device
*sc_wskbddev
;
67 struct device
*sc_wsmousedev
;
73 static void omkbd_input(void *, int);
74 static int omkbd_decode(void *, int, u_int
*, int *);
75 static int omkbd_enable(void *, int);
76 static void omkbd_set_leds(void *, int);
77 static int omkbd_ioctl(void *, u_long
, void *, int, struct lwp
*);
79 struct wscons_keydesc omkbd_keydesctab
[];
81 static const struct wskbd_mapdata omkbd_keymapdata
= {
85 static const struct wskbd_accessops omkbd_accessops
= {
91 void ws_cnattach(void);
92 static void ws_cngetc(void *, u_int
*, int *);
93 static void ws_cnpollc(void *, int);
94 static const struct wskbd_consops ws_consops
= {
100 static int omms_enable(void *);
101 static int omms_ioctl(void *, u_long
, void *, int, struct lwp
*);
102 static void omms_disable(void *);
104 static const struct wsmouse_accessops omms_accessops
= {
111 static void wsintr(int);
113 static int wsmatch(struct device
*, struct cfdata
*, void *);
114 static void wsattach(struct device
*, struct device
*, void *);
116 CFATTACH_DECL(ws
, sizeof(struct ws_softc
),
117 wsmatch
, wsattach
, NULL
, NULL
);
118 extern struct cfdriver ws_cd
;
120 extern int syscngetc(dev_t
);
121 extern void syscnputc(dev_t
, int);
124 wsmatch(struct device
*parent
, struct cfdata
*match
, void *aux
)
126 struct sio_attach_args
*args
= aux
;
128 if (args
->channel
!= 1)
134 wsattach(struct device
*parent
, struct device
*self
, void *aux
)
136 struct ws_softc
*sc
= (struct ws_softc
*)self
;
137 struct sio_softc
*scp
= (struct sio_softc
*)parent
;
138 struct sio_attach_args
*args
= aux
;
139 struct wskbddev_attach_args a
;
141 sc
->sc_ctl
= (struct sioreg
*)scp
->scp_ctl
+ 1;
142 memcpy(sc
->sc_wr
, ch1_regs
, sizeof(ch1_regs
));
143 scp
->scp_intr
[1] = wsintr
;
145 setsioreg(sc
->sc_ctl
, WR0
, sc
->sc_wr
[WR0
]);
146 setsioreg(sc
->sc_ctl
, WR4
, sc
->sc_wr
[WR4
]);
147 setsioreg(sc
->sc_ctl
, WR3
, sc
->sc_wr
[WR3
]);
148 setsioreg(sc
->sc_ctl
, WR5
, sc
->sc_wr
[WR5
]);
149 setsioreg(sc
->sc_ctl
, WR0
, sc
->sc_wr
[WR0
]);
150 setsioreg(sc
->sc_ctl
, WR1
, sc
->sc_wr
[WR1
]);
152 syscnputc((dev_t
)1, 0x20); /* keep quiet mouse */
156 a
.console
= (args
->hwflags
== 1);
157 a
.keymap
= &omkbd_keymapdata
;
158 a
.accessops
= &omkbd_accessops
;
159 a
.accesscookie
= (void *)sc
;
160 sc
->sc_wskbddev
= config_found_ia(self
, "wskbddev", &a
,
165 struct wsmousedev_attach_args b
;
166 b
.accessops
= &omms_accessops
;
167 b
.accesscookie
= (void *)sc
;
168 sc
->sc_wsmousedev
= config_found_ia(self
, "wsmousedev", &b
,
179 struct ws_softc
*sc
= device_lookup_private(&ws_cd
, 0);
180 struct sioreg
*sio
= sc
->sc_ctl
;
187 code
= sio
->sio_data
;
188 if (rr
& (RR_FRAMING
| RR_OVERRUN
| RR_PARITY
)) {
189 sio
->sio_cmd
= WR0_ERRRST
;
194 * if (code >= 0x80 && code <= 0x87), then
195 * it's the first byte of 3 byte long mouse report
196 * code[0] & 07 -> LMR button condition
197 * code[1], [2] -> x,y delta
198 * otherwise, key press or release event.
200 if (sc
->sc_msreport
== 0) {
201 if (code
< 0x80 || code
> 0x87) {
202 omkbd_input(sc
, code
);
205 code
= (code
& 07) ^ 07;
206 /* LMR->RML: wsevent counts 0 for leftmost */
207 sc
->buttons
= (code
& 02);
214 else if (sc
->sc_msreport
== 1) {
215 sc
->dx
= (signed char)code
;
218 else if (sc
->sc_msreport
== 2) {
219 sc
->dy
= (signed char)code
;
220 wsmouse_input(sc
->sc_wsmousedev
,
222 sc
->dx
, sc
->dy
, 0, 0,
223 WSMOUSE_INPUT_DELTA
);
228 omkbd_input(sc
, code
);
230 } while ((rr
= getsiocsr(sio
)) & RR_RXRDY
);
233 sio
->sio_cmd
= WR0_RSTPEND
;
234 /* not capable of transmit, yet */
238 omkbd_input(void *v
, int data
)
240 struct ws_softc
*sc
= v
;
244 if (omkbd_decode(v
, data
, &type
, &key
))
245 wskbd_input(sc
->sc_wskbddev
, type
, key
);
249 omkbd_decode(void *v
, int datain
, u_int
*type
, int *dataout
)
251 *type
= (datain
& 0x80) ? WSCONS_EVENT_KEY_UP
: WSCONS_EVENT_KEY_DOWN
;
252 *dataout
= datain
& 0x7f;
256 #define KC(n) KS_KEYCODE(n)
258 static const keysym_t omkbd_keydesc_1
[] = {
259 /* pos command normal shifted */
261 KC(0xa), KS_Control_L
,
262 KC(0xb), KS_Mode_switch
, /* Kana */
265 KC(0xe), KS_Caps_Lock
,
266 KC(0xf), KS_Meta_L
, /* Zenmen */
268 KC(0x11), KS_BackSpace
,
272 KC(0x16), KS_Alt_L
, /* Henkan */
273 KC(0x17), KS_Alt_R
, /* Kakutei */
274 KC(0x18), KS_f11
, /* Shokyo */
275 KC(0x19), KS_f12
, /* Yobidashi */
276 KC(0x1a), KS_f13
, /* Bunsetsu L */
277 KC(0x1b), KS_f14
, /* Bunsetsu R */
279 KC(0x1d), KS_KP_Left
,
280 KC(0x1e), KS_KP_Right
,
281 KC(0x1f), KS_KP_Down
,
282 /* KC(0x20), KS_f11, */
283 /* KC(0x21), KS_f12, */
284 KC(0x22), KS_1
, KS_exclam
,
285 KC(0x23), KS_2
, KS_quotedbl
,
286 KC(0x24), KS_3
, KS_numbersign
,
287 KC(0x25), KS_4
, KS_dollar
,
288 KC(0x26), KS_5
, KS_percent
,
289 KC(0x27), KS_6
, KS_ampersand
,
290 KC(0x28), KS_7
, KS_apostrophe
,
291 KC(0x29), KS_8
, KS_parenleft
,
292 KC(0x2a), KS_9
, KS_parenright
,
294 KC(0x2c), KS_minus
, KS_equal
,
295 KC(0x2d), KS_asciicircum
, KS_asciitilde
,
296 KC(0x2e), KS_backslash
, KS_bar
,
297 /* KC(0x30), KS_f13, */
298 /* KC(0x31), KS_f14, */
309 KC(0x3c), KS_at
, KS_grave
,
310 KC(0x3d), KS_bracketleft
, KS_braceleft
,
320 KC(0x4b), KS_semicolon
, KS_plus
,
321 KC(0x4c), KS_colon
, KS_asterisk
,
322 KC(0x4d), KS_bracketright
, KS_braceright
,
330 KC(0x59), KS_comma
, KS_less
,
331 KC(0x5a), KS_period
, KS_greater
,
332 KC(0x5b), KS_slash
, KS_question
,
333 KC(0x5c), KS_underscore
,
334 KC(0x60), KS_KP_Delete
,
336 KC(0x62), KS_KP_Subtract
,
347 KC(0x6d), KS_KP_Decimal
,
348 KC(0x6e), KS_KP_Enter
,
359 KC(0x7c), KS_KP_Multiply
,
360 KC(0x7d), KS_KP_Divide
,
361 KC(0x7e), KS_KP_Equal
,
362 KC(0x7f), KS_KP_Separator
,
365 #define SIZE(map) (sizeof(map)/sizeof(keysym_t))
367 struct wscons_keydesc omkbd_keydesctab
[] = {
368 { KB_JP
, 0, SIZE(omkbd_keydesc_1
), omkbd_keydesc_1
, },
373 ws_cngetc(void *v
, u_int
*type
, int *data
)
378 code
= syscngetc((dev_t
)1);
379 } while (!omkbd_decode(v
, code
, type
, data
));
383 ws_cnpollc(void *v
, int on
)
392 /* XXX need CH.B initialization XXX */
394 wskbd_cnattach(&ws_consops
, &voidfill
, &omkbd_keymapdata
);
398 omkbd_enable(void *v
, int on
)
404 omkbd_set_leds(void *v
, int leds
)
407 syscnputc((dev_t
)1, 0x10); /* kana LED on */
408 syscnputc((dev_t
)1, 0x00); /* kana LED off */
409 syscnputc((dev_t
)1, 0x11); /* caps LED on */
410 syscnputc((dev_t
)1, 0x01); /* caps LED off */
415 omkbd_ioctl(void *v
, u_long cmd
, void *data
, int flag
, struct lwp
*l
)
419 *(int *)data
= 0x19991005 /* XXX */;
421 case WSKBDIO_SETLEDS
:
422 case WSKBDIO_GETLEDS
:
423 case WSKBDIO_COMPLEXBELL
: /* XXX capable of complex bell */
434 struct ws_softc
*sc
= v
;
436 syscnputc((dev_t
)1, 0x60); /* enable 3 byte long mouse reporting */
443 omms_ioctl(void *v
, u_long cmd
, void *data
, int flag
, struct lwp
*l
)
445 if (cmd
== WSMOUSEIO_GTYPE
) {
446 *(u_int
*)data
= 0x19991005; /* XXX */
453 omms_disable(void *v
)
455 struct ws_softc
*sc
= v
;
457 syscnputc((dev_t
)1, 0x20); /* quiet mouse */