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