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