summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/ieee488/ibfoo.c144
-rw-r--r--sys/dev/ieee488/pcii.c5
-rw-r--r--sys/dev/ieee488/tnt4882.c71
-rw-r--r--sys/dev/ieee488/tnt4882.h77
-rw-r--r--sys/dev/ieee488/upd7210.c87
-rw-r--r--sys/dev/ieee488/upd7210.h1
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;
OpenPOWER on IntegriCloud