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