cy.c revision 1.9 1 /* $NetBSD: cy.c,v 1.9 1998/03/21 23:26:15 mjacob Exp $ */
2
3 /*
4 * cy.c
5 *
6 * Driver for Cyclades Cyclom-8/16/32 multiport serial cards
7 * (currently not tested with Cyclom-32 cards)
8 *
9 * Timo Rossi, 1996
10 *
11 * Supports both ISA and PCI Cyclom cards
12 *
13 * Uses CD1400 automatic CTS flow control, and
14 * if CY_HW_RTS is defined, uses CD1400 automatic input flow control.
15 * This requires a special cable that exchanges the RTS and DTR lines.
16 *
17 * Lots of debug output can be enabled by defining CY_DEBUG
18 * Some debugging counters (number of receive/transmit interrupts etc.)
19 * can be enabled by defining CY_DEBUG1
20 */
21
22 #include <sys/types.h>
23 #include <sys/param.h>
24 #include <sys/ioctl.h>
25 #include <sys/syslog.h>
26 #include <sys/fcntl.h>
27 #include <sys/tty.h>
28 #include <sys/proc.h>
29 #include <sys/conf.h>
30 #include <sys/user.h>
31 #include <sys/ioctl.h>
32 #include <sys/select.h>
33 #include <sys/device.h>
34 #include <sys/malloc.h>
35 #include <sys/systm.h>
36
37 #include <machine/bus.h>
38
39 #include <dev/ic/cd1400reg.h>
40 #include <dev/ic/cyreg.h>
41 #include <dev/ic/cyvar.h>
42
43 /* Macros to clear/set/test flags. */
44 #define SET(t, f) (t) |= (f)
45 #define CLR(t, f) (t) &= ~(f)
46 #define ISSET(t, f) ((t) & (f))
47
48 static int cyparam __P((struct tty *, struct termios *));
49 static void cystart __P((struct tty *));
50 static void cy_poll __P((void *));
51 static int cy_modem_control __P((struct cy_softc *,
52 struct cy_port *, int, int));
53 static void cy_enable_transmitter __P((struct cy_softc *, struct cy_port *));
54 static void cd1400_channel_cmd __P((struct cy_softc *, struct cy_port *, int));
55 static int cy_speed __P((speed_t, int *, int *));
56
57 extern struct cfdriver cy_cd;
58
59 static int cy_open = 0;
60 static int cy_events = 0;
61
62 cdev_decl(cy);
63
64 /*
65 * Common probe routine
66 */
67 int
68 cy_find(sc)
69 struct cy_softc *sc;
70 {
71 int cy_chip, chip;
72 u_char firmware_ver;
73 bus_space_tag_t tag = sc->sc_memt;
74 bus_space_handle_t bsh = sc->sc_bsh;
75 int bustype = sc->sc_bustype;
76
77 /* Cyclom card hardware reset */
78 bus_space_write_1(tag, bsh, CY16_RESET << bustype, 0);
79 DELAY(500); /* wait for reset to complete */
80 bus_space_write_1(tag, bsh, CY_CLEAR_INTR << bustype, 0);
81
82 #ifdef CY_DEBUG
83 printf("cy: card reset done\n");
84 #endif
85 sc->sc_nchips = 0;
86
87 for (cy_chip = 0, chip = 0; cy_chip < CY_MAX_CD1400s;
88 cy_chip++, chip += (CY_CD1400_MEMSPACING << bustype)) {
89 int i;
90
91 /*
92 * the last 4 nchips are 'interleaved' with the first 4 on
93 * 32-port boards
94 */
95 if (cy_chip == 4)
96 chip -= (CY32_ADDR_FIX << bustype);
97
98 #ifdef CY_DEBUG
99 printf("%s probe chip %d offset 0x%x ... ",
100 sc->sc_dev.dv_xname, cy_chip, chip);
101 #endif
102
103 /* wait until the chip is ready for command */
104 DELAY(1000);
105 if (bus_space_read_1(tag, bsh, chip +
106 ((CD1400_CCR << 1) << bustype)) != 0) {
107 #ifdef CY_DEBUG
108 printf("not ready for command\n");
109 #endif
110 break;
111 }
112 /* clear the firmware version reg. */
113 bus_space_write_1(tag, bsh, chip +
114 ((CD1400_GFRCR << 1) << bustype), 0);
115
116 /*
117 * On Cyclom-16 references to non-existent chip 4
118 * actually access chip 0 (address line 9 not decoded).
119 * Here we check if the clearing of chip 4 GFRCR actually
120 * cleared chip 0 GFRCR. In that case we have a 16 port card.
121 */
122 if (cy_chip == 4 &&
123 bus_space_read_1(tag, bsh, /* off for chip 0 (0) + */
124 ((CD1400_GFRCR << 1) << bustype)) == 0)
125 break;
126
127 /* reset the chip */
128 bus_space_write_1(tag, bsh, chip +
129 ((CD1400_CCR << 1) << bustype),
130 CD1400_CCR_CMDRESET | CD1400_CCR_FULLRESET);
131
132 /* wait for the chip to initialize itself */
133 for (i = 0; i < 200; i++) {
134 DELAY(50);
135 firmware_ver = bus_space_read_1(tag, bsh, chip +
136 ((CD1400_GFRCR << 1) << bustype));
137 if ((firmware_ver & 0xf0) == 0x40) /* found a CD1400 */
138 break;
139 }
140 #ifdef CY_DEBUG
141 printf("firmware version 0x%x\n", firmware_ver);
142 #endif
143
144 if ((firmware_ver & 0xf0) != 0x40)
145 break;
146
147 /* firmware version OK, CD1400 found */
148 sc->sc_nchips++;
149 }
150
151 if (sc->sc_nchips == 0) {
152 #ifdef CY_DEBUG
153 printf("no CD1400s found\n");
154 #endif
155 return 0;
156 }
157 #ifdef CY_DEBUG
158 printf("found %d CD1400s\n", sc->sc_nchips);
159 #endif
160
161 return 1;
162 }
163
164 void
165 cy_attach(parent, self, aux)
166 struct device *parent, *self;
167 void *aux;
168 {
169 int port, cy_chip, num_chips, cdu, chip;
170 struct cy_softc *sc = (void *) self;
171
172 num_chips = sc->sc_nchips;
173 if (num_chips == 0)
174 return;
175
176 bzero(sc->sc_ports, sizeof(sc->sc_ports));
177
178 port = 0;
179 for (cy_chip = 0, chip = 0; cy_chip < num_chips; cy_chip++,
180 chip += (CY_CD1400_MEMSPACING << sc->sc_bustype)) {
181
182 if (cy_chip == 4)
183 chip -= (CY32_ADDR_FIX << sc->sc_bustype);
184
185 #ifdef CY_DEBUG
186 printf("attach CD1400 #%d offset 0x%x\n", cy_chip, chip);
187 #endif
188 sc->sc_cd1400_offs[cy_chip] = chip;
189
190 /*
191 * configure port 0 as serial port (should already be after
192 * reset)
193 */
194 cd_write_reg(sc, cy_chip, CD1400_GCR, 0);
195
196 /* set up a receive timeout period (1ms) */
197 cd_write_reg(sc, cy_chip, CD1400_PPR,
198 (CY_CLOCK / CD1400_PPR_PRESCALER / 1000) + 1);
199
200 for (cdu = 0; cdu < CD1400_NO_OF_CHANNELS; cdu++) {
201 sc->sc_ports[port].cy_port_num = port;
202 sc->sc_ports[port].cy_chip = cy_chip;
203
204 /* should we initialize anything else here? */
205 port++;
206 } /* for(each port on one CD1400...) */
207
208 } /* for(each CD1400 on a card... ) */
209
210 printf(": %d ports\n", port);
211
212 /* ensure an edge for the next interrupt */
213 bus_space_write_1(sc->sc_memt, sc->sc_bsh,
214 CY_CLEAR_INTR << sc->sc_bustype, 0);
215 }
216
217 /*
218 * open routine. returns zero if successfull, else error code
219 */
220 int
221 cyopen(dev, flag, mode, p)
222 dev_t dev;
223 int flag, mode;
224 struct proc *p;
225 {
226 int card = CY_CARD(dev);
227 int port = CY_PORT(dev);
228 struct cy_softc *sc;
229 struct cy_port *cy;
230 struct tty *tp;
231 int s, error;
232
233 #ifdef CY_DEBUG
234 printf("cy%d open port %d flag 0x%x mode 0x%x\n",
235 card, port, flag, mode);
236 #endif
237
238 if (card >= cy_cd.cd_ndevs || (sc = cy_cd.cd_devs[card]) == NULL)
239 return ENXIO;
240
241 cy = &sc->sc_ports[port];
242
243 s = spltty();
244 if (cy->cy_tty == NULL) {
245 if ((cy->cy_tty = ttymalloc()) == NULL) {
246 splx(s);
247 printf("cy%d: port %d: can't allocate tty\n",
248 card, port);
249 return ENOMEM;
250 }
251 tty_attach(cy->cy_tty);
252 }
253 splx(s);
254
255 tp = cy->cy_tty;
256 tp->t_oproc = cystart;
257 tp->t_param = cyparam;
258 tp->t_dev = dev;
259
260 if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) {
261 ttychars(tp);
262 tp->t_iflag = TTYDEF_IFLAG;
263 tp->t_oflag = TTYDEF_OFLAG;
264 tp->t_cflag = TTYDEF_CFLAG;
265 if (ISSET(cy->cy_openflags, TIOCFLAG_CLOCAL))
266 SET(tp->t_cflag, CLOCAL);
267 if (ISSET(cy->cy_openflags, TIOCFLAG_CRTSCTS))
268 SET(tp->t_cflag, CRTSCTS);
269 if (ISSET(cy->cy_openflags, TIOCFLAG_MDMBUF))
270 SET(tp->t_cflag, MDMBUF);
271 tp->t_lflag = TTYDEF_LFLAG;
272 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
273
274 s = spltty();
275
276 /*
277 * Allocate input ring buffer if we don't already have one
278 */
279 if (cy->cy_ibuf == NULL) {
280 cy->cy_ibuf = malloc(CY_IBUF_SIZE, M_DEVBUF, M_NOWAIT);
281 if (cy->cy_ibuf == NULL) {
282 printf("%s: port %d: can't allocate input buffer\n",
283 sc->sc_dev.dv_xname, port);
284 splx(s);
285 return ENOMEM;
286 }
287 cy->cy_ibuf_end = cy->cy_ibuf + CY_IBUF_SIZE;
288 }
289 /* mark the ring buffer as empty */
290 cy->cy_ibuf_rd_ptr = cy->cy_ibuf_wr_ptr = cy->cy_ibuf;
291
292 /* select CD1400 channel */
293 cd_write_reg(sc, cy->cy_chip, CD1400_CAR,
294 port & CD1400_CAR_CHAN);
295 /* reset the channel */
296 cd1400_channel_cmd(sc, cy, CD1400_CCR_CMDRESET);
297 /* encode unit (port) number in LIVR */
298 /* there is just enough space for 5 bits (32 ports) */
299 cd_write_reg(sc, cy->cy_chip, CD1400_LIVR, port << 3);
300
301 cy->cy_channel_control = 0;
302
303 /* hmm... need spltty() here? */
304 if (cy_open == 0) {
305 cy_open = 1;
306 timeout(cy_poll, NULL, 1);
307 }
308 /* this sets parameters and raises DTR */
309 cyparam(tp, &tp->t_termios);
310
311 ttsetwater(tp);
312
313 /* raise RTS too */
314 cy_modem_control(sc, cy, TIOCM_RTS, DMBIS);
315
316 cy->cy_carrier_stat =
317 cd_read_reg(sc, cy->cy_chip, CD1400_MSVR2);
318
319 /* enable receiver and modem change interrupts */
320 cd_write_reg(sc, cy->cy_chip, CD1400_SRER,
321 CD1400_SRER_MDMCH | CD1400_SRER_RXDATA);
322
323 if (CY_DIALOUT(dev) ||
324 ISSET(cy->cy_openflags, TIOCFLAG_SOFTCAR) ||
325 ISSET(tp->t_cflag, MDMBUF) ||
326 ISSET(cy->cy_carrier_stat, CD1400_MSVR2_CD))
327 SET(tp->t_state, TS_CARR_ON);
328 else
329 CLR(tp->t_state, TS_CARR_ON);
330 } else if (ISSET(tp->t_state, TS_XCLUDE) && p->p_ucred->cr_uid != 0) {
331 return EBUSY;
332 } else {
333 s = spltty();
334 }
335
336 /* wait for carrier if necessary */
337 if (!ISSET(flag, O_NONBLOCK)) {
338 while (!ISSET(tp->t_cflag, CLOCAL) &&
339 !ISSET(tp->t_state, TS_CARR_ON)) {
340 tp->t_wopen++;
341 error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH,
342 "cydcd", 0);
343 tp->t_wopen--;
344 if (error != 0) {
345 splx(s);
346 return error;
347 }
348 }
349 }
350 splx(s);
351
352 return (*linesw[tp->t_line].l_open) (dev, tp);
353 }
354
355 /*
356 * close routine. returns zero if successfull, else error code
357 */
358 int
359 cyclose(dev, flag, mode, p)
360 dev_t dev;
361 int flag, mode;
362 struct proc *p;
363 {
364 int card = CY_CARD(dev);
365 int port = CY_PORT(dev);
366 struct cy_softc *sc = cy_cd.cd_devs[card];
367 struct cy_port *cy = &sc->sc_ports[port];
368 struct tty *tp = cy->cy_tty;
369 int s;
370
371 #ifdef CY_DEBUG
372 printf("%s: close port %d, flag 0x%x, mode 0x%x\n",
373 sc->sc_dev.dv_xname, port, flag, mode);
374 #endif
375
376 (*linesw[tp->t_line].l_close) (tp, flag);
377 s = spltty();
378
379 if (ISSET(tp->t_cflag, HUPCL) &&
380 !ISSET(cy->cy_openflags, TIOCFLAG_SOFTCAR)) {
381 /*
382 * drop DTR and RTS (should we wait for output buffer to
383 * become empty first?)
384 */
385 cy_modem_control(sc, cy, 0, DMSET);
386 }
387 /*
388 * XXX should we disable modem change and
389 * receive interrupts here or somewhere ?
390 */
391 CLR(tp->t_state, TS_BUSY | TS_FLUSH);
392
393 splx(s);
394 ttyclose(tp);
395
396 return 0;
397 }
398
399 /*
400 * Read routine
401 */
402 int
403 cyread(dev, uio, flag)
404 dev_t dev;
405 struct uio *uio;
406 int flag;
407 {
408 int card = CY_CARD(dev);
409 int port = CY_PORT(dev);
410 struct cy_softc *sc = cy_cd.cd_devs[card];
411 struct cy_port *cy = &sc->sc_ports[port];
412 struct tty *tp = cy->cy_tty;
413
414 #ifdef CY_DEBUG
415 printf("%s: read port %d uio 0x%x flag 0x%x\n",
416 sc->sc_dev.dv_xname, port, uio, flag);
417 #endif
418
419 return ((*linesw[tp->t_line].l_read) (tp, uio, flag));
420 }
421
422 /*
423 * Write routine
424 */
425 int
426 cywrite(dev, uio, flag)
427 dev_t dev;
428 struct uio *uio;
429 int flag;
430 {
431 int card = CY_CARD(dev);
432 int port = CY_PORT(dev);
433 struct cy_softc *sc = cy_cd.cd_devs[card];
434 struct cy_port *cy = &sc->sc_ports[port];
435 struct tty *tp = cy->cy_tty;
436
437 #ifdef CY_DEBUG
438 printf("%s: write port %d uio 0x%x flag 0x%x\n",
439 sc->sc_dev.dv_xname, port, uio, flag);
440 #endif
441
442 return ((*linesw[tp->t_line].l_write) (tp, uio, flag));
443 }
444
445 /*
446 * return tty pointer
447 */
448 struct tty *
449 cytty(dev)
450 dev_t dev;
451 {
452 int card = CY_CARD(dev);
453 int port = CY_PORT(dev);
454 struct cy_softc *sc = cy_cd.cd_devs[card];
455 struct cy_port *cy = &sc->sc_ports[port];
456 struct tty *tp = cy->cy_tty;
457
458 #ifdef CY_DEBUG
459 printf("%s: tty port %d tp 0x%x\n", sc->sc_dev.dv_xname, port, tp);
460 #endif
461 return tp;
462 }
463
464 /*
465 * ioctl routine
466 */
467 int
468 cyioctl(dev, cmd, data, flag, p)
469 dev_t dev;
470 u_long cmd;
471 caddr_t data;
472 int flag;
473 struct proc *p;
474 {
475 int card = CY_CARD(dev);
476 int port = CY_PORT(dev);
477 struct cy_softc *sc = cy_cd.cd_devs[card];
478 struct cy_port *cy = &sc->sc_ports[port];
479 struct tty *tp = cy->cy_tty;
480 int error;
481
482 #ifdef CY_DEBUG
483 printf("%s: port %d ioctl cmd 0x%x data 0x%x flag 0x%x\n",
484 sc->sc_dev.dv_xname, port, cmd, data, flag);
485 #endif
486
487 error = (*linesw[tp->t_line].l_ioctl) (tp, cmd, data, flag, p);
488 if (error >= 0)
489 return error;
490
491 error = ttioctl(tp, cmd, data, flag, p);
492 if (error >= 0)
493 return error;
494
495 /* XXX should not allow dropping DTR when dialin? */
496
497 switch (cmd) {
498 case TIOCSBRK: /* start break */
499 SET(cy->cy_flags, CY_F_START_BREAK);
500 cy_enable_transmitter(sc, cy);
501 break;
502
503 case TIOCCBRK: /* stop break */
504 SET(cy->cy_flags, CY_F_END_BREAK);
505 cy_enable_transmitter(sc, cy);
506 break;
507
508 case TIOCSDTR: /* DTR on */
509 cy_modem_control(sc, cy, TIOCM_DTR, DMBIS);
510 break;
511
512 case TIOCCDTR: /* DTR off */
513 cy_modem_control(sc, cy, TIOCM_DTR, DMBIC);
514 break;
515
516 case TIOCMSET: /* set new modem control line values */
517 cy_modem_control(sc, cy, *((int *) data), DMSET);
518 break;
519
520 case TIOCMBIS: /* turn modem control bits on */
521 cy_modem_control(sc, cy, *((int *) data), DMBIS);
522 break;
523
524 case TIOCMBIC: /* turn modem control bits off */
525 cy_modem_control(sc, cy, *((int *) data), DMBIC);
526 break;
527
528 case TIOCMGET: /* get modem control/status line state */
529 *((int *) data) = cy_modem_control(sc, cy, 0, DMGET);
530 break;
531
532 case TIOCGFLAGS:
533 *((int *) data) = cy->cy_openflags |
534 (CY_DIALOUT(dev) ? TIOCFLAG_SOFTCAR : 0);
535 break;
536
537 case TIOCSFLAGS:
538 error = suser(p->p_ucred, &p->p_acflag);
539 if (error != 0)
540 return EPERM;
541
542 cy->cy_openflags = *((int *) data) &
543 (TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL |
544 TIOCFLAG_CRTSCTS | TIOCFLAG_MDMBUF);
545 break;
546
547 default:
548 return ENOTTY;
549 }
550
551 return 0;
552 }
553
554 /*
555 * start output
556 */
557 void
558 cystart(tp)
559 struct tty *tp;
560 {
561 int card = CY_CARD(tp->t_dev);
562 int port = CY_PORT(tp->t_dev);
563 struct cy_softc *sc = cy_cd.cd_devs[card];
564 struct cy_port *cy = &sc->sc_ports[port];
565 int s;
566
567 #ifdef CY_DEBUG
568 printf("%s: port %d start, tty 0x%x\n", sc->sc_dev.dv_xname, port, tp);
569 #endif
570
571
572 s = spltty();
573
574 #ifdef CY_DEBUG1
575 cy->cy_start_count++;
576 #endif
577
578 if (!ISSET(tp->t_state, TS_TTSTOP | TS_TIMEOUT | TS_BUSY)) {
579 if (tp->t_outq.c_cc <= tp->t_lowat) {
580 if (ISSET(tp->t_state, TS_ASLEEP)) {
581 CLR(tp->t_state, TS_ASLEEP);
582 wakeup(&tp->t_outq);
583 }
584 selwakeup(&tp->t_wsel);
585
586 if (tp->t_outq.c_cc == 0)
587 goto out;
588 }
589 SET(tp->t_state, TS_BUSY);
590 cy_enable_transmitter(sc, cy);
591 }
592 out:
593
594 splx(s);
595 }
596
597 /*
598 * stop output
599 */
600 void
601 cystop(tp, flag)
602 struct tty *tp;
603 int flag;
604 {
605 int card = CY_CARD(tp->t_dev);
606 int port = CY_PORT(tp->t_dev);
607 struct cy_softc *sc = cy_cd.cd_devs[card];
608 struct cy_port *cy = &sc->sc_ports[port];
609 int s;
610
611 #ifdef CY_DEBUG
612 printf("%s: port %d stop tty 0x%x flag 0x%x\n",
613 sc->sc_dev.dv_xname, port, tp, flag);
614 #endif
615
616 s = spltty();
617
618 if (ISSET(tp->t_state, TS_BUSY)) {
619 if (!ISSET(tp->t_state, TS_TTSTOP))
620 SET(tp->t_state, TS_FLUSH);
621
622 /*
623 * the transmit interrupt routine will disable transmit when it
624 * notices that CY_F_STOP has been set.
625 */
626 SET(cy->cy_flags, CY_F_STOP);
627 }
628 splx(s);
629 }
630
631 /*
632 * parameter setting routine.
633 * returns 0 if successfull, else returns error code
634 */
635 static int
636 cyparam(tp, t)
637 struct tty *tp;
638 struct termios *t;
639 {
640 int card = CY_CARD(tp->t_dev);
641 int port = CY_PORT(tp->t_dev);
642 struct cy_softc *sc = cy_cd.cd_devs[card];
643 struct cy_port *cy = &sc->sc_ports[port];
644 int ibpr, obpr, i_clk_opt, o_clk_opt;
645 int s, opt;
646
647 #ifdef CY_DEBUG
648 printf("%s: port %d param tty 0x%x termios 0x%x\n",
649 sc->sc_dev.dv_xname, port, tp, t);
650 printf("ispeed %d ospeed %d\n", t->c_ispeed, t->c_ospeed);
651 #endif
652
653 if (t->c_ospeed != 0 && cy_speed(t->c_ospeed, &o_clk_opt, &obpr) < 0)
654 return EINVAL;
655
656 if (t->c_ispeed != 0 && cy_speed(t->c_ispeed, &i_clk_opt, &ibpr) < 0)
657 return EINVAL;
658
659 s = spltty();
660
661 /* hang up the line is ospeed is zero, else turn DTR on */
662 cy_modem_control(sc, cy, TIOCM_DTR, (t->c_ospeed == 0 ? DMBIC : DMBIS));
663
664 /* channel was selected by the above call to cy_modem_control() */
665 #if 0
666 cd_write_reg(sc, cy->cy_chip, CD1400_CAR, port & CD1400_CAR_CHAN);
667 #endif
668
669 /* set transmit speed */
670 if (t->c_ospeed != 0) {
671 cd_write_reg(sc, cy->cy_chip, CD1400_TCOR, o_clk_opt);
672 cd_write_reg(sc, cy->cy_chip, CD1400_TBPR, obpr);
673 }
674 /* set receive speed */
675 if (t->c_ispeed != 0) {
676 cd_write_reg(sc, cy->cy_chip, CD1400_RCOR, i_clk_opt);
677 cd_write_reg(sc, cy->cy_chip, CD1400_RBPR, ibpr);
678 }
679 opt = CD1400_CCR_CMDCHANCTL | CD1400_CCR_XMTEN
680 | (ISSET(t->c_cflag, CREAD) ? CD1400_CCR_RCVEN : CD1400_CCR_RCVDIS);
681
682 if (opt != cy->cy_channel_control) {
683 cy->cy_channel_control = opt;
684 cd1400_channel_cmd(sc, cy, opt);
685 }
686 /* compute COR1 contents */
687 opt = 0;
688 if (ISSET(t->c_cflag, PARENB)) {
689 if (ISSET(t->c_cflag, PARODD))
690 opt |= CD1400_COR1_PARODD;
691 opt |= CD1400_COR1_PARNORMAL;
692 }
693 if (!ISSET(t->c_iflag, INPCK))
694 opt |= CD1400_COR1_NOINPCK; /* no parity checking */
695
696 if (ISSET(t->c_cflag, CSTOPB))
697 opt |= CD1400_COR1_STOP2;
698
699 switch (t->c_cflag & CSIZE) {
700 case CS5:
701 opt |= CD1400_COR1_CS5;
702 break;
703
704 case CS6:
705 opt |= CD1400_COR1_CS6;
706 break;
707
708 case CS7:
709 opt |= CD1400_COR1_CS7;
710 break;
711
712 default:
713 opt |= CD1400_COR1_CS8;
714 break;
715 }
716
717 cd_write_reg(sc, cy->cy_chip, CD1400_COR1, opt);
718
719 #ifdef CY_DEBUG
720 printf("cor1 = 0x%x...", opt);
721 #endif
722
723 /*
724 * use the CD1400 automatic CTS flow control if CRTSCTS is set
725 *
726 * CD1400_COR2_ETC is used because breaks are generated with
727 * embedded transmit commands
728 */
729 cd_write_reg(sc, cy->cy_chip, CD1400_COR2,
730 CD1400_COR2_ETC |
731 (ISSET(t->c_cflag, CRTSCTS) ? CD1400_COR2_CCTS_OFLOW : 0));
732
733 cd_write_reg(sc, cy->cy_chip, CD1400_COR3, CY_RX_FIFO_THRESHOLD);
734
735 cd1400_channel_cmd(sc, cy, CD1400_CCR_CMDCORCHG |
736 CD1400_CCR_COR1 | CD1400_CCR_COR2 | CD1400_CCR_COR3);
737
738 cd_write_reg(sc, cy->cy_chip, CD1400_COR4, CD1400_COR4_PFO_EXCEPTION);
739 cd_write_reg(sc, cy->cy_chip, CD1400_COR5, 0);
740
741 /*
742 * set modem change option registers to generate interrupts
743 * on carrier detect changes.
744 *
745 * if hardware RTS handshaking is used (CY_HW_RTS, DTR and RTS lines
746 * exchanged), also set the handshaking threshold.
747 */
748 #ifdef CY_HW_RTS
749 cd_write_reg(sc, cy->cy_chip, CD1400_MCOR1, CD1400_MCOR1_CDzd |
750 (ISSET(t->c_cflag, CRTSCTS) ? RX_DTR_THRESHOLD : 0));
751 #else
752 cd_write_reg(sc, cy->cy_chip, CD1400_MCOR1, CD1400_MCOR1_CDzd);
753 #endif /* CY_HW_RTS */
754
755 cd_write_reg(sc, cy->cy_chip, CD1400_MCOR2, CD1400_MCOR2_CDod);
756
757 /*
758 * set receive timeout to approx. 2ms
759 * could use more complex logic here...
760 * (but is it actually needed or even useful?)
761 */
762 cd_write_reg(sc, cy->cy_chip, CD1400_RTPR, 2);
763
764 /*
765 * should do anything else here?
766 * XXX check MDMBUF handshaking like in com.c?
767 */
768
769 splx(s);
770 return 0;
771 }
772
773 /*
774 * set/get modem line status
775 *
776 * bits can be: TIOCM_DTR, TIOCM_RTS, TIOCM_CTS, TIOCM_CD, TIOCM_RI, TIOCM_DSR
777 *
778 * RTS and DTR are exchanged if CY_HW_RTS is set
779 *
780 */
781 static int
782 cy_modem_control(sc, cy, bits, howto)
783 struct cy_softc *sc;
784 struct cy_port *cy;
785 int bits;
786 int howto;
787 {
788 int s, msvr;
789 struct tty *tp = cy->cy_tty;
790
791 s = spltty();
792
793 /* select channel */
794 cd_write_reg(sc, cy->cy_chip, CD1400_CAR,
795 cy->cy_port_num & CD1400_CAR_CHAN);
796
797 /* does not manipulate RTS if it is used for flow control */
798 switch (howto) {
799 case DMGET:
800 splx(s);
801 bits = 0;
802 if (cy->cy_channel_control & CD1400_CCR_RCVEN)
803 bits |= TIOCM_LE;
804 msvr = cd_read_reg(sc, cy->cy_chip, CD1400_MSVR2);
805 #ifdef CY_HW_RTS
806 if (cd_read_reg(sc, cy->cy_chip, CD1400_MSVR1) &
807 CD1400_MSVR1_RTS)
808 bits |= TIOCM_DTR;
809 if (msvr & CD1400_MSVR2_DTR)
810 bits |= TIOCM_RTS;
811 #else
812 if (cd_read_reg(sc, cy->cy_chip, CD1400_MSVR1) &
813 CD1400_MSVR1_RTS)
814 bits |= TIOCM_RTS;
815 if (msvr & CD1400_MSVR2_DTR)
816 bits |= TIOCM_DTR;
817 #endif /* CY_HW_RTS */
818 if (msvr & CD1400_MSVR2_CTS)
819 bits |= TIOCM_CTS;
820 if (msvr & CD1400_MSVR2_CD)
821 bits |= TIOCM_CD;
822 if (msvr & CD1400_MSVR2_DSR) /* not connected on some
823 * Cyclom cards? */
824 bits |= TIOCM_DSR;
825 if (msvr & CD1400_MSVR2_RI) /* not connected on Cyclom-8Y
826 * cards? */
827 bits |= TIOCM_RI;
828 splx(s);
829 return bits;
830
831 case DMSET: /* replace old values with new ones */
832 #ifdef CY_HW_RTS
833 if (!ISSET(tp->>t_cflag, CRTSCTS))
834 cd_write_reg(sc, cy->cy_chip, CD1400_MSVR2,
835 ((bits & TIOCM_RTS) ? CD1400_MSVR2_DTR : 0));
836 cd_write_reg(sc, cy->cy_chip, CD1400_MSVR1,
837 ((bits & TIOCM_DTR) ? CD1400_MSVR1_RTS : 0));
838 #else
839 if (!ISSET(tp->t_cflag, CRTSCTS))
840 cd_write_reg(sc, cy->cy_chip, CD1400_MSVR1,
841 ((bits & TIOCM_RTS) ? CD1400_MSVR1_RTS : 0));
842 cd_write_reg(sc, cy->cy_chip, CD1400_MSVR2,
843 ((bits & TIOCM_DTR) ? CD1400_MSVR2_DTR : 0));
844 #endif /* CY_HW_RTS */
845 break;
846
847 case DMBIS: /* set bits */
848 #ifdef CY_HW_RTS
849 if (!ISSET(tp->t_cflag, CRTSCTS) && (bits & TIOCM_RTS) != 0)
850 cd_write_reg(sc, cy->cy_chip, CD1400_MSVR2,
851 CD1400_MSVR2_DTR);
852 if (bits & TIOCM_DTR)
853 cd_write_reg(sc, cy->cy_chip, CD1400_MSVR1,
854 CD1400_MSVR1_RTS);
855 #else
856 if (!ISSET(tp->t_cflag, CRTSCTS) && (bits & TIOCM_RTS) != 0)
857 cd_write_reg(sc, cy->cy_chip, CD1400_MSVR1,
858 CD1400_MSVR1_RTS);
859 if (bits & TIOCM_DTR)
860 cd_write_reg(sc, cy->cy_chip, CD1400_MSVR2,
861 CD1400_MSVR2_DTR);
862 #endif /* CY_HW_RTS */
863 break;
864
865 case DMBIC: /* clear bits */
866 #ifdef CY_HW_RTS
867 if (!ISSET(tp->t_cflag, CRTSCTS) && (bits & TIOCM_RTS))
868 cd_write_reg(sc, cy->cy_chip, CD1400_MSVR2, 0);
869 if (bits & TIOCM_DTR)
870 cd_write_reg(sc, cy->cy_chip, CD1400_MSVR1, 0);
871 #else
872 if (!ISSET(tp->t_cflag, CRTSCTS) && (bits & TIOCM_RTS))
873 cd_write_reg(sc, cy->cy_chip, CD1400_MSVR1, 0);
874 if (bits & TIOCM_DTR)
875 cd_write_reg(sc, cy->cy_chip, CD1400_MSVR2, 0);
876 #endif /* CY_HW_RTS */
877 break;
878 }
879 splx(s);
880 return 0;
881 }
882
883 /*
884 * Upper-level handler loop (called from timer interrupt?)
885 * This routine is common for multiple cards
886 */
887 static void
888 cy_poll(arg)
889 void *arg;
890 {
891 int card, port;
892 struct cy_softc *sc;
893 struct cy_port *cy;
894 struct tty *tp;
895 static int counter = 0;
896 #ifdef CY_DEBUG1
897 int did_something;
898 #endif
899 int s = spltty();
900
901 if (cy_events == 0 && ++counter < 200) {
902 splx(s);
903 goto out;
904 }
905 cy_events = 0;
906 splx(s);
907
908 for (card = 0; card < cy_cd.cd_ndevs; card++) {
909 sc = cy_cd.cd_devs[card];
910 if (sc == NULL)
911 continue;
912
913 #ifdef CY_DEBUG1
914 sc->sc_poll_count1++;
915 did_something = 0;
916 #endif
917
918 for (port = 0; port < sc->sc_nchips * CD1400_NO_OF_CHANNELS;
919 port++) {
920 cy = &sc->sc_ports[port];
921 if ((tp = cy->cy_tty) == NULL || cy->cy_ibuf == NULL ||
922 !ISSET(tp->t_state, TS_ISOPEN) || tp->t_wopen == 0)
923 continue;
924
925 /*
926 * handle received data
927 */
928 while (cy->cy_ibuf_rd_ptr != cy->cy_ibuf_wr_ptr) {
929 u_char line_stat;
930 int chr;
931
932 line_stat = cy->cy_ibuf_rd_ptr[0];
933 chr = cy->cy_ibuf_rd_ptr[1];
934
935 if (line_stat &
936 (CD1400_RDSR_BREAK | CD1400_RDSR_FE))
937 chr |= TTY_FE;
938 if (line_stat & CD1400_RDSR_PE)
939 chr |= TTY_PE;
940
941 /*
942 * on an overrun error the data is treated as
943 * good just as it should be.
944 */
945
946 #ifdef CY_DEBUG
947 printf("%s: port %d ttyinput 0x%x\n",
948 sc->sc_dev.dv_xname, port, chr);
949 #endif
950
951 (*linesw[tp->t_line].l_rint) (chr, tp);
952
953 s = spltty(); /* really necessary? */
954 if ((cy->cy_ibuf_rd_ptr += 2) ==
955 cy->cy_ibuf_end)
956 cy->cy_ibuf_rd_ptr = cy->cy_ibuf;
957 splx(s);
958
959 #ifdef CY_DEBUG1
960 did_something = 1;
961 #endif
962 }
963
964 #ifndef CY_HW_RTS
965 /*
966 * If we don't have any received data in ibuf and
967 * CRTSCTS is on and RTS is turned off, it is time to
968 * turn RTS back on
969 */
970 if (ISSET(tp->t_cflag, CRTSCTS)) {
971 /*
972 * we can't use cy_modem_control() here as it
973 * doesn't change RTS if RTSCTS is on
974 */
975 cd_write_reg(sc, cy->cy_chip, CD1400_CAR,
976 port & CD1400_CAR_CHAN);
977
978 if ((cd_read_reg(sc, cy->cy_chip,
979 CD1400_MSVR1) & CD1400_MSVR1_RTS) == 0) {
980 cd_write_reg(sc, cy->cy_chip, CD1400_MSVR1,
981 CD1400_MSVR1_RTS);
982 #ifdef CY_DEBUG1
983 did_something = 1;
984 #endif
985 }
986 }
987 #endif /* CY_HW_RTS */
988
989 /*
990 * handle carrier changes
991 */
992 s = spltty();
993 if (ISSET(cy->cy_flags, CY_F_CARRIER_CHANGED)) {
994 int carrier;
995
996 CLR(cy->cy_flags, CY_F_CARRIER_CHANGED);
997 splx(s);
998
999 carrier = ((cy->cy_carrier_stat &
1000 CD1400_MSVR2_CD) != 0);
1001
1002 #ifdef CY_DEBUG
1003 printf("cy_poll: carrier change "
1004 "(card %d, port %d, carrier %d)\n",
1005 card, port, carrier);
1006 #endif
1007 if (CY_DIALIN(tp->t_dev) &&
1008 !(*linesw[tp->t_line].l_modem)(tp, carrier))
1009 cy_modem_control(sc, cy,
1010 TIOCM_DTR, DMBIC);
1011
1012 #ifdef CY_DEBUG1
1013 did_something = 1;
1014 #endif
1015 } else
1016 splx(s);
1017
1018 s = spltty();
1019 if (ISSET(cy->cy_flags, CY_F_START)) {
1020 CLR(cy->cy_flags, CY_F_START);
1021 splx(s);
1022
1023 (*linesw[tp->t_line].l_start) (tp);
1024
1025 #ifdef CY_DEBUG1
1026 did_something = 1;
1027 #endif
1028 } else
1029 splx(s);
1030
1031 /* could move this to even upper level... */
1032 if (cy->cy_fifo_overruns) {
1033 cy->cy_fifo_overruns = 0;
1034 /*
1035 * doesn't report overrun count, but
1036 * shouldn't really matter
1037 */
1038 log(LOG_WARNING, "%s: port %d fifo overrun\n",
1039 sc->sc_dev.dv_xname, port);
1040 }
1041 if (cy->cy_ibuf_overruns) {
1042 cy->cy_ibuf_overruns = 0;
1043 log(LOG_WARNING, "%s: port %d ibuf overrun\n",
1044 sc->sc_dev.dv_xname, port);
1045 }
1046 } /* for(port...) */
1047 #ifdef CY_DEBUG1
1048 if (did_something && counter >= 200)
1049 sc->sc_poll_count2++;
1050 #endif
1051 } /* for(card...) */
1052
1053 counter = 0;
1054
1055 out:
1056 timeout(cy_poll, NULL, 1);
1057 }
1058
1059 /*
1060 * hardware interrupt routine
1061 */
1062 int
1063 cy_intr(arg)
1064 void *arg;
1065 {
1066 struct cy_softc *sc = arg;
1067 struct cy_port *cy;
1068 int cy_chip, stat;
1069 int int_serviced = 0;
1070
1071 /*
1072 * Check interrupt status of each CD1400 chip on this card
1073 * (multiple cards cannot share the same interrupt)
1074 */
1075 for (cy_chip = 0; cy_chip < sc->sc_nchips; cy_chip++) {
1076
1077 stat = cd_read_reg(sc, cy_chip, CD1400_SVRR);
1078 if (stat == 0)
1079 continue;
1080
1081 if (ISSET(stat, CD1400_SVRR_RXRDY)) {
1082 u_char save_car, save_rir, serv_type;
1083 u_char line_stat, recv_data, n_chars;
1084 u_char *buf_p;
1085
1086 save_rir = cd_read_reg(sc, cy_chip, CD1400_RIR);
1087 save_car = cd_read_reg(sc, cy_chip, CD1400_CAR);
1088 /* enter rx service */
1089 cd_write_reg(sc, cy_chip, CD1400_CAR, save_rir);
1090
1091 serv_type = cd_read_reg(sc, cy_chip, CD1400_RIVR);
1092 cy = &sc->sc_ports[serv_type >> 3];
1093
1094 #ifdef CY_DEBUG1
1095 cy->cy_rx_int_count++;
1096 #endif
1097
1098 if (cy->cy_tty == NULL ||
1099 !ISSET(cy->cy_tty->t_state, TS_ISOPEN))
1100 goto end_rx_serv;
1101
1102 buf_p = cy->cy_ibuf_wr_ptr;
1103
1104 if (ISSET(serv_type, CD1400_RIVR_EXCEPTION)) {
1105 line_stat = cd_read_reg(sc, cy->cy_chip,
1106 CD1400_RDSR);
1107 recv_data = cd_read_reg(sc, cy->cy_chip,
1108 CD1400_RDSR);
1109
1110 #ifdef CY_DEBUG
1111 printf("cy%d port %d recv exception, line_stat 0x%x, char 0x%x\n",
1112 card, cy->cy_port_num, line_stat, recv_data);
1113 #endif
1114 if (ISSET(line_stat, CD1400_RDSR_OE))
1115 cy->cy_fifo_overruns++;
1116
1117 *buf_p++ = line_stat;
1118 *buf_p++ = recv_data;
1119 if (buf_p == cy->cy_ibuf_end)
1120 buf_p = cy->cy_ibuf;
1121
1122 if (buf_p == cy->cy_ibuf_rd_ptr) {
1123 if (buf_p == cy->cy_ibuf)
1124 buf_p = cy->cy_ibuf_end;
1125 buf_p -= 2;
1126 cy->cy_ibuf_overruns++;
1127 }
1128 cy_events = 1;
1129 } else {/* no exception, received data OK */
1130 n_chars = cd_read_reg(sc, cy->cy_chip,
1131 CD1400_RDCR);
1132 #ifdef CY_DEBUG
1133 printf("cy%d port %d receive ok %d chars\n",
1134 card, cy->cy_port_num, n_chars);
1135 #endif
1136 while (n_chars--) {
1137 *buf_p++ = 0; /* status: OK */
1138 /* data byte */
1139 *buf_p++ = cd_read_reg(sc,
1140 cy->cy_chip, CD1400_RDSR);
1141 if (buf_p == cy->cy_ibuf_end)
1142 buf_p = cy->cy_ibuf;
1143 if (buf_p == cy->cy_ibuf_rd_ptr) {
1144 if (buf_p == cy->cy_ibuf)
1145 buf_p = cy->cy_ibuf_end;
1146 buf_p -= 2;
1147 cy->cy_ibuf_overruns++;
1148 break;
1149 }
1150 }
1151 cy_events = 1;
1152 }
1153
1154 cy->cy_ibuf_wr_ptr = buf_p;
1155
1156 #ifndef CY_HW_RTS
1157 /* RTS handshaking for incoming data */
1158 if (ISSET(cy->cy_tty->t_cflag, CRTSCTS)) {
1159 int bf;
1160
1161 bf = buf_p - cy->cy_ibuf_rd_ptr;
1162 if (bf < 0)
1163 bf += CY_IBUF_SIZE;
1164
1165 if (bf > (CY_IBUF_SIZE / 2)) /* turn RTS off */
1166 cd_write_reg(sc, cy->cy_chip, CD1400_MSVR1, 0);
1167 }
1168 #endif /* CY_HW_RTS */
1169
1170 end_rx_serv:
1171 /* terminate service context */
1172 cd_write_reg(sc, cy->cy_chip, CD1400_RIR, save_rir & 0x3f);
1173 cd_write_reg(sc, cy->cy_chip, CD1400_CAR, save_car);
1174 int_serviced = 1;
1175 } /* if(rx_service...) */
1176 if (ISSET(stat, CD1400_SVRR_MDMCH)) {
1177 u_char save_car, save_mir, serv_type, modem_stat;
1178
1179 save_mir = cd_read_reg(sc, cy_chip, CD1400_MIR);
1180 save_car = cd_read_reg(sc, cy_chip, CD1400_CAR);
1181 /* enter modem service */
1182 cd_write_reg(sc, cy_chip, CD1400_CAR, save_mir);
1183
1184 serv_type = cd_read_reg(sc, cy_chip, CD1400_MIVR);
1185 cy = &sc->sc_ports[serv_type >> 3];
1186
1187 #ifdef CY_DEBUG1
1188 cy->cy_modem_int_count++;
1189 #endif
1190
1191 modem_stat = cd_read_reg(sc, cy->cy_chip, CD1400_MSVR2);
1192
1193 #ifdef CY_DEBUG
1194 printf("cy%d port %d modem line change, new stat 0x%x\n",
1195 card, cy->cy_port_num, modem_stat);
1196 #endif
1197 if (ISSET((cy->cy_carrier_stat ^ modem_stat), CD1400_MSVR2_CD)) {
1198 SET(cy->cy_flags, CY_F_CARRIER_CHANGED);
1199 cy_events = 1;
1200 }
1201 cy->cy_carrier_stat = modem_stat;
1202
1203 /* terminate service context */
1204 cd_write_reg(sc, cy->cy_chip, CD1400_MIR, save_mir & 0x3f);
1205 cd_write_reg(sc, cy->cy_chip, CD1400_CAR, save_car);
1206 int_serviced = 1;
1207 } /* if(modem_service...) */
1208 if (ISSET(stat, CD1400_SVRR_TXRDY)) {
1209 u_char save_car, save_tir, serv_type,
1210 count, ch;
1211 struct tty *tp;
1212
1213 save_tir = cd_read_reg(sc, cy_chip, CD1400_TIR);
1214 save_car = cd_read_reg(sc, cy_chip, CD1400_CAR);
1215 /* enter tx service */
1216 cd_write_reg(sc, cy_chip, CD1400_CAR, save_tir);
1217
1218 serv_type = cd_read_reg(sc, cy_chip, CD1400_TIVR);
1219 cy = &sc->sc_ports[serv_type >> 3];
1220
1221 #ifdef CY_DEBUG1
1222 cy->cy_tx_int_count++;
1223 #endif
1224 #ifdef CY_DEBUG
1225 printf("cy%d port %d tx service\n", card,
1226 cy->cy_port_num);
1227 #endif
1228
1229 /* stop transmitting if no tty or CY_F_STOP set */
1230 tp = cy->cy_tty;
1231 if (tp == NULL || ISSET(cy->cy_flags, CY_F_STOP))
1232 goto txdone;
1233
1234 count = 0;
1235 if (ISSET(cy->cy_flags, CY_F_SEND_NUL)) {
1236 cd_write_reg(sc, cy->cy_chip, CD1400_TDR, 0);
1237 cd_write_reg(sc, cy->cy_chip, CD1400_TDR, 0);
1238 count += 2;
1239 CLR(cy->cy_flags, CY_F_SEND_NUL);
1240 }
1241 if (tp->t_outq.c_cc > 0) {
1242 SET(tp->t_state, TS_BUSY);
1243 while (tp->t_outq.c_cc > 0 &&
1244 count < CD1400_TX_FIFO_SIZE) {
1245 ch = getc(&tp->t_outq);
1246 /*
1247 * remember to double NUL characters
1248 * because embedded transmit commands
1249 * are enabled
1250 */
1251 if (ch == 0) {
1252 if (count >= CD1400_TX_FIFO_SIZE - 2) {
1253 SET(cy->cy_flags, CY_F_SEND_NUL);
1254 break;
1255 }
1256 cd_write_reg(sc, cy->cy_chip,
1257 CD1400_TDR, ch);
1258 count++;
1259 }
1260 cd_write_reg(sc, cy->cy_chip,
1261 CD1400_TDR, ch);
1262 count++;
1263 }
1264 } else {
1265 /*
1266 * no data to send -- check if we should
1267 * start/stop a break
1268 */
1269 /*
1270 * XXX does this cause too much delay before
1271 * breaks?
1272 */
1273 if (ISSET(cy->cy_flags, CY_F_START_BREAK)) {
1274 cd_write_reg(sc, cy->cy_chip,
1275 CD1400_TDR, 0);
1276 cd_write_reg(sc, cy->cy_chip,
1277 CD1400_TDR, 0x81);
1278 CLR(cy->cy_flags, CY_F_START_BREAK);
1279 }
1280 if (ISSET(cy->cy_flags, CY_F_END_BREAK)) {
1281 cd_write_reg(sc, cy->cy_chip,
1282 CD1400_TDR, 0);
1283 cd_write_reg(sc, cy->cy_chip,
1284 CD1400_TDR, 0x83);
1285 CLR(cy->cy_flags, CY_F_END_BREAK);
1286 }
1287 }
1288
1289 if (tp->t_outq.c_cc == 0) {
1290 txdone:
1291 /*
1292 * No data to send or requested to stop.
1293 * Disable transmit interrupt
1294 */
1295 cd_write_reg(sc, cy->cy_chip, CD1400_SRER,
1296 cd_read_reg(sc, cy->cy_chip, CD1400_SRER)
1297 & ~CD1400_SRER_TXRDY);
1298 CLR(cy->cy_flags, CY_F_STOP);
1299 CLR(tp->t_state, TS_BUSY);
1300 }
1301 if (tp->t_outq.c_cc <= tp->t_lowat) {
1302 SET(cy->cy_flags, CY_F_START);
1303 cy_events = 1;
1304 }
1305 /* terminate service context */
1306 cd_write_reg(sc, cy->cy_chip, CD1400_TIR, save_tir & 0x3f);
1307 cd_write_reg(sc, cy->cy_chip, CD1400_CAR, save_car);
1308 int_serviced = 1;
1309 } /* if(tx_service...) */
1310 } /* for(...all CD1400s on a card) */
1311
1312 /* ensure an edge for next interrupt */
1313 bus_space_write_1(sc->sc_memt, sc->sc_bsh,
1314 CY_CLEAR_INTR << sc->sc_bustype, 0);
1315 return int_serviced;
1316 }
1317
1318 /*
1319 * subroutine to enable CD1400 transmitter
1320 */
1321 static void
1322 cy_enable_transmitter(sc, cy)
1323 struct cy_softc *sc;
1324 struct cy_port *cy;
1325 {
1326 int s = spltty();
1327 cd_write_reg(sc, cy->cy_chip, CD1400_CAR,
1328 cy->cy_port_num & CD1400_CAR_CHAN);
1329 cd_write_reg(sc, cy->cy_chip, CD1400_SRER,
1330 cd_read_reg(sc, cy->cy_chip, CD1400_SRER) | CD1400_SRER_TXRDY);
1331 splx(s);
1332 }
1333
1334 /*
1335 * Execute a CD1400 channel command
1336 */
1337 static void
1338 cd1400_channel_cmd(sc, cy, cmd)
1339 struct cy_softc *sc;
1340 struct cy_port *cy;
1341 int cmd;
1342 {
1343 u_int waitcnt = 5 * 8 * 1024; /* approx 5 ms */
1344
1345 #ifdef CY_DEBUG
1346 printf("c1400_channel_cmd cy 0x%x command 0x%x\n", cy, cmd);
1347 #endif
1348
1349 /* wait until cd1400 is ready to process a new command */
1350 while (cd_read_reg(sc, cy->cy_chip, CD1400_CCR) != 0 && waitcnt-- > 0);
1351
1352 if (waitcnt == 0)
1353 log(LOG_ERR, "%s: channel command timeout\n",
1354 sc->sc_dev.dv_xname);
1355
1356 cd_write_reg(sc, cy->cy_chip, CD1400_CCR, cmd);
1357 }
1358
1359 /*
1360 * Compute clock option register and baud rate register values
1361 * for a given speed. Return 0 on success, -1 on failure.
1362 *
1363 * The error between requested and actual speed seems
1364 * to be well within allowed limits (less than 3%)
1365 * with every speed value between 50 and 150000 bps.
1366 */
1367 static int
1368 cy_speed(speed, cor, bpr)
1369 speed_t speed;
1370 int *cor, *bpr;
1371 {
1372 int c, co, br;
1373
1374 if (speed < 50 || speed > 150000)
1375 return -1;
1376
1377 for (c = 0, co = 8; co <= 2048; co <<= 2, c++) {
1378 br = (CY_CLOCK + (co * speed) / 2) / (co * speed);
1379 if (br < 0x100) {
1380 *bpr = br;
1381 *cor = c;
1382 return 0;
1383 }
1384 }
1385
1386 return -1;
1387 }
1388