1 /* $NetBSD: cec.c,v 1.2 2004/09/14 20:20:46 drochner Exp $ */ 2 3 /*- 4 * Copyright (c) 2003 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Gregory McGarry. 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> 40 __KERNEL_RCSID(0, "$NetBSD: cec.c,v 1.2 2004/09/14 20:20:46 drochner Exp $"); 41 42 #include <sys/param.h> 43 #include <sys/systm.h> 44 #include <sys/callout.h> 45 #include <sys/conf.h> 46 #include <sys/device.h> 47 #include <sys/kernel.h> 48 49 #include <machine/bus.h> 50 51 #include <dev/isa/isavar.h> 52 #include <dev/isa/isadmavar.h> 53 54 #include <dev/gpib/gpibvar.h> 55 56 #include <dev/ic/nec7210reg.h> 57 58 #define DEBUG 59 60 #ifdef DEBUG 61 int cecdebug = 0x1f; 62 #define DPRINTF(flag, str) if (cecdebug & (flag)) printf str 63 #define DBG_FOLLOW 0x01 64 #define DBG_CONFIG 0x02 65 #define DBG_INTR 0x04 66 #define DBG_REPORTTIME 0x08 67 #define DBG_FAIL 0x10 68 #define DBG_WAIT 0x20 69 #else 70 #define DPRINTF(flag, str) /* nothing */ 71 #endif 72 73 #define CEC_IOSIZE 8 74 75 struct cec_softc { 76 struct device sc_dev; /* generic device glue */ 77 78 bus_space_tag_t sc_iot; 79 bus_space_handle_t sc_ioh; 80 isa_chipset_tag_t sc_ic; 81 int sc_drq; 82 void *sc_ih; 83 84 int sc_myaddr; /* my address */ 85 struct gpib_softc *sc_gpib; 86 87 volatile int sc_flags; 88 #define CECF_IO 0x1 89 #define CECF_PPOLL 0x4 90 #define CECF_READ 0x8 91 #define CECF_TIMO 0x10 92 #define CECF_USEDMA 0x20 93 int sc_ppoll_slave; /* XXX stash our ppoll address */ 94 struct callout sc_timeout_ch; 95 }; 96 97 int cecprobe(struct device *, struct cfdata *, void *); 98 void cecattach(struct device *, struct device *, void *); 99 100 CFATTACH_DECL(cec, sizeof(struct cec_softc), 101 cecprobe, cecattach, NULL, NULL); 102 103 void cecreset(void *); 104 int cecpptest(void *, int); 105 void cecppwatch(void *, int); 106 void cecppclear(void *); 107 void cecxfer(void *, int, int, void *, int, int, int); 108 void cecgo(void *v); 109 int cecintr(void *); 110 int cecsendcmds(void *, void *, int); 111 int cecsenddata(void *, void *, int); 112 int cecrecvdata(void *, void *, int); 113 int cecgts(void *); 114 int cectc(void *, int); 115 void cecifc(void *); 116 117 static int cecwait(struct cec_softc *, int, int); 118 static void cectimeout(void *v); 119 static int nec7210_setaddress(struct cec_softc *, int, int); 120 static void nec7210_init(struct cec_softc *); 121 static void nec7210_ifc(struct cec_softc *); 122 123 /* 124 * Our chipset structure. 125 */ 126 struct gpib_chipset_tag cec_ic = { 127 cecreset, 128 NULL, 129 NULL, 130 cecpptest, 131 cecppwatch, 132 cecppclear, 133 cecxfer, 134 cectc, 135 cecgts, 136 cecifc, 137 cecsendcmds, 138 cecsenddata, 139 cecrecvdata 140 }; 141 142 int cecwtimeout = 0x10000; 143 int cecdmathresh = 3; 144 145 int 146 cecprobe(struct device *parent, struct cfdata *match, void *aux) 147 { 148 struct isa_attach_args *ia = aux; 149 bus_space_tag_t iot = ia->ia_iot; 150 bus_space_handle_t ioh; 151 152 DPRINTF(DBG_CONFIG, ("cecprobe: called\n")); 153 154 if (ia->ia_nio < 1) 155 return (0); 156 if (ia->ia_nirq < 1) 157 return (0); 158 if (ia->ia_ndrq < 1) 159 return (0); 160 161 if (ISA_DIRECT_CONFIG(ia)) 162 return (0); 163 164 if (ia->ia_io[0].ir_addr == ISA_UNKNOWN_PORT) 165 return (0); 166 167 if (ia->ia_ndrq > 0 && ia->ia_drq[0].ir_drq == ISA_UNKNOWN_DRQ) 168 ia->ia_ndrq = 0; 169 170 if (bus_space_map(iot, ia->ia_io[0].ir_addr, CEC_IOSIZE, 0, &ioh)) 171 return (0); 172 173 /* XXX insert probe here */ 174 175 ia->ia_io[0].ir_size = CEC_IOSIZE; 176 ia->ia_niomem = 0; 177 178 bus_space_unmap(iot, ioh, CEC_IOSIZE); 179 180 return (1); 181 } 182 183 void 184 cecattach(struct device *parent, struct device *self, void *aux) 185 { 186 struct cec_softc *sc = (struct cec_softc *)self; 187 struct isa_attach_args *ia = aux; 188 struct gpibdev_attach_args ga; 189 bus_size_t maxsize; 190 191 printf("\n"); 192 193 DPRINTF(DBG_CONFIG, ("cecattach: called\n")); 194 195 sc->sc_iot = ia->ia_iot; 196 sc->sc_ic = ia->ia_ic; 197 198 if (bus_space_map(sc->sc_iot, ia->ia_io[0].ir_addr, CEC_IOSIZE, 199 0, &sc->sc_ioh) != 0) { 200 printf("%s: unable to map I/O space\n", sc->sc_dev.dv_xname); 201 return; 202 } 203 204 if (ia->ia_ndrq > 0) { 205 sc->sc_flags |= CECF_USEDMA; 206 sc->sc_drq = ia->ia_drq[0].ir_drq; 207 208 (void) isa_drq_alloc(sc->sc_ic, sc->sc_drq); 209 maxsize = isa_dmamaxsize(sc->sc_ic, sc->sc_drq); 210 if (isa_dmamap_create(sc->sc_ic, sc->sc_drq, 211 maxsize, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW)) { 212 printf("%s: unable to create map for drq %d\n", 213 sc->sc_dev.dv_xname, sc->sc_drq); 214 sc->sc_flags &= ~CECF_USEDMA; 215 } 216 } 217 218 sc->sc_myaddr = 15; /* XXX */ 219 220 cecreset(sc); 221 (void) nec7210_setaddress(sc, sc->sc_myaddr, -1); 222 223 sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq[0].ir_irq, 224 IST_EDGE, IPL_BIO, cecintr, sc); 225 if (sc->sc_ih == NULL) { 226 printf("%s: couldn't establish interrupt\n", 227 sc->sc_dev.dv_xname); 228 return; 229 } 230 231 callout_init(&sc->sc_timeout_ch); 232 233 /* attach MI GPIB bus */ 234 cec_ic.cookie = (void *)sc; 235 ga.ga_ic = &cec_ic; 236 ga.ga_address = sc->sc_myaddr; 237 sc->sc_gpib = 238 (struct gpib_softc *)config_found(self, &ga, gpibdevprint); 239 } 240 241 int 242 cecintr(void *v) 243 { 244 struct cec_softc *sc = v; 245 bus_space_tag_t iot = sc->sc_iot; 246 bus_space_handle_t ioh = sc->sc_ioh; 247 u_int8_t stat1, stat2; 248 249 stat1 = bus_space_read_1(iot, ioh, NEC7210_ISR1); 250 stat2 = bus_space_read_1(iot, ioh, NEC7210_ISR2); 251 252 DPRINTF(DBG_INTR, ("cecintr: sc=%p stat1=0x%x stat2=0x%x\n", 253 sc, stat1, stat2)); 254 255 if (sc->sc_flags & CECF_IO) { 256 257 if (sc->sc_flags & CECF_TIMO) 258 callout_stop(&sc->sc_timeout_ch); 259 260 bus_space_write_1(iot, ioh, NEC7210_IMR1, 0); 261 bus_space_write_1(iot, ioh, NEC7210_IMR2, 0); 262 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_TCA); 263 sc->sc_flags &= ~(CECF_IO | CECF_READ | CECF_TIMO); 264 if (sc->sc_flags & CECF_USEDMA) 265 isa_dmadone(sc->sc_ic, sc->sc_drq); 266 gpibintr(sc->sc_gpib); 267 268 } else if (sc->sc_flags & CECF_PPOLL) { 269 270 if (cecpptest(sc, sc->sc_ppoll_slave)) { 271 sc->sc_flags &= ~CECF_PPOLL; 272 bus_space_write_1(iot, ioh, NEC7210_IMR2, 0); 273 gpibintr(sc->sc_gpib); 274 } 275 276 } 277 return (1); 278 } 279 280 void 281 cecreset(void *v) 282 { 283 struct cec_softc *sc = v; 284 u_int8_t cmd; 285 286 DPRINTF(DBG_FOLLOW, ("cecreset: sc=%p\n", sc)); 287 288 nec7210_init(sc); 289 nec7210_ifc(sc); 290 /* we're now the system controller */ 291 292 /* XXX should be pushed higher */ 293 294 /* universal device clear */ 295 cmd = GPIBCMD_DCL; 296 (void) cecsendcmds(sc, &cmd, 1); 297 /* delay for devices to clear */ 298 DELAY(100000); 299 } 300 301 int 302 cecsendcmds(void *v, void *ptr, int origcnt) 303 { 304 struct cec_softc *sc = v; 305 bus_space_tag_t iot = sc->sc_iot; 306 bus_space_handle_t ioh = sc->sc_ioh; 307 int cnt = origcnt; 308 u_int8_t *addr = ptr; 309 310 DPRINTF(DBG_FOLLOW, ("cecsendcmds: sc=%p, ptr=%p cnt=%d\n", 311 sc, ptr, origcnt)); 312 313 while (--cnt >= 0) { 314 bus_space_write_1(iot, ioh, NEC7210_CDOR, *addr++); 315 if (cecwait(sc, 0, ISR2_CO)) 316 return (origcnt - cnt - 1); 317 } 318 return (origcnt); 319 } 320 321 322 int 323 cecrecvdata(void *v, void *ptr, int origcnt) 324 { 325 struct cec_softc *sc = v; 326 bus_space_tag_t iot = sc->sc_iot; 327 bus_space_handle_t ioh = sc->sc_ioh; 328 int cnt = origcnt; 329 u_int8_t *addr = ptr; 330 331 DPRINTF(DBG_FOLLOW, ("cecrecvdata: sc=%p, ptr=%p cnt=%d\n", 332 sc, ptr, origcnt)); 333 334 /* XXX holdoff on end */ 335 bus_space_write_1(sc->sc_iot, sc->sc_ioh, NEC7210_AUXMR, AUXCMD_RHDF); 336 337 if (cnt) { 338 while (--cnt >= 0) { 339 if (cecwait(sc, ISR1_DI, 0)) 340 return (origcnt - cnt - 1); 341 *addr++ = bus_space_read_1(iot, ioh, NEC7210_DIR); 342 } 343 } 344 return (origcnt); 345 } 346 347 int 348 cecsenddata(void *v, void *ptr, int origcnt) 349 { 350 struct cec_softc *sc = v; 351 bus_space_tag_t iot = sc->sc_iot; 352 bus_space_handle_t ioh = sc->sc_ioh; 353 int cnt = origcnt; 354 u_int8_t *addr = ptr; 355 356 DPRINTF(DBG_FOLLOW, ("cecdsenddata: sc=%p, ptr=%p cnt=%d\n", 357 sc, ptr, origcnt)); 358 359 if (cnt) { 360 while (--cnt > 0) { 361 bus_space_write_1(iot, ioh, NEC7210_CDOR, *addr++); 362 if (cecwait(sc, ISR1_DO, 0)) 363 return (origcnt - cnt - 1); 364 } 365 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_SEOI); 366 bus_space_write_1(iot, ioh, NEC7210_CDOR, *addr); 367 (void) cecwait(sc, ISR1_DO, 0); 368 } 369 return (origcnt); 370 } 371 372 int 373 cectc(void *v, int sync) 374 { 375 struct cec_softc *sc = v; 376 bus_space_tag_t iot = sc->sc_iot; 377 bus_space_handle_t ioh = sc->sc_ioh; 378 u_int8_t adsr; 379 int timo = cecwtimeout; 380 381 DPRINTF(DBG_FOLLOW, ("cectc: sc=%p, sync=%d\n", sc, sync)); 382 383 adsr = bus_space_read_1(iot, ioh, NEC7210_ADSR); 384 #if 0 385 if ((adsr & (ADSR_CIC | ADSR_NATN)) == ADSR_CIC) { 386 DPRINTF(0xff, ("cectc: already CIC\n")); 387 return (0); 388 } 389 #endif 390 391 if (sync) { 392 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_RHDF); 393 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_TCS); 394 } else { 395 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_TCA); 396 } 397 398 /* wait until ATN is asserted */ 399 for (;;) { 400 adsr = bus_space_read_1(iot, ioh, NEC7210_ADSR); 401 if (--timo == 0) { 402 DPRINTF(DBG_REPORTTIME, ("cectc: timeout\n")); 403 return (1); 404 } 405 if ((adsr & ADSR_NATN) == 0) 406 break; 407 DELAY(1); 408 } 409 410 return (0); 411 } 412 413 int 414 cecgts(void *v) 415 { 416 struct cec_softc *sc = v; 417 bus_space_tag_t iot = sc->sc_iot; 418 bus_space_handle_t ioh = sc->sc_ioh; 419 u_int8_t adsr; 420 int timo = cecwtimeout; 421 422 DPRINTF(DBG_FOLLOW, ("cecgts: sc=%p\n", sc)); 423 424 adsr = bus_space_read_1(iot, ioh, NEC7210_ADSR); 425 #if 0 426 if ((adsr & (ADSR_CIC | ADSR_NATN)) == ADSR_NATN) { 427 DPRINTF(0xff, ("cecgts: already standby\n")); 428 return (0); 429 } 430 #endif 431 432 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_GTS); 433 434 /* wait unit ATN is released */ 435 for (;;) { 436 adsr = bus_space_read_1(iot, ioh, NEC7210_ADSR); 437 if (--timo == 0) { 438 DPRINTF(DBG_REPORTTIME, ("cecgts: timeout\n")); 439 return (1); 440 } 441 if ((adsr & ADSR_NATN) == ADSR_NATN) 442 break; 443 DELAY(1); 444 } 445 446 return (0); 447 } 448 449 int 450 cecpptest(void *v, int slave) 451 { 452 struct cec_softc *sc = v; 453 bus_space_tag_t iot = sc->sc_iot; 454 bus_space_handle_t ioh = sc->sc_ioh; 455 int ppoll; 456 457 DPRINTF(DBG_FOLLOW, ("cecpptest: sc=%p slave=%d\n", sc, slave)); 458 459 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_EPP); 460 DELAY(25); 461 ppoll = bus_space_read_1(iot, ioh, NEC7210_CPTR); 462 DPRINTF(0xff, ("cecpptest: ppoll=%x\n", ppoll)); 463 return ((ppoll & (0x80 >> slave)) != 0); 464 } 465 466 void 467 cecppwatch(void *v, int slave) 468 { 469 struct cec_softc *sc = v; 470 bus_space_tag_t iot = sc->sc_iot; 471 bus_space_handle_t ioh = sc->sc_ioh; 472 473 DPRINTF(DBG_FOLLOW, ("cecppwatch: sc=%p\n", sc)); 474 475 sc->sc_flags |= CECF_PPOLL; 476 sc->sc_ppoll_slave = slave; 477 bus_space_write_1(iot, ioh, NEC7210_IMR2, IMR2_CO); 478 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_EPP); 479 } 480 481 void 482 cecppclear(void *v) 483 { 484 struct cec_softc *sc = v; 485 486 DPRINTF(DBG_FOLLOW, ("cecppclear: sc=%p\n", sc)); 487 488 sc->sc_flags &= ~CECF_PPOLL; 489 bus_space_write_1(sc->sc_iot, sc->sc_ioh, NEC7210_IMR2, 0); 490 } 491 492 void 493 cecxfer(void *v, int slave, int sec, void *buf, int count, int dir, int timo) 494 { 495 struct cec_softc *sc = v; 496 bus_space_tag_t iot = sc->sc_iot; 497 bus_space_handle_t ioh = sc->sc_ioh; 498 499 DPRINTF(DBG_FOLLOW, 500 ("cecxfer: slave=%d sec=%d buf=%p count=%d dir=%x timo=%d\n", 501 slave, sec, buf, count, dir, timo)); 502 503 sc->sc_flags |= CECF_IO; 504 if (dir == GPIB_READ) 505 sc->sc_flags |= CECF_READ; 506 if (timo) { 507 sc->sc_flags |= CECF_TIMO; 508 callout_reset(&sc->sc_timeout_ch, 5*hz, cectimeout, sc); 509 } 510 511 if (sc->sc_flags & CECF_READ) { 512 DPRINTF(DBG_FOLLOW, ("cecxfer: DMA read request\n")); 513 if ((sc->sc_flags & CECF_USEDMA) != 0) { 514 isa_dmastart(sc->sc_ic, sc->sc_drq, buf, count, NULL, 515 DMAMODE_READ | DMAMODE_DEMAND, BUS_DMA_NOWAIT); 516 bus_space_write_1(iot, ioh, NEC7210_IMR2, IMR2_DMAI); 517 bus_space_write_1(iot, ioh, NEC7210_IMR1, IMR1_END); 518 // XXX (void) cecrecv(sc, slave, sec, NULL, 0); 519 (void) gpibrecv(&cec_ic, slave, sec, NULL, 0); 520 } else { 521 /* XXX this doesn't work */ 522 DPRINTF(DBG_FOLLOW, ("cecxfer: polling instead\n")); 523 bus_space_write_1(iot, ioh, NEC7210_IMR1, IMR1_END); 524 // XXX (void) cecrecv(sc, slave, sec, buf, count); 525 (void) gpibrecv(&cec_ic, slave, sec, buf, count); 526 bus_space_write_1(iot, ioh, NEC7210_IMR2, IMR2_CO); 527 } 528 } else { 529 DPRINTF(DBG_FOLLOW, ("cecxfer: DMA write request\n")); 530 bus_space_write_1(iot, ioh, NEC7210_IMR2, 0); 531 if (count < cecdmathresh || 532 (sc->sc_flags & CECF_USEDMA) == 0) { 533 DPRINTF(DBG_FOLLOW, ("cecxfer: polling instead\n")); 534 // XXX (void) cecsend(sc, slave, sec, buf, count); 535 (void) gpibsend(&cec_ic, slave, sec, buf, count); 536 bus_space_write_1(iot, ioh, NEC7210_IMR2, IMR2_CO); 537 return; 538 } 539 /* we send the last byte with EOI set */ 540 isa_dmastart(sc->sc_ic, sc->sc_drq, buf, count-1, NULL, 541 DMAMODE_WRITE | DMAMODE_DEMAND, BUS_DMA_NOWAIT); 542 bus_space_write_1(iot, ioh, NEC7210_IMR2, IMR2_DMAO); 543 // XXX (void) cecsend(sc, slave, sec, NULL, 0); 544 (void) gpibsend(&cec_ic, slave, sec, NULL, 0); 545 while (!isa_dmafinished(sc->sc_ic, sc->sc_drq)) 546 DELAY(1); 547 (void) cecwait(sc, ISR1_DO, 0); 548 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_SEOI); 549 bus_space_write_1(iot, ioh, NEC7210_CDOR, *(char *)buf+count); 550 /* generate interrupt */ 551 bus_space_write_1(iot, ioh, NEC7210_IMR1, IMR1_DO); 552 } 553 } 554 555 void 556 cecifc(void *v) 557 { 558 struct cec_softc *sc = v; 559 560 nec7210_ifc(sc); 561 } 562 563 static int 564 nec7210_setaddress(struct cec_softc *sc, int pri, int sec) 565 { 566 bus_space_tag_t iot = sc->sc_iot; 567 bus_space_handle_t ioh = sc->sc_ioh; 568 u_int8_t admr; 569 570 /* assign our primary address */ 571 bus_space_write_1(iot, ioh, NEC7210_ADDR, (pri & ADDR_MASK)); 572 573 admr = ADMR_TRM0 | ADMR_TRM1; 574 575 /* assign our secondary address */ 576 if (sec != -1) { 577 bus_space_write_1(iot, ioh, NEC7210_ADDR, 578 (ADDR_ARS | (sec & ADDR_MASK))); 579 admr |= ADMR_ADM1; 580 } else { 581 /* disable secondary address */ 582 bus_space_write_1(iot, ioh, NEC7210_ADDR, 583 (ADDR_ARS | ADDR_DT | ADDR_DL)); 584 admr |= ADMR_ADM0; 585 } 586 bus_space_write_1(iot, ioh, NEC7210_ADMR, admr); 587 588 return (0); 589 } 590 591 static void 592 nec7210_init(struct cec_softc *sc) 593 { 594 bus_space_tag_t iot = sc->sc_iot; 595 bus_space_handle_t ioh = sc->sc_ioh; 596 597 /* reset chip */ 598 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_CRST); 599 600 /* clear interrupts */ 601 bus_space_read_1(iot, ioh, NEC7210_CPTR); 602 bus_space_read_1(iot, ioh, NEC7210_ISR1); 603 bus_space_read_1(iot, ioh, NEC7210_ISR2); 604 605 /* initialise interrupts */ 606 bus_space_write_1(iot, ioh, NEC7210_IMR1, 0); 607 bus_space_write_1(iot, ioh, NEC7210_IMR2, 0); 608 bus_space_write_1(iot, ioh, NEC7210_SPMR, 0); 609 bus_space_write_1(iot, ioh, NEC7210_EOSR, 0); 610 611 /* set internal clock to 8MHz */ 612 bus_space_write_1(iot, ioh, NEC7210_AUXMR, (AUXMR_ICR | 0x8)); 613 /* parallel poll unconfigure */ 614 bus_space_write_1(iot, ioh, NEC7210_AUXMR, (AUXMR_PPOLL | PPOLL_PPU)); 615 616 /* assign our address */ 617 bus_space_write_1(iot, ioh, NEC7210_ADDR, 0); 618 /* disable secondary address */ 619 bus_space_write_1(iot, ioh, NEC7210_ADDR, 620 (ADDR_ARS | ADDR_DT | ADDR_DL)); 621 622 /* setup transceivers */ 623 bus_space_write_1(iot, ioh, NEC7210_ADMR, 624 (ADMR_ADM0 | ADMR_TRM0 | ADMR_TRM1)); 625 bus_space_write_1(iot, ioh, NEC7210_AUXMR, 626 (AUXMR_REGA | AUX_A_HSNORM)); 627 628 /* set INT pin to active high */ 629 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXMR_REGB); 630 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXMR_REGE); 631 632 /* holdoff on end condition */ 633 bus_space_write_1(iot, ioh, NEC7210_AUXMR, (AUXMR_REGA | AUX_A_HLDE)); 634 635 /* reconnect to bus */ 636 bus_space_write_1(iot, ioh, NEC7210_AUXMR, (AUXMR_CMD | AUXCMD_IEPON)); 637 } 638 639 /* 640 * Place all devices on the bus into quiescient state ready for 641 * remote programming. 642 * Obviously, we're the system controller upon exit. 643 */ 644 void 645 nec7210_ifc(struct cec_softc *sc) 646 { 647 bus_space_tag_t iot = sc->sc_iot; 648 bus_space_handle_t ioh = sc->sc_ioh; 649 650 /*XXX*/ bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_TCA); 651 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_CREN); 652 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_SIFC); 653 /* wait for devices to enter quiescient state */ 654 DELAY(100); 655 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_CIFC); 656 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_SREN); 657 } 658 659 static int 660 cecwait(struct cec_softc *sc, int x1, int x2) 661 { 662 int timo = cecwtimeout; 663 bus_space_tag_t iot = sc->sc_iot; 664 bus_space_handle_t ioh = sc->sc_ioh; 665 u_int8_t stat1, stat2; 666 667 DPRINTF(DBG_WAIT, ("cecwait: sc=%p, x1=0x%x x2=0x%x\n", sc, x1, x2)); 668 669 for (;;) { 670 stat1 = bus_space_read_1(iot, ioh, NEC7210_ISR1); 671 stat2 = bus_space_read_1(iot, ioh, NEC7210_ISR2); 672 #if 0 673 if ((stat1 & ISR1_ERR)) { 674 DPRINTF(DBG_WAIT, ("cecwait: got ERR\n")); 675 return (1); 676 } 677 #endif 678 if (--timo == 0) { 679 DPRINTF(DBG_REPORTTIME, 680 ("cecwait: timeout x1=0x%x x2=0x%x\n", x1, x2)); 681 return (1); 682 } 683 if ((stat1 & x1) || (stat2 & x2)) 684 break; 685 DELAY(1); 686 } 687 return (0); 688 } 689 690 static void 691 cectimeout(void *v) 692 { 693 struct cec_softc *sc = v; 694 bus_space_tag_t iot = sc->sc_iot; 695 bus_space_handle_t ioh = sc->sc_ioh; 696 int s; 697 698 DPRINTF(DBG_FOLLOW, ("cectimeout: sc=%p\n", sc)); 699 700 s = splbio(); 701 if (sc->sc_flags & CECF_IO) { 702 bus_space_write_1(iot, ioh, NEC7210_IMR1, 0); 703 bus_space_write_2(iot, ioh, NEC7210_IMR2, 0); 704 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_TCA); 705 sc->sc_flags &= ~(CECF_IO | CECF_READ | CECF_TIMO); 706 isa_dmaabort(sc->sc_ic, sc->sc_drq); 707 printf("%s: %s timeout\n", sc->sc_dev.dv_xname, 708 sc->sc_flags & CECF_READ ? "read" : "write"); 709 gpibintr(sc->sc_gpib); 710 } 711 splx(s); 712 } 713