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