Date: Mon, 1 Feb 2010 21:21:10 +0000 (UTC) From: Joerg Wunsch <joerg@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r203360 - head/sys/dev/ieee488 Message-ID: <201002012121.o11LLAag075889@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: joerg Date: Mon Feb 1 21:21:10 2010 New Revision: 203360 URL: http://svn.freebsd.org/changeset/base/203360 Log: GPIB overhaul, part #2: make the tnt4882 driver work with the newer TNT5004 IC. This involved a major rewrite of a number of things, as this chip no longer supports the NAT7210 legacy mode but requires the host to use the (more modern) FIFO mode. In theory, this also ought to work on the older TNT4882C chip. I'll probably add this as optional support (perhaps by a device.hints flag) later on. By now, FIFO mode is *only* activates iff a TNT5004 chip has been detected (where the old code didn't work at all), while everything else is supposed to use the old code. MFC after: 2 weeks Added: head/sys/dev/ieee488/tnt4882.h (contents, props changed) Modified: head/sys/dev/ieee488/ibfoo.c head/sys/dev/ieee488/pcii.c head/sys/dev/ieee488/tnt4882.c head/sys/dev/ieee488/upd7210.c head/sys/dev/ieee488/upd7210.h Modified: head/sys/dev/ieee488/ibfoo.c ============================================================================== --- head/sys/dev/ieee488/ibfoo.c Mon Feb 1 21:01:20 2010 (r203359) +++ head/sys/dev/ieee488/ibfoo.c Mon Feb 1 21:21:10 2010 (r203360) @@ -1,5 +1,6 @@ /*- * Copyright (c) 2005 Poul-Henning Kamp <phk@FreeBSD.org> + * Copyright (c) 2010 Joerg Wunsch <joerg@FreeBSD.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -40,6 +41,7 @@ __FBSDID("$FreeBSD$"); #include <sys/kernel.h> #include <sys/limits.h> #include <sys/module.h> +#include <sys/rman.h> #include <sys/bus.h> #include <sys/lock.h> #include <sys/mutex.h> @@ -53,6 +55,7 @@ __FBSDID("$FreeBSD$"); #define UPD7210_SW_DRIVER #include <dev/ieee488/upd7210.h> +#include <dev/ieee488/tnt4882.h> static MALLOC_DEFINE(M_IBFOO, "IBFOO", "IBFOO"); @@ -94,7 +97,10 @@ struct ibfoo { PIO_IDATA, PIO_ODATA, PIO_CMD, - DMA_IDATA + DMA_IDATA, + FIFO_IDATA, + FIFO_ODATA, + FIFO_CMD } mode; struct timeval deadline; @@ -170,7 +176,7 @@ ib_set_errno(struct ibarg *ap, int errno } static int -gpib_ib_irq(struct upd7210 *u, int intr __unused) +gpib_ib_irq(struct upd7210 *u, int isr_3) { struct ibfoo *ib; @@ -211,11 +217,53 @@ gpib_ib_irq(struct upd7210 *u, int intr if (!(u->rreg[ISR1] & IXR1_ENDRX)) return (0); break; + case FIFO_IDATA: + if (!(isr_3 & 0x15)) + return (0); + while (ib->buflen != 0 && (isr_3 & 0x04 /* NEF */) != 0) { + *ib->buf = bus_read_1(u->reg_res[0], fifob); + ib->buf++; + ib->buflen--; + isr_3 = bus_read_1(u->reg_res[0], isr3); + } + if ((isr_3 & 0x01) != 0 /* xfr done */ || + (u->rreg[ISR1] & IXR1_ENDRX) != 0 || + ib->buflen == 0) + break; + if (isr_3 & 0x10) + /* xfr stopped */ + bus_write_1(u->reg_res[0], cmdr, 0x04); /* GO */ + upd7210_wr(u, AUXMR, AUXMR_RFD); + return (1); + case FIFO_CMD: + case FIFO_ODATA: + if (!(isr_3 & 0x19)) + return (0); + if (ib->buflen == 0) + /* xfr DONE */ + break; + while (ib->buflen != 0 && (isr_3 & 0x08 /* NFF */) != 0) { + bus_write_1(u->reg_res[0], fifob, *ib->buf); + ib->buf++; + ib->buflen--; + isr_3 = bus_read_1(u->reg_res[0], isr3); + } + if (isr_3 & 0x10) + /* xfr stopped */ + bus_write_1(u->reg_res[0], cmdr, 0x04); /* GO */ + if (ib->buflen == 0) + /* no more NFF interrupts wanted */ + bus_write_1(u->reg_res[0], imr3, 0x11); /* STOP IE, DONE IE */ + return (1); default: return (0); } upd7210_wr(u, IMR1, 0); upd7210_wr(u, IMR2, 0); + if (u->use_fifo) { + bus_write_1(u->reg_res[0], imr3, 0x00); + bus_write_1(u->reg_res[0], cmdr, 0x22); /* soft RESET */ + } ib->mode = BUSY; wakeup(&ib->buflen); return (1); @@ -227,6 +275,7 @@ gpib_ib_timeout(void *arg) struct upd7210 *u; struct ibfoo *ib; struct timeval tv; + u_int isr_3; u = arg; ib = u->ibfoo; @@ -241,7 +290,11 @@ gpib_ib_timeout(void *arg) if (ib->mode > BUSY) { upd7210_rd(u, ISR1); upd7210_rd(u, ISR2); - gpib_ib_irq(u, 2); + if (u->use_fifo) + isr_3 = bus_read_1(u->reg_res[0], isr3); + else + isr_3 = 0; + gpib_ib_irq(u, isr_3); } if (ib->mode != IDLE && timevalisset(&ib->deadline)) { getmicrouptime(&tv); @@ -249,6 +302,10 @@ gpib_ib_timeout(void *arg) ib_had_timeout(ib->ap); upd7210_wr(u, IMR1, 0); upd7210_wr(u, IMR2, 0); + if (u->use_fifo) { + bus_write_1(u->reg_res[0], imr3, 0x00); + bus_write_1(u->reg_res[0], cmdr, 0x22); /* soft RESET */ + } ib->mode = BUSY; wakeup(&ib->buflen); } @@ -280,6 +337,8 @@ gpib_ib_wait_xfer(struct upd7210 *u, str ib->buf = NULL; upd7210_wr(u, IMR1, 0); upd7210_wr(u, IMR2, 0); + if (u->use_fifo) + bus_write_1(u->reg_res[0], imr3, 0x00); } static void @@ -335,15 +394,31 @@ pio_cmd(struct upd7210 *u, u_char *cmd, ib->wrh = NULL; } mtx_lock(&u->mutex); - ib->mode = PIO_CMD; ib->buf = cmd; ib->buflen = len; - upd7210_wr(u, IMR2, IXR2_CO); - - gpib_ib_irq(u, 1); + if (u->use_fifo) { + /* TNT5004 or TNT4882 in FIFO mode */ + ib->mode = FIFO_CMD; + upd7210_wr(u, AUXMR, 0x51); /* holdoff immediately */ + bus_write_1(u->reg_res[0], cmdr, 0x10); /* reset FIFO */ + bus_write_1(u->reg_res[0], cfg, 0x80); /* CMD, xfer OUT, 8-bit FIFO */ + bus_write_1(u->reg_res[0], imr3, 0x19); /* STOP IE, NFF IE, DONE IE */ + bus_write_1(u->reg_res[0], cnt0, -len); + bus_write_1(u->reg_res[0], cnt1, (-len) >> 8); + bus_write_1(u->reg_res[0], cnt2, (-len) >> 16); + bus_write_1(u->reg_res[0], cnt3, (-len) >> 24); + bus_write_1(u->reg_res[0], cmdr, 0x04); /* GO */ + } else { + ib->mode = PIO_CMD; + upd7210_wr(u, IMR2, IXR2_CO); + gpib_ib_irq(u, 0); + } gpib_ib_wait_xfer(u, ib); + if (u->use_fifo) + bus_write_1(u->reg_res[0], cmdr, 0x08); /* STOP */ + mtx_unlock(&u->mutex); return (len - ib->buflen); } @@ -358,13 +433,32 @@ pio_odata(struct upd7210 *u, u_char *dat if (len == 0) return (0); mtx_lock(&u->mutex); - ib->mode = PIO_ODATA; ib->buf = data; ib->buflen = len; - upd7210_wr(u, IMR1, IXR1_DO); + if (u->use_fifo) { + /* TNT5004 or TNT4882 in FIFO mode */ + ib->mode = FIFO_ODATA; + bus_write_1(u->reg_res[0], cmdr, 0x10); /* reset FIFO */ + if (ib->doeoi) + bus_write_1(u->reg_res[0], cfg, 0x08); /* CCEN */ + else + bus_write_1(u->reg_res[0], cfg, 0x00); /* xfer OUT, 8-bit FIFO */ + bus_write_1(u->reg_res[0], imr3, 0x19); /* STOP IE, NFF IE, DONE IE */ + bus_write_1(u->reg_res[0], cnt0, -len); + bus_write_1(u->reg_res[0], cnt1, (-len) >> 8); + bus_write_1(u->reg_res[0], cnt2, (-len) >> 16); + bus_write_1(u->reg_res[0], cnt3, (-len) >> 24); + bus_write_1(u->reg_res[0], cmdr, 0x04); /* GO */ + } else { + ib->mode = PIO_ODATA; + upd7210_wr(u, IMR1, IXR1_DO); + } gpib_ib_wait_xfer(u, ib); + if (u->use_fifo) + bus_write_1(u->reg_res[0], cmdr, 0x08); /* STOP */ + mtx_unlock(&u->mutex); return (len - ib->buflen); } @@ -377,13 +471,30 @@ pio_idata(struct upd7210 *u, u_char *dat ib = u->ibfoo; mtx_lock(&u->mutex); - ib->mode = PIO_IDATA; ib->buf = data; ib->buflen = len; - upd7210_wr(u, IMR1, IXR1_DI); + if (u->use_fifo) { + /* TNT5004 or TNT4882 in FIFO mode */ + ib->mode = FIFO_IDATA; + bus_write_1(u->reg_res[0], cmdr, 0x10); /* reset FIFO */ + bus_write_1(u->reg_res[0], cfg, 0x20); /* xfer IN, 8-bit FIFO */ + bus_write_1(u->reg_res[0], cnt0, -len); + bus_write_1(u->reg_res[0], cnt1, (-len) >> 8); + bus_write_1(u->reg_res[0], cnt2, (-len) >> 16); + bus_write_1(u->reg_res[0], cnt3, (-len) >> 24); + bus_write_1(u->reg_res[0], cmdr, 0x04); /* GO */ + upd7210_wr(u, AUXMR, AUXMR_RFD); + bus_write_1(u->reg_res[0], imr3, 0x15); /* STOP IE, NEF IE, DONE IE */ + } else { + ib->mode = PIO_IDATA; + upd7210_wr(u, IMR1, IXR1_DI); + } gpib_ib_wait_xfer(u, ib); + if (u->use_fifo) + bus_write_1(u->reg_res[0], cmdr, 0x08); /* STOP */ + mtx_unlock(&u->mutex); return (len - ib->buflen); } @@ -826,6 +937,12 @@ gpib_ib_open(struct cdev *dev, int oflag upd7210_wr(u, AUXMR, C_AUXB + 3); upd7210_wr(u, AUXMR, C_AUXE + 0); upd7210_wr(u, AUXMR, AUXMR_PON); + if (u->use_fifo) { + bus_write_1(u->reg_res[0], imr3, 0x00); + bus_write_1(u->reg_res[0], cmdr, 0x22); /* soft reset */ + bus_write_1(u->reg_res[0], cmdr, 0x03); /* set system + * controller bit */ + } upd7210_wr(u, AUXMR, AUXMR_CIFC); DELAY(100); upd7210_wr(u, AUXMR, AUXMR_SIFC); @@ -856,6 +973,11 @@ gpib_ib_close(struct cdev *dev, int ofla ibdebug = 0; upd7210_wr(u, IMR1, 0x00); upd7210_wr(u, IMR2, 0x00); + if (u->use_fifo) { + bus_write_1(u->reg_res[0], imr3, 0x00); + bus_write_1(u->reg_res[0], cmdr, 0x02); /* clear system + * controller bit */ + } upd7210_wr(u, AUXMR, AUXMR_CRST); DELAY(10000); mtx_unlock(&u->mutex); Modified: head/sys/dev/ieee488/pcii.c ============================================================================== --- head/sys/dev/ieee488/pcii.c Mon Feb 1 21:01:20 2010 (r203359) +++ head/sys/dev/ieee488/pcii.c Mon Feb 1 21:21:10 2010 (r203360) @@ -238,6 +238,7 @@ pcii_attach(device_t dev) sc->upd7210.reg_offset[rid] = 0; } sc->upd7210.irq_clear_res = sc->res[10]; + sc->upd7210.use_fifo = 0; if (sc->res[1] == NULL) sc->upd7210.dmachan = -1; @@ -245,7 +246,9 @@ pcii_attach(device_t dev) sc->upd7210.dmachan = rman_get_start(sc->res[1]); upd7210attach(&sc->upd7210); - return (error); + device_printf(dev, "attached gpib%d\n", sc->upd7210.unit); + + return (0); } DRIVER_MODULE(pcii, isa, pcii_driver, pcii_devclass, 0, 0); Modified: head/sys/dev/ieee488/tnt4882.c ============================================================================== --- head/sys/dev/ieee488/tnt4882.c Mon Feb 1 21:01:20 2010 (r203359) +++ head/sys/dev/ieee488/tnt4882.c Mon Feb 1 21:21:10 2010 (r203360) @@ -1,5 +1,6 @@ /*- * Copyright (c) 2005 Poul-Henning Kamp + * Copyright (c) 2010 Joerg Wunsch * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -46,6 +47,7 @@ #define UPD7210_HW_DRIVER 1 #include <dev/ieee488/upd7210.h> +#include <dev/ieee488/tnt4882.h> struct tnt_softc { int foo; @@ -62,55 +64,6 @@ static struct resource_spec tnt_res_spec { -1, 0 } }; -enum tnt4882reg { - dir = 0x00, - cdor = 0x00, - isr1 = 0x02, - imr1 = 0x02, - isr2 = 0x04, - imr2 = 0x04, - accwr = 0x05, - spsr = 0x06, - spmr = 0x06, - intr = 0x07, - adsr = 0x08, - admr = 0x08, - cnt2 = 0x09, - cptr = 0x0a, - auxmr = 0x0a, - tauxcr = 0x0a, /* 9914 mode register */ - cnt3 = 0x0b, - adr0 = 0x0c, - adr = 0x0c, - hssel = 0x0d, - adr1 = 0x0e, - eosr = 0x0e, - sts1 = 0x10, - cfg = 0x10, - dsr = 0x11, - sh_cnt = 0x11, - imr3 = 0x12, - hier = 0x13, - cnt0 = 0x14, - misc = 0x15, - cnt1 = 0x16, - csr = 0x17, - keyreg = 0x17, - fifob = 0x18, - fifoa = 0x19, - isr3 = 0x1a, - ccr = 0x1a, - sasr = 0x1b, - dcr = 0x1b, - sts2 = 0x1c, - cmdr = 0x1c, - isr0 = 0x1d, - imr0 = 0x1d, - timer = 0x1e, - bsr = 0x1f, - bcr = 0x1f -}; - struct tst { enum {RD, WT, xDELAY, END} action; @@ -276,6 +229,7 @@ tnt_attach(device_t dev) { struct tnt_softc *sc; int error, i; + uint8_t version; sc = device_get_softc(dev); @@ -286,7 +240,7 @@ tnt_attach(device_t dev) error = bus_setup_intr(dev, sc->res[2], INTR_TYPE_MISC | INTR_MPSAFE, NULL, upd7210intr, &sc->upd7210, &sc->intr_handler); - /* Necessary magic for MITE */ + /* IO Device Window Base Size Register (IODWBSR) */ bus_write_4(sc->res[0], 0xc0, rman_get_start(sc->res[1]) | 0x80); tst_exec(sc, tst_reset, "Reset"); @@ -298,6 +252,18 @@ tnt_attach(device_t dev) tst_exec(sc, tst_count0_1, "COUNT0:1"); tst_exec(sc, tst_reset, "Reset"); + version = bus_read_1(sc->res[1], csr); + version = (version >> 4) & 0x0f; + device_printf(dev, "Chip version 0x%02x (TNT%s)\n", + version, + version >= 4? "5004 or above": "4882"); + if (version >= 4) { + device_printf(dev, "Forcing FIFO mode\n"); + sc->upd7210.use_fifo = 1; + } else { + sc->upd7210.use_fifo = 0; + } + /* pass 7210 interrupts through */ bus_write_1(sc->res[1], imr3, 0x02); @@ -313,6 +279,11 @@ tnt_attach(device_t dev) sc->upd7210.irq_clear_res = NULL; upd7210attach(&sc->upd7210); + device_printf(dev, "attached gpib%d\n", sc->upd7210.unit); + + if (sc->upd7210.use_fifo) + bus_write_1(sc->res[0], hssel, 0x01); /* one-chip mode */ + return (0); } Added: head/sys/dev/ieee488/tnt4882.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/dev/ieee488/tnt4882.h Mon Feb 1 21:21:10 2010 (r203360) @@ -0,0 +1,77 @@ +/*- + * Copyright (c) 2010 Joerg Wunsch + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +enum tnt4882reg { + dir = 0x00, + cdor = 0x00, + isr1 = 0x02, + imr1 = 0x02, + isr2 = 0x04, + imr2 = 0x04, + accwr = 0x05, + spsr = 0x06, + spmr = 0x06, + intr = 0x07, + adsr = 0x08, + admr = 0x08, + cnt2 = 0x09, + cptr = 0x0a, + auxmr = 0x0a, + tauxcr = 0x0a, /* 9914 mode register */ + cnt3 = 0x0b, + adr0 = 0x0c, + adr = 0x0c, + hssel = 0x0d, + adr1 = 0x0e, + eosr = 0x0e, + sts1 = 0x10, + cfg = 0x10, + dsr = 0x11, + sh_cnt = 0x11, + imr3 = 0x12, + hier = 0x13, + cnt0 = 0x14, + misc = 0x15, + cnt1 = 0x16, + csr = 0x17, + keyreg = 0x17, + fifob = 0x18, + fifoa = 0x19, + isr3 = 0x1a, + ccr = 0x1a, + sasr = 0x1b, + dcr = 0x1b, + sts2 = 0x1c, + cmdr = 0x1c, + isr0 = 0x1d, + imr0 = 0x1d, + timer = 0x1e, + bsr = 0x1f, + bcr = 0x1f +}; + Modified: head/sys/dev/ieee488/upd7210.c ============================================================================== --- head/sys/dev/ieee488/upd7210.c Mon Feb 1 21:01:20 2010 (r203359) +++ head/sys/dev/ieee488/upd7210.c Mon Feb 1 21:21:10 2010 (r203360) @@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$"); #define UPD7210_HW_DRIVER #define UPD7210_SW_DRIVER #include <dev/ieee488/upd7210.h> +#include <dev/ieee488/tnt4882.h> static MALLOC_DEFINE(M_GPIB, "GPIB", "GPIB"); @@ -90,15 +91,20 @@ upd7210_wr(struct upd7210 *u, enum upd72 void upd7210intr(void *arg) { - u_int isr1, isr2; + u_int isr_1, isr_2, isr_3; struct upd7210 *u; u = arg; mtx_lock(&u->mutex); - isr1 = upd7210_rd(u, ISR1); - isr2 = upd7210_rd(u, ISR2); - if (isr1 != 0 || isr2 != 0) { - if (u->busy == 0 || u->irq == NULL || !u->irq(u, 1)) { + isr_1 = upd7210_rd(u, ISR1); + isr_2 = upd7210_rd(u, ISR2); + if (u->use_fifo) { + isr_3 = bus_read_1(u->reg_res[0], isr3); + } else { + isr_3 = 0; + } + if (isr_1 != 0 || isr_2 != 0 || isr_3 != 0) { + if (u->busy == 0 || u->irq == NULL || !u->irq(u, isr_3)) { #if 0 printf("upd7210intr [%02x %02x %02x", upd7210_rd(u, DIR), isr1, isr2); @@ -168,17 +174,38 @@ upd7210_goto_standby(struct upd7210 *u) /* Unaddressed Listen Only mode */ static int -gpib_l_irq(struct upd7210 *u, int intr __unused) +gpib_l_irq(struct upd7210 *u, int isr_3) { int i; + int have_data = 0; - if (u->rreg[ISR1] & 1) { + if (u->use_fifo) { + /* TNT5004 or TNT4882 in FIFO mode */ + if (isr_3 & 0x04) { + /* FIFO not empty */ + i = bus_read_1(u->reg_res[0], fifob); + have_data = 1; + bus_write_1(u->reg_res[0], cnt0, -1); + bus_write_1(u->reg_res[0], cnt1, (-1) >> 8); + bus_write_1(u->reg_res[0], cnt2, (-1) >> 16); + bus_write_1(u->reg_res[0], cnt3, (-1) >> 24); + bus_write_1(u->reg_res[0], cmdr, 0x04); /* GO */ + } + } else if (u->rreg[ISR1] & 1) { i = upd7210_rd(u, DIR); + have_data = 1; + } + + if (have_data) { u->buf[u->buf_wp++] = i; u->buf_wp &= (u->bufsize - 1); i = (u->buf_rp + u->bufsize - u->buf_wp) & (u->bufsize - 1); - if (i < 8) - upd7210_wr(u, IMR1, 0); + if (i < 8) { + if (u->use_fifo) + bus_write_1(u->reg_res[0], imr3, 0x00); + else + upd7210_wr(u, IMR1, 0); + } wakeup(u->buf); return (1); } @@ -206,15 +233,28 @@ gpib_l_open(struct cdev *dev, int oflags u->buf_wp = 0; u->buf_rp = 0; - upd7210_wr(u, AUXMR, AUXMR_CRST); + upd7210_wr(u, AUXMR, AUXMR_CRST); /* chip reset */ DELAY(10000); - upd7210_wr(u, AUXMR, C_ICR | 8); + upd7210_wr(u, AUXMR, C_ICR | 8); /* 8 MHz clock */ DELAY(1000); - upd7210_wr(u, ADR, 0x60); - upd7210_wr(u, ADR, 0xe0); - upd7210_wr(u, ADMR, 0x70); - upd7210_wr(u, AUXMR, AUXMR_PON); - upd7210_wr(u, IMR1, 0x01); + upd7210_wr(u, ADR, 0x60); /* ADR0: disable listener and talker 0 */ + upd7210_wr(u, ADR, 0xe0); /* ADR1: disable listener and talker 1 */ + upd7210_wr(u, ADMR, 0x70); /* listen-only (lon) */ + upd7210_wr(u, AUXMR, AUXMR_PON); /* immediate execute power-on (pon) */ + if (u->use_fifo) { + /* TNT5004 or TNT4882 in FIFO mode */ + bus_write_1(u->reg_res[0], cmdr, 0x10); /* reset FIFO */ + bus_write_1(u->reg_res[0], cfg, 0x20); /* xfer IN, 8-bit FIFO */ + bus_write_1(u->reg_res[0], cnt0, -1); + bus_write_1(u->reg_res[0], cnt1, (-1) >> 8); + bus_write_1(u->reg_res[0], cnt2, (-1) >> 16); + bus_write_1(u->reg_res[0], cnt3, (-1) >> 24); + bus_write_1(u->reg_res[0], cmdr, 0x04); /* GO */ + bus_write_1(u->reg_res[0], imr3, 0x04); /* NEF IE */ + } else { + /* µPD7210/NAT7210, or TNT4882 in non-FIFO mode */ + upd7210_wr(u, IMR1, 0x01); /* data in interrupt enable */ + } return (0); } @@ -227,6 +267,11 @@ gpib_l_close(struct cdev *dev, int oflag mtx_lock(&u->mutex); u->busy = 0; + if (u->use_fifo) { + /* TNT5004 or TNT4882 in FIFO mode */ + bus_write_1(u->reg_res[0], cmdr, 0x22); /* soft RESET */ + bus_write_1(u->reg_res[0], imr3, 0x00); + } upd7210_wr(u, AUXMR, AUXMR_CRST); DELAY(10000); upd7210_wr(u, IMR1, 0x00); @@ -271,8 +316,12 @@ gpib_l_read(struct cdev *dev, struct uio u->buf_rp += z; u->buf_rp &= (u->bufsize - 1); } - if (u->wreg[IMR1] == 0) - upd7210_wr(u, IMR1, 0x01); + if (u->use_fifo) { + bus_write_1(u->reg_res[0], imr3, 0x04); /* NFF IE */ + } else { + if (u->wreg[IMR1] == 0) + upd7210_wr(u, IMR1, 0x01); + } mtx_unlock(&u->mutex); return (error); } Modified: head/sys/dev/ieee488/upd7210.h ============================================================================== --- head/sys/dev/ieee488/upd7210.h Mon Feb 1 21:01:20 2010 (r203359) +++ head/sys/dev/ieee488/upd7210.h Mon Feb 1 21:21:10 2010 (r203360) @@ -53,6 +53,7 @@ struct upd7210 { u_int reg_offset[8]; int dmachan; int unit; + int use_fifo; /* private stuff */ struct mtx mutex;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201002012121.o11LLAag075889>