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