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