tx39io.c revision 1.4 1 /* $NetBSD: tx39io.c,v 1.4 2000/01/09 18:56:37 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 #undef TX39IO_MFIOOUTPORT_OFF
44
45 int tx39io_match __P((struct device*, struct cfdata*, void*));
46 void tx39io_attach __P((struct device*, struct device*, void*));
47
48 struct tx39io_softc {
49 struct device sc_dev;
50 tx_chipset_tag_t sc_tc;
51 };
52
53 struct cfattach tx39io_ca = {
54 sizeof(struct tx39io_softc), tx39io_match, tx39io_attach
55 };
56
57 int tx39io_intr __P((void*));
58 int tx39mfio_intr __P((void*));
59
60 void tx39io_dump_and_attach_handler __P((struct tx39io_softc*, int));
61 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*));
62
63 #define ISSET(x, s) ((x) & (1 << (s)))
64 #define STD_IN 1
65 #define STD_OUT 2
66 #define STD_INOUT 3
67
68 const struct {
69 char *std_pin_name;
70 int std_type;
71 } mfio_map[TX39_IO_MFIO_MAX] = {
72 [31] = {"CHIFS", STD_INOUT},
73 [30] = {"CHICLK", STD_INOUT},
74 [29] = {"CHIDOUT", STD_OUT},
75 [28] = {"CHIDIN", STD_IN},
76 [27] = {"DREQ", STD_IN},
77 [26] = {"DGRINT", STD_OUT},
78 [25] = {"BC32K", STD_OUT},
79 [24] = {"TXD", STD_OUT},
80 [23] = {"RXD", STD_IN},
81 [22] = {"CS1", STD_OUT},
82 [21] = {"CS2", STD_OUT},
83 [20] = {"CS3", STD_OUT},
84 [19] = {"MCS0", STD_OUT},
85 [18] = {"MCS1", STD_OUT},
86 #ifdef TX391X
87 [17] = {"MCS2", STD_OUT},
88 [16] = {"MCS3", STD_OUT},
89 #endif /* TX391X */
90 #ifdef TX392X
91 [17] = {"RXPWR", STD_OUT},
92 [16] = {"IROUT", STD_OUT},
93 #endif /* TX392X */
94 [15] = {"SPICLK", STD_OUT},
95 [14] = {"SPIOUT", STD_OUT},
96 [13] = {"SPIN", STD_IN},
97 [12] = {"SIBMCLK", STD_INOUT},
98 [11] = {"CARDREG", STD_OUT},
99 [10] = {"CARDIOWR", STD_OUT},
100 [9] = {"CARDIORD", STD_OUT},
101 [8] = {"CARD1CSL", STD_OUT},
102 [7] = {"CARD1CSH", STD_OUT},
103 [6] = {"CARD2CSL", STD_OUT},
104 [5] = {"CARD2CSH", STD_OUT},
105 [4] = {"CARD1WAIT", STD_IN},
106 [3] = {"CARD2WAIT", STD_IN},
107 [2] = {"CARDDIR", STD_OUT},
108 #ifdef TX391X
109 [1] = {"MFIO[1]", 0},
110 [0] = {"MFIO[0]", 0}
111 #endif /* TX391X */
112 #ifdef TX392X
113 [1] = {"MCS1WAIT", 0},
114 [0] = {"MCS0WAIT", 0}
115 #endif /* TX392X */
116 };
117
118 int
119 tx39io_match(parent, cf, aux)
120 struct device *parent;
121 struct cfdata *cf;
122 void *aux;
123 {
124
125 return 1;
126 }
127
128 int
129 tx39io_intr(arg)
130 void *arg;
131 {
132 #ifdef TX39_DEBUG
133 #if 0
134 static int i;
135 if (i ^= 1) {
136 tx39debugflag = 1;
137 } else {
138 tx39debugflag = 0;
139 }
140 #endif
141 printf("io (%d:%d)\n", (tx39intrvec >> 16) & 0xffff,
142 tx39intrvec & 0xfff);
143 #endif
144 return 0;
145 }
146
147 int
148 tx39mfio_intr(arg)
149 void *arg;
150 {
151 #ifdef TX39_DEBUG
152 #if 0
153 struct tx39io_softc *sc = arg;
154 tx39io_dump_and_attach_handler(sc, 0);
155 #endif
156 printf("mfio (%d:%d)\n", (tx39intrvec >> 16) & 0xffff,
157 tx39intrvec & 0xfff);
158 #endif
159 return 0;
160 }
161
162 void
163 tx39io_attach(parent, self, aux)
164 struct device *parent;
165 struct device *self;
166 void *aux;
167 {
168 struct txsim_attach_args *ta = aux;
169 struct tx39io_softc *sc = (void*)self;
170 tx_chipset_tag_t tc;
171 tc = sc->sc_tc = ta->ta_tc;
172
173 printf("\n");
174 #ifdef COMPAQ_LOCAL_INTR
175 /* 2010c Rec button */
176 tx_intr_establish(tc, MAKEINTR(5, (1<<6)), IST_EDGE, IPL_CLOCK, tx39io_intr, sc);
177 /* Play button */
178 tx_intr_establish(tc, MAKEINTR(5, (1<<5)), IST_EDGE, IPL_CLOCK, tx39io_intr, sc);
179 /* It seems that these interrupt arise when serial session start */
180 tx_intr_establish(tc, MAKEINTR(3, (1<<30)), IST_EDGE, IPL_CLOCK, tx39mfio_intr, sc);
181 tx_intr_establish(tc, MAKEINTR(3, (1<<5)), IST_EDGE, IPL_CLOCK, tx39mfio_intr, sc);
182 tx_intr_establish(tc, MAKEINTR(4, (1<<30)), IST_EDGE, IPL_CLOCK, tx39mfio_intr, sc);
183 tx_intr_establish(tc, MAKEINTR(4, (1<<5)), IST_EDGE, IPL_CLOCK, tx39mfio_intr, sc);
184 #endif
185
186 #ifdef VICTOR_INTERLINK_INTR
187 /* open panel */
188 tx_intr_establish(tc, MAKEINTR(8, (1<<20)), IST_EDGE, IPL_CLOCK, tx39io_intr, sc);
189 /* close panel */
190 tx_intr_establish(tc, MAKEINTR(8, (1<<4)), IST_EDGE, IPL_CLOCK, tx39io_intr, sc);
191 /* serial session */
192 tx_intr_establish(tc, MAKEINTR(4, (1<<29)), IST_EDGE, IPL_CLOCK, tx39mfio_intr, sc);
193 tx_intr_establish(tc, MAKEINTR(4, (1<<30)), IST_EDGE, IPL_CLOCK, tx39mfio_intr, sc);
194 /* REC button */
195 tx_intr_establish(tc, MAKEINTR(8, (1<<7)), IST_EDGE, IPL_CLOCK, tx39io_intr, sc);
196 /* kbd */
197 tx_intr_establish(tc, MAKEINTR(3, (1<<7)), IST_EDGE, IPL_CLOCK, tx39mfio_intr, sc);
198 #endif
199
200 #ifdef TX39IODEBUG
201 tx39io_dump_and_attach_handler(sc, TX39IO_ATTACH_DUMMYHANDLER);
202 #endif /* TX39IODEBUG */
203 }
204
205 #ifdef TX39IODEBUG
206 void
207 tx39io_dump_and_attach_handler(sc, dummy)
208 struct tx39io_softc *sc;
209 int dummy;
210 {
211 tx_chipset_tag_t tc;
212 u_int32_t reg, reg_out, reg_dir, reg_in, reg_sel, reg_pwr, reg_deb;
213 int i;
214 int (*iointr) __P((void*));
215 int (*mfiointr) __P((void*));
216
217 tc = sc->sc_tc;
218 if (dummy) {
219 iointr = tx39io_intr;
220 mfiointr = tx39mfio_intr;
221 } else {
222 iointr = mfiointr = 0;
223 }
224
225 printf("--------------------------------------------------------------\n");
226 printf(" Debounce Direction DataOut DataIn PowerDown Select\n");
227 printf("--------------------------------------------------------------\n");
228 /* IO */
229 reg = tx_conf_read(tc, TX39_IOCTRL_REG);
230 reg_deb = TX39_IOCTRL_IODEBSEL(reg);
231 reg_dir = TX39_IOCTRL_IODIREC(reg);
232 #ifdef TX391X
233 reg_out = TX39_IOCTRL_IODOUT(reg);
234 reg_in = TX39_IOCTRL_IODIN(reg);
235 #endif /* TX391X */
236 #ifdef TX392X
237 reg = tx_conf_read(tc, TX39_IODATAINOUT_REG);
238 reg_out = TX39_IODATAINOUT_DOUT(reg);
239 reg_in = TX39_IODATAINOUT_DIN(reg);
240 #endif /* TX392X */
241 reg = tx_conf_read(tc, TX39_IOIOPOWERDWN_REG);
242 reg_pwr = TX39_IOIOPOWERDWN_IOPD(reg);
243 for (i = TX39_IO_IO_MAX - 1; i >= 0 ; i--) {
244 printf("IO %2d: ", i);
245 printf("%s", ISSET(reg_dir, i) ? "On " : "Off");
246 printf(" ");
247 __dump_and_attach_handler(tc, reg_dir, reg_out, reg_in,
248 reg_pwr, i, 1, iointr, sc);
249
250 printf(" -");
251 printf("\n");
252 }
253 /* MFIO */
254 printf("--------------------------------------------------------------\n");
255 reg_out = tx_conf_read(tc, TX39_IOMFIODATAOUT_REG);
256 reg_dir = tx_conf_read(tc, TX39_IOMFIODATADIR_REG);
257 reg_in = tx_conf_read(tc, TX39_IOMFIODATAIN_REG);
258 reg_sel = tx_conf_read(tc, TX39_IOMFIODATASEL_REG);
259 reg_pwr = tx_conf_read(tc, TX39_IOMFIOPOWERDWN_REG);
260 for (i = TX39_IO_MFIO_MAX - 1; i >= 0 ; i--) {
261 printf("MFIO %2d: - ", i);
262 __dump_and_attach_handler(tc, reg_dir, reg_out, reg_in,
263 reg_pwr, i, 0, mfiointr, sc);
264 printf(" ");
265 printf(ISSET(reg_sel, i) ? "MFIO(%s)" : "%s",
266 mfio_map[i].std_pin_name);
267 printf("\n");
268 }
269 printf("--------------------------------------------------------------\n");
270 }
271
272 void
273 __dump_and_attach_handler(tc, reg_dir, reg_out, reg_in, reg_pwr,
274 i, io, func, arg)
275 tx_chipset_tag_t tc;
276 u_int32_t reg_dir, reg_out, reg_in, reg_pwr;
277 int i, io;
278 int (*func) __P((void*));
279 void *arg;
280 {
281 int pset, nset, pofs, nofs;
282
283 if (io) {
284 #ifdef TX391X
285 pset = nset = 5;
286 pofs = i + 7;
287 nofs = i;
288 #endif
289 #ifdef TX392X
290 pset = nset = 8;
291 pofs = i + 16;
292 nofs = i;
293 #endif
294 } else {
295 pset = 3;
296 nset = 4;
297 pofs = nofs = i;
298 }
299
300 if (ISSET(reg_dir, i)) {
301 #if defined TX39IO_MFIOOUTPORT_ON || defined TX39IO_MFIOOUTPORT_OFF
302 txreg_t reg;
303 #ifdef TX392X
304 if (io) {
305 reg = tx_conf_read(tc, TX39_IODATAINOUT_REG);
306 #ifdef TX39IO_MFIOOUTPORT_ON
307 reg |= (1 << (i + 16));
308 printf("on.");
309 #else
310 reg &= ~(1 << (i + 16));
311 printf("off.");
312 #endif
313 tx_conf_write(tc, TX39_IODATAINOUT_REG, reg);
314 } else
315 #endif /* TX392X */
316 {
317 reg = tx_conf_read(tc, TX39_IOMFIODATAOUT_REG);
318 #ifdef TX39IO_MFIOOUTPORT_ON
319 reg |= (1 << i);
320 printf("on.");
321 #else
322 reg &= ~(1 << i);
323 printf("off.");
324 #endif
325 tx_conf_write(tc, TX39_IOMFIODATAOUT_REG, reg);
326 }
327 #endif /* TX39IO_MFIOOUTPORT_ON */
328 printf("Out");
329 } else {
330 printf("In ");
331 if (func) {
332 /* Positive Edge */
333 tx_intr_establish(
334 tc, MAKEINTR(pset, (1 << pofs)),
335 IST_EDGE, IPL_TTY, func, arg);
336 /* Negative Edge */
337 tx_intr_establish(
338 tc, MAKEINTR(nset, (1 << nofs)),
339 IST_EDGE, IPL_TTY, func, arg);
340 }
341 }
342 printf(" ");
343 printf("%d", ISSET(reg_out, i) ? 1 : 0);
344 printf(" ");
345 printf("%d", ISSET(reg_in, i) ? 1 : 0);
346 printf(" ");
347 printf("%s", ISSET(reg_pwr, i) ? "Down ": "Active");
348 };
349
350 #endif /* TX39IODEBUG */
351