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