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