diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/ieee488/ibfoo.c | 144 | ||||
-rw-r--r-- | sys/dev/ieee488/pcii.c | 5 | ||||
-rw-r--r-- | sys/dev/ieee488/tnt4882.c | 71 | ||||
-rw-r--r-- | sys/dev/ieee488/tnt4882.h | 77 | ||||
-rw-r--r-- | sys/dev/ieee488/upd7210.c | 87 | ||||
-rw-r--r-- | sys/dev/ieee488/upd7210.h | 1 |
6 files changed, 304 insertions, 81 deletions
diff --git a/sys/dev/ieee488/ibfoo.c b/sys/dev/ieee488/ibfoo.c index 7458d8b..7ae9160 100644 --- a/sys/dev/ieee488/ibfoo.c +++ b/sys/dev/ieee488/ibfoo.c @@ -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 __unused) 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, struct ibfoo *ib) 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, int len) 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 *data, int len) 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 *data, int len) 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 oflags, int devtype, struct thread *td) 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 oflags, int devtype, struct thread *td) 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); diff --git a/sys/dev/ieee488/pcii.c b/sys/dev/ieee488/pcii.c index 7e92432..3c5699e 100644 --- a/sys/dev/ieee488/pcii.c +++ b/sys/dev/ieee488/pcii.c @@ -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); diff --git a/sys/dev/ieee488/tnt4882.c b/sys/dev/ieee488/tnt4882.c index a4222a6..4b69d0d 100644 --- a/sys/dev/ieee488/tnt4882.c +++ b/sys/dev/ieee488/tnt4882.c @@ -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); } diff --git a/sys/dev/ieee488/tnt4882.h b/sys/dev/ieee488/tnt4882.h new file mode 100644 index 0000000..221cfd9 --- /dev/null +++ b/sys/dev/ieee488/tnt4882.h @@ -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 +}; + diff --git a/sys/dev/ieee488/upd7210.c b/sys/dev/ieee488/upd7210.c index b245a65..ed6c64e 100644 --- a/sys/dev/ieee488/upd7210.c +++ b/sys/dev/ieee488/upd7210.c @@ -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 upd7210_wreg reg, u_int val) 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; - - if (u->rreg[ISR1] & 1) { + int have_data = 0; + + 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, int devtype, struct thread *td) 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 oflags, int devtype, struct thread *td) 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 *uio, int ioflag) 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); } diff --git a/sys/dev/ieee488/upd7210.h b/sys/dev/ieee488/upd7210.h index 9d619b7..88235dd 100644 --- a/sys/dev/ieee488/upd7210.h +++ b/sys/dev/ieee488/upd7210.h @@ -53,6 +53,7 @@ struct upd7210 { u_int reg_offset[8]; int dmachan; int unit; + int use_fifo; /* private stuff */ struct mtx mutex; |