tx39io.c revision 1.1 1 /* $NetBSD: tx39io.c,v 1.1 1999/11/20 19:56:34 uch Exp $ */
2
3 /*
4 * Copyright (c) 1999, by UCHIYAMA Yasushi
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. The name of the developer may NOT be used to endorse or promote products
13 * derived from this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 */
28 #include "opt_tx39_debug.h"
29 #include "opt_tx39iodebug.h"
30
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/device.h>
34
35 #include <machine/bus.h>
36
37 #include <hpcmips/tx/tx39var.h>
38 #include <hpcmips/tx/tx39ioreg.h>
39 #include <hpcmips/tx/tx39icureg.h>
40
41 #define TX39IO_ATTACH_DUMMYHANDLER 0
42 #undef TX39IO_MFIOOUTPORT_ON
43
44 int tx39io_match __P((struct device*, struct cfdata*, void*));
45 void tx39io_attach __P((struct device*, struct device*, void*));
46
47 struct tx39io_softc {
48 struct device sc_dev;
49 tx_chipset_tag_t sc_tc;
50 };
51
52 struct cfattach tx39io_ca = {
53 sizeof(struct tx39io_softc), tx39io_match, tx39io_attach
54 };
55
56 int tx39io_intr __P((void*));
57 int tx39mfio_intr __P((void*));
58
59 void tx39io_dump_and_attach_handler __P((struct tx39io_softc*, int));
60 void __dump_and_attach_handler __P((tx_chipset_tag_t, u_int32_t, u_int32_t, u_int32_t, u_int32_t, int, int, int (*) __P((void*)), void*));
61
62 #define ISSET(x, s) ((x) & (1 << (s)))
63 #define STD_IN 1
64 #define STD_OUT 2
65 #define STD_INOUT 3
66
67 struct {
68 char *std_pin_name;
69 int std_type;
70 } mfio_map[TX39_IO_MFIO_MAX] = {
71 [31] = {"CHIFS", STD_INOUT},
72 [30] = {"CHICLK", STD_INOUT},
73 [29] = {"CHIDOUT", STD_OUT},
74 [28] = {"CHIDIN", STD_IN},
75 [27] = {"DREQ", STD_IN},
76 [26] = {"DGRINT", STD_OUT},
77 [25] = {"BC32K", STD_OUT},
78 [24] = {"TXD", STD_OUT},
79 [23] = {"RXD", STD_IN},
80 [22] = {"CS1", STD_OUT},
81 [21] = {"CS2", STD_OUT},
82 [20] = {"CS3", STD_OUT},
83 [19] = {"MCS0", STD_OUT},
84 [18] = {"MCS1", STD_OUT},
85 #ifdef TX391X
86 [17] = {"MCS2", STD_OUT},
87 [16] = {"MCS3", STD_OUT},
88 #endif /* TX391X */
89 #ifdef TX392X
90 [17] = {"RXPWR", STD_OUT},
91 [16] = {"IROUT", STD_OUT},
92 #endif /* TX392X */
93 [15] = {"SPICLK", STD_OUT},
94 [14] = {"SPIOUT", STD_OUT},
95 [13] = {"SPIN", STD_IN},
96 [12] = {"SIBMCLK", STD_INOUT},
97 [11] = {"CARDREG", STD_OUT},
98 [10] = {"CARDIOWR", STD_OUT},
99 [9] = {"CARDIORD", STD_OUT},
100 [8] = {"CARD1CSL", STD_OUT},
101 [7] = {"CARD1CSH", STD_OUT},
102 [6] = {"CARD2CSL", STD_OUT},
103 [5] = {"CARD2CSH", STD_OUT},
104 [4] = {"CARD1WAIT", STD_IN},
105 [3] = {"CARD2WAIT", STD_IN},
106 [2] = {"CARDDIR", STD_OUT},
107 #ifdef TX391X
108 [1] = {"MFIO[1]", 0},
109 [0] = {"MFIO[0]", 0}
110 #endif /* TX391X */
111 #ifdef TX392X
112 [1] = {"MCS1WAIT", 0},
113 [0] = {"MCS0WAIT", 0}
114 #endif /* TX392X */
115 };
116
117 int
118 tx39io_match(parent, cf, aux)
119 struct device *parent;
120 struct cfdata *cf;
121 void *aux;
122 {
123
124 return 1;
125 }
126
127 int
128 tx39io_intr(arg)
129 void *arg;
130 {
131 #ifdef TX39_DEBUG
132 static int i;
133 if (i ^= 1) {
134 tx39debugflag = 1;
135 } else {
136 tx39debugflag = 0;
137 }
138 printf("io (%d:%d)\n", (tx39intrvec >> 16) & 0xffff,
139 tx39intrvec & 0xfff);
140 #endif
141 return 0;
142 }
143
144 int
145 tx39mfio_intr(arg)
146 void *arg;
147 {
148 #ifdef TX39_DEBUG
149 #ifdef TX39IODEBUG
150 struct tx39io_softc *sc = arg;
151 tx39io_dump_and_attach_handler(sc, 0);
152 #endif
153 printf("mfio (%d:%d)\n", (tx39intrvec >> 16) & 0xffff,
154 tx39intrvec & 0xfff);
155 #endif
156 return 0;
157 }
158
159 void
160 tx39io_attach(parent, self, aux)
161 struct device *parent;
162 struct device *self;
163 void *aux;
164 {
165 struct txsim_attach_args *ta = aux;
166 struct tx39io_softc *sc = (void*)self;
167 tx_chipset_tag_t tc;
168 tc = sc->sc_tc = ta->ta_tc;
169
170 printf("\n");
171 #ifdef COMPAQ_LOCAL_INTR
172 /* 2010c Rec button */
173 tx_intr_establish(tc, MAKEINTR(5, (1<<6)), IST_EDGE, IPL_CLOCK, tx39io_intr, sc);
174 /* Play button */
175 tx_intr_establish(tc, MAKEINTR(5, (1<<5)), IST_EDGE, IPL_CLOCK, tx39io_intr, sc);
176 /* It seems that these interrupt arise when serial session start */
177 tx_intr_establish(tc, MAKEINTR(3, (1<<30)), IST_EDGE, IPL_CLOCK, tx39mfio_intr, sc);
178 tx_intr_establish(tc, MAKEINTR(3, (1<<5)), IST_EDGE, IPL_CLOCK, tx39mfio_intr, sc);
179 tx_intr_establish(tc, MAKEINTR(4, (1<<30)), IST_EDGE, IPL_CLOCK, tx39mfio_intr, sc);
180 tx_intr_establish(tc, MAKEINTR(4, (1<<5)), IST_EDGE, IPL_CLOCK, tx39mfio_intr, sc);
181 #endif
182
183 #ifdef TX39IODEBUG
184 tx39io_dump_and_attach_handler(sc, TX39IO_ATTACH_DUMMYHANDLER);
185 #endif /* TX39IODEBUG */
186 }
187
188 #ifdef TX39IODEBUG
189 void
190 tx39io_dump_and_attach_handler(sc, dummy)
191 struct tx39io_softc *sc;
192 int dummy;
193 {
194 tx_chipset_tag_t tc;
195 u_int32_t reg, reg_out, reg_dir, reg_in, reg_sel, reg_pwr, reg_deb;
196 int i;
197 int (*iointr) __P((void*));
198 int (*mfiointr) __P((void*));
199
200 tc = sc->sc_tc;
201 if (dummy) {
202 iointr = tx39io_intr;
203 mfiointr = tx39mfio_intr;
204 } else {
205 iointr = mfiointr = 0;
206 }
207
208 printf("--------------------------------------------------------------\n");
209 printf(" Debounce Direction DataOut DataIn PowerDown Select\n");
210 printf("--------------------------------------------------------------\n");
211 /* IO */
212 reg = tx_conf_read(tc, TX39_IOCTRL_REG);
213 reg_deb = TX39_IOCTRL_IODEBSEL(reg);
214 reg_dir = TX39_IOCTRL_IODIREC(reg);
215 #ifdef TX391X
216 reg_out = TX39_IOCTRL_IODOUT(reg);
217 reg_in = TX39_IOCTRL_IODIN(reg);
218 #endif /* TX391X */
219 #ifdef TX392X
220 reg = tx_conf_read(tc, TX39_IODATAINOUT_REG);
221 reg_out = TX39_IODATAINOUT_DOUT(reg);
222 reg_in = TX39_IODATAINOUT_DIN(reg);
223 #endif /* TX392X */
224 reg = tx_conf_read(tc, TX39_IOIOPOWERDWN_REG);
225 reg_pwr = TX39_IOIOPOWERDWN_IOPD(reg);
226 for (i = TX39_IO_IO_MAX - 1; i >= 0 ; i--) {
227 printf("IO %2d: ", i);
228 printf("%s", ISSET(reg_dir, i) ? "On " : "Off");
229 printf(" ");
230 __dump_and_attach_handler(tc, reg_dir, reg_out, reg_in,
231 reg_pwr, i, 1, iointr, sc);
232
233 printf(" -");
234 printf("\n");
235 }
236 /* MFIO */
237 printf("--------------------------------------------------------------\n");
238 reg_out = tx_conf_read(tc, TX39_IOMFIODATAOUT_REG);
239 reg_dir = tx_conf_read(tc, TX39_IOMFIODATADIR_REG);
240 reg_in = tx_conf_read(tc, TX39_IOMFIODATAIN_REG);
241 reg_sel = tx_conf_read(tc, TX39_IOMFIODATASEL_REG);
242 reg_pwr = tx_conf_read(tc, TX39_IOMFIOPOWERDWN_REG);
243 for (i = TX39_IO_MFIO_MAX - 1; i >= 0 ; i--) {
244 printf("MFIO %2d: - ", i);
245 __dump_and_attach_handler(tc, reg_dir, reg_out, reg_in,
246 reg_pwr, i, 0, mfiointr, sc);
247 printf(" ");
248 printf(ISSET(reg_sel, i) ? "MFIO(%s)" : "%s",
249 mfio_map[i].std_pin_name);
250 printf("\n");
251 }
252 printf("--------------------------------------------------------------\n");
253 }
254
255 void
256 __dump_and_attach_handler(tc, reg_dir, reg_out, reg_in, reg_pwr,
257 i, io, func, arg)
258 tx_chipset_tag_t tc;
259 u_int32_t reg_dir, reg_out, reg_in, reg_pwr;
260 int i, io;
261 int (*func) __P((void*));
262 void *arg;
263 {
264 int pset, nset, pofs, nofs;
265
266 if (io) {
267 #ifdef TX391X
268 pset = nset = 5;
269 pofs = i + 7;
270 nofs = i;
271 #endif
272 #ifdef TX392X
273 pset = nset = 8;
274 pofs = i + 16;
275 nofs = i;
276 #endif
277 } else {
278 pset = 3;
279 nset = 4;
280 pofs = nofs = i;
281 }
282
283 if (ISSET(reg_dir, i)) {
284 #ifdef TX39IO_MFIOOUTPORT_ON
285 txreg_t reg;
286 if (io) {
287 #ifdef TX392X
288 reg = tx_conf_read(tc, TX39_IODATAINOUT_REG);
289 reg |= (1 << (i + 16));
290 tx_conf_write(tc, TX39_IODATAINOUT_REG, reg);
291 #endif /* TX392X */
292 } else {
293 reg = tx_conf_read(tc, TX39_IOMFIODATAOUT_REG);
294 reg |= (1 << i);
295 tx_conf_write(tc, TX39_IOMFIODATAOUT_REG, reg);
296 }
297 #endif /* TX39IO_MFIOOUTPORT_ON */
298 printf("Out");
299 } else {
300 printf("In ");
301 if (func) {
302 /* Positive Edge */
303 tx_intr_establish(
304 tc, MAKEINTR(pset, (1 << pofs)),
305 IST_EDGE, IPL_TTY, func, arg);
306 /* Negative Edge */
307 tx_intr_establish(
308 tc, MAKEINTR(nset, (1 << nofs)),
309 IST_EDGE, IPL_TTY, func, arg);
310 }
311 }
312 printf(" ");
313 printf("%d", ISSET(reg_out, i) ? 1 : 0);
314 printf(" ");
315 printf("%d", ISSET(reg_in, i) ? 1 : 0);
316 printf(" ");
317 printf("%s", ISSET(reg_pwr, i) ? "Down ": "Active");
318 };
319
320 #endif /* TX39IODEBUG */
321