1 /*-
2  * Copyright (c) 2005 Poul-Henning Kamp
3  * Copyright (c) 2010 Joerg Wunsch
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  * $FreeBSD: stable/10/sys/dev/ieee488/tnt4882.c 203360 2010-02-01 21:21:10Z joerg $
28  */
29 
30 #include <sys/param.h>
31 #include <sys/kernel.h>
32 #include <sys/systm.h>
33 #include <sys/module.h>
34 #include <sys/bus.h>
35 #include <dev/pci/pcireg.h>
36 #include <dev/pci/pcivar.h>
37 
38 #include <machine/bus.h>
39 #include <machine/resource.h>
40 #include <machine/stdarg.h>
41 #include <sys/rman.h>
42 
43 /* vtophys */
44 #include <vm/vm.h>
45 #include <vm/pmap.h>
46 #include <machine/pmap.h>
47 
48 #define UPD7210_HW_DRIVER 1
49 #include <dev/ieee488/upd7210.h>
50 #include <dev/ieee488/tnt4882.h>
51 
52 struct tnt_softc {
53 	int foo;
54 	struct upd7210		upd7210;
55 
56 	struct resource		*res[3];
57 	void			*intr_handler;
58 };
59 
60 static struct resource_spec tnt_res_spec[] = {
61 	{ SYS_RES_MEMORY,	PCIR_BAR(0),	RF_ACTIVE},
62 	{ SYS_RES_MEMORY,	PCIR_BAR(1),	RF_ACTIVE},
63 	{ SYS_RES_IRQ,		0,		RF_ACTIVE | RF_SHAREABLE},
64 	{ -1, 0 }
65 };
66 
67 struct tst {
68 	enum {RD, WT, xDELAY, END}
69 				action;
70 	enum tnt4882reg 	reg;
71 	uint8_t			val;
72 };
73 
74 /*
75  * From NI Application note 095:
76  *   Writing Functional Self-Tests for the TNT4882 GPIB Interface Chip
77  * XXX: fill in the rest ?
78  */
79 static struct tst tst_reset[] = {
80 	{WT, tauxcr, 0x80},	/* chip reset if in 9914 mode */
81 	{WT, auxmr, 0x80},	/* swrst if swapped */
82 	{WT, tauxcr, 0x99},	/* switch to 7210 mode */
83 	{WT, auxmr, 0x99},	/* switch to 7210 mode if swapped */
84 	{WT, auxmr, 0x02},	/* execute chip reset */
85 	{WT, keyreg, 0x00},	/* important! clear the swap bit */
86 	{WT, eosr, 0x00},	/* clear EOS register */
87 	{WT, cdor, 0x00},	/* clear data lines */
88 	{WT, imr1, 0x00},	/* disable all interrupts */
89 	{WT, imr2, 0x00},
90 	{WT, imr0, 0x80},
91 	{WT, adr, 0x80},
92 	{WT, adr, 0x00},
93 	{WT, admr, 0x00},	/* clear addressing modes */
94 	{WT, auxmr, 0x00},	/* release from idle state with pon */
95 	{WT, auxmr, 0x60},	/* reset ppr */
96 	{WT, bcr, 0x00},	/* reset bcr */
97 	{WT, misc, 0x04},	/* set wrap plug bit */
98 	{WT, cmdr, 0xB2},	/* issue soft reset */
99 	{WT, hssel, 0x00},	/* select two-chip mode */
100 	{END, 0, 0}
101 };
102 
103 static struct tst tst_read_reg[] = {
104 	{RD, isr1, 0x00},	/* Verify mask registers are clear */
105 	{RD, isr2, 0x00},
106 	{RD, adsr, 0x40},	/* Verify ATN is not asserted */
107 	{RD, adr0, 0x00},	/* Verify Primary address not set */
108 	{RD, adr1, 0x00},	/* Verify Secondary address not set */
109 	{RD, sts1, 0x8B},	/* Verify DONE, STOP, HALT, and GSYNC set */
110 	{RD, isr3, 0x19},	/* Verify STOP, Not Full FIFO, & DONE set */
111 	{RD, sts2, 0x9A},	/* Verify FIFO A/B is empty */
112 	{RD, sasr, 0x00},	/* Verify clear */
113 	{RD, isr0, 0x01},	/* Verify SYNC bit is set */
114 	{END, 0, 0}
115 };
116 
117 static struct tst tst_bsr_dcr[] = {
118 	{WT, bcr, 0x55},	/* Set DAV, NRFD, SRQ, and REN */
119 	{WT, dcr, 0xAA},	/* Write pattern to GPIB data lines */
120 	{RD, bsr, 0x55},	/* Verify DAV, NRFD, SRQ, and REN are set */
121 	{RD, dsr, 0xAA},	/* Verify data pattern written previously */
122 	{WT, bcr, 0xAA},	/* Set ATN, NDAC, EOI, & IFC */
123 	{WT, dcr, 0x55},	/* Write pattern to GPIB data lines */
124 	{RD, bsr, 0xAA},	/* Verify ATN, NDAC, EOI, & IFC are set */
125 	{RD, dsr, 0x55},	/* Verify data pattern written previously */
126 	{WT, bcr, 0x00},	/* Clear control lines */
127 	{WT, dcr, 0x00},	/* Clear data lines */
128 	{RD, bsr, 0x00},	/* Verify control lines are clear */
129 	{RD, dsr, 0x00},	/* Verify data lines are clear */
130 	{END, 0, 0}
131 };
132 
133 static struct tst tst_adr0_1[] = {
134 	{WT, adr, 0x55},	/* Set Primary talk address */
135 	{WT, adr, 0xAA},	/* Set Secondary listen address */
136 	{RD, adr0, 0x55},	/* Read Primary address */
137 	{RD, adr1, 0x2A},	/* Read Secondary address */
138 	{WT, adr, 0x2A},	/* Set Primay listen address */
139 	{WT, adr, 0xD5},	/* Set Secondary talk address */
140 	{RD, adr0, 0x2A},	/* Read Primary address */
141 	{RD, adr1, 0x55},	/* Read Secondary address */
142 	{END, 0, 0}
143 };
144 
145 static struct tst tst_cdor_dir[] = {
146 	{WT, admr, 0xF0},	/* program AT-GPIB as talker only and
147 				 * listener only */
148 	{RD, isr1, 0x02},	/* check DO bit set */
149 	{RD, adsr, 0x46},	/* check AT-GPIB is both talker active
150 				 * and listener active */
151 	{WT, cdor, 0xAA},	/* write out data byte */
152 	{xDELAY, 0, 1},		/* One ISA I/O Cycle (500-ns) */
153 	{RD, isr1, 0x03},	/* check DO and DI bits set */
154 	{RD, dir, 0xAA},	/* verify data received */
155 	{WT, cdor, 0x55},	/* write out data byte */
156 	{xDELAY, 0, 1},		/* One ISA I/O Cycle (500-ns) */
157 	{RD, dir, 0x55},	/* verify data received */
158 	{END, 0, 0}
159 };
160 
161 static struct tst tst_spmr_spsr[] = {
162 	{WT, spsr, 0x00},	/* Write pattern to SPSR register */
163 	{RD, spmr, 0x00},	/* Read back previously written pattern */
164 	{WT, spsr, 0xBF},	/* Write pattern to SPSR register */
165 	{RD, spmr, 0xBF},	/* Read back previously written pattern */
166 	{END, 0, 0}
167 };
168 
169 static struct tst tst_count0_1[] = {
170 	{WT, cnt0, 0x55}, 	/* Verify every other bit can be set */
171 	{WT, cnt1, 0xAA},
172 	{RD, cnt0, 0x55}, 	/* Read back previously written pattern */
173 	{RD, cnt1, 0xAA},
174 	{WT, cnt0, 0xAA}, 	/* Verify every other bit can be set */
175 	{WT, cnt1, 0x55},
176 	{RD, cnt0, 0xAA}, 	/* Read back previously written pattern */
177 	{RD, cnt1, 0x55},
178 	{END, 0, 0}
179 };
180 
181 static int
tst_exec(struct tnt_softc * sc,struct tst * tp,const char * name)182 tst_exec(struct tnt_softc *sc, struct tst *tp, const char *name)
183 {
184 	uint8_t u;
185 	int step;
186 
187 	for (step = 0; tp->action != END; tp++, step++) {
188 		switch (tp->action) {
189 		case WT:
190 			bus_write_1(sc->res[1], tp->reg, tp->val);
191 			break;
192 		case RD:
193 			u = bus_read_1(sc->res[1], tp->reg);
194 			if (u != tp->val) {
195 				printf(
196 				    "Test %s, step %d: reg(%02x) = %02x",
197 				    name, step, tp->reg, u);
198 				printf( "should have been %02x\n", tp->val);
199 				return (1);
200 			}
201 			break;
202 		case xDELAY:
203 			DELAY(tp->val);
204 			break;
205 		default:
206 			printf("Unknown action in test %s, step %d: %d\n",
207 			name, step, tp->action);
208 			return (1);
209 		}
210 	}
211 	if (bootverbose)
212 		printf("Test %s passed\n", name);
213 	return (0);
214 }
215 
216 static int
tnt_probe(device_t dev)217 tnt_probe(device_t dev)
218 {
219 
220 	if (pci_get_vendor(dev) == 0x1093 && pci_get_device(dev) == 0xc801) {
221 		device_set_desc(dev, "NI PCI-GPIB");
222 		return (BUS_PROBE_DEFAULT);
223 	}
224 	return (ENXIO);
225 }
226 
227 static int
tnt_attach(device_t dev)228 tnt_attach(device_t dev)
229 {
230 	struct tnt_softc *sc;
231 	int error, i;
232 	uint8_t version;
233 
234 	sc = device_get_softc(dev);
235 
236 	error = bus_alloc_resources(dev, tnt_res_spec, sc->res);
237 	if (error)
238 		return (error);
239 
240 	error = bus_setup_intr(dev, sc->res[2], INTR_TYPE_MISC | INTR_MPSAFE,
241 	    NULL, upd7210intr, &sc->upd7210, &sc->intr_handler);
242 
243 	/* IO Device Window Base Size Register (IODWBSR) */
244 	bus_write_4(sc->res[0], 0xc0, rman_get_start(sc->res[1]) | 0x80);
245 
246 	tst_exec(sc, tst_reset, "Reset");
247 	tst_exec(sc, tst_read_reg, "Read registers");
248 	tst_exec(sc, tst_bsr_dcr, "BSR & DCR");
249 	tst_exec(sc, tst_adr0_1, "ADR0,1");
250 	tst_exec(sc, tst_cdor_dir, "CDOR/DIR");
251 	tst_exec(sc, tst_spmr_spsr, "CPMR/SPSR");
252 	tst_exec(sc, tst_count0_1, "COUNT0:1");
253 	tst_exec(sc, tst_reset, "Reset");
254 
255 	version = bus_read_1(sc->res[1], csr);
256 	version = (version >> 4) & 0x0f;
257 	device_printf(dev, "Chip version 0x%02x (TNT%s)\n",
258 		      version,
259 		      version >= 4? "5004 or above": "4882");
260 	if (version >= 4) {
261 		device_printf(dev, "Forcing FIFO mode\n");
262 		sc->upd7210.use_fifo = 1;
263 	} else {
264 		sc->upd7210.use_fifo = 0;
265 	}
266 
267 	/* pass 7210 interrupts through */
268 	bus_write_1(sc->res[1], imr3, 0x02);
269 
270 	for (i = 0; i < 8; i++) {
271 		sc->upd7210.reg_res[i] = sc->res[1];
272 		sc->upd7210.reg_offset[i] = i * 2;
273 	}
274 
275 	/* No DMA help */
276 	sc->upd7210.dmachan = -1;
277 
278 	/* No "special interrupt handling" needed here. */
279 	sc->upd7210.irq_clear_res = NULL;
280 
281 	upd7210attach(&sc->upd7210);
282 	device_printf(dev, "attached gpib%d\n", sc->upd7210.unit);
283 
284 	if (sc->upd7210.use_fifo)
285 		bus_write_1(sc->res[0], hssel, 0x01); /* one-chip mode */
286 
287 
288 	return (0);
289 }
290 
291 static int
tnt_detach(device_t dev)292 tnt_detach(device_t dev)
293 {
294 	struct tnt_softc *sc;
295 
296 	sc = device_get_softc(dev);
297 	bus_teardown_intr(dev, sc->res[2], sc->intr_handler);
298 	upd7210detach(&sc->upd7210);
299 
300 	bus_release_resources(dev, tnt_res_spec, sc->res);
301 
302 	return (0);
303 }
304 
305 static device_method_t	tnt4882_methods[] = {
306 	DEVMETHOD(device_probe,		tnt_probe),
307 	DEVMETHOD(device_attach,	tnt_attach),
308 	DEVMETHOD(device_detach,	tnt_detach),
309 	{ 0, 0 }
310 };
311 
312 static driver_t pci_gpib_driver = {
313 	"tnt4882",
314 	tnt4882_methods,
315 	sizeof(struct tnt_softc)
316 };
317 
318 static devclass_t pci_gpib_devclass;
319 
320 DRIVER_MODULE(pci_gpib, pci, pci_gpib_driver, pci_gpib_devclass, 0, 0);
321