FreeBSD/Linux Kernel Cross Reference
sys/dev/isa/cec.c
1 /* $NetBSD: cec.c,v 1.1 2003/06/02 03:57:15 gmcgarry Exp $ */
2
3 /*-
4 * Copyright (c) 2003 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Gregory McGarry.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the NetBSD
21 * Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 * contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39 #include <sys/cdefs.h>
40 __KERNEL_RCSID(0, "$NetBSD: cec.c,v 1.1 2003/06/02 03:57:15 gmcgarry Exp $");
41
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/callout.h>
45 #include <sys/conf.h>
46 #include <sys/device.h>
47 #include <sys/kernel.h>
48
49 #include <machine/bus.h>
50
51 #include <dev/isa/isavar.h>
52 #include <dev/isa/isadmavar.h>
53
54 #include <dev/gpib/gpibvar.h>
55
56 #include <dev/ic/nec7210reg.h>
57
58 #define DEBUG
59
60 #ifdef DEBUG
61 int cecdebug = 0x1f;
62 #define DPRINTF(flag, str) if (cecdebug & (flag)) printf str
63 #define DBG_FOLLOW 0x01
64 #define DBG_CONFIG 0x02
65 #define DBG_INTR 0x04
66 #define DBG_REPORTTIME 0x08
67 #define DBG_FAIL 0x10
68 #define DBG_WAIT 0x20
69 #else
70 #define DPRINTF(flag, str) /* nothing */
71 #endif
72
73 #define CEC_IOSIZE 8
74
75 struct cec_softc {
76 struct device sc_dev; /* generic device glue */
77
78 bus_space_tag_t sc_iot;
79 bus_space_handle_t sc_ioh;
80 isa_chipset_tag_t sc_ic;
81 int sc_drq;
82 void *sc_ih;
83
84 int sc_myaddr; /* my address */
85 struct gpib_softc *sc_gpib;
86
87 volatile int sc_flags;
88 #define CECF_IO 0x1
89 #define CECF_PPOLL 0x4
90 #define CECF_READ 0x8
91 #define CECF_TIMO 0x10
92 #define CECF_USEDMA 0x20
93 int sc_ppoll_slave; /* XXX stash our ppoll address */
94 struct callout sc_timeout_ch;
95 };
96
97 int cecprobe(struct device *, struct cfdata *, void *);
98 void cecattach(struct device *, struct device *, void *);
99
100 CFATTACH_DECL(cec, sizeof(struct cec_softc),
101 cecprobe, cecattach, NULL, NULL);
102
103 void cecreset(void *);
104 int cecpptest(void *, int);
105 void cecppwatch(void *, int);
106 void cecppclear(void *);
107 void cecxfer(void *, int, int, void *, int, int, int);
108 void cecgo(void *v);
109 int cecintr(void *);
110 int cecsendcmds(void *, void *, int);
111 int cecsenddata(void *, void *, int);
112 int cecrecvdata(void *, void *, int);
113 int cecgts(void *);
114 int cectc(void *, int);
115 void cecifc(void *);
116
117 static int cecwait(struct cec_softc *, int, int);
118 static void cectimeout(void *v);
119 static int nec7210_setaddress(struct cec_softc *, int, int);
120 static void nec7210_init(struct cec_softc *);
121 static void nec7210_ifc(struct cec_softc *);
122
123 /*
124 * Our chipset structure.
125 */
126 struct gpib_chipset_tag cec_ic = {
127 cecreset,
128 NULL,
129 NULL,
130 cecpptest,
131 cecppwatch,
132 cecppclear,
133 cecxfer,
134 cectc,
135 cecgts,
136 cecifc,
137 cecsendcmds,
138 cecsenddata,
139 cecrecvdata
140 };
141
142 int cecwtimeout = 0x10000;
143 int cecdmathresh = 3;
144
145 int
146 cecprobe(struct device *parent, struct cfdata *match, void *aux)
147 {
148 struct isa_attach_args *ia = aux;
149 bus_space_tag_t iot = ia->ia_iot;
150 bus_space_handle_t ioh;
151
152 DPRINTF(DBG_CONFIG, ("cecprobe: called\n"));
153
154 if (ia->ia_nio < 1)
155 return (0);
156 if (ia->ia_nirq < 1)
157 return (0);
158 if (ia->ia_ndrq < 1)
159 return (0);
160
161 if (ISA_DIRECT_CONFIG(ia))
162 return (0);
163
164 if (ia->ia_io[0].ir_addr == ISACF_PORT_DEFAULT)
165 return (0);
166
167 if (ia->ia_ndrq > 0 && ia->ia_drq[0].ir_drq == ISACF_DRQ_DEFAULT)
168 ia->ia_ndrq = 0;
169
170 if (bus_space_map(iot, ia->ia_io[0].ir_addr, CEC_IOSIZE, 0, &ioh))
171 return (0);
172
173 /* XXX insert probe here */
174
175 ia->ia_io[0].ir_size = CEC_IOSIZE;
176 ia->ia_niomem = 0;
177
178 bus_space_unmap(iot, ioh, CEC_IOSIZE);
179
180 return (1);
181 }
182
183 void
184 cecattach(struct device *parent, struct device *self, void *aux)
185 {
186 struct cec_softc *sc = (struct cec_softc *)self;
187 struct isa_attach_args *ia = aux;
188 struct gpibdev_attach_args ga;
189 bus_size_t maxsize;
190
191 printf("\n");
192
193 DPRINTF(DBG_CONFIG, ("cecattach: called\n"));
194
195 sc->sc_iot = ia->ia_iot;
196 sc->sc_ic = ia->ia_ic;
197
198 if (bus_space_map(sc->sc_iot, ia->ia_io[0].ir_addr, CEC_IOSIZE,
199 0, &sc->sc_ioh) != 0) {
200 printf("%s: unable to map I/O space\n", sc->sc_dev.dv_xname);
201 return;
202 }
203
204 if (ia->ia_ndrq > 0) {
205 sc->sc_flags |= CECF_USEDMA;
206 sc->sc_drq = ia->ia_drq[0].ir_drq;
207
208 (void) isa_drq_alloc(sc->sc_ic, sc->sc_drq);
209 maxsize = isa_dmamaxsize(sc->sc_ic, sc->sc_drq);
210 if (isa_dmamap_create(sc->sc_ic, sc->sc_drq,
211 maxsize, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW)) {
212 printf("%s: unable to create map for drq %d\n",
213 sc->sc_dev.dv_xname, sc->sc_drq);
214 sc->sc_flags &= ~CECF_USEDMA;
215 }
216 }
217
218 sc->sc_myaddr = 15; /* XXX */
219
220 cecreset(sc);
221 (void) nec7210_setaddress(sc, sc->sc_myaddr, -1);
222
223 sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq[0].ir_irq,
224 IST_EDGE, IPL_BIO, cecintr, sc);
225 if (sc->sc_ih == NULL) {
226 printf("%s: couldn't establish interrupt\n",
227 sc->sc_dev.dv_xname);
228 return;
229 }
230
231 callout_init(&sc->sc_timeout_ch);
232
233 /* attach MI GPIB bus */
234 cec_ic.cookie = (void *)sc;
235 ga.ga_ic = &cec_ic;
236 ga.ga_address = sc->sc_myaddr;
237 sc->sc_gpib =
238 (struct gpib_softc *)config_found(self, &ga, gpibdevprint);
239 }
240
241 int
242 cecintr(void *v)
243 {
244 struct cec_softc *sc = v;
245 bus_space_tag_t iot = sc->sc_iot;
246 bus_space_handle_t ioh = sc->sc_ioh;
247 u_int8_t stat1, stat2;
248
249 stat1 = bus_space_read_1(iot, ioh, NEC7210_ISR1);
250 stat2 = bus_space_read_1(iot, ioh, NEC7210_ISR2);
251
252 DPRINTF(DBG_INTR, ("cecintr: sc=%p stat1=0x%x stat2=0x%x\n",
253 sc, stat1, stat2));
254
255 if (sc->sc_flags & CECF_IO) {
256
257 if (sc->sc_flags & CECF_TIMO)
258 callout_stop(&sc->sc_timeout_ch);
259
260 bus_space_write_1(iot, ioh, NEC7210_IMR1, 0);
261 bus_space_write_1(iot, ioh, NEC7210_IMR2, 0);
262 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_TCA);
263 sc->sc_flags &= ~(CECF_IO | CECF_READ | CECF_TIMO);
264 if (sc->sc_flags & CECF_USEDMA)
265 isa_dmadone(sc->sc_ic, sc->sc_drq);
266 gpibintr(sc->sc_gpib);
267
268 } else if (sc->sc_flags & CECF_PPOLL) {
269
270 if (cecpptest(sc, sc->sc_ppoll_slave)) {
271 sc->sc_flags &= ~CECF_PPOLL;
272 bus_space_write_1(iot, ioh, NEC7210_IMR2, 0);
273 gpibintr(sc->sc_gpib);
274 }
275
276 }
277 return (1);
278 }
279
280 void
281 cecreset(void *v)
282 {
283 struct cec_softc *sc = v;
284 u_int8_t cmd;
285
286 DPRINTF(DBG_FOLLOW, ("cecreset: sc=%p\n", sc));
287
288 nec7210_init(sc);
289 nec7210_ifc(sc);
290 /* we're now the system controller */
291
292 /* XXX should be pushed higher */
293
294 /* universal device clear */
295 cmd = GPIBCMD_DCL;
296 (void) cecsendcmds(sc, &cmd, 1);
297 /* delay for devices to clear */
298 DELAY(100000);
299 }
300
301 int
302 cecsendcmds(void *v, void *ptr, int origcnt)
303 {
304 struct cec_softc *sc = v;
305 bus_space_tag_t iot = sc->sc_iot;
306 bus_space_handle_t ioh = sc->sc_ioh;
307 int cnt = origcnt;
308 u_int8_t *addr = ptr;
309
310 DPRINTF(DBG_FOLLOW, ("cecsendcmds: sc=%p, ptr=%p cnt=%d\n",
311 sc, ptr, origcnt));
312
313 while (--cnt >= 0) {
314 bus_space_write_1(iot, ioh, NEC7210_CDOR, *addr++);
315 if (cecwait(sc, 0, ISR2_CO))
316 return (origcnt - cnt - 1);
317 }
318 return (origcnt);
319 }
320
321
322 int
323 cecrecvdata(void *v, void *ptr, int origcnt)
324 {
325 struct cec_softc *sc = v;
326 bus_space_tag_t iot = sc->sc_iot;
327 bus_space_handle_t ioh = sc->sc_ioh;
328 int cnt = origcnt;
329 u_int8_t *addr = ptr;
330
331 DPRINTF(DBG_FOLLOW, ("cecrecvdata: sc=%p, ptr=%p cnt=%d\n",
332 sc, ptr, origcnt));
333
334 /* XXX holdoff on end */
335 bus_space_write_1(sc->sc_iot, sc->sc_ioh, NEC7210_AUXMR, AUXCMD_RHDF);
336
337 if (cnt) {
338 while (--cnt >= 0) {
339 if (cecwait(sc, ISR1_DI, 0))
340 return (origcnt - cnt - 1);
341 *addr++ = bus_space_read_1(iot, ioh, NEC7210_DIR);
342 }
343 }
344 return (origcnt);
345 }
346
347 int
348 cecsenddata(void *v, void *ptr, int origcnt)
349 {
350 struct cec_softc *sc = v;
351 bus_space_tag_t iot = sc->sc_iot;
352 bus_space_handle_t ioh = sc->sc_ioh;
353 int cnt = origcnt;
354 u_int8_t *addr = ptr;
355
356 DPRINTF(DBG_FOLLOW, ("cecdsenddata: sc=%p, ptr=%p cnt=%d\n",
357 sc, ptr, origcnt));
358
359 if (cnt) {
360 while (--cnt > 0) {
361 bus_space_write_1(iot, ioh, NEC7210_CDOR, *addr++);
362 if (cecwait(sc, ISR1_DO, 0))
363 return (origcnt - cnt - 1);
364 }
365 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_SEOI);
366 bus_space_write_1(iot, ioh, NEC7210_CDOR, *addr);
367 (void) cecwait(sc, ISR1_DO, 0);
368 }
369 return (origcnt);
370 }
371
372 int
373 cectc(void *v, int sync)
374 {
375 struct cec_softc *sc = v;
376 bus_space_tag_t iot = sc->sc_iot;
377 bus_space_handle_t ioh = sc->sc_ioh;
378 u_int8_t adsr;
379 int timo = cecwtimeout;
380
381 DPRINTF(DBG_FOLLOW, ("cectc: sc=%p, sync=%d\n", sc, sync));
382
383 adsr = bus_space_read_1(iot, ioh, NEC7210_ADSR);
384 #if 0
385 if ((adsr & (ADSR_CIC | ADSR_NATN)) == ADSR_CIC) {
386 DPRINTF(0xff, ("cectc: already CIC\n"));
387 return (0);
388 }
389 #endif
390
391 if (sync) {
392 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_RHDF);
393 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_TCS);
394 } else {
395 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_TCA);
396 }
397
398 /* wait until ATN is asserted */
399 for (;;) {
400 adsr = bus_space_read_1(iot, ioh, NEC7210_ADSR);
401 if (--timo == 0) {
402 DPRINTF(DBG_REPORTTIME, ("cectc: timeout\n"));
403 return (1);
404 }
405 if ((adsr & ADSR_NATN) == 0)
406 break;
407 DELAY(1);
408 }
409
410 return (0);
411 }
412
413 int
414 cecgts(void *v)
415 {
416 struct cec_softc *sc = v;
417 bus_space_tag_t iot = sc->sc_iot;
418 bus_space_handle_t ioh = sc->sc_ioh;
419 u_int8_t adsr;
420 int timo = cecwtimeout;
421
422 DPRINTF(DBG_FOLLOW, ("cecgts: sc=%p\n", sc));
423
424 adsr = bus_space_read_1(iot, ioh, NEC7210_ADSR);
425 #if 0
426 if ((adsr & (ADSR_CIC | ADSR_NATN)) == ADSR_NATN) {
427 DPRINTF(0xff, ("cecgts: already standby\n"));
428 return (0);
429 }
430 #endif
431
432 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_GTS);
433
434 /* wait unit ATN is released */
435 for (;;) {
436 adsr = bus_space_read_1(iot, ioh, NEC7210_ADSR);
437 if (--timo == 0) {
438 DPRINTF(DBG_REPORTTIME, ("cecgts: timeout\n"));
439 return (1);
440 }
441 if ((adsr & ADSR_NATN) == ADSR_NATN)
442 break;
443 DELAY(1);
444 }
445
446 return (0);
447 }
448
449 int
450 cecpptest(void *v, int slave)
451 {
452 struct cec_softc *sc = v;
453 bus_space_tag_t iot = sc->sc_iot;
454 bus_space_handle_t ioh = sc->sc_ioh;
455 int ppoll;
456
457 DPRINTF(DBG_FOLLOW, ("cecpptest: sc=%p slave=%d\n", sc, slave));
458
459 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_EPP);
460 DELAY(25);
461 ppoll = bus_space_read_1(iot, ioh, NEC7210_CPTR);
462 DPRINTF(0xff, ("cecpptest: ppoll=%x\n", ppoll));
463 return ((ppoll & (0x80 >> slave)) != 0);
464 }
465
466 void
467 cecppwatch(void *v, int slave)
468 {
469 struct cec_softc *sc = v;
470 bus_space_tag_t iot = sc->sc_iot;
471 bus_space_handle_t ioh = sc->sc_ioh;
472
473 DPRINTF(DBG_FOLLOW, ("cecppwatch: sc=%p\n", sc));
474
475 sc->sc_flags |= CECF_PPOLL;
476 sc->sc_ppoll_slave = slave;
477 bus_space_write_1(iot, ioh, NEC7210_IMR2, IMR2_CO);
478 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_EPP);
479 }
480
481 void
482 cecppclear(void *v)
483 {
484 struct cec_softc *sc = v;
485
486 DPRINTF(DBG_FOLLOW, ("cecppclear: sc=%p\n", sc));
487
488 sc->sc_flags &= ~CECF_PPOLL;
489 bus_space_write_1(sc->sc_iot, sc->sc_ioh, NEC7210_IMR2, 0);
490 }
491
492 void
493 cecxfer(void *v, int slave, int sec, void *buf, int count, int dir, int timo)
494 {
495 struct cec_softc *sc = v;
496 bus_space_tag_t iot = sc->sc_iot;
497 bus_space_handle_t ioh = sc->sc_ioh;
498
499 DPRINTF(DBG_FOLLOW,
500 ("cecxfer: slave=%d sec=%d buf=%p count=%d dir=%x timo=%d\n",
501 slave, sec, buf, count, dir, timo));
502
503 sc->sc_flags |= CECF_IO;
504 if (dir == GPIB_READ)
505 sc->sc_flags |= CECF_READ;
506 if (timo) {
507 sc->sc_flags |= CECF_TIMO;
508 callout_reset(&sc->sc_timeout_ch, 5*hz, cectimeout, sc);
509 }
510
511 if (sc->sc_flags & CECF_READ) {
512 DPRINTF(DBG_FOLLOW, ("cecxfer: DMA read request\n"));
513 if ((sc->sc_flags & CECF_USEDMA) != 0) {
514 isa_dmastart(sc->sc_ic, sc->sc_drq, buf, count, NULL,
515 DMAMODE_READ | DMAMODE_DEMAND, BUS_DMA_NOWAIT);
516 bus_space_write_1(iot, ioh, NEC7210_IMR2, IMR2_DMAI);
517 bus_space_write_1(iot, ioh, NEC7210_IMR1, IMR1_END);
518 // XXX (void) cecrecv(sc, slave, sec, NULL, 0);
519 (void) gpibrecv(&cec_ic, slave, sec, NULL, 0);
520 } else {
521 /* XXX this doesn't work */
522 DPRINTF(DBG_FOLLOW, ("cecxfer: polling instead\n"));
523 bus_space_write_1(iot, ioh, NEC7210_IMR1, IMR1_END);
524 // XXX (void) cecrecv(sc, slave, sec, buf, count);
525 (void) gpibrecv(&cec_ic, slave, sec, buf, count);
526 bus_space_write_1(iot, ioh, NEC7210_IMR2, IMR2_CO);
527 }
528 } else {
529 DPRINTF(DBG_FOLLOW, ("cecxfer: DMA write request\n"));
530 bus_space_write_1(iot, ioh, NEC7210_IMR2, 0);
531 if (count < cecdmathresh ||
532 (sc->sc_flags & CECF_USEDMA) == 0) {
533 DPRINTF(DBG_FOLLOW, ("cecxfer: polling instead\n"));
534 // XXX (void) cecsend(sc, slave, sec, buf, count);
535 (void) gpibsend(&cec_ic, slave, sec, buf, count);
536 bus_space_write_1(iot, ioh, NEC7210_IMR2, IMR2_CO);
537 return;
538 }
539 /* we send the last byte with EOI set */
540 isa_dmastart(sc->sc_ic, sc->sc_drq, buf, count-1, NULL,
541 DMAMODE_WRITE | DMAMODE_DEMAND, BUS_DMA_NOWAIT);
542 bus_space_write_1(iot, ioh, NEC7210_IMR2, IMR2_DMAO);
543 // XXX (void) cecsend(sc, slave, sec, NULL, 0);
544 (void) gpibsend(&cec_ic, slave, sec, NULL, 0);
545 while (!isa_dmafinished(sc->sc_ic, sc->sc_drq))
546 DELAY(1);
547 (void) cecwait(sc, ISR1_DO, 0);
548 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_SEOI);
549 bus_space_write_1(iot, ioh, NEC7210_CDOR, *(char *)buf+count);
550 /* generate interrupt */
551 bus_space_write_1(iot, ioh, NEC7210_IMR1, IMR1_DO);
552 }
553 }
554
555 void
556 cecifc(void *v)
557 {
558 struct cec_softc *sc = v;
559
560 nec7210_ifc(sc);
561 }
562
563 static int
564 nec7210_setaddress(struct cec_softc *sc, int pri, int sec)
565 {
566 bus_space_tag_t iot = sc->sc_iot;
567 bus_space_handle_t ioh = sc->sc_ioh;
568 u_int8_t admr;
569
570 /* assign our primary address */
571 bus_space_write_1(iot, ioh, NEC7210_ADDR, (pri & ADDR_MASK));
572
573 admr = ADMR_TRM0 | ADMR_TRM1;
574
575 /* assign our secondary address */
576 if (sec != -1) {
577 bus_space_write_1(iot, ioh, NEC7210_ADDR,
578 (ADDR_ARS | (sec & ADDR_MASK)));
579 admr |= ADMR_ADM1;
580 } else {
581 /* disable secondary address */
582 bus_space_write_1(iot, ioh, NEC7210_ADDR,
583 (ADDR_ARS | ADDR_DT | ADDR_DL));
584 admr |= ADMR_ADM0;
585 }
586 bus_space_write_1(iot, ioh, NEC7210_ADMR, admr);
587
588 return (0);
589 }
590
591 static void
592 nec7210_init(struct cec_softc *sc)
593 {
594 bus_space_tag_t iot = sc->sc_iot;
595 bus_space_handle_t ioh = sc->sc_ioh;
596
597 /* reset chip */
598 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_CRST);
599
600 /* clear interrupts */
601 bus_space_read_1(iot, ioh, NEC7210_CPTR);
602 bus_space_read_1(iot, ioh, NEC7210_ISR1);
603 bus_space_read_1(iot, ioh, NEC7210_ISR2);
604
605 /* initialise interrupts */
606 bus_space_write_1(iot, ioh, NEC7210_IMR1, 0);
607 bus_space_write_1(iot, ioh, NEC7210_IMR2, 0);
608 bus_space_write_1(iot, ioh, NEC7210_SPMR, 0);
609 bus_space_write_1(iot, ioh, NEC7210_EOSR, 0);
610
611 /* set internal clock to 8MHz */
612 bus_space_write_1(iot, ioh, NEC7210_AUXMR, (AUXMR_ICR | 0x8));
613 /* parallel poll unconfigure */
614 bus_space_write_1(iot, ioh, NEC7210_AUXMR, (AUXMR_PPOLL | PPOLL_PPU));
615
616 /* assign our address */
617 bus_space_write_1(iot, ioh, NEC7210_ADDR, 0);
618 /* disable secondary address */
619 bus_space_write_1(iot, ioh, NEC7210_ADDR,
620 (ADDR_ARS | ADDR_DT | ADDR_DL));
621
622 /* setup transceivers */
623 bus_space_write_1(iot, ioh, NEC7210_ADMR,
624 (ADMR_ADM0 | ADMR_TRM0 | ADMR_TRM1));
625 bus_space_write_1(iot, ioh, NEC7210_AUXMR,
626 (AUXMR_REGA | AUX_A_HSNORM));
627
628 /* set INT pin to active high */
629 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXMR_REGB);
630 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXMR_REGE);
631
632 /* holdoff on end condition */
633 bus_space_write_1(iot, ioh, NEC7210_AUXMR, (AUXMR_REGA | AUX_A_HLDE));
634
635 /* reconnect to bus */
636 bus_space_write_1(iot, ioh, NEC7210_AUXMR, (AUXMR_CMD | AUXCMD_IEPON));
637 }
638
639 /*
640 * Place all devices on the bus into quiescient state ready for
641 * remote programming.
642 * Obviously, we're the system controller upon exit.
643 */
644 void
645 nec7210_ifc(struct cec_softc *sc)
646 {
647 bus_space_tag_t iot = sc->sc_iot;
648 bus_space_handle_t ioh = sc->sc_ioh;
649
650 /*XXX*/ bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_TCA);
651 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_CREN);
652 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_SIFC);
653 /* wait for devices to enter quiescient state */
654 DELAY(100);
655 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_CIFC);
656 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_SREN);
657 }
658
659 static int
660 cecwait(struct cec_softc *sc, int x1, int x2)
661 {
662 int timo = cecwtimeout;
663 bus_space_tag_t iot = sc->sc_iot;
664 bus_space_handle_t ioh = sc->sc_ioh;
665 u_int8_t stat1, stat2;
666
667 DPRINTF(DBG_WAIT, ("cecwait: sc=%p, x1=0x%x x2=0x%x\n", sc, x1, x2));
668
669 for (;;) {
670 stat1 = bus_space_read_1(iot, ioh, NEC7210_ISR1);
671 stat2 = bus_space_read_1(iot, ioh, NEC7210_ISR2);
672 #if 0
673 if ((stat1 & ISR1_ERR)) {
674 DPRINTF(DBG_WAIT, ("cecwait: got ERR\n"));
675 return (1);
676 }
677 #endif
678 if (--timo == 0) {
679 DPRINTF(DBG_REPORTTIME,
680 ("cecwait: timeout x1=0x%x x2=0x%x\n", x1, x2));
681 return (1);
682 }
683 if ((stat1 & x1) || (stat2 & x2))
684 break;
685 DELAY(1);
686 }
687 return (0);
688 }
689
690 static void
691 cectimeout(void *v)
692 {
693 struct cec_softc *sc = v;
694 bus_space_tag_t iot = sc->sc_iot;
695 bus_space_handle_t ioh = sc->sc_ioh;
696 int s;
697
698 DPRINTF(DBG_FOLLOW, ("cectimeout: sc=%p\n", sc));
699
700 s = splbio();
701 if (sc->sc_flags & CECF_IO) {
702 bus_space_write_1(iot, ioh, NEC7210_IMR1, 0);
703 bus_space_write_2(iot, ioh, NEC7210_IMR2, 0);
704 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_TCA);
705 sc->sc_flags &= ~(CECF_IO | CECF_READ | CECF_TIMO);
706 isa_dmaabort(sc->sc_ic, sc->sc_drq);
707 printf("%s: %s timeout\n", sc->sc_dev.dv_xname,
708 sc->sc_flags & CECF_READ ? "read" : "write");
709 gpibintr(sc->sc_gpib);
710 }
711 splx(s);
712 }
Cache object: 8a3203f2051aec7f4c43f35ae2e314d9
|