cec.c revision 1.14 1 /* $NetBSD: cec.c,v 1.14 2016/07/11 11:31:50 msaitoh 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.14 2016/07/11 11:31:50 msaitoh 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 device_t 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_NEW(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 = device_private(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_dev = self;
193 sc->sc_iot = ia->ia_iot;
194 sc->sc_ic = ia->ia_ic;
195
196 if (bus_space_map(sc->sc_iot, ia->ia_io[0].ir_addr, CEC_IOSIZE,
197 0, &sc->sc_ioh) != 0) {
198 aprint_error_dev(sc->sc_dev, "unable to map I/O space\n");
199 return;
200 }
201
202 if (ia->ia_ndrq > 0) {
203 sc->sc_flags |= CECF_USEDMA;
204 sc->sc_drq = ia->ia_drq[0].ir_drq;
205
206 (void) isa_drq_alloc(sc->sc_ic, sc->sc_drq);
207 maxsize = isa_dmamaxsize(sc->sc_ic, sc->sc_drq);
208 if (isa_dmamap_create(sc->sc_ic, sc->sc_drq,
209 maxsize, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW)) {
210 aprint_error_dev(sc->sc_dev,
211 "unable to create map for drq %d\n", sc->sc_drq);
212 sc->sc_flags &= ~CECF_USEDMA;
213 }
214 }
215
216 sc->sc_myaddr = 15; /* XXX */
217
218 cecreset(sc);
219 (void) nec7210_setaddress(sc, sc->sc_myaddr, -1);
220
221 sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq[0].ir_irq,
222 IST_EDGE, IPL_BIO, cecintr, sc);
223 if (sc->sc_ih == NULL) {
224 aprint_error_dev(sc->sc_dev, "couldn't establish interrupt\n");
225 return;
226 }
227
228 callout_init(&sc->sc_timeout_ch, 0);
229
230 /* attach MI GPIB bus */
231 cec_ic.cookie = (void *)sc;
232 ga.ga_ic = &cec_ic;
233 ga.ga_address = sc->sc_myaddr;
234 sc->sc_gpib =
235 (struct gpib_softc *)config_found(self, &ga, gpibdevprint);
236 }
237
238 int
239 cecintr(void *v)
240 {
241 struct cec_softc *sc = v;
242 bus_space_tag_t iot = sc->sc_iot;
243 bus_space_handle_t ioh = sc->sc_ioh;
244 u_int8_t stat1, stat2;
245
246 stat1 = bus_space_read_1(iot, ioh, NEC7210_ISR1);
247 stat2 = bus_space_read_1(iot, ioh, NEC7210_ISR2);
248
249 DPRINTF(DBG_INTR, ("cecintr: sc=%p stat1=0x%x stat2=0x%x\n",
250 sc, stat1, stat2));
251
252 if (sc->sc_flags & CECF_IO) {
253
254 if (sc->sc_flags & CECF_TIMO)
255 callout_stop(&sc->sc_timeout_ch);
256
257 bus_space_write_1(iot, ioh, NEC7210_IMR1, 0);
258 bus_space_write_1(iot, ioh, NEC7210_IMR2, 0);
259 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_TCA);
260 sc->sc_flags &= ~(CECF_IO | CECF_READ | CECF_TIMO);
261 if (sc->sc_flags & CECF_USEDMA)
262 isa_dmadone(sc->sc_ic, sc->sc_drq);
263 gpibintr(sc->sc_gpib);
264
265 } else if (sc->sc_flags & CECF_PPOLL) {
266
267 if (cecpptest(sc, sc->sc_ppoll_slave)) {
268 sc->sc_flags &= ~CECF_PPOLL;
269 bus_space_write_1(iot, ioh, NEC7210_IMR2, 0);
270 gpibintr(sc->sc_gpib);
271 }
272
273 }
274 return (1);
275 }
276
277 void
278 cecreset(void *v)
279 {
280 struct cec_softc *sc = v;
281 u_int8_t cmd;
282
283 DPRINTF(DBG_FOLLOW, ("cecreset: sc=%p\n", sc));
284
285 nec7210_init(sc);
286 nec7210_ifc(sc);
287 /* we're now the system controller */
288
289 /* XXX should be pushed higher */
290
291 /* universal device clear */
292 cmd = GPIBCMD_DCL;
293 (void) cecsendcmds(sc, &cmd, 1);
294 /* delay for devices to clear */
295 DELAY(100000);
296 }
297
298 int
299 cecsendcmds(void *v, void *ptr, int origcnt)
300 {
301 struct cec_softc *sc = v;
302 bus_space_tag_t iot = sc->sc_iot;
303 bus_space_handle_t ioh = sc->sc_ioh;
304 int cnt = origcnt;
305 u_int8_t *addr = ptr;
306
307 DPRINTF(DBG_FOLLOW, ("cecsendcmds: sc=%p, ptr=%p cnt=%d\n",
308 sc, ptr, origcnt));
309
310 while (--cnt >= 0) {
311 bus_space_write_1(iot, ioh, NEC7210_CDOR, *addr++);
312 if (cecwait(sc, 0, ISR2_CO))
313 return (origcnt - cnt - 1);
314 }
315 return (origcnt);
316 }
317
318
319 int
320 cecrecvdata(void *v, void *ptr, int origcnt)
321 {
322 struct cec_softc *sc = v;
323 bus_space_tag_t iot = sc->sc_iot;
324 bus_space_handle_t ioh = sc->sc_ioh;
325 int cnt = origcnt;
326 u_int8_t *addr = ptr;
327
328 DPRINTF(DBG_FOLLOW, ("cecrecvdata: sc=%p, ptr=%p cnt=%d\n",
329 sc, ptr, origcnt));
330
331 /* XXX holdoff on end */
332 bus_space_write_1(sc->sc_iot, sc->sc_ioh, NEC7210_AUXMR, AUXCMD_RHDF);
333
334 if (cnt) {
335 while (--cnt >= 0) {
336 if (cecwait(sc, ISR1_DI, 0))
337 return (origcnt - cnt - 1);
338 *addr++ = bus_space_read_1(iot, ioh, NEC7210_DIR);
339 }
340 }
341 return (origcnt);
342 }
343
344 int
345 cecsenddata(void *v, void *ptr, int origcnt)
346 {
347 struct cec_softc *sc = v;
348 bus_space_tag_t iot = sc->sc_iot;
349 bus_space_handle_t ioh = sc->sc_ioh;
350 int cnt = origcnt;
351 u_int8_t *addr = ptr;
352
353 DPRINTF(DBG_FOLLOW, ("cecdsenddata: sc=%p, ptr=%p cnt=%d\n",
354 sc, ptr, origcnt));
355
356 if (cnt) {
357 while (--cnt > 0) {
358 bus_space_write_1(iot, ioh, NEC7210_CDOR, *addr++);
359 if (cecwait(sc, ISR1_DO, 0))
360 return (origcnt - cnt - 1);
361 }
362 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_SEOI);
363 bus_space_write_1(iot, ioh, NEC7210_CDOR, *addr);
364 (void) cecwait(sc, ISR1_DO, 0);
365 }
366 return (origcnt);
367 }
368
369 int
370 cectc(void *v, int sync)
371 {
372 struct cec_softc *sc = v;
373 bus_space_tag_t iot = sc->sc_iot;
374 bus_space_handle_t ioh = sc->sc_ioh;
375 u_int8_t adsr;
376 int timo = cecwtimeout;
377
378 DPRINTF(DBG_FOLLOW, ("cectc: sc=%p, sync=%d\n", sc, sync));
379
380 adsr = bus_space_read_1(iot, ioh, NEC7210_ADSR);
381 #if 0
382 if ((adsr & (ADSR_CIC | ADSR_NATN)) == ADSR_CIC) {
383 DPRINTF(0xff, ("cectc: already CIC\n"));
384 return (0);
385 }
386 #endif
387
388 if (sync) {
389 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_RHDF);
390 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_TCS);
391 } else {
392 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_TCA);
393 }
394
395 /* wait until ATN is asserted */
396 for (;;) {
397 adsr = bus_space_read_1(iot, ioh, NEC7210_ADSR);
398 if (--timo == 0) {
399 DPRINTF(DBG_REPORTTIME, ("cectc: timeout\n"));
400 return (1);
401 }
402 if ((adsr & ADSR_NATN) == 0)
403 break;
404 DELAY(1);
405 }
406
407 return (0);
408 }
409
410 int
411 cecgts(void *v)
412 {
413 struct cec_softc *sc = v;
414 bus_space_tag_t iot = sc->sc_iot;
415 bus_space_handle_t ioh = sc->sc_ioh;
416 u_int8_t adsr;
417 int timo = cecwtimeout;
418
419 DPRINTF(DBG_FOLLOW, ("cecgts: sc=%p\n", sc));
420
421 adsr = bus_space_read_1(iot, ioh, NEC7210_ADSR);
422 #if 0
423 if ((adsr & (ADSR_CIC | ADSR_NATN)) == ADSR_NATN) {
424 DPRINTF(0xff, ("cecgts: already standby\n"));
425 return (0);
426 }
427 #endif
428
429 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_GTS);
430
431 /* wait unit ATN is released */
432 for (;;) {
433 adsr = bus_space_read_1(iot, ioh, NEC7210_ADSR);
434 if (--timo == 0) {
435 DPRINTF(DBG_REPORTTIME, ("cecgts: timeout\n"));
436 return (1);
437 }
438 if ((adsr & ADSR_NATN) == ADSR_NATN)
439 break;
440 DELAY(1);
441 }
442
443 return (0);
444 }
445
446 int
447 cecpptest(void *v, int slave)
448 {
449 struct cec_softc *sc = v;
450 bus_space_tag_t iot = sc->sc_iot;
451 bus_space_handle_t ioh = sc->sc_ioh;
452 int ppoll;
453
454 DPRINTF(DBG_FOLLOW, ("cecpptest: sc=%p slave=%d\n", sc, slave));
455
456 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_EPP);
457 DELAY(25);
458 ppoll = bus_space_read_1(iot, ioh, NEC7210_CPTR);
459 DPRINTF(0xff, ("cecpptest: ppoll=%x\n", ppoll));
460 return ((ppoll & (0x80 >> slave)) != 0);
461 }
462
463 void
464 cecppwatch(void *v, int slave)
465 {
466 struct cec_softc *sc = v;
467 bus_space_tag_t iot = sc->sc_iot;
468 bus_space_handle_t ioh = sc->sc_ioh;
469
470 DPRINTF(DBG_FOLLOW, ("cecppwatch: sc=%p\n", sc));
471
472 sc->sc_flags |= CECF_PPOLL;
473 sc->sc_ppoll_slave = slave;
474 bus_space_write_1(iot, ioh, NEC7210_IMR2, IMR2_CO);
475 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_EPP);
476 }
477
478 void
479 cecppclear(void *v)
480 {
481 struct cec_softc *sc = v;
482
483 DPRINTF(DBG_FOLLOW, ("cecppclear: sc=%p\n", sc));
484
485 sc->sc_flags &= ~CECF_PPOLL;
486 bus_space_write_1(sc->sc_iot, sc->sc_ioh, NEC7210_IMR2, 0);
487 }
488
489 void
490 cecxfer(void *v, int slave, int sec, void *buf, int count, int dir, int timo)
491 {
492 struct cec_softc *sc = v;
493 bus_space_tag_t iot = sc->sc_iot;
494 bus_space_handle_t ioh = sc->sc_ioh;
495
496 DPRINTF(DBG_FOLLOW,
497 ("cecxfer: slave=%d sec=%d buf=%p count=%d dir=%x timo=%d\n",
498 slave, sec, buf, count, dir, timo));
499
500 sc->sc_flags |= CECF_IO;
501 if (dir == GPIB_READ)
502 sc->sc_flags |= CECF_READ;
503 if (timo) {
504 sc->sc_flags |= CECF_TIMO;
505 callout_reset(&sc->sc_timeout_ch, 5*hz, cectimeout, sc);
506 }
507
508 if (sc->sc_flags & CECF_READ) {
509 DPRINTF(DBG_FOLLOW, ("cecxfer: DMA read request\n"));
510 if ((sc->sc_flags & CECF_USEDMA) != 0) {
511 isa_dmastart(sc->sc_ic, sc->sc_drq, buf, count, NULL,
512 DMAMODE_READ | DMAMODE_DEMAND, BUS_DMA_NOWAIT);
513 bus_space_write_1(iot, ioh, NEC7210_IMR2, IMR2_DMAI);
514 bus_space_write_1(iot, ioh, NEC7210_IMR1, IMR1_END);
515 // XXX (void) cecrecv(sc, slave, sec, NULL, 0);
516 (void) gpibrecv(&cec_ic, slave, sec, NULL, 0);
517 } else {
518 /* XXX this doesn't work */
519 DPRINTF(DBG_FOLLOW, ("cecxfer: polling instead\n"));
520 bus_space_write_1(iot, ioh, NEC7210_IMR1, IMR1_END);
521 // XXX (void) cecrecv(sc, slave, sec, buf, count);
522 (void) gpibrecv(&cec_ic, slave, sec, buf, count);
523 bus_space_write_1(iot, ioh, NEC7210_IMR2, IMR2_CO);
524 }
525 } else {
526 DPRINTF(DBG_FOLLOW, ("cecxfer: DMA write request\n"));
527 bus_space_write_1(iot, ioh, NEC7210_IMR2, 0);
528 if (count < cecdmathresh ||
529 (sc->sc_flags & CECF_USEDMA) == 0) {
530 DPRINTF(DBG_FOLLOW, ("cecxfer: polling instead\n"));
531 // XXX (void) cecsend(sc, slave, sec, buf, count);
532 (void) gpibsend(&cec_ic, slave, sec, buf, count);
533 bus_space_write_1(iot, ioh, NEC7210_IMR2, IMR2_CO);
534 return;
535 }
536 /* we send the last byte with EOI set */
537 isa_dmastart(sc->sc_ic, sc->sc_drq, buf, count-1, NULL,
538 DMAMODE_WRITE | DMAMODE_DEMAND, BUS_DMA_NOWAIT);
539 bus_space_write_1(iot, ioh, NEC7210_IMR2, IMR2_DMAO);
540 // XXX (void) cecsend(sc, slave, sec, NULL, 0);
541 (void) gpibsend(&cec_ic, slave, sec, NULL, 0);
542 while (!isa_dmafinished(sc->sc_ic, sc->sc_drq))
543 DELAY(1);
544 (void) cecwait(sc, ISR1_DO, 0);
545 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_SEOI);
546 bus_space_write_1(iot, ioh, NEC7210_CDOR, *(char *)buf+count);
547 /* generate interrupt */
548 bus_space_write_1(iot, ioh, NEC7210_IMR1, IMR1_DO);
549 }
550 }
551
552 void
553 cecifc(void *v)
554 {
555 struct cec_softc *sc = v;
556
557 nec7210_ifc(sc);
558 }
559
560 static int
561 nec7210_setaddress(struct cec_softc *sc, int pri, int sec)
562 {
563 bus_space_tag_t iot = sc->sc_iot;
564 bus_space_handle_t ioh = sc->sc_ioh;
565 u_int8_t admr;
566
567 /* assign our primary address */
568 bus_space_write_1(iot, ioh, NEC7210_ADDR, (pri & ADDR_MASK));
569
570 admr = ADMR_TRM0 | ADMR_TRM1;
571
572 /* assign our secondary address */
573 if (sec != -1) {
574 bus_space_write_1(iot, ioh, NEC7210_ADDR,
575 (ADDR_ARS | (sec & ADDR_MASK)));
576 admr |= ADMR_ADM1;
577 } else {
578 /* disable secondary address */
579 bus_space_write_1(iot, ioh, NEC7210_ADDR,
580 (ADDR_ARS | ADDR_DT | ADDR_DL));
581 admr |= ADMR_ADM0;
582 }
583 bus_space_write_1(iot, ioh, NEC7210_ADMR, admr);
584
585 return (0);
586 }
587
588 static void
589 nec7210_init(struct cec_softc *sc)
590 {
591 bus_space_tag_t iot = sc->sc_iot;
592 bus_space_handle_t ioh = sc->sc_ioh;
593
594 /* reset chip */
595 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_CRST);
596
597 /* clear interrupts */
598 bus_space_read_1(iot, ioh, NEC7210_CPTR);
599 bus_space_read_1(iot, ioh, NEC7210_ISR1);
600 bus_space_read_1(iot, ioh, NEC7210_ISR2);
601
602 /* initialise interrupts */
603 bus_space_write_1(iot, ioh, NEC7210_IMR1, 0);
604 bus_space_write_1(iot, ioh, NEC7210_IMR2, 0);
605 bus_space_write_1(iot, ioh, NEC7210_SPMR, 0);
606 bus_space_write_1(iot, ioh, NEC7210_EOSR, 0);
607
608 /* set internal clock to 8MHz */
609 bus_space_write_1(iot, ioh, NEC7210_AUXMR, (AUXMR_ICR | 0x8));
610 /* parallel poll unconfigure */
611 bus_space_write_1(iot, ioh, NEC7210_AUXMR, (AUXMR_PPOLL | PPOLL_PPU));
612
613 /* assign our address */
614 bus_space_write_1(iot, ioh, NEC7210_ADDR, 0);
615 /* disable secondary address */
616 bus_space_write_1(iot, ioh, NEC7210_ADDR,
617 (ADDR_ARS | ADDR_DT | ADDR_DL));
618
619 /* setup transceivers */
620 bus_space_write_1(iot, ioh, NEC7210_ADMR,
621 (ADMR_ADM0 | ADMR_TRM0 | ADMR_TRM1));
622 bus_space_write_1(iot, ioh, NEC7210_AUXMR,
623 (AUXMR_REGA | AUX_A_HSNORM));
624
625 /* set INT pin to active high */
626 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXMR_REGB);
627 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXMR_REGE);
628
629 /* holdoff on end condition */
630 bus_space_write_1(iot, ioh, NEC7210_AUXMR, (AUXMR_REGA | AUX_A_HLDE));
631
632 /* reconnect to bus */
633 bus_space_write_1(iot, ioh, NEC7210_AUXMR, (AUXMR_CMD | AUXCMD_IEPON));
634 }
635
636 /*
637 * Place all devices on the bus into quiescient state ready for
638 * remote programming.
639 * Obviously, we're the system controller upon exit.
640 */
641 void
642 nec7210_ifc(struct cec_softc *sc)
643 {
644 bus_space_tag_t iot = sc->sc_iot;
645 bus_space_handle_t ioh = sc->sc_ioh;
646
647 /*XXX*/ bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_TCA);
648 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_CREN);
649 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_SIFC);
650 /* wait for devices to enter quiescient state */
651 DELAY(100);
652 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_CIFC);
653 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_SREN);
654 }
655
656 static int
657 cecwait(struct cec_softc *sc, int x1, int x2)
658 {
659 int timo = cecwtimeout;
660 bus_space_tag_t iot = sc->sc_iot;
661 bus_space_handle_t ioh = sc->sc_ioh;
662 u_int8_t stat1, stat2;
663
664 DPRINTF(DBG_WAIT, ("cecwait: sc=%p, x1=0x%x x2=0x%x\n", sc, x1, x2));
665
666 for (;;) {
667 stat1 = bus_space_read_1(iot, ioh, NEC7210_ISR1);
668 stat2 = bus_space_read_1(iot, ioh, NEC7210_ISR2);
669 #if 0
670 if ((stat1 & ISR1_ERR)) {
671 DPRINTF(DBG_WAIT, ("cecwait: got ERR\n"));
672 return (1);
673 }
674 #endif
675 if (--timo == 0) {
676 DPRINTF(DBG_REPORTTIME,
677 ("cecwait: timeout x1=0x%x x2=0x%x\n", x1, x2));
678 return (1);
679 }
680 if ((stat1 & x1) || (stat2 & x2))
681 break;
682 DELAY(1);
683 }
684 return (0);
685 }
686
687 static void
688 cectimeout(void *v)
689 {
690 struct cec_softc *sc = v;
691 bus_space_tag_t iot = sc->sc_iot;
692 bus_space_handle_t ioh = sc->sc_ioh;
693 int s;
694
695 DPRINTF(DBG_FOLLOW, ("cectimeout: sc=%p\n", sc));
696
697 s = splbio();
698 if (sc->sc_flags & CECF_IO) {
699 bus_space_write_1(iot, ioh, NEC7210_IMR1, 0);
700 bus_space_write_2(iot, ioh, NEC7210_IMR2, 0);
701 bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_TCA);
702 sc->sc_flags &= ~(CECF_IO | CECF_READ | CECF_TIMO);
703 isa_dmaabort(sc->sc_ic, sc->sc_drq);
704 aprint_error_dev(sc->sc_dev, "%s timeout\n",
705 sc->sc_flags & CECF_READ ? "read" : "write");
706 gpibintr(sc->sc_gpib);
707 }
708 splx(s);
709 }
710