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