1 /* $NetBSD: zs.c,v 1.63 2009/07/19 05:43:23 tsutsui Exp $ */
4 * Copyright (c) 1992, 1993
5 * The Regents of the University of California. All rights reserved.
7 * This software was developed by the Computer Systems Engineering group
8 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
9 * contributed to Berkeley.
12 * All advertising materials mentioning features or use of this software
13 * must display the following acknowledgement:
14 * This product includes software developed by the University of
15 * California, Lawrence Berkeley Laboratory.
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions
20 * 1. Redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer.
22 * 2. Redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution.
25 * 3. Neither the name of the University nor the names of its contributors
26 * may be used to endorse or promote products derived from this software
27 * without specific prior written permission.
29 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
30 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
41 * @(#)zs.c 8.1 (Berkeley) 7/19/93
45 * Copyright (c) 1995 The NetBSD Foundation, Inc. (Atari modifications)
46 * All rights reserved.
48 * This code is derived from software contributed to The NetBSD Foundation
51 * Redistribution and use in source and binary forms, with or without
52 * modification, are permitted provided that the following conditions
54 * 1. Redistributions of source code must retain the above copyright
55 * notice, this list of conditions and the following disclaimer.
56 * 2. Redistributions in binary form must reproduce the above copyright
57 * notice, this list of conditions and the following disclaimer in the
58 * documentation and/or other materials provided with the distribution.
60 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
61 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
62 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
63 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
64 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
65 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
66 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
67 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
68 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
69 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
70 * POSSIBILITY OF SUCH DAMAGE.
74 * Zilog Z8530 (ZSCC) driver.
76 * Runs two tty ports (modem2 and serial2) on zs0.
78 * This driver knows far too much about chip to usage mappings.
81 #include <sys/cdefs.h>
82 __KERNEL_RCSID(0, "$NetBSD: zs.c,v 1.63 2009/07/19 05:43:23 tsutsui Exp $");
84 #include <sys/param.h>
85 #include <sys/systm.h>
87 #include <sys/device.h>
90 #include <sys/ioctl.h>
91 #include <sys/malloc.h>
94 #include <sys/kernel.h>
95 #include <sys/syslog.h>
96 #include <sys/kauth.h>
98 #include <machine/cpu.h>
99 #include <machine/iomap.h>
100 #include <machine/scu.h>
101 #include <machine/mfp.h>
102 #include <atari/dev/ym2149reg.h>
104 #include <dev/ic/z8530reg.h>
105 #include <atari/dev/zsvar.h>
108 #error "This driver supports only 1 85C30!"
113 #define PCLK (8053976) /* PCLK pin input clock rate */
114 #define PCLK_HD (9600 * 1536) /* PCLK on Hades pin input clock rate */
119 * Software state per found chip.
122 struct device zi_dev
; /* base device */
123 volatile struct zsdevice
*zi_zs
; /* chip registers */
124 struct zs_chanstate zi_cs
[2]; /* chan A and B software state */
127 static void *zs_softint_cookie
; /* for callback */
129 * Define the registers for a closed port
131 static u_char zs_init_regs
[16] = {
141 /* 9 */ ZSWR9_MASTER_IE
| ZSWR9_VECTOR_INCL_STAT
,
143 /* 11 */ ZSWR11_TXCLK_BAUD
| ZSWR11_RXCLK_BAUD
,
146 /* 14 */ ZSWR14_BAUD_FROM_PCLK
| ZSWR14_BAUD_ENA
,
151 * Define the machine dependant clock frequencies
152 * If BRgen feeds sender/receiver we always use a
153 * divisor 16, therefor the division by 16 can as
156 static u_long zs_freqs_tt
[] = {
158 * Atari TT, RTxCB is generated by TT-MFP timer C,
159 * which is set to 307.2 kHz during initialisation
160 * and never changed afterwards.
162 PCLK
/16, /* BRgen, PCLK, divisor 16 */
163 229500, /* BRgen, RTxCA, divisor 16 */
164 3672000, /* RTxCA, from PCLK4 */
165 0, /* TRxCA, external */
167 PCLK
/16, /* BRgen, PCLK, divisor 16 */
168 19200, /* BRgen, RTxCB, divisor 16 */
169 307200, /* RTxCB, from TT-MFP TCO */
170 2457600 /* TRxCB, from BCLK */
173 static u_long zs_freqs_falcon
[] = {
175 * Atari Falcon, XXX no specs available, this might be wrong
177 PCLK
/16, /* BRgen, PCLK, divisor 16 */
178 229500, /* BRgen, RTxCA, divisor 16 */
179 3672000, /* RTxCA, ??? */
180 0, /* TRxCA, external */
182 PCLK
/16, /* BRgen, PCLK, divisor 16 */
183 229500, /* BRgen, RTxCB, divisor 16 */
184 3672000, /* RTxCB, ??? */
185 2457600 /* TRxCB, ??? */
188 static u_long zs_freqs_hades
[] = {
190 * XXX: Channel-A unchecked!!!!!
192 PCLK_HD
/16, /* BRgen, PCLK, divisor 16 */
193 229500, /* BRgen, RTxCA, divisor 16 */
194 3672000, /* RTxCA, from PCLK4 */
195 0, /* TRxCA, external */
197 PCLK_HD
/16, /* BRgen, PCLK, divisor 16 */
198 235550, /* BRgen, RTxCB, divisor 16 */
199 3768800, /* RTxCB, 3.7688MHz */
200 3768800 /* TRxCB, 3.7688MHz */
203 static u_long zs_freqs_generic
[] = {
205 * other machines, assume only PCLK is available
207 PCLK
/16, /* BRgen, PCLK, divisor 16 */
208 0, /* BRgen, RTxCA, divisor 16 */
209 0, /* RTxCA, unknown */
210 0, /* TRxCA, unknown */
212 PCLK
/16, /* BRgen, PCLK, divisor 16 */
213 0, /* BRgen, RTxCB, divisor 16 */
214 0, /* RTxCB, unknown */
215 0 /* TRxCB, unknown */
217 static u_long
*zs_frequencies
;
219 /* Definition of the driver for autoconfig. */
220 static int zsmatch(struct device
*, struct cfdata
*, void *);
221 static void zsattach(struct device
*, struct device
*, void *);
223 CFATTACH_DECL(zs
, sizeof(struct zs_softc
),
224 zsmatch
, zsattach
, NULL
, NULL
);
226 extern struct cfdriver zs_cd
;
228 /* {b,c}devsw[] function prototypes */
229 dev_type_open(zsopen
);
230 dev_type_close(zsclose
);
231 dev_type_read(zsread
);
232 dev_type_write(zswrite
);
233 dev_type_ioctl(zsioctl
);
234 dev_type_stop(zsstop
);
236 dev_type_poll(zspoll
);
238 const struct cdevsw zs_cdevsw
= {
239 zsopen
, zsclose
, zsread
, zswrite
, zsioctl
,
240 zsstop
, zstty
, zspoll
, nommap
, ttykqfilter
, D_TTY
243 /* Interrupt handlers. */
245 static int zssoft(long);
246 static int zsrint(struct zs_chanstate
*, volatile struct zschan
*);
247 static int zsxint(struct zs_chanstate
*, volatile struct zschan
*);
248 static int zssint(struct zs_chanstate
*, volatile struct zschan
*);
250 static struct zs_chanstate
*zslist
;
252 /* Routines called from other code. */
253 static void zsstart(struct tty
*);
255 /* Routines purely local to this driver. */
256 static void zsoverrun(int, long *, const char *);
257 static int zsparam(struct tty
*, struct termios
*);
258 static int zsbaudrate(int, int, int *, int *, int *, int *);
259 static int zs_modem(struct zs_chanstate
*, int, int);
260 static void zs_loadchannelregs(volatile struct zschan
*, u_char
*);
261 static void zs_shutdown(struct zs_chanstate
*);
264 zsmatch(struct device
*pdp
, struct cfdata
*cfp
, void *auxp
)
266 static int zs_matched
= 0;
268 if(strcmp("zs", auxp
) || zs_matched
)
278 zsattach(struct device
*parent
, struct device
*dev
, void *aux
)
280 register struct zs_softc
*zi
;
281 register struct zs_chanstate
*cs
;
282 register volatile struct zsdevice
*addr
;
285 addr
= (struct zsdevice
*)AD_SCC
;
286 zi
= (struct zs_softc
*)dev
;
291 * Get the command register into a known state.
293 tmp
= addr
->zs_chan
[ZS_CHAN_A
].zc_csr
;
294 tmp
= addr
->zs_chan
[ZS_CHAN_A
].zc_csr
;
295 tmp
= addr
->zs_chan
[ZS_CHAN_B
].zc_csr
;
296 tmp
= addr
->zs_chan
[ZS_CHAN_B
].zc_csr
;
299 * Do a hardware reset.
301 ZS_WRITE(&addr
->zs_chan
[ZS_CHAN_A
], 9, ZSWR9_HARD_RESET
);
302 delay(50000); /*enough ? */
303 ZS_WRITE(&addr
->zs_chan
[ZS_CHAN_A
], 9, 0);
306 * Initialize both channels
308 zs_loadchannelregs(&addr
->zs_chan
[ZS_CHAN_A
], zs_init_regs
);
309 zs_loadchannelregs(&addr
->zs_chan
[ZS_CHAN_B
], zs_init_regs
);
311 if(machineid
& ATARI_TT
) {
313 * ininitialise TT-MFP timer C: 307200Hz
314 * timer C and D share one control register:
315 * bits 0-2 control timer D
316 * bits 4-6 control timer C
318 int cr
= MFP2
->mf_tcdcr
& 7;
319 MFP2
->mf_tcdcr
= cr
; /* stop timer C */
320 MFP2
->mf_tcdr
= 1; /* counter 1 */
321 cr
|= T_Q004
<< 4; /* divisor 4 */
322 MFP2
->mf_tcdcr
= cr
; /* start timer C */
324 * enable scc related interrupts
326 SCU
->vme_mask
|= SCU_SCC
;
328 zs_frequencies
= zs_freqs_tt
;
329 } else if (machineid
& ATARI_FALCON
) {
330 zs_frequencies
= zs_freqs_falcon
;
331 } else if (machineid
& ATARI_HADES
) {
332 zs_frequencies
= zs_freqs_hades
;
334 zs_frequencies
= zs_freqs_generic
;
337 /* link into interrupt list with order (A,B) (B=A+1) */
338 cs
[0].cs_next
= &cs
[1];
339 cs
[1].cs_next
= zslist
;
343 cs
->cs_zc
= &addr
->zs_chan
[ZS_CHAN_A
];
346 cs
->cs_zc
= &addr
->zs_chan
[ZS_CHAN_B
];
348 zs_softint_cookie
= softint_establish(SOFTINT_SERIAL
,
349 (void (*)(void *))zssoft
, 0);
351 printf(": serial2 on channel a and modem2 on channel b\n");
355 * Open a zs serial port.
358 zsopen(dev_t dev
, int flags
, int mode
, struct lwp
*l
)
360 register struct tty
*tp
;
361 register struct zs_chanstate
*cs
;
363 int unit
= ZS_UNIT(dev
);
367 zi
= device_lookup_private(&zs_cd
, zs
);
370 cs
= &zi
->zi_cs
[unit
& 1];
373 * When port A (ser02) is selected on the TT, make sure
374 * the port is enabled.
376 if((machineid
& ATARI_TT
) && !(unit
& 1))
379 if (cs
->cs_rbuf
== NULL
) {
380 cs
->cs_rbuf
= malloc(ZLRB_RING_SIZE
* sizeof(int), M_DEVBUF
,
386 cs
->cs_ttyp
= tp
= ttymalloc();
389 tp
->t_oproc
= zsstart
;
390 tp
->t_param
= zsparam
;
393 if (kauth_authorize_device_tty(l
->l_cred
, KAUTH_DEVICE_TTY_OPEN
, tp
))
399 * Do the following iff this is a first open.
401 if (!(tp
->t_state
& TS_ISOPEN
) && tp
->t_wopen
== 0) {
402 if(tp
->t_ispeed
== 0) {
403 tp
->t_iflag
= TTYDEF_IFLAG
;
404 tp
->t_oflag
= TTYDEF_OFLAG
;
405 tp
->t_cflag
= TTYDEF_CFLAG
;
406 tp
->t_lflag
= TTYDEF_LFLAG
;
407 tp
->t_ispeed
= tp
->t_ospeed
= TTYDEF_SPEED
;
412 (void)zsparam(tp
, &tp
->t_termios
);
415 * Turn on DTR. We must always do this, even if carrier is not
416 * present, because otherwise we'd have to use TIOCSDTR
417 * immediately after setting CLOCAL, which applications do not
418 * expect. We always assert DTR while the device is open
419 * unless explicitly requested to deassert it.
421 zs_modem(cs
, ZSWR5_RTS
|ZSWR5_DTR
, DMSET
);
422 /* May never get a status intr. if DCD already on. -gwr */
423 if((cs
->cs_rr0
= cs
->cs_zc
->zc_csr
) & ZSRR0_DCD
)
424 tp
->t_state
|= TS_CARR_ON
;
426 tp
->t_state
|= TS_CARR_ON
;
431 error
= ttyopen(tp
, ZS_DIALOUT(dev
), (flags
& O_NONBLOCK
));
435 error
= tp
->t_linesw
->l_open(dev
, tp
);
441 if (!(tp
->t_state
& TS_ISOPEN
) && tp
->t_wopen
== 0) {
443 * We failed to open the device, and nobody else had it opened.
444 * Clean up the state as appropriate.
452 * Close a zs serial port.
455 zsclose(dev_t dev
, int flags
, int mode
, struct lwp
*l
)
457 register struct zs_chanstate
*cs
;
458 register struct tty
*tp
;
460 int unit
= ZS_UNIT(dev
);
462 zi
= device_lookup_private(&zs_cd
, unit
>> 1);
463 cs
= &zi
->zi_cs
[unit
& 1];
466 tp
->t_linesw
->l_close(tp
, flags
);
469 if (!(tp
->t_state
& TS_ISOPEN
) && tp
->t_wopen
== 0) {
471 * Although we got a last close, the device may still be in
472 * use; e.g. if this was the dialout node, and there are still
473 * processes waiting for carrier on the non-dialout node.
481 * Read/write zs serial port.
484 zsread(dev_t dev
, struct uio
*uio
, int flags
)
486 register struct zs_chanstate
*cs
;
487 register struct zs_softc
*zi
;
488 register struct tty
*tp
;
492 zi
= device_lookup_private(&zs_cd
, unit
>> 1);
493 cs
= &zi
->zi_cs
[unit
& 1];
496 return(tp
->t_linesw
->l_read(tp
, uio
, flags
));
500 zswrite(dev_t dev
, struct uio
*uio
, int flags
)
502 register struct zs_chanstate
*cs
;
503 register struct zs_softc
*zi
;
504 register struct tty
*tp
;
508 zi
= device_lookup_private(&zs_cd
, unit
>> 1);
509 cs
= &zi
->zi_cs
[unit
& 1];
512 return(tp
->t_linesw
->l_write(tp
, uio
, flags
));
516 zspoll(dev_t dev
, int events
, struct lwp
*l
)
518 register struct zs_chanstate
*cs
;
519 register struct zs_softc
*zi
;
520 register struct tty
*tp
;
524 zi
= device_lookup_private(&zs_cd
, unit
>> 1);
525 cs
= &zi
->zi_cs
[unit
& 1];
528 return ((*tp
->t_linesw
->l_poll
)(tp
, events
, l
));
534 register struct zs_chanstate
*cs
;
535 register struct zs_softc
*zi
;
539 zi
= device_lookup_private(&zs_cd
, unit
>> 1);
540 cs
= &zi
->zi_cs
[unit
& 1];
545 * ZS hardware interrupt. Scan all ZS channels. NB: we know here that
546 * channels are kept in (A,B) pairs.
548 * Do just a little, then get out; set a software interrupt if more
551 * We deliberately ignore the vectoring Zilog gives us, and match up
552 * only the number of `reset interrupt under service' operations, not
559 register struct zs_chanstate
*a
;
561 register volatile struct zschan
*zc
;
562 register int rr3
, intflags
= 0, v
, i
;
566 for(a
= zslist
; a
!= NULL
; a
= b
->cs_next
) {
567 rr3
= ZS_READ(a
->cs_zc
, 3);
568 if(rr3
& (ZSRR3_IP_A_RX
|ZSRR3_IP_A_TX
|ZSRR3_IP_A_STAT
)) {
572 if(rr3
& ZSRR3_IP_A_RX
&& (v
= zsrint(a
, zc
)) != 0) {
573 a
->cs_rbuf
[i
++ & ZLRB_RING_MASK
] = v
;
576 if(rr3
& ZSRR3_IP_A_TX
&& (v
= zsxint(a
, zc
)) != 0) {
577 a
->cs_rbuf
[i
++ & ZLRB_RING_MASK
] = v
;
580 if(rr3
& ZSRR3_IP_A_STAT
&& (v
= zssint(a
, zc
)) != 0) {
581 a
->cs_rbuf
[i
++ & ZLRB_RING_MASK
] = v
;
586 if(rr3
& (ZSRR3_IP_B_RX
|ZSRR3_IP_B_TX
|ZSRR3_IP_B_STAT
)) {
590 if(rr3
& ZSRR3_IP_B_RX
&& (v
= zsrint(b
, zc
)) != 0) {
591 b
->cs_rbuf
[i
++ & ZLRB_RING_MASK
] = v
;
594 if(rr3
& ZSRR3_IP_B_TX
&& (v
= zsxint(b
, zc
)) != 0) {
595 b
->cs_rbuf
[i
++ & ZLRB_RING_MASK
] = v
;
598 if(rr3
& ZSRR3_IP_B_STAT
&& (v
= zssint(b
, zc
)) != 0) {
599 b
->cs_rbuf
[i
++ & ZLRB_RING_MASK
] = v
;
605 } while(intflags
& 4);
609 softint_schedule(zs_softint_cookie
);
611 return(intflags
& 2);
615 zsrint(register struct zs_chanstate
*cs
, register volatile struct zschan
*zc
)
620 * First read the status, because read of the received char
621 * destroy the status of this char.
624 c
|= (zc
->zc_data
<< 8);
626 /* clear receive error & interrupt condition */
627 zc
->zc_csr
= ZSWR0_RESET_ERRORS
;
628 zc
->zc_csr
= ZSWR0_CLR_INTR
;
630 return(ZRING_MAKE(ZRING_RINT
, c
));
634 zsxint(register struct zs_chanstate
*cs
, register volatile struct zschan
*zc
)
636 register int i
= cs
->cs_tbc
;
639 zc
->zc_csr
= ZSWR0_RESET_TXINT
;
640 zc
->zc_csr
= ZSWR0_CLR_INTR
;
641 return(ZRING_MAKE(ZRING_XINT
, 0));
644 zc
->zc_data
= *cs
->cs_tba
++;
645 zc
->zc_csr
= ZSWR0_CLR_INTR
;
650 zssint(register struct zs_chanstate
*cs
, register volatile struct zschan
*zc
)
655 zc
->zc_csr
= ZSWR0_RESET_STATUS
;
656 zc
->zc_csr
= ZSWR0_CLR_INTR
;
658 * The chip's hardware flow control is, as noted in zsreg.h,
659 * busted---if the DCD line goes low the chip shuts off the
660 * receiver (!). If we want hardware CTS flow control but do
661 * not have it, and carrier is now on, turn HFC on; if we have
662 * HFC now but carrier has gone low, turn it off.
664 if(rr0
& ZSRR0_DCD
) {
665 if(cs
->cs_ttyp
->t_cflag
& CCTS_OFLOW
&&
666 (cs
->cs_creg
[3] & ZSWR3_HFC
) == 0) {
667 cs
->cs_creg
[3] |= ZSWR3_HFC
;
668 ZS_WRITE(zc
, 3, cs
->cs_creg
[3]);
672 if (cs
->cs_creg
[3] & ZSWR3_HFC
) {
673 cs
->cs_creg
[3] &= ~ZSWR3_HFC
;
674 ZS_WRITE(zc
, 3, cs
->cs_creg
[3]);
677 return(ZRING_MAKE(ZRING_SINT
, rr0
));
681 * Print out a ring or fifo overrun error message.
684 zsoverrun(int unit
, long *ptime
, const char *what
)
686 time_t cur_sec
= time_second
;
688 if(*ptime
!= cur_sec
) {
690 log(LOG_WARNING
, "zs%d%c: %s overrun\n", unit
>> 1,
691 (unit
& 1) + 'a', what
);
696 * ZS software interrupt. Scan all channels for deferred interrupts.
701 register struct zs_chanstate
*cs
;
702 register volatile struct zschan
*zc
;
703 register struct linesw
*line
;
704 register struct tty
*tp
;
705 register int get
, n
, c
, cc
, unit
, s
;
709 for(cs
= zslist
; cs
!= NULL
; cs
= cs
->cs_next
) {
712 n
= cs
->cs_rbput
; /* atomic */
713 if(get
== n
) /* nothing more on this line */
716 unit
= cs
->cs_unit
; /* set up to handle interrupts */
721 * Compute the number of interrupts in the receive ring.
722 * If the count is overlarge, we lost some events, and
723 * must advance to the first valid one. It may get
724 * overwritten if more data are arriving, but this is
725 * too expensive to check and gains nothing (we already
726 * lost out; all we can do at this point is trade one
727 * kind of loss for another).
730 if(n
> ZLRB_RING_SIZE
) {
731 zsoverrun(unit
, &cs
->cs_rotime
, "ring");
732 get
+= n
- ZLRB_RING_SIZE
;
736 /* race to keep ahead of incoming interrupts */
737 c
= cs
->cs_rbuf
[get
++ & ZLRB_RING_MASK
];
738 switch (ZRING_TYPE(c
)) {
743 zsoverrun(unit
, &cs
->cs_fotime
, "fifo");
749 line
->l_rint(cc
, tp
);
754 * Transmit done: change registers and resume,
757 if(cs
->cs_heldchange
) {
762 if((c
& ZSRR0_DCD
) == 0)
763 cs
->cs_preg
[3] &= ~ZSWR3_HFC
;
764 memcpy((void *)cs
->cs_creg
,
765 (void *)cs
->cs_preg
, 16);
766 zs_loadchannelregs(zc
, cs
->cs_creg
);
768 cs
->cs_heldchange
= 0;
770 && (tp
->t_state
& TS_TTSTOP
) == 0) {
771 cs
->cs_tbc
= cs
->cs_heldtbc
- 1;
772 zc
->zc_data
= *cs
->cs_tba
++;
776 tp
->t_state
&= ~TS_BUSY
;
777 if(tp
->t_state
& TS_FLUSH
)
778 tp
->t_state
&= ~TS_FLUSH
;
779 else ndflush(&tp
->t_outq
,cs
->cs_tba
786 * Status line change. HFC bit is run in
787 * hardware interrupt, to avoid locking
791 if((c
^ cs
->cs_rr0
) & ZSRR0_DCD
) {
792 cc
= (c
& ZSRR0_DCD
) != 0;
793 if(line
->l_modem(tp
, cc
) == 0)
794 zs_modem(cs
, ZSWR5_RTS
|ZSWR5_DTR
,
801 log(LOG_ERR
, "zs%d%c: bad ZRING_TYPE (%x)\n",
802 unit
>> 1, (unit
& 1) + 'a', c
);
814 zsioctl(dev_t dev
, u_long cmd
, void * data
, int flag
, struct lwp
*l
)
816 int unit
= ZS_UNIT(dev
);
817 struct zs_softc
*zi
= device_lookup_private(&zs_cd
, unit
>> 1);
818 register struct tty
*tp
= zi
->zi_cs
[unit
& 1].cs_ttyp
;
819 register int error
, s
;
820 register struct zs_chanstate
*cs
= &zi
->zi_cs
[unit
& 1];
822 error
= tp
->t_linesw
->l_ioctl(tp
, cmd
, data
, flag
, l
);
823 if(error
!= EPASSTHROUGH
)
826 error
= ttioctl(tp
, cmd
, data
, flag
, l
);
827 if(error
!=EPASSTHROUGH
)
833 cs
->cs_preg
[5] |= ZSWR5_BREAK
;
834 cs
->cs_creg
[5] |= ZSWR5_BREAK
;
835 ZS_WRITE(cs
->cs_zc
, 5, cs
->cs_creg
[5]);
840 cs
->cs_preg
[5] &= ~ZSWR5_BREAK
;
841 cs
->cs_creg
[5] &= ~ZSWR5_BREAK
;
842 ZS_WRITE(cs
->cs_zc
, 5, cs
->cs_creg
[5]);
849 bits
|= TIOCFLAG_SOFTCAR
;
850 if(cs
->cs_creg
[15] & ZSWR15_DCD_IE
)
851 bits
|= TIOCFLAG_CLOCAL
;
852 if(cs
->cs_creg
[3] & ZSWR3_HFC
)
853 bits
|= TIOCFLAG_CRTSCTS
;
860 error
= kauth_authorize_device_tty(l
->l_cred
,
861 KAUTH_DEVICE_TTY_PRIVSET
, tp
);
865 userbits
= *(int *)data
;
868 * can have `local' or `softcar', and `rtscts' or `mdmbuf'
869 # defaulting to software flow control.
871 if(userbits
& TIOCFLAG_SOFTCAR
&& userbits
& TIOCFLAG_CLOCAL
)
873 if(userbits
& TIOCFLAG_MDMBUF
) /* don't support this (yet?) */
877 if((userbits
& TIOCFLAG_SOFTCAR
)) {
878 cs
->cs_softcar
= 1; /* turn on softcar */
879 cs
->cs_preg
[15] &= ~ZSWR15_DCD_IE
; /* turn off dcd */
880 cs
->cs_creg
[15] &= ~ZSWR15_DCD_IE
;
881 ZS_WRITE(cs
->cs_zc
, 15, cs
->cs_creg
[15]);
883 else if(userbits
& TIOCFLAG_CLOCAL
) {
884 cs
->cs_softcar
= 0; /* turn off softcar */
885 cs
->cs_preg
[15] |= ZSWR15_DCD_IE
; /* turn on dcd */
886 cs
->cs_creg
[15] |= ZSWR15_DCD_IE
;
887 ZS_WRITE(cs
->cs_zc
, 15, cs
->cs_creg
[15]);
888 tp
->t_termios
.c_cflag
|= CLOCAL
;
890 if(userbits
& TIOCFLAG_CRTSCTS
) {
891 cs
->cs_preg
[15] |= ZSWR15_CTS_IE
;
892 cs
->cs_creg
[15] |= ZSWR15_CTS_IE
;
893 ZS_WRITE(cs
->cs_zc
, 15, cs
->cs_creg
[15]);
894 cs
->cs_preg
[3] |= ZSWR3_HFC
;
895 cs
->cs_creg
[3] |= ZSWR3_HFC
;
896 ZS_WRITE(cs
->cs_zc
, 3, cs
->cs_creg
[3]);
897 tp
->t_termios
.c_cflag
|= CRTSCTS
;
900 /* no mdmbuf, so we must want software flow control */
901 cs
->cs_preg
[15] &= ~ZSWR15_CTS_IE
;
902 cs
->cs_creg
[15] &= ~ZSWR15_CTS_IE
;
903 ZS_WRITE(cs
->cs_zc
, 15, cs
->cs_creg
[15]);
904 cs
->cs_preg
[3] &= ~ZSWR3_HFC
;
905 cs
->cs_creg
[3] &= ~ZSWR3_HFC
;
906 ZS_WRITE(cs
->cs_zc
, 3, cs
->cs_creg
[3]);
907 tp
->t_termios
.c_cflag
&= ~CRTSCTS
;
913 zs_modem(cs
, ZSWR5_DTR
, DMBIS
);
916 zs_modem(cs
, ZSWR5_DTR
, DMBIC
);
919 zs_modem(cs
, 0, DMGET
);
925 return (EPASSTHROUGH
);
931 * Start or restart transmission.
934 zsstart(register struct tty
*tp
)
936 register struct zs_chanstate
*cs
;
938 int unit
= ZS_UNIT(tp
->t_dev
);
939 struct zs_softc
*zi
= device_lookup_private(&zs_cd
, unit
>> 1);
941 cs
= &zi
->zi_cs
[unit
& 1];
945 * If currently active or delaying, no need to do anything.
947 if(tp
->t_state
& (TS_TIMEOUT
| TS_BUSY
| TS_TTSTOP
))
951 * If there are sleepers, and output has drained below low
952 * water mark, awaken.
956 nch
= ndqb(&tp
->t_outq
, 0); /* XXX */
958 register char *p
= tp
->t_outq
.c_cf
;
960 /* mark busy, enable tx done interrupts, & send first byte */
961 tp
->t_state
|= TS_BUSY
;
963 cs
->cs_preg
[1] |= ZSWR1_TIE
;
964 cs
->cs_creg
[1] |= ZSWR1_TIE
;
965 ZS_WRITE(cs
->cs_zc
, 1, cs
->cs_creg
[1]);
966 cs
->cs_zc
->zc_data
= *p
;
968 cs
->cs_tbc
= nch
- 1;
971 * Nothing to send, turn off transmit done interrupts.
972 * This is useful if something is doing polled output.
975 cs
->cs_preg
[1] &= ~ZSWR1_TIE
;
976 cs
->cs_creg
[1] &= ~ZSWR1_TIE
;
977 ZS_WRITE(cs
->cs_zc
, 1, cs
->cs_creg
[1]);
984 * Stop output, e.g., for ^S or output flush.
987 zsstop(register struct tty
*tp
, int flag
)
989 register struct zs_chanstate
*cs
;
990 register int s
, unit
= ZS_UNIT(tp
->t_dev
);
991 struct zs_softc
*zi
= device_lookup_private(&zs_cd
, unit
>> 1);
993 cs
= &zi
->zi_cs
[unit
& 1];
995 if(tp
->t_state
& TS_BUSY
) {
997 * Device is transmitting; must stop it.
1000 if ((tp
->t_state
& TS_TTSTOP
) == 0)
1001 tp
->t_state
|= TS_FLUSH
;
1007 zs_shutdown(struct zs_chanstate
*cs
)
1009 struct tty
*tp
= cs
->cs_ttyp
;
1015 * Hang up if necessary. Wait a bit, so the other side has time to
1016 * notice even if we immediately open the port again.
1018 if(tp
->t_cflag
& HUPCL
) {
1019 zs_modem(cs
, 0, DMSET
);
1020 (void)tsleep((void *)cs
, TTIPRI
, ttclos
, hz
);
1023 /* Clear any break condition set with TIOCSBRK. */
1024 if(cs
->cs_creg
[5] & ZSWR5_BREAK
) {
1025 cs
->cs_preg
[5] &= ~ZSWR5_BREAK
;
1026 cs
->cs_creg
[5] &= ~ZSWR5_BREAK
;
1027 ZS_WRITE(cs
->cs_zc
, 5, cs
->cs_creg
[5]);
1031 * Drop all lines and cancel interrupts
1033 zs_loadchannelregs(cs
->cs_zc
, zs_init_regs
);
1038 * Set ZS tty parameters from termios.
1040 * This routine makes use of the fact that only registers
1041 * 1, 3, 4, 5, 9, 10, 11, 12, 13, 14, and 15 are written.
1044 zsparam(register struct tty
*tp
, register struct termios
*t
)
1046 int unit
= ZS_UNIT(tp
->t_dev
);
1047 struct zs_softc
*zi
= device_lookup_private(&zs_cd
, unit
>> 1);
1048 register struct zs_chanstate
*cs
= &zi
->zi_cs
[unit
& 1];
1049 int cdiv
= 0, /* XXX gcc4 -Wuninitialized */
1050 clkm
= 0, /* XXX gcc4 -Wuninitialized */
1051 brgm
= 0, /* XXX gcc4 -Wuninitialized */
1052 tcon
= 0; /* XXX gcc4 -Wuninitialized */
1053 register int tmp
, tmp5
, cflag
, s
;
1057 if(tmp
< 0 || (tmp5
&& tmp5
!= tmp
))
1060 /* stty 0 => drop DTR and RTS */
1061 zs_modem(cs
, 0, DMSET
);
1064 tmp
= zsbaudrate(unit
, tmp
, &cdiv
, &clkm
, &brgm
, &tcon
);
1067 tp
->t_ispeed
= tp
->t_ospeed
= tmp
;
1069 cflag
= tp
->t_cflag
= t
->c_cflag
;
1071 cdiv
|= ZSWR4_TWOSB
;
1073 cdiv
|= ZSWR4_ONESB
;
1074 if (!(cflag
& PARODD
))
1075 cdiv
|= ZSWR4_EVENP
;
1077 cdiv
|= ZSWR4_PARENB
;
1079 switch(cflag
& CSIZE
) {
1098 tmp
|= ZSWR3_RX_ENABLE
;
1099 tmp5
|= ZSWR5_TX_ENABLE
| ZSWR5_DTR
| ZSWR5_RTS
;
1102 * Block interrupts so that state will not
1103 * be altered until we are done setting it up.
1106 cs
->cs_preg
[4] = cdiv
;
1107 cs
->cs_preg
[11] = clkm
;
1108 cs
->cs_preg
[12] = tcon
;
1109 cs
->cs_preg
[13] = tcon
>> 8;
1110 cs
->cs_preg
[14] = brgm
;
1111 cs
->cs_preg
[1] = ZSWR1_RIE
| ZSWR1_TIE
| ZSWR1_SIE
;
1112 cs
->cs_preg
[9] = ZSWR9_MASTER_IE
| ZSWR9_VECTOR_INCL_STAT
;
1113 cs
->cs_preg
[10] = ZSWR10_NRZ
;
1114 cs
->cs_preg
[15] = ZSWR15_BREAK_IE
| ZSWR15_DCD_IE
;
1117 * Output hardware flow control on the chip is horrendous: if
1118 * carrier detect drops, the receiver is disabled. Hence we
1119 * can only do this when the carrier is on.
1121 if(cflag
& CCTS_OFLOW
&& cs
->cs_zc
->zc_csr
& ZSRR0_DCD
)
1123 cs
->cs_preg
[3] = tmp
;
1124 cs
->cs_preg
[5] = tmp5
;
1127 * If nothing is being transmitted, set up new current values,
1128 * else mark them as pending.
1130 if(cs
->cs_heldchange
== 0) {
1131 if (cs
->cs_ttyp
->t_state
& TS_BUSY
) {
1132 cs
->cs_heldtbc
= cs
->cs_tbc
;
1134 cs
->cs_heldchange
= 1;
1136 memcpy((void *)cs
->cs_creg
, (void *)cs
->cs_preg
, 16);
1137 zs_loadchannelregs(cs
->cs_zc
, cs
->cs_creg
);
1145 * search for the best matching baudrate
1148 zsbaudrate(int unit
, int wanted
, int *divisor
, int *clockmode
, int *brgenmode
, int *timeconst
)
1150 int bestdiff
, bestbps
, source
;
1152 bestdiff
= bestbps
= 0;
1153 unit
= (unit
& 1) << 2;
1154 for (source
= 0; source
< 4; ++source
) {
1155 long freq
= zs_frequencies
[unit
+ source
];
1156 int diff
, bps
, div
, clkm
, brgm
, tcon
;
1158 bps
= div
= clkm
= brgm
= tcon
= 0;
1160 case 0: /* BRgen, PCLK */
1161 brgm
= ZSWR14_BAUD_ENA
|ZSWR14_BAUD_FROM_PCLK
;
1163 case 1: /* BRgen, RTxC */
1164 brgm
= ZSWR14_BAUD_ENA
;
1167 clkm
= ZSWR11_RXCLK_RTXC
|ZSWR11_TXCLK_RTXC
;
1170 clkm
= ZSWR11_RXCLK_TRXC
|ZSWR11_TXCLK_TRXC
;
1176 div
= ZSWR4_CLK_X16
;
1177 clkm
= ZSWR11_RXCLK_BAUD
|ZSWR11_TXCLK_BAUD
;
1178 tcon
= BPS_TO_TCONST(freq
, wanted
);
1181 bps
= TCONST_TO_BPS(freq
, tcon
);
1185 { int b1
= freq
/ 16, d1
= abs(b1
- wanted
);
1186 int b2
= freq
/ 32, d2
= abs(b2
- wanted
);
1187 int b3
= freq
/ 64, d3
= abs(b3
- wanted
);
1189 if (d1
< d2
&& d1
< d3
) {
1190 div
= ZSWR4_CLK_X16
;
1192 } else if (d2
< d3
&& d2
< d1
) {
1193 div
= ZSWR4_CLK_X32
;
1196 div
= ZSWR4_CLK_X64
;
1203 diff
= abs(bps
- wanted
);
1204 if (!source
|| diff
< bestdiff
) {
1215 /* Allow deviations upto 5% */
1216 if (20 * bestdiff
> wanted
)
1222 * Raise or lower modem control (DTR/RTS) signals. If a character is
1223 * in transmission, the change is deferred.
1226 zs_modem(struct zs_chanstate
*cs
, int bits
, int how
)
1230 bits
&= ZSWR5_DTR
| ZSWR5_RTS
;
1233 mbits
= cs
->cs_preg
[5] & (ZSWR5_DTR
| ZSWR5_RTS
);
1250 cs
->cs_preg
[5] = (cs
->cs_preg
[5] & ~(ZSWR5_DTR
| ZSWR5_RTS
)) | mbits
;
1251 if(cs
->cs_heldchange
== 0) {
1252 if(cs
->cs_ttyp
->t_state
& TS_BUSY
) {
1253 cs
->cs_heldtbc
= cs
->cs_tbc
;
1255 cs
->cs_heldchange
= 1;
1258 ZS_WRITE(cs
->cs_zc
, 5, cs
->cs_creg
[5]);
1266 * Write the given register set to the given zs channel in the proper order.
1267 * The channel must not be transmitting at the time. The receiver will
1268 * be disabled for the time it takes to write all the registers.
1271 zs_loadchannelregs(volatile struct zschan
*zc
, u_char
*reg
)
1275 zc
->zc_csr
= ZSM_RESET_ERR
; /* reset error condition */
1276 i
= zc
->zc_data
; /* drain fifo */
1279 ZS_WRITE(zc
, 4, reg
[4]);
1280 ZS_WRITE(zc
, 10, reg
[10]);
1281 ZS_WRITE(zc
, 3, reg
[3] & ~ZSWR3_RX_ENABLE
);
1282 ZS_WRITE(zc
, 5, reg
[5] & ~ZSWR5_TX_ENABLE
);
1283 ZS_WRITE(zc
, 1, reg
[1]);
1284 ZS_WRITE(zc
, 9, reg
[9]);
1285 ZS_WRITE(zc
, 11, reg
[11]);
1286 ZS_WRITE(zc
, 12, reg
[12]);
1287 ZS_WRITE(zc
, 13, reg
[13]);
1288 ZS_WRITE(zc
, 14, reg
[14]);
1289 ZS_WRITE(zc
, 15, reg
[15]);
1290 ZS_WRITE(zc
, 3, reg
[3]);
1291 ZS_WRITE(zc
, 5, reg
[5]);
1293 #endif /* NZS > 1 */