zs_ap.c revision 1.24 1 1.24 tsutsui /* $NetBSD: zs_ap.c,v 1.24 2008/03/29 19:15:35 tsutsui Exp $ */
2 1.1 tsubai
3 1.1 tsubai /*-
4 1.1 tsubai * Copyright (c) 1996 The NetBSD Foundation, Inc.
5 1.1 tsubai * All rights reserved.
6 1.1 tsubai *
7 1.1 tsubai * This code is derived from software contributed to The NetBSD Foundation
8 1.1 tsubai * by Gordon W. Ross.
9 1.1 tsubai *
10 1.1 tsubai * Redistribution and use in source and binary forms, with or without
11 1.1 tsubai * modification, are permitted provided that the following conditions
12 1.1 tsubai * are met:
13 1.1 tsubai * 1. Redistributions of source code must retain the above copyright
14 1.1 tsubai * notice, this list of conditions and the following disclaimer.
15 1.1 tsubai * 2. Redistributions in binary form must reproduce the above copyright
16 1.1 tsubai * notice, this list of conditions and the following disclaimer in the
17 1.1 tsubai * documentation and/or other materials provided with the distribution.
18 1.1 tsubai * 3. All advertising materials mentioning features or use of this software
19 1.1 tsubai * must display the following acknowledgement:
20 1.1 tsubai * This product includes software developed by the NetBSD
21 1.1 tsubai * Foundation, Inc. and its contributors.
22 1.1 tsubai * 4. Neither the name of The NetBSD Foundation nor the names of its
23 1.1 tsubai * contributors may be used to endorse or promote products derived
24 1.1 tsubai * from this software without specific prior written permission.
25 1.1 tsubai *
26 1.1 tsubai * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 1.1 tsubai * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 1.1 tsubai * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 1.1 tsubai * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 1.1 tsubai * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 1.1 tsubai * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 1.1 tsubai * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 1.1 tsubai * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 1.1 tsubai * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 1.1 tsubai * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 1.1 tsubai * POSSIBILITY OF SUCH DAMAGE.
37 1.1 tsubai */
38 1.1 tsubai
39 1.1 tsubai /*
40 1.1 tsubai * Zilog Z8530 Dual UART driver (machine-dependent part)
41 1.1 tsubai *
42 1.1 tsubai * Runs two serial lines per chip using slave drivers.
43 1.1 tsubai * Plain tty/async lines use the zs_async slave.
44 1.1 tsubai * Sun keyboard/mouse uses the zs_kbd/zs_ms slaves.
45 1.1 tsubai */
46 1.16 lukem
47 1.16 lukem #include <sys/cdefs.h>
48 1.24 tsutsui __KERNEL_RCSID(0, "$NetBSD: zs_ap.c,v 1.24 2008/03/29 19:15:35 tsutsui Exp $");
49 1.1 tsubai
50 1.1 tsubai #include <sys/param.h>
51 1.1 tsubai #include <sys/systm.h>
52 1.1 tsubai #include <sys/device.h>
53 1.1 tsubai #include <sys/tty.h>
54 1.6 gehenna #include <sys/conf.h>
55 1.23 ad #include <sys/cpu.h>
56 1.23 ad #include <sys/intr.h>
57 1.1 tsubai
58 1.1 tsubai #include <machine/adrsmap.h>
59 1.1 tsubai #include <machine/z8530var.h>
60 1.1 tsubai
61 1.1 tsubai #include <dev/cons.h>
62 1.1 tsubai #include <dev/ic/z8530reg.h>
63 1.1 tsubai
64 1.1 tsubai #include <newsmips/apbus/apbusvar.h>
65 1.1 tsubai
66 1.1 tsubai #include "zsc.h" /* NZSC */
67 1.1 tsubai #define NZS NZSC
68 1.1 tsubai
69 1.1 tsubai /* Make life easier for the initialized arrays here. */
70 1.1 tsubai #if NZS < 2
71 1.1 tsubai #undef NZS
72 1.1 tsubai #define NZS 2
73 1.1 tsubai #endif
74 1.1 tsubai
75 1.2 tsubai #define PORTB_XPORT 0x00000000
76 1.2 tsubai #define PORTB_RPORT 0x00010000
77 1.2 tsubai #define PORTA_XPORT 0x00020000
78 1.2 tsubai #define PORTA_RPORT 0x00030000
79 1.2 tsubai #define DMA_MODE_REG 3
80 1.2 tsubai #define DMA_ENABLE 0x01 /* DMA enable */
81 1.2 tsubai #define DMA_DIR_DM 0x00 /* device to memory */
82 1.2 tsubai #define DMA_DIR_MD 0x02 /* memory to device */
83 1.2 tsubai #define DMA_EXTRDY 0x08 /* DMA external ready */
84 1.2 tsubai #define PORTB_OFFSET 0x00040000
85 1.2 tsubai #define PORTA_OFFSET 0x00050000
86 1.2 tsubai #define PORT_CTL 2
87 1.2 tsubai #define PORTCTL_RI 0x01
88 1.12 tsutsui #define PORTCTL_DSR 0x02
89 1.2 tsubai #define PORTCTL_DTR 0x04
90 1.2 tsubai #define PORT_SEL 3
91 1.2 tsubai #define PORTSEL_LOCALTALK 0x01
92 1.2 tsubai #define PORTSEL_RS232C 0x02
93 1.2 tsubai #define ESCC_REG 0x00060000
94 1.2 tsubai #define ESCCREG_INTSTAT 0
95 1.2 tsubai #define INTSTAT_SCC 0x01
96 1.2 tsubai #define ESCCREG_INTMASK 1
97 1.2 tsubai #define INTMASK_SCC 0x01
98 1.1 tsubai
99 1.1 tsubai extern int zs_def_cflag;
100 1.17 tsutsui extern void (*zs_delay)(void);
101 1.1 tsubai
102 1.1 tsubai /*
103 1.1 tsubai * The news5000 provides a 9.8304 MHz clock to the ZS chips.
104 1.1 tsubai */
105 1.1 tsubai #define PCLK (9600 * 1024) /* PCLK pin input clock rate */
106 1.1 tsubai
107 1.1 tsubai #define ZS_DELAY() DELAY(2)
108 1.1 tsubai
109 1.1 tsubai /* The layout of this is hardware-dependent (padding, order). */
110 1.1 tsubai struct zschan {
111 1.24 tsutsui volatile uint8_t pad1[3];
112 1.24 tsutsui volatile uint8_t zc_csr; /* ctrl,status, and indirect access */
113 1.24 tsutsui volatile uint8_t pad2[3];
114 1.24 tsutsui volatile uint8_t zc_data; /* data */
115 1.1 tsubai };
116 1.1 tsubai
117 1.20 christos static void *zsaddr[NZS];
118 1.1 tsubai
119 1.1 tsubai /* Flags from cninit() */
120 1.1 tsubai static int zs_hwflags[NZS][2];
121 1.1 tsubai
122 1.1 tsubai /* Default speed for all channels */
123 1.1 tsubai static int zs_defspeed = 9600;
124 1.1 tsubai
125 1.24 tsutsui static uint8_t zs_init_reg[16] = {
126 1.1 tsubai 0, /* 0: CMD (reset, etc.) */
127 1.1 tsubai 0, /* 1: No interrupts yet. */
128 1.1 tsubai 0, /* IVECT */
129 1.1 tsubai ZSWR3_RX_8 | ZSWR3_RX_ENABLE,
130 1.1 tsubai ZSWR4_CLK_X16 | ZSWR4_ONESB | ZSWR4_EVENP,
131 1.1 tsubai ZSWR5_TX_8 | ZSWR5_TX_ENABLE,
132 1.1 tsubai 0, /* 6: TXSYNC/SYNCLO */
133 1.1 tsubai 0, /* 7: RXSYNC/SYNCHI */
134 1.1 tsubai 0, /* 8: alias for data port */
135 1.1 tsubai ZSWR9_MASTER_IE,
136 1.1 tsubai 0, /*10: Misc. TX/RX control bits */
137 1.1 tsubai ZSWR11_TXCLK_BAUD | ZSWR11_RXCLK_BAUD,
138 1.1 tsubai ((PCLK/32)/9600)-2, /*12: BAUDLO (default=9600) */
139 1.1 tsubai 0, /*13: BAUDHI (default=9600) */
140 1.1 tsubai ZSWR14_BAUD_ENA | ZSWR14_BAUD_FROM_PCLK,
141 1.1 tsubai ZSWR15_BREAK_IE,
142 1.1 tsubai };
143 1.1 tsubai
144 1.17 tsutsui static struct zschan * zs_get_chan_addr(int, int);
145 1.17 tsutsui static void zs_ap_delay(void);
146 1.17 tsutsui static int zshard_ap(void *);
147 1.17 tsutsui static int zs_getc(void *);
148 1.17 tsutsui static void zs_putc(void *, int);
149 1.1 tsubai
150 1.1 tsubai struct zschan *
151 1.17 tsutsui zs_get_chan_addr(int zs_unit, int channel)
152 1.1 tsubai {
153 1.20 christos void *addr;
154 1.1 tsubai struct zschan *zc;
155 1.1 tsubai
156 1.1 tsubai if (zs_unit >= NZS)
157 1.1 tsubai return NULL;
158 1.1 tsubai addr = zsaddr[zs_unit];
159 1.1 tsubai if (addr == NULL)
160 1.1 tsubai return NULL;
161 1.1 tsubai if (channel == 0) {
162 1.24 tsutsui zc = (void *)((uint8_t *)addr + PORTA_OFFSET);
163 1.1 tsubai } else {
164 1.24 tsutsui zc = (void *)((uint8_t *)addr + PORTB_OFFSET);
165 1.1 tsubai }
166 1.17 tsutsui return zc;
167 1.1 tsubai }
168 1.1 tsubai
169 1.1 tsubai void
170 1.17 tsutsui zs_ap_delay(void)
171 1.1 tsubai {
172 1.13 tsutsui
173 1.1 tsubai ZS_DELAY();
174 1.1 tsubai }
175 1.1 tsubai
176 1.1 tsubai /****************************************************************
177 1.1 tsubai * Autoconfig
178 1.1 tsubai ****************************************************************/
179 1.1 tsubai
180 1.1 tsubai /* Definition of the driver for autoconfig. */
181 1.24 tsutsui int zs_ap_match(device_t, cfdata_t, void *);
182 1.24 tsutsui void zs_ap_attach(device_t, device_t, void *);
183 1.1 tsubai
184 1.24 tsutsui CFATTACH_DECL_NEW(zsc_ap, sizeof(struct zsc_softc),
185 1.8 thorpej zs_ap_match, zs_ap_attach, NULL, NULL);
186 1.1 tsubai
187 1.1 tsubai /*
188 1.1 tsubai * Is the zs chip present?
189 1.1 tsubai */
190 1.1 tsubai int
191 1.24 tsutsui zs_ap_match(device_t parent, cfdata_t cf, void *aux)
192 1.1 tsubai {
193 1.1 tsubai struct apbus_attach_args *apa = aux;
194 1.1 tsubai
195 1.1 tsubai if (strcmp("esccf", apa->apa_name) != 0)
196 1.1 tsubai return 0;
197 1.1 tsubai
198 1.1 tsubai return 1;
199 1.1 tsubai }
200 1.1 tsubai
201 1.1 tsubai /*
202 1.1 tsubai * Attach a found zs.
203 1.1 tsubai *
204 1.1 tsubai * Match slave number to zs unit number, so that misconfiguration will
205 1.1 tsubai * not set up the keyboard as ttya, etc.
206 1.1 tsubai */
207 1.1 tsubai void
208 1.24 tsutsui zs_ap_attach(device_t parent, device_t self, void *aux)
209 1.1 tsubai {
210 1.24 tsutsui struct zsc_softc *zsc = device_private(self);
211 1.1 tsubai struct apbus_attach_args *apa = aux;
212 1.1 tsubai struct zsc_attach_args zsc_args;
213 1.1 tsubai volatile struct zschan *zc;
214 1.1 tsubai struct zs_chanstate *cs;
215 1.1 tsubai int s, zs_unit, channel;
216 1.2 tsubai volatile u_int *txBfifo = (void *)(apa->apa_hwbase + PORTB_XPORT);
217 1.2 tsubai volatile u_int *rxBfifo = (void *)(apa->apa_hwbase + PORTB_RPORT);
218 1.2 tsubai volatile u_int *txAfifo = (void *)(apa->apa_hwbase + PORTA_XPORT);
219 1.2 tsubai volatile u_int *rxAfifo = (void *)(apa->apa_hwbase + PORTA_RPORT);
220 1.2 tsubai volatile u_int *portBctl = (void *)(apa->apa_hwbase + PORTB_OFFSET);
221 1.2 tsubai volatile u_int *portActl = (void *)(apa->apa_hwbase + PORTA_OFFSET);
222 1.2 tsubai volatile u_int *esccregs = (void *)(apa->apa_hwbase + ESCC_REG);
223 1.1 tsubai static int didintr;
224 1.1 tsubai
225 1.24 tsutsui zsc->zsc_dev = self;
226 1.24 tsutsui zs_unit = device_unit(self);
227 1.20 christos zsaddr[zs_unit] = (void *)apa->apa_hwbase;
228 1.1 tsubai
229 1.24 tsutsui aprint_normal(" slot%d addr 0x%lx\n", apa->apa_slotno, apa->apa_hwbase);
230 1.1 tsubai
231 1.2 tsubai txAfifo[DMA_MODE_REG] = rxAfifo[DMA_MODE_REG] = DMA_EXTRDY;
232 1.2 tsubai txBfifo[DMA_MODE_REG] = rxBfifo[DMA_MODE_REG] = DMA_EXTRDY;
233 1.1 tsubai
234 1.1 tsubai /* assert DTR */ /* XXX */
235 1.2 tsubai portBctl[PORT_CTL] = portActl[PORT_CTL] = PORTCTL_DTR;
236 1.1 tsubai
237 1.1 tsubai /* select RS-232C (ch1 only) */
238 1.2 tsubai portActl[PORT_SEL] = PORTSEL_RS232C;
239 1.1 tsubai
240 1.1 tsubai /* enable SCC interrupts */
241 1.2 tsubai esccregs[ESCCREG_INTMASK] = INTMASK_SCC;
242 1.1 tsubai
243 1.1 tsubai zs_delay = zs_ap_delay;
244 1.1 tsubai
245 1.1 tsubai /*
246 1.1 tsubai * Initialize software state for each channel.
247 1.1 tsubai */
248 1.1 tsubai for (channel = 0; channel < 2; channel++) {
249 1.1 tsubai zsc_args.channel = channel;
250 1.1 tsubai zsc_args.hwflags = zs_hwflags[zs_unit][channel];
251 1.1 tsubai cs = &zsc->zsc_cs_store[channel];
252 1.1 tsubai zsc->zsc_cs[channel] = cs;
253 1.1 tsubai
254 1.22 ad zs_lock_init(cs);
255 1.1 tsubai cs->cs_channel = channel;
256 1.1 tsubai cs->cs_private = NULL;
257 1.1 tsubai cs->cs_ops = &zsops_null;
258 1.1 tsubai cs->cs_brg_clk = PCLK / 16;
259 1.1 tsubai
260 1.1 tsubai zc = zs_get_chan_addr(zs_unit, channel);
261 1.1 tsubai cs->cs_reg_csr = &zc->zc_csr;
262 1.1 tsubai cs->cs_reg_data = &zc->zc_data;
263 1.1 tsubai
264 1.17 tsutsui memcpy(cs->cs_creg, zs_init_reg, 16);
265 1.17 tsutsui memcpy(cs->cs_preg, zs_init_reg, 16);
266 1.1 tsubai
267 1.1 tsubai /* XXX: Get these from the EEPROM instead? */
268 1.1 tsubai /* XXX: See the mvme167 code. Better. */
269 1.1 tsubai if (zsc_args.hwflags & ZS_HWFLAG_CONSOLE)
270 1.1 tsubai cs->cs_defspeed = zs_get_speed(cs);
271 1.1 tsubai else
272 1.1 tsubai cs->cs_defspeed = zs_defspeed;
273 1.1 tsubai cs->cs_defcflag = zs_def_cflag;
274 1.1 tsubai
275 1.1 tsubai /* Make these correspond to cs_defcflag (-crtscts) */
276 1.1 tsubai cs->cs_rr0_dcd = ZSRR0_DCD;
277 1.1 tsubai cs->cs_rr0_cts = 0;
278 1.1 tsubai cs->cs_wr5_dtr = ZSWR5_DTR | ZSWR5_RTS;
279 1.1 tsubai cs->cs_wr5_rts = 0;
280 1.1 tsubai
281 1.1 tsubai /*
282 1.1 tsubai * Clear the master interrupt enable.
283 1.1 tsubai * The INTENA is common to both channels,
284 1.1 tsubai * so just do it on the A channel.
285 1.1 tsubai */
286 1.1 tsubai if (channel == 0) {
287 1.1 tsubai zs_write_reg(cs, 9, 0);
288 1.1 tsubai }
289 1.1 tsubai
290 1.1 tsubai /*
291 1.1 tsubai * Look for a child driver for this channel.
292 1.1 tsubai * The child attach will setup the hardware.
293 1.1 tsubai */
294 1.1 tsubai if (!config_found(self, (void *)&zsc_args, zs_print)) {
295 1.1 tsubai /* No sub-driver. Just reset it. */
296 1.24 tsutsui uint8_t reset = (channel == 0) ?
297 1.24 tsutsui ZSWR9_A_RESET : ZSWR9_B_RESET;
298 1.1 tsubai s = splhigh();
299 1.1 tsubai zs_write_reg(cs, 9, reset);
300 1.1 tsubai splx(s);
301 1.1 tsubai }
302 1.1 tsubai }
303 1.1 tsubai
304 1.1 tsubai /*
305 1.1 tsubai * Now safe to install interrupt handlers. Note the arguments
306 1.1 tsubai * to the interrupt handlers aren't used. Note, we only do this
307 1.1 tsubai * once since both SCCs interrupt at the same level and vector.
308 1.1 tsubai */
309 1.1 tsubai if (!didintr) {
310 1.1 tsubai didintr = 1;
311 1.1 tsubai
312 1.23 ad zsc->zsc_si = softint_establish(SOFTINT_SERIAL, zssoft, zsc);
313 1.1 tsubai apbus_intr_establish(1, /* interrupt level ( 0 or 1 ) */
314 1.2 tsubai NEWS5000_INT1_SCC,
315 1.1 tsubai 0, /* priority */
316 1.3 tsubai zshard_ap, zsc,
317 1.1 tsubai apa->apa_name, apa->apa_ctlnum);
318 1.1 tsubai }
319 1.1 tsubai /* XXX; evcnt_attach() ? */
320 1.1 tsubai
321 1.1 tsubai #if 0
322 1.1 tsubai {
323 1.1 tsubai u_int x;
324 1.1 tsubai
325 1.1 tsubai /* determine SCC/ESCC type */
326 1.1 tsubai x = zs_read_reg(cs, 15);
327 1.1 tsubai zs_write_reg(cs, 15, x | ZSWR15_ENABLE_ENHANCED);
328 1.1 tsubai
329 1.1 tsubai if (zs_read_reg(cs, 15) & ZSWR15_ENABLE_ENHANCED) { /* ESCC Z85230 */
330 1.1 tsubai zs_write_reg(cs, 7, ZSWR7P_EXTEND_READ | ZSWR7P_TX_FIFO);
331 1.1 tsubai }
332 1.1 tsubai }
333 1.1 tsubai #endif
334 1.1 tsubai
335 1.1 tsubai /*
336 1.1 tsubai * Set the master interrupt enable and interrupt vector.
337 1.1 tsubai * (common to both channels, do it on A)
338 1.1 tsubai */
339 1.1 tsubai cs = zsc->zsc_cs[0];
340 1.1 tsubai s = splhigh();
341 1.1 tsubai /* interrupt vector */
342 1.1 tsubai zs_write_reg(cs, 2, zs_init_reg[2]);
343 1.1 tsubai /* master interrupt control (enable) */
344 1.1 tsubai zs_write_reg(cs, 9, zs_init_reg[9]);
345 1.1 tsubai splx(s);
346 1.1 tsubai }
347 1.1 tsubai
348 1.5 onoe static int
349 1.17 tsutsui zshard_ap(void *arg)
350 1.1 tsubai {
351 1.13 tsutsui
352 1.3 tsubai zshard(arg);
353 1.5 onoe return 1;
354 1.1 tsubai }
355 1.1 tsubai
356 1.1 tsubai /*
357 1.1 tsubai * Polled input char.
358 1.1 tsubai */
359 1.1 tsubai int
360 1.17 tsutsui zs_getc(void *arg)
361 1.1 tsubai {
362 1.13 tsutsui volatile struct zschan *zc = arg;
363 1.24 tsutsui int s, c;
364 1.24 tsutsui uint8_t rr0;
365 1.1 tsubai
366 1.1 tsubai s = splhigh();
367 1.1 tsubai /* Wait for a character to arrive. */
368 1.1 tsubai do {
369 1.1 tsubai rr0 = zc->zc_csr;
370 1.1 tsubai ZS_DELAY();
371 1.1 tsubai } while ((rr0 & ZSRR0_RX_READY) == 0);
372 1.1 tsubai
373 1.1 tsubai c = zc->zc_data;
374 1.1 tsubai ZS_DELAY();
375 1.1 tsubai splx(s);
376 1.1 tsubai
377 1.1 tsubai /*
378 1.1 tsubai * This is used by the kd driver to read scan codes,
379 1.1 tsubai * so don't translate '\r' ==> '\n' here...
380 1.1 tsubai */
381 1.17 tsutsui return c;
382 1.1 tsubai }
383 1.1 tsubai
384 1.1 tsubai /*
385 1.1 tsubai * Polled output char.
386 1.1 tsubai */
387 1.1 tsubai void
388 1.17 tsutsui zs_putc(void *arg, int c)
389 1.1 tsubai {
390 1.13 tsutsui volatile struct zschan *zc = arg;
391 1.24 tsutsui int s;
392 1.24 tsutsui uint8_t rr0;
393 1.1 tsubai
394 1.1 tsubai s = splhigh();
395 1.1 tsubai /* Wait for transmitter to become ready. */
396 1.1 tsubai do {
397 1.1 tsubai rr0 = zc->zc_csr;
398 1.1 tsubai ZS_DELAY();
399 1.1 tsubai } while ((rr0 & ZSRR0_TX_READY) == 0);
400 1.1 tsubai
401 1.1 tsubai zc->zc_data = c;
402 1.1 tsubai ZS_DELAY();
403 1.1 tsubai splx(s);
404 1.1 tsubai }
405 1.1 tsubai
406 1.1 tsubai /*****************************************************************/
407 1.1 tsubai
408 1.17 tsutsui static void zscnprobe(struct consdev *);
409 1.17 tsutsui static void zscninit(struct consdev *);
410 1.17 tsutsui static int zscngetc(dev_t);
411 1.17 tsutsui static void zscnputc(dev_t, int);
412 1.1 tsubai
413 1.1 tsubai struct consdev consdev_zs_ap = {
414 1.1 tsubai zscnprobe,
415 1.1 tsubai zscninit,
416 1.1 tsubai zscngetc,
417 1.1 tsubai zscnputc,
418 1.13 tsutsui nullcnpollc,
419 1.13 tsutsui NULL,
420 1.13 tsutsui NULL,
421 1.4 thorpej NULL,
422 1.13 tsutsui NODEV,
423 1.13 tsutsui CN_DEAD
424 1.1 tsubai };
425 1.1 tsubai
426 1.13 tsutsui static void
427 1.17 tsutsui zscnprobe(struct consdev *cn)
428 1.1 tsubai {
429 1.1 tsubai }
430 1.1 tsubai
431 1.13 tsutsui static void
432 1.17 tsutsui zscninit(struct consdev *cn)
433 1.1 tsubai {
434 1.6 gehenna extern const struct cdevsw zstty_cdevsw;
435 1.6 gehenna
436 1.6 gehenna cn->cn_dev = makedev(cdevsw_lookup_major(&zstty_cdevsw), 0);
437 1.1 tsubai cn->cn_pri = CN_REMOTE;
438 1.1 tsubai zs_hwflags[0][0] = ZS_HWFLAG_CONSOLE;
439 1.1 tsubai }
440 1.1 tsubai
441 1.13 tsutsui static int
442 1.17 tsutsui zscngetc(dev_t dev)
443 1.1 tsubai {
444 1.13 tsutsui
445 1.1 tsubai return zs_getc((void *)NEWS5000_SCCPORT0A);
446 1.1 tsubai }
447 1.1 tsubai
448 1.13 tsutsui static void
449 1.17 tsutsui zscnputc(dev_t dev, int c)
450 1.1 tsubai {
451 1.13 tsutsui
452 1.1 tsubai zs_putc((void *)NEWS5000_SCCPORT0A, c);
453 1.1 tsubai }
454