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