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