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