zs.c revision 1.2 1 /* $NetBSD: zs.c,v 1.2 2008/03/23 17:19:57 tsutsui Exp $ */
2
3 /*-
4 * Copyright (C) 2008 Izumi Tsutsui.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #ifdef CONS_ZS
30 /*
31 * optional Z85C30 serial support for Qube 2700
32 */
33
34 #include <lib/libsa/stand.h>
35 #include <lib/libkern/libkern.h>
36
37 #include <dev/ic/z8530reg.h>
38
39 #include <machine/cpu.h>
40
41 #include "boot.h"
42 #include "zs.h"
43
44 #define ZSCLOCK 11059200 /* 19200 * 576 */
45
46 #define ZS_DELAY() delay(2)
47
48 static uint8_t zs_read(void *, uint8_t);
49 static void zs_write(void *, uint8_t, uint8_t);
50 static void zs_write_reg(void *, uint8_t, uint8_t);
51 static void zs_reset(void *);
52
53 static uint8_t
54 zs_read(void *dev, uint8_t reg)
55 {
56 volatile uint8_t *zs = dev;
57 uint8_t val;
58
59 val = *(volatile uint8_t *)(zs + reg);
60 ZS_DELAY();
61
62 return val;
63 }
64
65 static void
66 zs_write(void *dev, uint8_t reg, uint8_t val)
67 {
68 volatile uint8_t *zs = dev;
69
70 *(volatile uint8_t *)(zs + reg) = val;
71 ZS_DELAY();
72 }
73
74 static void
75 zs_write_reg(void *dev, uint8_t reg, uint8_t val)
76 {
77
78 zs_write(dev, ZS_CSR, reg);
79 zs_write(dev, ZS_CSR, val);
80 }
81
82 static void
83 zs_reset(void *dev)
84 {
85
86 /* clear errors */
87 zs_write_reg(dev, 9, 0);
88 /* hardware reset */
89 zs_write_reg(dev, 9, ZSWR9_HARD_RESET);
90 delay(1000);
91
92 /* disable all inerttupts */
93 zs_write_reg(dev, 1, 0);
94
95 /* set TX/RX misc parameters and modes */
96 zs_write_reg(dev, 4, ZSWR4_CLK_X16 | ZSWR4_ONESB | ZSWR4_EVENP);
97 zs_write_reg(dev, 10, ZSWR10_NRZ);
98 zs_write_reg(dev, 3, ZSWR3_RX_8);
99 zs_write_reg(dev, 5, ZSWR5_TX_8 | ZSWR5_DTR | ZSWR5_RTS);
100
101 /* sync registers unused */
102 zs_write_reg(dev, 6, 0);
103 zs_write_reg(dev, 7, 0);
104
105 /* set baud rate generator mode */
106 zs_write_reg(dev, 14, ZSWR14_BAUD_FROM_PCLK);
107 /* set clock mode */
108 zs_write_reg(dev, 11, ZSWR11_RXCLK_BAUD | ZSWR11_TXCLK_BAUD);
109 /* set baud rate constant */
110 zs_write_reg(dev, 12, BPS_TO_TCONST(ZSCLOCK / 16, ZSSPEED));
111 zs_write_reg(dev, 13, 0);
112
113 /* enable baud rate generator */
114 zs_write_reg(dev, 14, ZSWR14_BAUD_FROM_PCLK | ZSWR14_BAUD_ENA);
115 /* disable all external interrupts */
116 zs_write_reg(dev, 15, 0);
117
118 /* reset external status twice (see src/sys/dev/ic/z8530sc.c) */
119 zs_write(dev, ZS_CSR, ZSWR0_RESET_STATUS);
120 zs_write(dev, ZS_CSR, ZSWR0_RESET_STATUS);
121
122 /* enable TX and RX */
123 zs_write_reg(dev, 3, ZSWR3_RX_8 | ZSWR3_RX_ENABLE);
124 zs_write_reg(dev, 5,
125 ZSWR5_TX_8 | ZSWR5_DTR | ZSWR5_RTS | ZSWR5_TX_ENABLE);
126 }
127
128 void *
129 zs_init(int addr, int speed)
130 {
131 void *zs;
132
133 zs = (void *)MIPS_PHYS_TO_KSEG1(ZS_BASE + addr);
134 zs_reset(zs);
135
136 return zs;
137 }
138
139 void
140 zs_putc(void *dev, int c)
141 {
142 uint8_t csr;
143
144 do {
145 csr = zs_read(dev, ZS_CSR);
146 } while ((csr & ZSRR0_TX_READY) == 0);
147
148 zs_write(dev, ZS_DATA, c);
149 }
150
151 int
152 zs_getc(void *dev)
153 {
154 uint8_t csr, data;
155
156 do {
157 csr = zs_read(dev, ZS_CSR);
158 } while ((csr & ZSRR0_RX_READY) == 0);
159
160 data = zs_read(dev, ZS_DATA);
161 return data;
162 }
163
164 int
165 zs_scan(void *dev)
166 {
167 uint8_t csr, data;
168
169 csr = zs_read(dev, ZS_CSR);
170 if ((csr & ZSRR0_RX_READY) == 0)
171 return -1;
172
173 data = zs_read(dev, ZS_DATA);
174 return data;
175 }
176 #endif /* CONS_ZS */
177