Home | History | Annotate | Line # | Download | only in isa
cec.c revision 1.14
      1 /*	$NetBSD: cec.c,v 1.14 2016/07/11 11:31:50 msaitoh 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.14 2016/07/11 11:31:50 msaitoh 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 }
    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