2 * Copyright (c) 2005 Poul-Henning Kamp
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/param.h>
30 #include <sys/kernel.h>
31 #include <sys/systm.h>
32 #include <sys/module.h>
34 #include <dev/pci/pcireg.h>
35 #include <dev/pci/pcivar.h>
37 #include <machine/bus.h>
38 #include <machine/resource.h>
39 #include <machine/stdarg.h>
45 #include <machine/pmap.h>
47 #define UPD7210_HW_DRIVER 1
48 #include <dev/ieee488/upd7210.h>
52 struct upd7210 upd7210;
54 struct resource *res[3];
58 static struct resource_spec tnt_res_spec[] = {
59 { SYS_RES_MEMORY, PCIR_BAR(0), RF_ACTIVE},
60 { SYS_RES_MEMORY, PCIR_BAR(1), RF_ACTIVE},
61 { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE},
81 tauxcr = 0x0a, /* 9914 mode register */
115 enum {RD, WT, xDELAY, END}
122 * From NI Application note 095:
123 * Writing Functional Self-Tests for the TNT4882 GPIB Interface Chip
124 * XXX: fill in the rest ?
126 static struct tst tst_reset[] = {
127 {WT, tauxcr, 0x80}, /* chip reset if in 9914 mode */
128 {WT, auxmr, 0x80}, /* swrst if swapped */
129 {WT, tauxcr, 0x99}, /* switch to 7210 mode */
130 {WT, auxmr, 0x99}, /* switch to 7210 mode if swapped */
131 {WT, auxmr, 0x02}, /* execute chip reset */
132 {WT, keyreg, 0x00}, /* important! clear the swap bit */
133 {WT, eosr, 0x00}, /* clear EOS register */
134 {WT, cdor, 0x00}, /* clear data lines */
135 {WT, imr1, 0x00}, /* disable all interrupts */
140 {WT, admr, 0x00}, /* clear addressing modes */
141 {WT, auxmr, 0x00}, /* release from idle state with pon */
142 {WT, auxmr, 0x60}, /* reset ppr */
143 {WT, bcr, 0x00}, /* reset bcr */
144 {WT, misc, 0x04}, /* set wrap plug bit */
145 {WT, cmdr, 0xB2}, /* issue soft reset */
146 {WT, hssel, 0x00}, /* select two-chip mode */
150 static struct tst tst_read_reg[] = {
151 {RD, isr1, 0x00}, /* Verify mask registers are clear */
153 {RD, adsr, 0x40}, /* Verify ATN is not asserted */
154 {RD, adr0, 0x00}, /* Verify Primary address not set */
155 {RD, adr1, 0x00}, /* Verify Secondary address not set */
156 {RD, sts1, 0x8B}, /* Verify DONE, STOP, HALT, and GSYNC set */
157 {RD, isr3, 0x19}, /* Verify STOP, Not Full FIFO, & DONE set */
158 {RD, sts2, 0x9A}, /* Verify FIFO A/B is empty */
159 {RD, sasr, 0x00}, /* Verify clear */
160 {RD, isr0, 0x01}, /* Verify SYNC bit is set */
164 static struct tst tst_bsr_dcr[] = {
165 {WT, bcr, 0x55}, /* Set DAV, NRFD, SRQ, and REN */
166 {WT, dcr, 0xAA}, /* Write pattern to GPIB data lines */
167 {RD, bsr, 0x55}, /* Verify DAV, NRFD, SRQ, and REN are set */
168 {RD, dsr, 0xAA}, /* Verify data pattern written previously */
169 {WT, bcr, 0xAA}, /* Set ATN, NDAC, EOI, & IFC */
170 {WT, dcr, 0x55}, /* Write pattern to GPIB data lines */
171 {RD, bsr, 0xAA}, /* Verify ATN, NDAC, EOI, & IFC are set */
172 {RD, dsr, 0x55}, /* Verify data pattern written previously */
173 {WT, bcr, 0x00}, /* Clear control lines */
174 {WT, dcr, 0x00}, /* Clear data lines */
175 {RD, bsr, 0x00}, /* Verify control lines are clear */
176 {RD, dsr, 0x00}, /* Verify data lines are clear */
180 static struct tst tst_adr0_1[] = {
181 {WT, adr, 0x55}, /* Set Primary talk address */
182 {WT, adr, 0xAA}, /* Set Secondary listen address */
183 {RD, adr0, 0x55}, /* Read Primary address */
184 {RD, adr1, 0x2A}, /* Read Secondary address */
185 {WT, adr, 0x2A}, /* Set Primay listen address */
186 {WT, adr, 0xD5}, /* Set Secondary talk address */
187 {RD, adr0, 0x2A}, /* Read Primary address */
188 {RD, adr1, 0x55}, /* Read Secondary address */
192 static struct tst tst_cdor_dir[] = {
193 {WT, admr, 0xF0}, /* program AT-GPIB as talker only and
195 {RD, isr1, 0x02}, /* check DO bit set */
196 {RD, adsr, 0x46}, /* check AT-GPIB is both talker active
197 * and listener active */
198 {WT, cdor, 0xAA}, /* write out data byte */
199 {xDELAY, 0, 1}, /* One ISA I/O Cycle (500-ns) */
200 {RD, isr1, 0x03}, /* check DO and DI bits set */
201 {RD, dir, 0xAA}, /* verify data received */
202 {WT, cdor, 0x55}, /* write out data byte */
203 {xDELAY, 0, 1}, /* One ISA I/O Cycle (500-ns) */
204 {RD, dir, 0x55}, /* verify data received */
208 static struct tst tst_spmr_spsr[] = {
209 {WT, spsr, 0x00}, /* Write pattern to SPSR register */
210 {RD, spmr, 0x00}, /* Read back previously written pattern */
211 {WT, spsr, 0xBF}, /* Write pattern to SPSR register */
212 {RD, spmr, 0xBF}, /* Read back previously written pattern */
216 static struct tst tst_count0_1[] = {
217 {WT, cnt0, 0x55}, /* Verify every other bit can be set */
219 {RD, cnt0, 0x55}, /* Read back previously written pattern */
221 {WT, cnt0, 0xAA}, /* Verify every other bit can be set */
223 {RD, cnt0, 0xAA}, /* Read back previously written pattern */
229 tst_exec(struct tnt_softc *sc, struct tst *tp, const char *name)
234 for (step = 0; tp->action != END; tp++, step++) {
235 switch (tp->action) {
237 bus_write_1(sc->res[1], tp->reg, tp->val);
240 u = bus_read_1(sc->res[1], tp->reg);
243 "Test %s, step %d: reg(%02x) = %02x",
244 name, step, tp->reg, u);
245 printf( "should have been %02x\n", tp->val);
253 printf("Unknown action in test %s, step %d: %d\n",
254 name, step, tp->action);
259 printf("Test %s passed\n", name);
264 tnt_probe(device_t dev)
267 if (pci_get_vendor(dev) == 0x1093 && pci_get_device(dev) == 0xc801) {
268 device_set_desc(dev, "NI PCI-GPIB");
269 return (BUS_PROBE_DEFAULT);
275 tnt_attach(device_t dev)
277 struct tnt_softc *sc;
280 sc = device_get_softc(dev);
282 error = bus_alloc_resources(dev, tnt_res_spec, sc->res);
286 error = bus_setup_intr(dev, sc->res[2], INTR_TYPE_MISC | INTR_MPSAFE,
287 NULL, upd7210intr, &sc->upd7210, &sc->intr_handler);
289 /* Necessary magic for MITE */
290 bus_write_4(sc->res[0], 0xc0, rman_get_start(sc->res[1]) | 0x80);
292 tst_exec(sc, tst_reset, "Reset");
293 tst_exec(sc, tst_read_reg, "Read registers");
294 tst_exec(sc, tst_bsr_dcr, "BSR & DCR");
295 tst_exec(sc, tst_adr0_1, "ADR0,1");
296 tst_exec(sc, tst_cdor_dir, "CDOR/DIR");
297 tst_exec(sc, tst_spmr_spsr, "CPMR/SPSR");
298 tst_exec(sc, tst_count0_1, "COUNT0:1");
299 tst_exec(sc, tst_reset, "Reset");
301 /* pass 7210 interrupts through */
302 bus_write_1(sc->res[1], imr3, 0x02);
304 for (i = 0; i < 8; i++) {
305 sc->upd7210.reg_res[i] = sc->res[1];
306 sc->upd7210.reg_offset[i] = i * 2;
310 sc->upd7210.dmachan = -1;
312 upd7210attach(&sc->upd7210);
318 tnt_detach(device_t dev)
320 struct tnt_softc *sc;
322 sc = device_get_softc(dev);
323 bus_teardown_intr(dev, sc->res[2], sc->intr_handler);
324 upd7210detach(&sc->upd7210);
326 bus_release_resources(dev, tnt_res_spec, sc->res);
331 static device_method_t tnt4882_methods[] = {
332 DEVMETHOD(device_probe, tnt_probe),
333 DEVMETHOD(device_attach, tnt_attach),
334 DEVMETHOD(device_detach, tnt_detach),
338 static driver_t pci_gpib_driver = {
341 sizeof(struct tnt_softc)
344 static devclass_t pci_gpib_devclass;
346 DRIVER_MODULE(pci_gpib, pci, pci_gpib_driver, pci_gpib_devclass, 0, 0);