2 * Mach Operating System
3 * Copyright (c) 1993-1989 Carnegie Mellon University
6 * Permission to use, copy, modify and distribute this software and its
7 * documentation is hereby granted, provided that both the copyright
8 * notice and this permission notice appear in all copies of the
9 * software, derivative works or modified versions, and any portions
10 * thereof, and that both notices appear in supporting documentation.
12 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
16 * Carnegie Mellon requests users of this software to return to
18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
19 * School of Computer Science
20 * Carnegie Mellon University
21 * Pittsburgh PA 15213-3890
23 * any improvements or extensions that they make and grant Carnegie Mellon
24 * the rights to redistribute these changes.
28 * $Log: scc_8530_hdw.c,v $
29 * Revision 2.9 93/03/26 17:58:01 mrt
30 * No minor()s, no dev_t.
33 * Revision 2.8 93/03/09 10:52:21 danner
35 * [93/03/07 13:29:58 af]
37 * Post-debugging lint.
40 * Revision 2.7 93/02/05 08:05:17 danner
41 * Flamingo, full_modem and isa_console per-line.
44 * Revision 2.6 93/01/14 17:21:44 danner
45 * static/extern cleanups.
51 * Revision 2.5 92/05/05 10:04:59 danner
52 * Fixed how the interrupt routine plays with priorities.
53 * Ask for buffering on all lines.
54 * [92/05/04 11:15:43 af]
56 * Fixed for more than just rconsole-ing. Two bugs: the chip
57 * needs one char out to generate the xmit-empty (so it really
58 * is a xmit-done) interrupt, and the t_addr game was not played
60 * Tested both on maxine and the two serial lines kmin has.
61 * [92/04/14 11:47:26 af]
63 * Revision 2.4 92/02/19 16:46:10 elf
64 * Uhmm, lotsa changes. Basically, got channel B working
65 * and made it possible to use it as rconsole line.
66 * Missing modem bitsies only.
67 * A joint Terri&Sandro feature presentation.
68 * [92/02/10 17:03:08 af]
70 * Revision 2.3 91/08/28 11:09:53 jsb
71 * Fixed scc_scan to actually check the tp->state each time,
72 * we are not notified when the MI code brutally zeroes it
73 * on close and so we cannot update our software CARrier.
74 * [91/08/27 16:18:05 af]
76 * Revision 2.2 91/08/24 11:52:54 af
77 * Created, from the Zilog specs:
78 * "Z8530 SCC Serial Communications Controller, Product Specification"
79 * in the "1983/84 Components Data Book" pp 409-429, September 1983
80 * Zilog, Campbell, CA 95008
84 #ident "$Id: scc_8530_hdw.c,v 1.1 1993/09/29 06:09:27 briggs Exp $"
86 * File: scc_8530_hdw.c
87 * Author: Alessandro Forin, Carnegie Mellon University
90 * Hardware-level operations for the SCC Serial Line Driver
96 #include <platforms.h>
100 #include <machine/machparam.h> /* spl definitions */
101 #include <sys/types.h>
102 #include <mach/std_types.h>
103 #include <device/io_req.h>
104 #include <device/tty.h>
106 #include <chips/busses.h>
107 #include <chips/serial_defs.h>
108 #include <chips/screen_defs.h>
110 /* Alignment and padding */
111 #if defined(DECSTATION)
117 volatile unsigned char datum
;
119 } scc_padded1_register_t
;
121 #define scc_register_t scc_padded1_register_t
124 #if defined(FLAMINGO)
126 volatile unsigned int datum
;
128 } scc_padded1_register_t
;
130 #define scc_register_t scc_padded1_register_t
132 #define scc_set_datum(d,v) (d) = (volatile unsigned int) (v) << 8, wbflush()
133 #define scc_get_datum(d,v) (v) = ((d) >> 8) & 0xff
137 #include <chips/scc_8530.h> /* needs the above defs */
140 * On the 3min keyboard and mouse come in on channels A
141 * of the two units. The MI code expects them at 'lines'
142 * 0 and 1, respectively. So we map here back and forth.
143 * Note also the MI code believes unit 0 has four lines.
146 #define SCC_KBDUNIT 1
147 #define SCC_PTRUNIT 0
149 mi_to_scc(unitp
, linep
)
152 /* only play games on MI 'unit' 0 */
154 /* e.g. by mapping the first four lines specially */
159 /* always get unit=0 (console) and line = 0|1 */
160 if (*linep
== SCREEN_LINE_KEYBOARD
) {
161 *unitp
= SCC_KBDUNIT
;
162 *linep
= SCC_CHANNEL_A
;
163 } else if (*linep
== SCREEN_LINE_POINTER
) {
164 *unitp
= SCC_PTRUNIT
;
165 *linep
= SCC_CHANNEL_A
;
167 *unitp
= (*linep
& 1);
168 *linep
= SCC_CHANNEL_B
;
170 /* line 0 is channel B, line 1 is channel A */
173 #define NSCC_LINE 2 /* 2 ttys per chip */
175 /* only care for mapping to ttyno */
176 scc_to_mi(sccunit
, sccline
)
179 return (sccunit
* NSCC_LINE
+ sccline
);
180 /* only for console (first pair of SCCs): */
181 if (sccline
== SCC_CHANNEL_A
)
182 return ((!sccunit
) & 1);
193 /* software copy of some write regs, for reg |= */
199 } softr
[2]; /* per channel */
201 unsigned short breaks
;
202 unsigned short fake
; /* missing rs232 bits, channel A */
204 char softCAR
, osoftCAR
;
207 boolean_t full_modem
;
208 boolean_t isa_console
;
210 } scc_softc_data
[NSCC
];
212 typedef struct scc_softc
*scc_softc_t
;
214 scc_softc_t scc_softc
[NSCC
];
216 scc_softCAR(unit
, line
, on
)
218 mi_to_scc(&unit
, &line
);
220 scc_softc
[unit
]->softCAR
|= 1<<line
;
222 scc_softc
[unit
]->softCAR
&= ~(1 << line
);
229 * BRGconstant = --------------------------- - 2
230 * 2 * BaudRate * ClockDivider
232 /* Speed selections with Pclk=7.3728Mhz, clock x16 */
235 /* 0 50 75 110 134.5 150 200 300 600 1200 1800 2400 */
236 { 0, 4606, 3070, 2093, 1711, 1534, 1150, 766, 382, 190, 126, 94,
238 /* 4800 9600 19.2k 38.4k */
242 * Definition of the driver for the auto-configuration program.
245 int scc_probe(), scc_attach(), scc_intr();
247 caddr_t scc_std
[NSCC
] = { 0 };
248 struct bus_device
*scc_info
[NSCC
];
249 struct bus_driver scc_driver
=
250 { scc_probe
, 0, scc_attach
, 0, scc_std
, "scc", scc_info
,};
253 * Adapt/Probe/Attach functions
255 boolean_t scc_uses_modem_control
= FALSE
;/* patch this with adb */
257 set_scc_address( sccunit
, regs
, has_modem
, isa_console
)
260 boolean_t isa_console
;
262 extern int scc_probe(), scc_param(), scc_start(),
263 scc_putc(), scc_getc(),
264 scc_pollc(), scc_mctl(), scc_softCAR();
266 scc_std
[sccunit
] = regs
;
267 scc_softc_data
[sccunit
].full_modem
= has_modem
& scc_uses_modem_control
;
268 scc_softc_data
[sccunit
].isa_console
= isa_console
;
271 console_probe
= scc_probe
;
272 console_param
= scc_param
;
273 console_start
= scc_start
;
274 console_putc
= scc_putc
;
275 console_getc
= scc_getc
;
276 console_pollc
= scc_pollc
;
277 console_mctl
= scc_mctl
;
278 console_softCAR
= scc_softCAR
;
283 struct bus_device
*ui
;
285 int sccunit
= ui
->unit
;
288 register scc_regmap_t
*regs
;
290 regs
= (scc_regmap_t
*)scc_std
[sccunit
];
297 if (check_memory(regs
, 0)) {
302 scc
= &scc_softc_data
[sccunit
];
304 if (scc
->probed_once
++){
308 * Chip once-only initialization
310 * NOTE: The wiring we assume is the one on the 3min:
312 * out A-TxD --> TxD keybd or mouse
313 * in A-RxD --> RxD keybd or mouse
314 * out A-DTR~ --> DTR comm
315 * out A-RTS~ --> RTS comm
316 * in A-CTS~ --> SI comm
317 * in A-DCD~ --> RI comm
318 * in A-SYNCH~--> DSR comm
319 * out B-TxD --> TxD comm
320 * in B-RxD --> RxD comm
321 * in B-RxC --> TRxCB comm
322 * in B-TxC --> RTxCB comm
323 * out B-RTS~ --> SS comm
324 * in B-CTS~ --> CTS comm
325 * in B-DCD~ --> CD comm
328 scc_softc
[sccunit
] = scc
;
331 scc
->fake
= 1<<SCC_CHANNEL_A
;
335 /* We need this in scc_start only, hence the funny
336 value: we need it non-zero and we want to avoid
337 too much overhead in getting to (scc,regs,line) */
338 for (i
= 0; i
< NSCC_LINE
; i
++) {
339 register struct tty
*tp
;
341 tp
= console_tty
[scc_to_mi(sccunit
,i
)];
342 tp
->t_addr
= (char*)(0x80000000L
+ (sccunit
<<1) + (i
&1));
343 /* do min buffering */
344 tp
->t_state
|= TS_MIN
;
348 /* make sure reg pointer is in known state */
349 scc_init_reg(regs
, SCC_CHANNEL_A
);
350 scc_init_reg(regs
, SCC_CHANNEL_B
);
352 /* reset chip, fully */
353 scc_write_reg(regs
, SCC_CHANNEL_A
, SCC_WR9
, SCC_WR9_HW_RESET
);
354 delay(50000);/*enough ? */
355 scc_write_reg(regs
, SCC_CHANNEL_A
, SCC_WR9
, 0);
357 /* program the interrupt vector */
358 scc_write_reg(regs
, SCC_CHANNEL_A
, SCC_WR2
, 0xf0);
359 scc_write_reg(regs
, SCC_CHANNEL_B
, SCC_WR2
, 0xf0);
360 scc_write_reg(regs
, SCC_CHANNEL_A
, SCC_WR9
, SCC_WR9_VIS
);
362 /* most of the init is in scc_param() */
364 /* timing base defaults */
365 scc
->softr
[SCC_CHANNEL_A
].wr4
= SCC_WR4_CLK_x16
;
366 scc
->softr
[SCC_CHANNEL_B
].wr4
= SCC_WR4_CLK_x16
;
368 /* enable DTR, RTS and SS */
369 scc
->softr
[SCC_CHANNEL_B
].wr5
= SCC_WR5_RTS
;
370 scc
->softr
[SCC_CHANNEL_A
].wr5
= SCC_WR5_RTS
| SCC_WR5_DTR
;
373 val
= SCC_WR14_BAUDR_ENABLE
|SCC_WR14_BAUDR_SRC
;
374 scc
->softr
[SCC_CHANNEL_B
].wr14
= val
;
375 scc
->softr
[SCC_CHANNEL_A
].wr14
= val
;
377 /* interrupt conditions */
378 val
= SCC_WR1_RXI_ALL_CHAR
| SCC_WR1_PARITY_IE
|
379 SCC_WR1_EXT_IE
| SCC_WR1_TX_IE
;
380 scc
->softr
[SCC_CHANNEL_A
].wr1
= val
;
381 scc
->softr
[SCC_CHANNEL_B
].wr1
= val
;
384 * After probing, any line that should be active
385 * (keybd,mouse,rcline) is activated via scc_param().
388 scc_set_modem_control(scc
, scc
->full_modem
);
390 #if defined(KMIN) || defined (FLAMINGO)
392 * Crock: MI code knows of unit 0 as console, we need
393 * unit 1 as well since the keyboard is there
394 * This is acceptable on maxine, which has to call its
395 * only one chip unit 1 so that rconsole is happy.
407 boolean_t scc_timer_started
= FALSE
;
410 register struct bus_device
*ui
;
412 int sccunit
= ui
->unit
;
414 extern int tty_inq_size
;
417 /* We only have 4 ttys, but always at 9600
418 * Give em a lot of room (plus dma..)
421 if (!scc_timer_started
) {
422 /* do all of them, before we call scc_scan() */
423 /* harmless if done already */
424 for (i
= 0; i
< NSCC
*NSCC_LINE
; i
++)
425 ttychars(console_tty
[i
]);
427 scc_timer_started
= TRUE
;
432 if (SCREEN_ISA_CONSOLE() && scc_softc
[sccunit
]->isa_console
) {
434 if (sccunit
&& rcline
== 3) printf("( rconsole )");
436 if (sccunit
== SCC_KBDUNIT
) {
437 printf("\n sl1: "); lk201_attach(0, sccunit
>> 1);
438 } else if (sccunit
== SCC_PTRUNIT
) {
439 printf("\n sl1: "); mouse_attach(0, sccunit
>> 1);
444 printf("%s", (sccunit
== 1) ?
445 "\n sl0: ( alternate console )\n sl1:" :
451 * Would you like to make a phone call ?
453 scc_set_modem_control(scc
, on
)
458 /* your problem if the hardware then is broke */
462 scc
->full_modem
= on
;
463 /* user should do an scc_param() ifchanged */
467 * Polled I/O (debugger)
473 int line
= SCREEN_LINE_KEYBOARD
,
476 mi_to_scc(&sccunit
, &line
);
478 scc
= scc_softc
[sccunit
];
482 screen_on_off(unit
, TRUE
);
493 scc_intr(unit
,spllevel
)
496 scc_softc_t scc
= scc_softc
[unit
];
497 register scc_regmap_t
*regs
= scc
->regs
;
498 register int rr1
, rr2
;
504 splx(spllevel
); /* lower priority */
509 scc_read_reg(regs
, SCC_CHANNEL_B
, SCC_RR2
, rr2
);
511 rr2
= SCC_RR2_STATUS(rr2
);
513 /* are we done yet ? */
514 if (rr2
== 6) { /* strange, distinguished value */
516 scc_read_reg(regs
, SCC_CHANNEL_A
, SCC_RR3
, rr3
);
521 if ((rr2
== SCC_RR2_A_XMIT_DONE
) || (rr2
== SCC_RR2_B_XMIT_DONE
)) {
523 register chan
= (rr2
== SCC_RR2_A_XMIT_DONE
) ?
524 SCC_CHANNEL_A
: SCC_CHANNEL_B
;
526 scc_write_reg(regs
, SCC_CHANNEL_A
, SCC_RR0
, SCC_RESET_HIGHEST_IUS
);
527 c
= cons_simple_tint(scc_to_mi(unit
,chan
), FALSE
);
530 /* no more data for this line */
532 scc_read_reg(regs
, chan
, SCC_RR15
, c
);
533 c
&= ~SCC_WR15_TX_UNDERRUN_IE
;
534 scc_write_reg(regs
, chan
, SCC_WR15
, c
);
536 c
= scc
->softr
[chan
].wr1
& ~SCC_WR1_TX_IE
;
537 scc_write_reg(regs
, chan
, SCC_WR1
, c
);
538 scc
->softr
[chan
].wr1
= c
;
540 c
= cons_simple_tint(scc_to_mi(unit
,chan
), TRUE
);
542 /* funny race, scc_start has been called already */
543 scc_write_data(regs
, chan
, c
);
545 scc_write_data(regs
, chan
, c
);
546 /* and leave it enabled */
550 else if (rr2
== SCC_RR2_A_RECV_DONE
) {
553 scc_write_reg(regs
, SCC_CHANNEL_A
, SCC_RR0
, SCC_RESET_HIGHEST_IUS
);
554 if (scc
->polling_mode
)
557 scc_read_data(regs
, SCC_CHANNEL_A
, c
);
558 rr1
= scc_to_mi(unit
,SCC_CHANNEL_A
);
559 cons_simple_rint (rr1
, rr1
, c
, 0);
562 else if (rr2
== SCC_RR2_B_RECV_DONE
) {
565 scc_write_reg(regs
, SCC_CHANNEL_A
, SCC_RR0
, SCC_RESET_HIGHEST_IUS
);
566 if (scc
->polling_mode
)
569 scc_read_data(regs
, SCC_CHANNEL_B
, c
);
570 rr1
= scc_to_mi(unit
,SCC_CHANNEL_B
);
571 cons_simple_rint (rr1
, rr1
, c
, 0);
574 else if ((rr2
== SCC_RR2_A_EXT_STATUS
) || (rr2
== SCC_RR2_B_EXT_STATUS
)) {
575 int chan
= (rr2
== SCC_RR2_A_EXT_STATUS
) ?
576 SCC_CHANNEL_A
: SCC_CHANNEL_B
;
577 scc_write_reg(regs
, chan
, SCC_RR0
, SCC_RESET_EXT_IP
);
578 scc_write_reg(regs
, SCC_CHANNEL_A
, SCC_RR0
, SCC_RESET_HIGHEST_IUS
);
579 scc_modem_intr(scc
, chan
);
582 else if ((rr2
== SCC_RR2_A_RECV_SPECIAL
) || (rr2
== SCC_RR2_B_RECV_SPECIAL
)) {
583 register int chan
= (rr2
== SCC_RR2_A_RECV_SPECIAL
) ?
584 SCC_CHANNEL_A
: SCC_CHANNEL_B
;
586 scc_read_reg(regs
, chan
, SCC_RR1
, rr1
);
587 if (rr1
& (SCC_RR1_PARITY_ERR
| SCC_RR1_RX_OVERRUN
| SCC_RR1_FRAME_ERR
)) {
589 /* map to CONS_ERR_xxx MI error codes */
590 err
= ((rr1
& SCC_RR1_PARITY_ERR
)<<8) |
591 ((rr1
& SCC_RR1_RX_OVERRUN
)<<9) |
592 ((rr1
& SCC_RR1_FRAME_ERR
)<<7);
593 scc_write_reg(regs
, chan
, SCC_RR0
, SCC_RESET_ERROR
);
594 rr1
= scc_to_mi(unit
,chan
);
595 cons_simple_rint(rr1
, rr1
, 0, err
);
597 scc_write_reg(regs
, SCC_CHANNEL_A
, SCC_RR0
, SCC_RESET_HIGHEST_IUS
);
608 register scc_regmap_t
*regs
;
609 register int chan
, temp
;
610 register struct softreg
*sr
;
612 temp
= (natural_t
)tp
->t_addr
;
613 chan
= (temp
& 1); /* channel */
614 temp
= (temp
>> 1)&0xff;/* sccunit */
615 regs
= scc_softc
[temp
]->regs
;
616 sr
= &scc_softc
[temp
]->softr
[chan
];
618 scc_read_reg(regs
, chan
, SCC_RR15
, temp
);
619 temp
|= SCC_WR15_TX_UNDERRUN_IE
;
620 scc_write_reg(regs
, chan
, SCC_WR15
, temp
);
622 temp
= sr
->wr1
| SCC_WR1_TX_IE
;
623 scc_write_reg(regs
, chan
, SCC_WR1
, temp
);
626 /* but we need a first char out or no cookie */
627 scc_read_reg(regs
, chan
, SCC_RR0
, temp
);
628 if (temp
& SCC_RR0_TX_EMPTY
)
632 c
= getc(&tp
->t_outq
);
633 scc_write_data(regs
, chan
, c
);
638 * Get a char from a specific SCC line
639 * [this is only used for console&screen purposes]
641 scc_getc( unit
, line
, wait
, raw
)
646 register scc_regmap_t
*regs
;
648 int value
, mi_line
, rcvalue
, from_line
;
651 mi_to_scc(&unit
, &line
);
653 scc
= scc_softc
[unit
];
657 * wait till something available
659 * NOTE: we know! that rcline==3
661 if (rcline
) rcline
= 3;
665 scc_read_reg_zero(regs
, line
, value
);
666 if (rcline
&& (mi_line
== SCREEN_LINE_KEYBOARD
)) {
667 scc_read_reg_zero(regs
, SCC_CHANNEL_B
, rcvalue
);
670 if (((value
& SCC_RR0_RX_AVAIL
) == 0) && wait
)
677 * if nothing found return -1
679 from_line
= (rcvalue
& SCC_RR0_RX_AVAIL
) ? SCC_CHANNEL_B
: line
;
681 if (value
& SCC_RR0_RX_AVAIL
) {
682 scc_read_reg(regs
, from_line
, SCC_RR1
, value
);
683 scc_read_data(regs
, from_line
, c
);
692 if (value
&(SCC_RR1_PARITY_ERR
| SCC_RR1_RX_OVERRUN
| SCC_RR1_FRAME_ERR
)) {
693 /* scc_state(unit,from_line); */
694 scc_write_reg(regs
, from_line
, SCC_RR0
, SCC_RESET_ERROR
);
696 scc_write_reg(regs
, SCC_CHANNEL_A
, SCC_RR0
, SCC_RESET_HIGHEST_IUS
);
700 scc_write_reg(regs
, SCC_CHANNEL_A
, SCC_RR0
, SCC_RESET_HIGHEST_IUS
);
705 if ((mi_line
== SCREEN_LINE_KEYBOARD
) && (from_line
== SCC_CHANNEL_A
) &&
706 !raw
&& SCREEN_ISA_CONSOLE() && scc
->isa_console
)
707 return lk201_rint(SCREEN_CONS_UNIT(), c
, wait
, scc
->polling_mode
);
714 * Put a char on a specific SCC line
716 scc_putc( unit
, line
, c
)
719 register scc_regmap_t
*regs
;
723 mi_to_scc(&unit
, &line
);
725 scc
= scc_softc
[unit
];
729 scc_read_reg(regs
, line
, SCC_RR0
, value
);
730 if (value
& SCC_RR0_TX_EMPTY
)
735 scc_write_data(regs
, line
, c
);
736 /* wait for it to swallow the char ? */
745 int value
, sccline
, unit
;
750 /* MI code wants us to handle 4 lines on unit 0 */
751 unit
= (line
< 4) ? 0 : (line
/ NSCC_LINE
);
753 mi_to_scc(&unit
, &sccline
);
755 if ((scc
= scc_softc
[unit
]) == 0) return; /* sanity */
758 sr
= &scc
->softr
[sccline
];
761 * Do not let user fool around with kbd&mouse
764 if (screen_captures(line
)) {
765 tp
->t_ispeed
= tp
->t_ospeed
= B4800
;
766 tp
->t_flags
|= TF_LITOUT
;
770 if (tp
->t_ispeed
== 0) {
771 (void) scc_mctl(tp
->t_dev
, TM_HUP
, DMSET
); /* hang up line */
776 value
= (sccline
== SCC_CHANNEL_A
) ? SCC_WR9_RESET_CHA_A
: SCC_WR9_RESET_CHA_B
;
777 scc_write_reg(regs
, sccline
, SCC_WR9
, value
);
780 /* stop bits, normally 1 */
781 value
= sr
->wr4
& 0xf0;
782 value
|= (tp
->t_ispeed
== B110
) ? SCC_WR4_2_STOP
: SCC_WR4_1_STOP
;
785 if ((tp
->t_flags
& (TF_ODDP
| TF_EVENP
)) == TF_EVENP
)
786 value
|= SCC_WR4_EVEN_PARITY
;
787 value
|= SCC_WR4_PARITY_ENABLE
;
789 if ((tp
->t_flags
& (TF_ODDP
| TF_EVENP
)) == TF_ODDP
)
790 value
|= SCC_WR4_PARITY_ENABLE
;
793 /* set it now, remember it must be first after reset */
795 scc_write_reg(regs
, sccline
, SCC_WR4
, value
);
798 scc_write_reg(regs
, sccline
, SCC_WR2
, 0xf0);
800 /* we only do 8 bits per char */
801 value
= SCC_WR3_RX_8_BITS
;
802 scc_write_reg(regs
, sccline
, SCC_WR3
, value
);
804 /* clear break, keep rts dtr */
805 value
= sr
->wr5
& (SCC_WR5_DTR
|SCC_WR5_RTS
);
806 value
|= SCC_WR5_TX_8_BITS
;
808 scc_write_reg(regs
, sccline
, SCC_WR5
, value
);
810 scc_write_reg(regs
, sccline
, SCC_WR6
, 0);
811 scc_write_reg(regs
, sccline
, SCC_WR7
, 0);
813 scc_write_reg(regs
, sccline
, SCC_WR9
, SCC_WR9_VIS
);
815 scc_write_reg(regs
, sccline
, SCC_WR10
, 0);
818 value
= SCC_WR11_RCLK_BAUDR
| SCC_WR11_XTLK_BAUDR
|
819 SCC_WR11_TRc_OUT
| SCC_WR11_TRcOUT_BAUDR
;
820 scc_write_reg(regs
, sccline
, SCC_WR11
, value
);
822 value
= scc_speeds
[tp
->t_ispeed
];
823 scc_set_timing_base(regs
,sccline
,value
);
826 scc_write_reg(regs
, sccline
, SCC_WR14
, value
);
828 value
= (scc
->full_modem
) ?
829 SCC_WR15_BREAK_IE
| SCC_WR15_CTS_IE
| SCC_WR15_DCD_IE
:
831 scc_write_reg(regs
, sccline
, SCC_WR15
, value
);
833 /* and now the enables */
834 value
= SCC_WR3_RX_8_BITS
| SCC_WR3_RX_ENABLE
;
835 scc_write_reg(regs
, sccline
, SCC_WR3
, value
);
837 value
= sr
->wr5
| SCC_WR5_TX_ENABLE
;
839 scc_write_reg(regs
, sccline
, SCC_WR5
, value
);
841 /* master inter enable */
842 scc_write_reg(regs
,sccline
,SCC_WR9
,SCC_WR9_MASTER_IE
|SCC_WR9_VIS
);
844 scc_write_reg(regs
, sccline
, SCC_WR1
, sr
->wr1
);
849 * Modem control functions
851 scc_mctl(dev
, bits
, how
)
857 register scc_regmap_t
*regs
;
859 register int tcr
, msr
, brk
, n_tcr
, n_brk
;
867 mi_to_scc(&unit
, &sccline
);
869 /* no modem support on channel A */
870 /* XXX break on 0&1 */
871 if (sccline
== SCC_CHANNEL_A
)
872 return TM_LE
| TM_DTR
| TM_CTS
| TM_CAR
| TM_DSR
;
874 scc
= scc_softc
[unit
];
880 tcr
= ((regs
->scc_tcr
| (scc
->fake
>>4)) & 0xf00) >> (8 + b
*2);
881 brk
= (scc
->breaks
>> (8 + (unit
&3))) & 1; /* THE break bit */
883 n_tcr
= (bits
& (TM_RTS
| TM_DTR
)) >> 1;
884 n_brk
= (bits
& TM_BRK
) >> 9;
886 /* break transitions, must 'send' a char out */
887 bits
= (brk
^ n_brk
) & 1;
906 msr
= ((regs
->scc_msr
| scc
->fake
) & 0xf0f) >> (b
*8);
908 return (tcr
<<1)|/* DTR, RTS */
909 ((msr
&1)<<5)|/* CTS */
910 ((msr
&2)<<7)|/* DSR */
911 ((msr
&0xc)<<4)|/* CD, RNG */
915 n_tcr
= (regs
->scc_tcr
& ~(3 << (8 + b
*2))) |
918 regs
->scc_tcr
= n_tcr
;
919 scc
->fake
= (scc
->fake
& 0xf0f) | (n_tcr
<<4&0xf000);
921 scc
->breaks
= (scc
->breaks
& ~(1 << (8 + (unit
&3)))) |
922 (brk
<< (8 + (unit
&3)));
923 if(bits
) scc_putc( unit
>>2, unit
&3, 0);/* force break, now */
925 return 0;/* useless to compute it */
929 scc_modem_intr(scc
, chan
)
935 register struct tty
*tp
,
941 /* cancel modem timeout if need to */
942 if (car
& (SCC_MSR_CD2
| SCC_MSR_CD3
))
943 untimeout(scc_hup
, (caddr_t
)tp
);
946 /* I think this belongs in the MI code */
947 if (tp
->t_state
& TS_WOPEN
)
948 tp
->t_state
|= TS_ISOPEN
;
949 /* carrier present */
950 if ((tp
->t_state
& TS_CARR_ON
) == 0)
951 (void)ttymodem(tp
, 1);
952 } else if ((tp
->t_state
&TS_CARR_ON
) && ttymodem(tp
, 0) == 0)
953 scc_mctl( tp
->t_dev
, TM_DTR
, DMBIC
);
957 * Periodically look at the CD signals:
958 * they do generate interrupts but we
959 * must fake them on channel A. We might
960 * also fake them on channel B.
967 for (i
= 0; i
< NSCC
; i
++) {
968 register scc_softc_t scc
;
970 register struct tty
**tpp
;
975 car
= scc
->softCAR
| scc
->fake
;
977 tpp
= &console_tty
[i
* NSCC_LINE
];
988 timeout(scc_scan
, (caddr_t
)0, 5*hz
);
993 scc_rreg(unit
,chan
,n
)
996 scc_read_reg(scc_softc
[unit
]->regs
, chan
, n
, val
);
1000 scc_wreg(unit
,chan
,n
,val
)
1002 scc_write_reg(scc_softc
[unit
]->regs
, chan
, n
, val
);
1005 scc_state(unit
,soft
)
1007 printf("{%d intr, A: R0 %x R1 %x R3 %x baudr %x R15 %x}\n",
1009 scc_rreg(unit
, 1, SCC_RR0
),
1010 scc_rreg(unit
, 1, SCC_RR1
),
1011 scc_rreg(unit
, 1, SCC_RR3
),
1012 (scc_rreg(unit
, 1, SCC_RR13
) << 8) | scc_rreg(unit
, 1, SCC_RR12
),
1013 scc_rreg(unit
, 1, SCC_RR15
));
1014 printf("{B: R0 %x R1 %x R2 %x baudr %x R15 %x}\n",
1015 scc_rreg(unit
, 1, SCC_RR0
),
1016 scc_rreg(unit
, 1, SCC_RR1
),
1017 scc_rreg(unit
, 1, SCC_RR2
),
1018 (scc_rreg(unit
, 1, SCC_RR13
) << 8) | scc_rreg(unit
, 1, SCC_RR12
),
1019 scc_rreg(unit
, 1, SCC_RR15
));
1022 sr
= scc_softc
[unit
]->softr
;
1023 printf("{B: W1 %x W4 %x W5 %x W14 %x}",
1024 sr
->wr1
, sr
->wr4
, sr
->wr5
, sr
->wr14
);
1026 printf("{A: W1 %x W4 %x W5 %x W14 %x}\n",
1027 sr
->wr1
, sr
->wr4
, sr
->wr5
, sr
->wr14
);