1 /* $NetBSD: dz_ibus.c,v 1.3 2005/12/11 12:18:36 christos Exp $ */ 2 3 /*- 4 * Copyright (c) 2002, 2003 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Andrew Doran. 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 /* 40 * Copyright (c) 1998 Ludd, University of Lule}, Sweden. 41 * All rights reserved. 42 * 43 * Redistribution and use in source and binary forms, with or without 44 * modification, are permitted provided that the following conditions 45 * are met: 46 * 1. Redistributions of source code must retain the above copyright 47 * notice, this list of conditions and the following disclaimer. 48 * 2. Redistributions in binary form must reproduce the above copyright 49 * notice, this list of conditions and the following disclaimer in the 50 * documentation and/or other materials provided with the distribution. 51 * 3. All advertising materials mentioning features or use of this software 52 * must display the following acknowledgement: 53 * This product includes software developed at Ludd, University of 54 * Lule}, Sweden and its contributors. 55 * 4. The name of the author may not be used to endorse or promote products 56 * derived from this software without specific prior written permission 57 * 58 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 59 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 60 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 61 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 62 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 63 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 64 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 65 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 66 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 67 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 68 */ 69 70 #include <sys/cdefs.h> 71 __KERNEL_RCSID(0, "$NetBSD: dz_ibus.c,v 1.3 2005/12/11 12:18:36 christos Exp $"); 72 73 #include "dzkbd.h" 74 #include "dzms.h" 75 76 #include <sys/param.h> 77 #include <sys/proc.h> 78 #include <sys/systm.h> 79 #include <sys/ioctl.h> 80 #include <sys/tty.h> 81 #include <sys/file.h> 82 #include <sys/conf.h> 83 #include <sys/device.h> 84 #include <sys/reboot.h> 85 86 #include <machine/bus.h> 87 88 #include <dev/cons.h> 89 90 #include <dev/tc/tcvar.h> /* tc_addr_t */ 91 92 #include <dev/dec/dzreg.h> 93 #include <dev/dec/dzvar.h> 94 #include <dev/dec/dzkbdvar.h> 95 96 #include <pmax/ibus/ibusvar.h> 97 #include <pmax/pmax/pmaxtype.h> 98 #include <pmax/pmax/cons.h> 99 100 #define DZ_LINE_KBD 0 101 #define DZ_LINE_MOUSE 1 102 #define DZ_LINE_CONSOLE 2 103 #define DZ_LINE_AUX 3 104 105 int dz_ibus_match(struct device *, struct cfdata *, void *); 106 void dz_ibus_attach(struct device *, struct device *, void *); 107 int dz_ibus_intr(void *); 108 void dz_ibus_cnsetup(paddr_t); 109 int dz_ibus_cngetc(dev_t); 110 void dz_ibus_cnputc(dev_t, int); 111 void dz_ibus_cnpollc(dev_t, int); 112 int dz_ibus_getmajor(void); 113 int dz_ibus_print(void *, const char *); 114 115 int dzgetc(struct dz_linestate *); 116 void dzputc(struct dz_linestate *, int); 117 118 CFATTACH_DECL(dz_ibus, sizeof(struct dz_softc), 119 dz_ibus_match, dz_ibus_attach, NULL, NULL); 120 121 struct consdev dz_ibus_consdev = { 122 NULL, NULL, dz_ibus_cngetc, dz_ibus_cnputc, 123 dz_ibus_cnpollc, NULL, NULL, NULL, NODEV, CN_NORMAL, 124 }; 125 126 struct dzregs { 127 uint16_t csr; /* 00 Csr: control/status */ 128 uint16_t p0[3]; 129 130 uint16_t rbuf; /* 08 Rbuf/Lpr: receive buffer/line param */ 131 uint16_t p1[3]; 132 133 uint16_t tcr; /* 10 Tcr: transmit console */ 134 uint16_t p2[3]; 135 136 uint16_t tdr; /* 18 Msr/Tdr: modem status reg/xmit data */ 137 uint16_t p3[3]; 138 } volatile *dzcn; 139 140 int dz_ibus_iscn; 141 int dz_ibus_consln = -1; 142 143 int 144 dz_ibus_match(struct device *parent, struct cfdata *cf, void *aux) 145 { 146 struct ibus_attach_args *iba; 147 148 iba = aux; 149 150 if (strcmp(iba->ia_name, "dc") != 0 && 151 strcmp(iba->ia_name, "mdc") != 0 && 152 strcmp(iba->ia_name, "dc7085") != 0) 153 return (0); 154 155 if (badaddr((caddr_t)iba->ia_addr, 2)) 156 return (0); 157 158 return (1); 159 } 160 161 void 162 dz_ibus_attach(struct device *parent, struct device *self, void *aux) 163 { 164 struct ibus_attach_args *iba; 165 struct dz_softc *sc; 166 volatile struct dzregs *dz; 167 struct dzkm_attach_args daa; 168 int i; 169 170 iba = aux; 171 sc = (struct dz_softc *)self; 172 173 DELAY(100000); 174 175 /* 176 * XXX - This is evil and ugly, but... due to the nature of how 177 * bus_space_* works on pmax it will do for the time being. 178 */ 179 sc->sc_ioh = (bus_space_handle_t)MIPS_PHYS_TO_KSEG1(iba->ia_addr); 180 181 sc->sc_dr.dr_csr = 0; 182 sc->sc_dr.dr_rbuf = 8; 183 sc->sc_dr.dr_dtr = 17; 184 sc->sc_dr.dr_break = 25; 185 sc->sc_dr.dr_tbuf = 24; 186 sc->sc_dr.dr_tcr = 16; 187 sc->sc_dr.dr_dcd = 25; 188 sc->sc_dr.dr_ring = 24; 189 190 sc->sc_dr.dr_firstreg = 0; 191 sc->sc_dr.dr_winsize = sizeof(struct dzregs); 192 193 sc->sc_type = DZ_DZV; 194 195 dz = (volatile struct dzregs *)sc->sc_ioh; 196 i = dz->tcr; 197 dz->csr = DZ_CSR_MSE | DZ_CSR_TXIE; 198 dz->tcr = 0; 199 wbflush(); 200 DELAY(1000); 201 dz->tcr = 1; 202 wbflush(); 203 DELAY(100000); 204 dz->tcr = i; 205 wbflush(); 206 207 sc->sc_dsr = 0x0f; /* XXX check if VS has modem ctrl bits */ 208 209 printf(": DC-7085, 4 lines"); 210 ibus_intr_establish(parent, (void *)iba->ia_cookie, IPL_TTY, 211 dz_ibus_intr, sc); 212 dzattach(sc, NULL, dz_ibus_consln); 213 DELAY(10000); 214 215 if (systype == DS_PMAX || systype == DS_3MAX) { 216 #if NDZKBD > 0 217 if (!dz_ibus_iscn) 218 dz->rbuf = DZ_LPR_RX_ENABLE | (DZ_LPR_B4800 << 8) | 219 DZ_LPR_8_BIT_CHAR | DZ_LINE_KBD; 220 daa.daa_line = DZ_LINE_KBD; 221 daa.daa_flags = (dz_ibus_iscn ? 0 : DZKBD_CONSOLE); 222 config_found(self, &daa, dz_ibus_print); 223 #endif 224 #if NDZMS > 0 225 dz->rbuf = DZ_LPR_RX_ENABLE | (DZ_LPR_B4800 << 8) | 226 DZ_LPR_8_BIT_CHAR | DZ_LPR_PARENB | DZ_LPR_OPAR | 227 DZ_LINE_MOUSE; 228 daa.daa_line = DZ_LINE_MOUSE; 229 daa.daa_flags = 0; 230 config_found(self, &daa, dz_ibus_print); 231 #endif 232 } 233 } 234 235 int 236 dz_ibus_getmajor(void) 237 { 238 extern const struct cdevsw dz_cdevsw; 239 static int cache = -1; 240 241 if (cache != -1) 242 return (cache); 243 244 return (cache = cdevsw_lookup_major(&dz_cdevsw)); 245 } 246 247 int 248 dz_ibus_intr(void *cookie) 249 { 250 struct dz_softc *sc; 251 volatile struct dzregs *dzr; 252 unsigned csr; 253 254 sc = cookie; 255 dzr = (volatile struct dzregs *)sc->sc_ioh; 256 257 while (((csr = dzr->csr) & (DZ_CSR_RX_DONE | DZ_CSR_TX_READY)) != 0) { 258 if ((csr & DZ_CSR_RX_DONE) != 0) 259 dzrint(sc); 260 if ((csr & DZ_CSR_TX_READY) != 0) 261 dzxint(sc); 262 } 263 264 return (0); 265 } 266 267 void 268 dz_ibus_cnsetup(paddr_t addr) 269 { 270 271 dzcn = (void *)MIPS_PHYS_TO_KSEG1(addr); 272 } 273 274 void 275 dz_ibus_cnattach(int line) 276 { 277 278 switch (line) { 279 case 0: 280 line = DZ_LINE_KBD; 281 break; 282 case 4: 283 line = DZ_LINE_CONSOLE; 284 break; 285 default: 286 line = DZ_LINE_AUX; 287 break; 288 } 289 290 dz_ibus_iscn = 1; 291 dz_ibus_consln = line; 292 293 /* Disable scanning until init is done. */ 294 dzcn->csr = 0; 295 wbflush(); 296 297 /* Turn on transmitter for the console. */ 298 dzcn->tcr = (1 << line); 299 wbflush(); 300 301 /* Turn scanning back on. */ 302 dzcn->csr = 0x20; 303 wbflush(); 304 305 /* 306 * Point the console at the DZ-11. 307 */ 308 cn_tab = &dz_ibus_consdev; 309 cn_tab->cn_pri = CN_REMOTE; 310 cn_tab->cn_dev = makedev(dz_ibus_getmajor(), line); 311 } 312 313 int 314 dz_ibus_cngetc(dev_t dev) 315 { 316 int c, line, s; 317 uint16_t rbuf; 318 319 c = 0; 320 line = minor(dev); 321 s = spltty(); 322 323 do { 324 while ((dzcn->csr & DZ_CSR_RX_DONE) == 0) 325 DELAY(10); 326 rbuf = dzcn->rbuf; 327 if (((rbuf >> 8) & 3) != line) 328 continue; 329 c = rbuf & 0x7f; 330 } while (c == 17 || c == 19); /* ignore XON/XOFF */ 331 332 splx(s); 333 if (c == 13) 334 c = 10; 335 return (c); 336 } 337 338 void 339 dz_ibus_cnputc(dev_t dev, int ch) 340 { 341 int timeout, s; 342 uint16_t tcr; 343 344 s = spltty(); 345 346 /* Don't hang the machine! */ 347 timeout = 1 << 15; 348 349 /* Remember which lines to scan */ 350 tcr = dzcn->tcr; 351 dzcn->tcr = (1 << minor(dev)); 352 wbflush(); 353 354 /* Wait until ready */ 355 while ((dzcn->csr & 0x8000) == 0) 356 if (--timeout < 0) 357 break; 358 359 /* Put the character */ 360 dzcn->tdr = ch; 361 timeout = 1 << 15; 362 wbflush(); 363 364 /* Wait until ready */ 365 while ((dzcn->csr & 0x8000) == 0) 366 if (--timeout < 0) 367 break; 368 369 dzcn->tcr = tcr; 370 wbflush(); 371 splx(s); 372 } 373 374 void 375 dz_ibus_cnpollc(dev_t dev, int pollflag) 376 { 377 378 } 379 380 #if NDZKBD > 0 || NDZMS > 0 381 int 382 dz_ibus_print(void *aux, const char *pnp) 383 { 384 struct dzkm_attach_args *daa; 385 386 daa = aux; 387 if (pnp != NULL) 388 printf("lkkbd/vsms at %s", pnp); 389 printf(" line %d", daa->daa_line); 390 return (UNCONF); 391 } 392 393 int 394 dzgetc(struct dz_linestate *ls) 395 { 396 volatile struct dzregs *dzr; 397 int line, s; 398 uint16_t rbuf; 399 400 if (ls == NULL) { 401 /* 402 * dzkbd is the only thing that should put us here. 403 */ 404 line = DZ_LINE_KBD; 405 dzr = dzcn; 406 } else { 407 line = ls->dz_line; 408 dzr = (volatile struct dzregs *)ls->dz_sc->sc_ioh; 409 } 410 411 s = spltty(); 412 for (;;) { 413 while ((dzr->csr & DZ_CSR_RX_DONE) == 0) 414 DELAY(10); 415 rbuf = dzr->rbuf; 416 if (((rbuf >> 8) & 3) == line) 417 return (rbuf & 0xff); 418 } 419 splx(s); 420 } 421 422 void 423 dzputc(struct dz_linestate *ls, int ch) 424 { 425 volatile struct dzregs *dzr; 426 int line; 427 uint16_t tcr; 428 int s; 429 430 /* 431 * If the dz has already been attached, the MI driver will do the 432 * transmitting: 433 */ 434 if (ls != NULL && ls->dz_sc != NULL) { 435 line = ls->dz_line; 436 dzr = (volatile struct dzregs *)ls->dz_sc->sc_ioh; 437 s = spltty(); 438 putc(ch, &ls->dz_tty->t_outq); 439 tcr = dzr->tcr; 440 if ((tcr & (1 << line)) == 0) { 441 dzr->tcr = tcr | (1 << line); 442 wbflush(); 443 } 444 dzxint(ls->dz_sc); 445 splx(s); 446 return; 447 } 448 449 /* Use dzcnputc to do the transmitting. */ 450 dz_ibus_cnputc(makedev(dz_ibus_getmajor(), DZ_LINE_KBD), ch); 451 } 452 #endif /* NDZKBD > 0 || NDZMS > 0 */ 453