1 /* $OpenBSD: lunaws.c,v 1.12 2016/06/05 20:02:36 bru Exp $ */ 2 /* $NetBSD: lunaws.c,v 1.6 2002/03/17 19:40:42 atatat Exp $ */ 3 4 /*- 5 * Copyright (c) 2000 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Tohru Nishimura. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #include <sys/param.h> 34 #include <sys/systm.h> 35 #include <sys/conf.h> 36 #include <sys/device.h> 37 38 #include <dev/wscons/wsconsio.h> 39 #include <dev/wscons/wskbdvar.h> 40 #include <dev/wscons/wsksymdef.h> 41 #include <dev/wscons/wsksymvar.h> 42 #ifdef WSDISPLAY_COMPAT_RAWKBD 43 #include <dev/wscons/wskbdraw.h> 44 #endif 45 #include "wsmouse.h" 46 #if NWSMOUSE > 0 47 #include <dev/wscons/wsmousevar.h> 48 #endif 49 50 #include <luna88k/dev/omkbdmap.h> 51 #include <luna88k/dev/sioreg.h> 52 #include <luna88k/dev/siovar.h> 53 54 static const u_int8_t ch1_regs[6] = { 55 WR0_RSTINT, /* Reset E/S Interrupt */ 56 WR1_RXALLS, /* Rx per char, No Tx */ 57 0, /* */ 58 WR3_RX8BIT | WR3_RXENBL, /* Rx */ 59 WR4_BAUD96 | WR4_STOP1 | WR4_NPARITY, /* Tx/Rx */ 60 WR5_TX8BIT | WR5_TXENBL, /* Tx */ 61 }; 62 63 struct ws_softc { 64 struct device sc_dv; 65 struct sioreg *sc_ctl; 66 u_int8_t sc_wr[6]; 67 struct device *sc_wskbddev; 68 #if NWSMOUSE > 0 69 struct device *sc_wsmousedev; 70 int sc_msreport; 71 int buttons, dx, dy; 72 #endif 73 74 #ifdef WSDISPLAY_COMPAT_RAWKBD 75 int sc_rawkbd; 76 #endif 77 }; 78 79 void omkbd_input(void *, int); 80 void omkbd_decode(void *, int, u_int *, int *); 81 int omkbd_enable(void *, int); 82 void omkbd_set_leds(void *, int); 83 int omkbd_ioctl(void *, u_long, caddr_t, int, struct proc *); 84 85 const struct wskbd_mapdata omkbd_keymapdata = { 86 omkbd_keydesctab, 87 #ifdef OMKBD_LAYOUT 88 OMKBD_LAYOUT, 89 #else 90 KB_JP | KB_DEFAULT, 91 #endif 92 }; 93 94 const struct wskbd_accessops omkbd_accessops = { 95 omkbd_enable, 96 omkbd_set_leds, 97 omkbd_ioctl, 98 }; 99 100 void ws_cnattach(void); 101 void ws_cngetc(void *, u_int *, int *); 102 void ws_cnpollc(void *, int); 103 const struct wskbd_consops ws_consops = { 104 ws_cngetc, 105 ws_cnpollc, 106 NULL /* bell */ 107 }; 108 109 #if NWSMOUSE > 0 110 int omms_enable(void *); 111 int omms_ioctl(void *, u_long, caddr_t, int, struct proc *); 112 void omms_disable(void *); 113 114 const struct wsmouse_accessops omms_accessops = { 115 omms_enable, 116 omms_ioctl, 117 omms_disable, 118 }; 119 #endif 120 121 void wsintr(int); 122 123 int wsmatch(struct device *, void *, void *); 124 void wsattach(struct device *, struct device *, void *); 125 int ws_submatch_kbd(struct device *, void *, void *); 126 #if NWSMOUSE > 0 127 int ws_submatch_mouse(struct device *, void *, void *); 128 #endif 129 130 const struct cfattach ws_ca = { 131 sizeof(struct ws_softc), wsmatch, wsattach 132 }; 133 134 struct cfdriver ws_cd = { 135 NULL, "ws", DV_TTY 136 }; 137 138 extern int syscngetc(dev_t); 139 extern void syscnputc(dev_t, int); 140 141 int 142 wsmatch(struct device *parent, void *match, void *aux) 143 { 144 struct sio_attach_args *args = aux; 145 146 if (args->channel != 1) 147 return 0; 148 return 1; 149 } 150 151 void 152 wsattach(struct device *parent, struct device *self, void *aux) 153 { 154 struct ws_softc *sc = (struct ws_softc *)self; 155 struct sio_softc *scp = (struct sio_softc *)parent; 156 struct sio_attach_args *args = aux; 157 struct wskbddev_attach_args a; 158 159 sc->sc_ctl = (struct sioreg *)scp->scp_ctl + 1; 160 bcopy(ch1_regs, sc->sc_wr, sizeof(ch1_regs)); 161 scp->scp_intr[1] = wsintr; 162 163 setsioreg(sc->sc_ctl, WR0, sc->sc_wr[WR0]); 164 setsioreg(sc->sc_ctl, WR4, sc->sc_wr[WR4]); 165 setsioreg(sc->sc_ctl, WR3, sc->sc_wr[WR3]); 166 setsioreg(sc->sc_ctl, WR5, sc->sc_wr[WR5]); 167 setsioreg(sc->sc_ctl, WR0, sc->sc_wr[WR0]); 168 setsioreg(sc->sc_ctl, WR1, sc->sc_wr[WR1]); 169 170 syscnputc((dev_t)1, 0x20); /* keep quiet mouse */ 171 172 printf("\n"); 173 174 a.console = (args->hwflags == 1); 175 a.keymap = &omkbd_keymapdata; 176 a.accessops = &omkbd_accessops; 177 a.accesscookie = (void *)sc; 178 sc->sc_wskbddev = config_found_sm(self, &a, wskbddevprint, 179 ws_submatch_kbd); 180 181 #if NWSMOUSE > 0 182 { 183 struct wsmousedev_attach_args b; 184 b.accessops = &omms_accessops; 185 b.accesscookie = (void *)sc; 186 sc->sc_wsmousedev = config_found_sm(self, &b, wsmousedevprint, 187 ws_submatch_mouse); 188 sc->sc_msreport = 0; 189 } 190 #endif 191 } 192 193 int 194 ws_submatch_kbd(struct device *parent, void *match, void *aux) 195 { 196 struct cfdata *cf = match; 197 198 if (strcmp(cf->cf_driver->cd_name, "wskbd")) 199 return (0); 200 return ((*cf->cf_attach->ca_match)(parent, cf, aux)); 201 } 202 203 #if NWSMOUSE > 0 204 205 int 206 ws_submatch_mouse(struct device *parent, void *match, void *aux) 207 { 208 struct cfdata *cf = match; 209 210 if (strcmp(cf->cf_driver->cd_name, "wsmouse")) 211 return (0); 212 return ((*cf->cf_attach->ca_match)(parent, cf, aux)); 213 } 214 215 #endif 216 217 /*ARGSUSED*/ 218 void 219 wsintr(int chan) 220 { 221 struct ws_softc *sc = ws_cd.cd_devs[0]; 222 struct sioreg *sio = sc->sc_ctl; 223 u_int code; 224 int rr; 225 226 rr = getsiocsr(sio); 227 if (rr & RR_RXRDY) { 228 do { 229 code = sio->sio_data; 230 if (rr & (RR_FRAMING | RR_OVERRUN | RR_PARITY)) { 231 sio->sio_cmd = WR0_ERRRST; 232 continue; 233 } 234 #if NWSMOUSE > 0 235 /* 236 * if (code >= 0x80 && code <= 0x87), then 237 * it's the first byte of 3 byte long mouse report 238 * code[0] & 07 -> LMR button condition 239 * code[1], [2] -> x,y delta 240 * otherwise, key press or release event. 241 */ 242 if (sc->sc_msreport == 0) { 243 if (code < 0x80 || code > 0x87) { 244 omkbd_input(sc, code); 245 continue; 246 } 247 code = (code & 07) ^ 07; 248 /* LMR->RML: wsevent counts 0 for leftmost */ 249 sc->buttons = (code & 02); 250 if (code & 01) 251 sc->buttons |= 04; 252 if (code & 04) 253 sc->buttons |= 01; 254 sc->sc_msreport = 1; 255 } 256 else if (sc->sc_msreport == 1) { 257 sc->dx = (signed char)code; 258 sc->sc_msreport = 2; 259 } 260 else if (sc->sc_msreport == 2) { 261 sc->dy = (signed char)code; 262 if (sc->sc_wsmousedev != NULL) 263 WSMOUSE_INPUT(sc->sc_wsmousedev, 264 sc->buttons, sc->dx, sc->dy, 0, 0); 265 sc->sc_msreport = 0; 266 } 267 #else 268 omkbd_input(sc, code); 269 #endif 270 } while ((rr = getsiocsr(sio)) & RR_RXRDY); 271 } 272 if (rr & RR_TXRDY) 273 sio->sio_cmd = WR0_RSTPEND; 274 /* not capable of transmit, yet */ 275 } 276 277 void 278 omkbd_input(void *v, int data) 279 { 280 struct ws_softc *sc = v; 281 u_int type; 282 int key; 283 284 omkbd_decode(v, data, &type, &key); 285 286 #if WSDISPLAY_COMPAT_RAWKBD 287 if (sc->sc_rawkbd) { 288 u_char cbuf[2]; 289 int c, j = 0; 290 291 c = omkbd_raw[key]; 292 if (c != RAWKEY_Null) { 293 /* fake extended scancode if necessary */ 294 if (c & 0x80) 295 cbuf[j++] = 0xe0; 296 cbuf[j] = c & 0x7f; 297 if (type == WSCONS_EVENT_KEY_UP) 298 cbuf[j] |= 0x80; 299 j++; 300 301 wskbd_rawinput(sc->sc_wskbddev, cbuf, j); 302 } 303 } else 304 #endif 305 { 306 if (sc->sc_wskbddev != NULL) 307 wskbd_input(sc->sc_wskbddev, type, key); 308 } 309 } 310 311 void 312 omkbd_decode(void *v, int datain, u_int *type, int *dataout) 313 { 314 *type = (datain & 0x80) ? WSCONS_EVENT_KEY_UP : WSCONS_EVENT_KEY_DOWN; 315 *dataout = datain & 0x7f; 316 } 317 318 void 319 ws_cngetc(void *v, u_int *type, int *data) 320 { 321 int code; 322 323 code = syscngetc((dev_t)1); 324 omkbd_decode(v, code, type, data); 325 } 326 327 void 328 ws_cnpollc(void *v, int on) 329 { 330 } 331 332 /* EXPORT */ void 333 ws_cnattach() 334 { 335 static int voidfill; 336 337 /* XXX need CH.B initialization XXX */ 338 339 wskbd_cnattach(&ws_consops, &voidfill, &omkbd_keymapdata); 340 } 341 342 int 343 omkbd_enable(void *v, int on) 344 { 345 return 0; 346 } 347 348 void 349 omkbd_set_leds(void *v, int leds) 350 { 351 #if 0 352 syscnputc((dev_t)1, 0x10); /* kana LED on */ 353 syscnputc((dev_t)1, 0x00); /* kana LED off */ 354 syscnputc((dev_t)1, 0x11); /* caps LED on */ 355 syscnputc((dev_t)1, 0x01); /* caps LED off */ 356 #endif 357 } 358 359 int 360 omkbd_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p) 361 { 362 #if WSDISPLAY_COMPAT_RAWKBD 363 struct ws_softc *sc = v; 364 #endif 365 366 switch (cmd) { 367 case WSKBDIO_GTYPE: 368 *(int *)data = WSKBD_TYPE_LUNA; 369 return 0; 370 case WSKBDIO_SETLEDS: 371 case WSKBDIO_GETLEDS: 372 case WSKBDIO_COMPLEXBELL: /* XXX capable of complex bell */ 373 return -1; 374 #if WSDISPLAY_COMPAT_RAWKBD 375 case WSKBDIO_SETMODE: 376 sc->sc_rawkbd = *(int *)data == WSKBD_RAW; 377 return 0; 378 case WSKBDIO_GETMODE: 379 *(int *)data = sc->sc_rawkbd; 380 return 0; 381 #endif 382 } 383 return -1; 384 } 385 386 #if NWSMOUSE > 0 387 388 int 389 omms_enable(void *v) 390 { 391 struct ws_softc *sc = v; 392 393 syscnputc((dev_t)1, 0x60); /* enable 3 byte long mouse reporting */ 394 sc->sc_msreport = 0; 395 return 0; 396 } 397 398 /*ARGUSED*/ 399 int 400 omms_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p) 401 { 402 #if 0 403 struct ws_softc *sc = v; 404 #endif 405 406 switch (cmd) { 407 case WSMOUSEIO_GTYPE: 408 *(u_int *)data = WSMOUSE_TYPE_LUNA; 409 return 0; 410 } 411 412 return -1; 413 } 414 415 void 416 omms_disable(void *v) 417 { 418 struct ws_softc *sc = v; 419 420 syscnputc((dev_t)1, 0x20); /* quiet mouse */ 421 sc->sc_msreport = 0; 422 } 423 #endif 424