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