vrc4172gpio.c revision 1.1 1 1.1 takemura /* $NetBSD: vrc4172gpio.c,v 1.1 2001/05/06 14:25:16 takemura Exp $ */
2 1.1 takemura /*-
3 1.1 takemura * Copyright (c) 2001 TAKEMRUA Shin. All rights reserved.
4 1.1 takemura *
5 1.1 takemura * Redistribution and use in source and binary forms, with or without
6 1.1 takemura * modification, are permitted provided that the following conditions
7 1.1 takemura * are met:
8 1.1 takemura * 1. Redistributions of source code must retain the above copyright
9 1.1 takemura * notice, this list of conditions and the following disclaimer.
10 1.1 takemura * 2. Redistributions in binary form must reproduce the above copyright
11 1.1 takemura * notice, this list of conditions and the following disclaimer in the
12 1.1 takemura * documentation and/or other materials provided with the distribution.
13 1.1 takemura * 3. Neither the name of the project nor the names of its contributors
14 1.1 takemura * may be used to endorse or promote products derived from this software
15 1.1 takemura * without specific prior written permission.
16 1.1 takemura *
17 1.1 takemura * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 1.1 takemura * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 1.1 takemura * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 1.1 takemura * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 1.1 takemura * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 1.1 takemura * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 1.1 takemura * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 1.1 takemura * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 1.1 takemura * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 1.1 takemura * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 1.1 takemura * SUCH DAMAGE.
28 1.1 takemura *
29 1.1 takemura */
30 1.1 takemura
31 1.1 takemura #include <sys/param.h>
32 1.1 takemura #include <sys/systm.h>
33 1.1 takemura #include <sys/device.h>
34 1.1 takemura #include <sys/malloc.h>
35 1.1 takemura #include <sys/queue.h>
36 1.1 takemura #include <sys/reboot.h>
37 1.1 takemura #include <machine/bus.h>
38 1.1 takemura #include <machine/platid.h>
39 1.1 takemura #include <machine/platid_mask.h>
40 1.1 takemura
41 1.1 takemura #include <dev/hpc/hpciovar.h>
42 1.1 takemura
43 1.1 takemura #include <hpcmips/vr/vripvar.h>
44 1.1 takemura #include <hpcmips/vr/vrc4172gpioreg.h>
45 1.1 takemura
46 1.1 takemura #include "locators.h"
47 1.1 takemura
48 1.1 takemura #define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
49 1.1 takemura
50 1.1 takemura #define VRC2GPIODEBUG
51 1.1 takemura #ifdef VRC2GPIODEBUG
52 1.1 takemura #define DBG_IO (1<<0)
53 1.1 takemura #define DBG_INTR (1<<1)
54 1.1 takemura #define DBG_INFO (1<<2)
55 1.1 takemura #ifndef VRC2GPIODEBUG_CONF
56 1.1 takemura #define VRC2GPIODEBUG_CONF 0
57 1.1 takemura #endif /* VRC2GPIODEBUG_CONF */
58 1.1 takemura int vrc4172gpio_debug = VRC2GPIODEBUG_CONF;
59 1.1 takemura #define DBG(flag) (vrc4172gpio_debug & (flag))
60 1.1 takemura #define DPRINTF(flag, arg...) do { \
61 1.1 takemura if (DBG(flag)) \
62 1.1 takemura printf(##arg); \
63 1.1 takemura } while (0)
64 1.1 takemura #else
65 1.1 takemura #define DBG(flag) (0)
66 1.1 takemura #define DPRINTF(flag, arg...) do {} while(0)
67 1.1 takemura #endif
68 1.1 takemura #define VPRINTF(arg...) do { \
69 1.1 takemura if (bootverbose) \
70 1.1 takemura printf(##arg); \
71 1.1 takemura } while (0)
72 1.1 takemura
73 1.1 takemura #define CHECK_PORT(x) (0 <= (x) && (x) < VRC2_EXGP_NPORTS)
74 1.1 takemura
75 1.1 takemura struct vrc4172gpio_intr_entry {
76 1.1 takemura int ih_port;
77 1.1 takemura int (*ih_fun)(void*);
78 1.1 takemura void *ih_arg;
79 1.1 takemura TAILQ_ENTRY(vrc4172gpio_intr_entry) ih_link;
80 1.1 takemura };
81 1.1 takemura
82 1.1 takemura struct vrc4172gpio_softc {
83 1.1 takemura struct device sc_dev;
84 1.1 takemura bus_space_tag_t sc_iot;
85 1.1 takemura bus_space_handle_t sc_ioh;
86 1.1 takemura struct hpcio_attach_args sc_args;
87 1.1 takemura struct hpcio_chip *sc_hc;
88 1.1 takemura
89 1.1 takemura void *sc_intr_handle;
90 1.1 takemura u_int32_t sc_intr_mask;
91 1.1 takemura u_int32_t sc_data;
92 1.1 takemura u_int32_t sc_intr_mode[VRC2_EXGP_NPORTS];
93 1.1 takemura TAILQ_HEAD(, vrc4172gpio_intr_entry) sc_intr_head[VRC2_EXGP_NPORTS];
94 1.1 takemura struct hpcio_chip sc_iochip;
95 1.1 takemura struct hpcio_attach_args sc_haa;
96 1.1 takemura };
97 1.1 takemura
98 1.1 takemura int vrc4172gpio_match(struct device*, struct cfdata*, void*);
99 1.1 takemura void vrc4172gpio_attach(struct device*, struct device*, void*);
100 1.1 takemura void vrc4172gpio_callback(struct device *self);
101 1.1 takemura int vrc4172gpio_intr(void*);
102 1.1 takemura int vrc4172gpio_print(void*, const char*);
103 1.1 takemura
104 1.1 takemura int vrc4172gpio_port_read(hpcio_chip_t, int);
105 1.1 takemura void vrc4172gpio_port_write(hpcio_chip_t, int, int);
106 1.1 takemura void *vrc4172gpio_intr_establish(hpcio_chip_t, int, int, int (*)(void *), void*);
107 1.1 takemura void vrc4172gpio_intr_disestablish(hpcio_chip_t, void*);
108 1.1 takemura void vrc4172gpio_intr_clear(hpcio_chip_t, void*);
109 1.1 takemura void vrc4172gpio_register_iochip(hpcio_chip_t, hpcio_chip_t);
110 1.1 takemura void vrc4172gpio_update(hpcio_chip_t);
111 1.1 takemura void vrc4172gpio_dump(hpcio_chip_t);
112 1.1 takemura void vrc4172gpio_intr_dump(struct vrc4172gpio_softc *, int);
113 1.1 takemura hpcio_chip_t vrc4172gpio_getchip(void*, int);
114 1.1 takemura static void vrc4172gpio_diffport(struct vrc4172gpio_softc *sc);
115 1.1 takemura
116 1.1 takemura static u_int16_t read_2(struct vrc4172gpio_softc *, bus_addr_t);
117 1.1 takemura static void write_2(struct vrc4172gpio_softc *, bus_addr_t, u_int16_t);
118 1.1 takemura static u_int32_t read_4(struct vrc4172gpio_softc *, bus_addr_t);
119 1.1 takemura static void write_4(struct vrc4172gpio_softc *, bus_addr_t, u_int32_t);
120 1.1 takemura static void dumpbits(u_int32_t*, int, int, int, const char[2]);
121 1.1 takemura
122 1.1 takemura static struct hpcio_chip vrc4172gpio_iochip = {
123 1.1 takemura .hc_portread = vrc4172gpio_port_read,
124 1.1 takemura .hc_portwrite = vrc4172gpio_port_write,
125 1.1 takemura .hc_intr_establish = vrc4172gpio_intr_establish,
126 1.1 takemura .hc_intr_disestablish = vrc4172gpio_intr_disestablish,
127 1.1 takemura .hc_intr_clear = vrc4172gpio_intr_clear,
128 1.1 takemura .hc_register_iochip = vrc4172gpio_register_iochip,
129 1.1 takemura .hc_update = vrc4172gpio_update,
130 1.1 takemura .hc_dump = vrc4172gpio_dump,
131 1.1 takemura };
132 1.1 takemura
133 1.1 takemura static int intlv_regs[] = {
134 1.1 takemura VRC2_EXGPINTLV0L,
135 1.1 takemura VRC2_EXGPINTLV0H,
136 1.1 takemura VRC2_EXGPINTLV1L
137 1.1 takemura };
138 1.1 takemura
139 1.1 takemura struct cfattach vrc4172gpio_ca = {
140 1.1 takemura sizeof(struct vrc4172gpio_softc), vrc4172gpio_match, vrc4172gpio_attach
141 1.1 takemura };
142 1.1 takemura
143 1.1 takemura /*
144 1.1 takemura * regster access method
145 1.1 takemura */
146 1.1 takemura static inline u_int16_t
147 1.1 takemura read_2(struct vrc4172gpio_softc *sc, bus_addr_t off)
148 1.1 takemura {
149 1.1 takemura return bus_space_read_2(sc->sc_iot, sc->sc_ioh, off);
150 1.1 takemura }
151 1.1 takemura
152 1.1 takemura static inline void
153 1.1 takemura write_2(struct vrc4172gpio_softc *sc, bus_addr_t off, u_int16_t data)
154 1.1 takemura {
155 1.1 takemura bus_space_write_2(sc->sc_iot, sc->sc_ioh, off, data);
156 1.1 takemura }
157 1.1 takemura
158 1.1 takemura static u_int32_t
159 1.1 takemura read_4(struct vrc4172gpio_softc *sc, bus_addr_t off)
160 1.1 takemura {
161 1.1 takemura u_int16_t reg0, reg1;
162 1.1 takemura
163 1.1 takemura reg0 = read_2(sc, off);
164 1.1 takemura reg1 = read_2(sc, off + VRC2_EXGP_OFFSET);
165 1.1 takemura
166 1.1 takemura return (reg0|(reg1<<16));
167 1.1 takemura }
168 1.1 takemura
169 1.1 takemura static void
170 1.1 takemura write_4(struct vrc4172gpio_softc *sc, bus_addr_t off, u_int32_t data)
171 1.1 takemura {
172 1.1 takemura write_2(sc, off, data & 0xffff);
173 1.1 takemura write_2(sc, off + VRC2_EXGP_OFFSET, (data>>16)&0xffff);
174 1.1 takemura }
175 1.1 takemura
176 1.1 takemura int
177 1.1 takemura vrc4172gpio_match(struct device *parent, struct cfdata *cf, void *aux)
178 1.1 takemura {
179 1.1 takemura struct hpcio_attach_args *haa = aux;
180 1.1 takemura platid_mask_t mask;
181 1.1 takemura
182 1.1 takemura if (strcmp(haa->haa_busname, HPCIO_BUSNAME))
183 1.1 takemura return (0);
184 1.1 takemura if (cf->cf_loc[HPCIOIFCF_PLATFORM] == 0)
185 1.1 takemura return (0);
186 1.1 takemura mask = PLATID_DEREF(cf->cf_loc[HPCIOIFCF_PLATFORM]);
187 1.1 takemura
188 1.1 takemura return platid_match(&platid, &mask);
189 1.1 takemura }
190 1.1 takemura
191 1.1 takemura void
192 1.1 takemura vrc4172gpio_attach(struct device *parent, struct device *self, void *aux)
193 1.1 takemura {
194 1.1 takemura struct hpcio_attach_args *args = aux;
195 1.1 takemura struct vrc4172gpio_softc *sc = (void*)self;
196 1.1 takemura int i, *loc, port, mode;
197 1.1 takemura u_int32_t regs[6], t0, t1, t2;
198 1.1 takemura
199 1.1 takemura printf("\n");
200 1.1 takemura loc = sc->sc_dev.dv_cfdata->cf_loc;
201 1.1 takemura
202 1.1 takemura /*
203 1.1 takemura * map bus space
204 1.1 takemura */
205 1.1 takemura sc->sc_iot = args->haa_iot;
206 1.1 takemura sc->sc_hc = (*args->haa_getchip)(args->haa_sc, loc[HPCIOIFCF_IOCHIP]);
207 1.1 takemura sc->sc_args = *args; /* structure copy */
208 1.1 takemura bus_space_map(sc->sc_iot, loc[HPCIOIFCF_ADDR], loc[HPCIOIFCF_SIZE],
209 1.1 takemura 0 /* no cache */, &sc->sc_ioh);
210 1.1 takemura if (sc->sc_ioh == NULL) {
211 1.1 takemura printf("%s: can't map bus space\n", sc->sc_dev.dv_xname);
212 1.1 takemura return;
213 1.1 takemura }
214 1.1 takemura
215 1.1 takemura /*
216 1.1 takemura * dump Windows CE register setting
217 1.1 takemura */
218 1.1 takemura regs[0] = read_4(sc, VRC2_EXGPDATA);
219 1.1 takemura regs[1] = read_4(sc, VRC2_EXGPDIR);
220 1.1 takemura regs[2] = read_4(sc, VRC2_EXGPINTEN);
221 1.1 takemura regs[3] = read_4(sc, VRC2_EXGPINTTYP);
222 1.1 takemura t0 = read_2(sc, VRC2_EXGPINTLV0L);
223 1.1 takemura t1 = read_2(sc, VRC2_EXGPINTLV0H);
224 1.1 takemura t2 = read_2(sc, VRC2_EXGPINTLV1L);
225 1.1 takemura regs[4] = ((t2&0xff00)<<8) | (t1&0xff00) | ((t0&0xff00)>>8);
226 1.1 takemura regs[5] = ((t2&0xff)<<16) | ((t1&0xff)<<8) | (t0&0xff);
227 1.1 takemura
228 1.1 takemura if (bootverbose || DBG(DBG_INFO)) {
229 1.1 takemura /*
230 1.1 takemura * o: output
231 1.1 takemura * i: input (no interrupt)
232 1.1 takemura * H: level sense interrupt (active high)
233 1.1 takemura * L: level sense interrupt (active low)
234 1.1 takemura * B: both edge trigger interrupt
235 1.1 takemura * P: positive edge trigger interrupt
236 1.1 takemura * N: negative edge trigger interrupt
237 1.1 takemura */
238 1.1 takemura printf(" port#:321098765432109876543210\n");
239 1.1 takemura printf(" EXGPDATA :");
240 1.1 takemura dumpbits(®s[0], 1, 23, 0, "10\n");
241 1.1 takemura printf("WIN setting:");
242 1.1 takemura dumpbits(®s[1], 5, 23, 0,
243 1.1 takemura "oooo" /* dir=1 en=1 typ=1 */
244 1.1 takemura "oooo" /* dir=1 en=1 typ=0 */
245 1.1 takemura "oooo" /* dir=1 en=0 typ=1 */
246 1.1 takemura "oooo" /* dir=1 en=0 typ=0 */
247 1.1 takemura "BBPN" /* dir=0 en=1 typ=1 */
248 1.1 takemura "HLHL" /* dir=0 en=1 typ=0 */
249 1.1 takemura "iiii" /* dir=0 en=0 typ=1 */
250 1.1 takemura "iiii" /* dir=0 en=0 typ=0 */
251 1.1 takemura );
252 1.1 takemura printf("\n");
253 1.1 takemura }
254 1.1 takemura #ifdef VRC2GPIODEBUG
255 1.1 takemura if (DBG(DBG_INFO)) {
256 1.1 takemura printf(" EXGPDIR :");
257 1.1 takemura dumpbits(®s[1], 1, 23, 0, "oi\n");
258 1.1 takemura
259 1.1 takemura printf(" EXGPINTEN :");
260 1.1 takemura dumpbits(®s[2], 1, 23, 0, "I-\n");
261 1.1 takemura
262 1.1 takemura printf(" EXGPINTTYP:");
263 1.1 takemura dumpbits(®s[3], 1, 23, 0, "EL\n");
264 1.1 takemura
265 1.1 takemura printf(" EXPIB :");
266 1.1 takemura dumpbits(®s[4], 1, 23, 0, "10\n");
267 1.1 takemura
268 1.1 takemura printf(" EXPIL :");
269 1.1 takemura dumpbits(®s[5], 1, 23, 0, "10\n");
270 1.1 takemura
271 1.1 takemura printf(" EXGPINTLV :%04x %04x %04x\n", t2, t1, t0);
272 1.1 takemura }
273 1.1 takemura #endif /* VRC2GPIODEBUG */
274 1.1 takemura
275 1.1 takemura /*
276 1.1 takemura * initialize register and internal data
277 1.1 takemura */
278 1.1 takemura sc->sc_intr_mask = 0;
279 1.1 takemura write_2(sc, VRC2_EXGPINTEN, sc->sc_intr_mask);
280 1.1 takemura for (i = 0; i < VRC2_EXGP_NPORTS; i++)
281 1.1 takemura TAILQ_INIT(&sc->sc_intr_head[i]);
282 1.1 takemura sc->sc_data = read_4(sc, VRC2_EXGPDATA);
283 1.1 takemura if (bootverbose || DBG(DBG_INFO)) {
284 1.1 takemura u_int32_t data;
285 1.1 takemura
286 1.1 takemura sc->sc_intr_mask = (~read_4(sc, VRC2_EXGPDIR) & 0xffffff);
287 1.1 takemura write_4(sc, VRC2_EXGPINTTYP, 0); /* level sence interrupt */
288 1.1 takemura data = ~read_4(sc, VRC2_EXGPDATA);
289 1.1 takemura write_2(sc, VRC2_EXGPINTLV0L, (data >> 0) & 0xff);
290 1.1 takemura write_2(sc, VRC2_EXGPINTLV0H, (data >> 8) & 0xff);
291 1.1 takemura write_2(sc, VRC2_EXGPINTLV1L, (data >> 16) & 0xff);
292 1.1 takemura }
293 1.1 takemura
294 1.1 takemura /*
295 1.1 takemura * install interrupt handler
296 1.1 takemura */
297 1.1 takemura port = loc[HPCIOIFCF_PORT];
298 1.1 takemura mode = HPCIO_INTR_LEVEL | HPCIO_INTR_HIGH;
299 1.1 takemura sc->sc_intr_handle =
300 1.1 takemura hpcio_intr_establish(sc->sc_hc, port, mode, vrc4172gpio_intr, sc);
301 1.1 takemura if (sc->sc_intr_handle == NULL) {
302 1.1 takemura printf("%s: can't establish interrupt\n", sc->sc_dev.dv_xname);
303 1.1 takemura return;
304 1.1 takemura }
305 1.1 takemura
306 1.1 takemura /*
307 1.1 takemura * fill hpcio_chip structure
308 1.1 takemura */
309 1.1 takemura sc->sc_iochip = vrc4172gpio_iochip; /* structure copy */
310 1.1 takemura sc->sc_iochip.hc_chipid = VRIP_IOCHIP_VRC4172GPIO;
311 1.1 takemura sc->sc_iochip.hc_name = sc->sc_dev.dv_xname;
312 1.1 takemura sc->sc_iochip.hc_sc = sc;
313 1.1 takemura /* Register functions to upper interface */
314 1.1 takemura hpcio_register_iochip(sc->sc_hc, &sc->sc_iochip);
315 1.1 takemura
316 1.1 takemura /*
317 1.1 takemura * hpcio I/F
318 1.1 takemura */
319 1.1 takemura sc->sc_haa.haa_busname = HPCIO_BUSNAME;
320 1.1 takemura sc->sc_haa.haa_sc = sc;
321 1.1 takemura sc->sc_haa.haa_getchip = vrc4172gpio_getchip;
322 1.1 takemura sc->sc_haa.haa_iot = sc->sc_iot;
323 1.1 takemura while (config_found(self, &sc->sc_haa, vrc4172gpio_print)) ;
324 1.1 takemura /*
325 1.1 takemura * GIU-ISA bridge
326 1.1 takemura */
327 1.1 takemura #if 1 /* XXX Sometimes mounting root device failed. Why? XXX*/
328 1.1 takemura config_defer(self, vrc4172gpio_callback);
329 1.1 takemura #else
330 1.1 takemura vrc4172gpio_callback(self);
331 1.1 takemura #endif
332 1.1 takemura }
333 1.1 takemura
334 1.1 takemura void
335 1.1 takemura vrc4172gpio_callback(struct device *self)
336 1.1 takemura {
337 1.1 takemura struct vrc4172gpio_softc *sc = (void*)self;
338 1.1 takemura
339 1.1 takemura sc->sc_haa.haa_busname = "vrisab";
340 1.1 takemura config_found(self, &sc->sc_haa, vrc4172gpio_print);
341 1.1 takemura }
342 1.1 takemura
343 1.1 takemura int
344 1.1 takemura vrc4172gpio_print(void *aux, const char *pnp)
345 1.1 takemura {
346 1.1 takemura if (pnp)
347 1.1 takemura return (QUIET);
348 1.1 takemura return (UNCONF);
349 1.1 takemura }
350 1.1 takemura
351 1.1 takemura /*
352 1.1 takemura * PORT
353 1.1 takemura */
354 1.1 takemura int
355 1.1 takemura vrc4172gpio_port_read(hpcio_chip_t hc, int port)
356 1.1 takemura {
357 1.1 takemura struct vrc4172gpio_softc *sc = hc->hc_sc;
358 1.1 takemura int on;
359 1.1 takemura
360 1.1 takemura if (!CHECK_PORT(port))
361 1.1 takemura panic("%s: illegal gpio port", __FUNCTION__);
362 1.1 takemura
363 1.1 takemura on = (read_4(sc, VRC2_EXGPDATA) & (1 << port));
364 1.1 takemura
365 1.1 takemura return (on ? 1 : 0);
366 1.1 takemura }
367 1.1 takemura
368 1.1 takemura void
369 1.1 takemura vrc4172gpio_port_write(hpcio_chip_t hc, int port, int onoff)
370 1.1 takemura {
371 1.1 takemura struct vrc4172gpio_softc *sc = hc->hc_sc;
372 1.1 takemura u_int32_t data;
373 1.1 takemura
374 1.1 takemura if (!CHECK_PORT(port))
375 1.1 takemura panic("%s: illegal gpio port", __FUNCTION__);
376 1.1 takemura data = read_4(sc, VRC2_EXGPDATA);
377 1.1 takemura if (onoff)
378 1.1 takemura data |= (1<<port);
379 1.1 takemura else
380 1.1 takemura data &= ~(1<<port);
381 1.1 takemura write_4(sc, VRC2_EXGPDATA, data);
382 1.1 takemura }
383 1.1 takemura
384 1.1 takemura void
385 1.1 takemura vrc4172gpio_update(hpcio_chip_t hc)
386 1.1 takemura {
387 1.1 takemura }
388 1.1 takemura
389 1.1 takemura void
390 1.1 takemura vrc4172gpio_intr_dump(struct vrc4172gpio_softc *sc, int port)
391 1.1 takemura {
392 1.1 takemura u_int32_t mask, mask2;
393 1.1 takemura int intlv_reg;
394 1.1 takemura
395 1.1 takemura mask = (1 << port);
396 1.1 takemura mask2 = (1 << (port % 8));
397 1.1 takemura intlv_reg = intlv_regs[port/8];
398 1.1 takemura
399 1.1 takemura if (read_4(sc, VRC2_EXGPDIR) & mask) {
400 1.1 takemura printf(" output");
401 1.1 takemura return;
402 1.1 takemura }
403 1.1 takemura printf(" input");
404 1.1 takemura
405 1.1 takemura if (read_4(sc, VRC2_EXGPINTTYP) & mask) {
406 1.1 takemura if (read_4(sc, intlv_reg) & (mask2 << 8)) {
407 1.1 takemura printf(", both edge");
408 1.1 takemura } else {
409 1.1 takemura if (read_4(sc, intlv_reg) & mask2)
410 1.1 takemura printf(", positive edge");
411 1.1 takemura else
412 1.1 takemura printf(", negative edge");
413 1.1 takemura }
414 1.1 takemura } else {
415 1.1 takemura if (read_4(sc, intlv_reg) & mask2)
416 1.1 takemura printf(", high level");
417 1.1 takemura else
418 1.1 takemura printf(", low level");
419 1.1 takemura }
420 1.1 takemura }
421 1.1 takemura
422 1.1 takemura static void
423 1.1 takemura vrc4172gpio_diffport(struct vrc4172gpio_softc *sc)
424 1.1 takemura {
425 1.1 takemura u_int32_t data;
426 1.1 takemura data = read_4(sc, VRC2_EXGPDATA);
427 1.1 takemura if (sc->sc_data != data) {
428 1.1 takemura printf(" port# 321098765432109876543210\n");
429 1.1 takemura printf("vrc4172data:");
430 1.1 takemura dumpbits(&data, 1, 23, 0, "10\n");
431 1.1 takemura /* bits which changed */
432 1.1 takemura data = (data & ~sc->sc_data)|(~data & sc->sc_data);
433 1.1 takemura printf(" ");
434 1.1 takemura dumpbits(&data, 1, 23, 0, "^ \n");
435 1.1 takemura sc->sc_data = data;
436 1.1 takemura }
437 1.1 takemura }
438 1.1 takemura
439 1.1 takemura static void
440 1.1 takemura dumpbits(u_int32_t *data, int ndata, int start, int end, const char *sym)
441 1.1 takemura {
442 1.1 takemura int i, j;
443 1.1 takemura
444 1.1 takemura if (start <= end)
445 1.1 takemura panic("%s(%d): %s", __FILE__, __LINE__, __FUNCTION__);
446 1.1 takemura
447 1.1 takemura for (i = start; end <= i; i--) {
448 1.1 takemura int d = 0;
449 1.1 takemura for (j = 0; j < ndata; j++)
450 1.1 takemura d = (d << 1) | ((data[j] & (1 << i)) ? 1 : 0);
451 1.1 takemura printf("%c", sym[(1 << ndata) - d - 1]);
452 1.1 takemura
453 1.1 takemura }
454 1.1 takemura if (sym[1<<ndata])
455 1.1 takemura printf("%c", sym[1<<ndata]);
456 1.1 takemura }
457 1.1 takemura
458 1.1 takemura void
459 1.1 takemura vrc4172gpio_dump(hpcio_chip_t hc)
460 1.1 takemura {
461 1.1 takemura }
462 1.1 takemura
463 1.1 takemura hpcio_chip_t
464 1.1 takemura vrc4172gpio_getchip(void* scx, int chipid)
465 1.1 takemura {
466 1.1 takemura struct vrc4172gpio_softc *sc = scx;
467 1.1 takemura
468 1.1 takemura return (&sc->sc_iochip);
469 1.1 takemura }
470 1.1 takemura
471 1.1 takemura /*
472 1.1 takemura * Interrupt staff
473 1.1 takemura */
474 1.1 takemura void *
475 1.1 takemura vrc4172gpio_intr_establish(
476 1.1 takemura hpcio_chip_t hc,
477 1.1 takemura int port, /* GPIO pin # */
478 1.1 takemura int mode, /* GIU trigger setting */
479 1.1 takemura int (*ih_fun)(void*),
480 1.1 takemura void *ih_arg)
481 1.1 takemura {
482 1.1 takemura struct vrc4172gpio_softc *sc = hc->hc_sc;
483 1.1 takemura int s;
484 1.1 takemura u_int32_t reg, mask, mask2;
485 1.1 takemura struct vrc4172gpio_intr_entry *ih;
486 1.1 takemura int intlv_reg;
487 1.1 takemura
488 1.1 takemura s = splhigh();
489 1.1 takemura
490 1.1 takemura if (!CHECK_PORT(port))
491 1.1 takemura panic (__FUNCTION__": bogus interrupt line");
492 1.1 takemura if (sc->sc_intr_mode[port] && mode != sc->sc_intr_mode[port])
493 1.1 takemura panic (__FUNCTION__": bogus interrupt type");
494 1.1 takemura else
495 1.1 takemura sc->sc_intr_mode[port] = mode;
496 1.1 takemura
497 1.1 takemura mask = (1 << port);
498 1.1 takemura mask2 = (1 << (port % 8));
499 1.1 takemura intlv_reg = intlv_regs[port/8];
500 1.1 takemura
501 1.1 takemura ih = malloc(sizeof(struct vrc4172gpio_intr_entry), M_DEVBUF, M_NOWAIT);
502 1.1 takemura if (ih == NULL)
503 1.1 takemura panic(__FUNCTION__": no memory");
504 1.1 takemura
505 1.1 takemura ih->ih_port = port;
506 1.1 takemura ih->ih_fun = ih_fun;
507 1.1 takemura ih->ih_arg = ih_arg;
508 1.1 takemura TAILQ_INSERT_TAIL(&sc->sc_intr_head[port], ih, ih_link);
509 1.1 takemura
510 1.1 takemura #ifdef VRC2GPIODEBUG
511 1.1 takemura if (DBG(DBG_INFO)) {
512 1.1 takemura printf("port %2d:", port);
513 1.1 takemura vrc4172gpio_intr_dump(sc, port);
514 1.1 takemura printf("->");
515 1.1 takemura }
516 1.1 takemura #endif
517 1.1 takemura
518 1.1 takemura /*
519 1.1 takemura * Setup registers
520 1.1 takemura */
521 1.1 takemura /* I/O direction */
522 1.1 takemura reg = read_4(sc, VRC2_EXGPDIR);
523 1.1 takemura reg &= ~mask;
524 1.1 takemura write_4(sc, VRC2_EXGPDIR, reg);
525 1.1 takemura
526 1.1 takemura /* interrupt triger (level/edge) */
527 1.1 takemura reg = read_4(sc, VRC2_EXGPINTTYP);
528 1.1 takemura if (mode & HPCIO_INTR_EDGE)
529 1.1 takemura reg |= mask; /* edge */
530 1.1 takemura else
531 1.1 takemura reg &= ~mask; /* level */
532 1.1 takemura write_4(sc, VRC2_EXGPINTTYP, reg);
533 1.1 takemura
534 1.1 takemura /* interrupt trigger option */
535 1.1 takemura reg = read_4(sc, intlv_reg);
536 1.1 takemura if (mode & HPCIO_INTR_EDGE) {
537 1.1 takemura switch (mode & (HPCIO_INTR_POSEDGE | HPCIO_INTR_NEGEDGE)) {
538 1.1 takemura case HPCIO_INTR_POSEDGE:
539 1.1 takemura reg &= ~(mask2 << 8);
540 1.1 takemura reg |= mask2;
541 1.1 takemura break;
542 1.1 takemura case HPCIO_INTR_NEGEDGE:
543 1.1 takemura reg &= ~(mask2 << 8);
544 1.1 takemura reg &= ~mask2;
545 1.1 takemura break;
546 1.1 takemura case HPCIO_INTR_POSEDGE | HPCIO_INTR_NEGEDGE:
547 1.1 takemura default:
548 1.1 takemura reg |= (mask2 << 8);
549 1.1 takemura break;
550 1.1 takemura }
551 1.1 takemura } else {
552 1.1 takemura if (mode & HPCIO_INTR_HIGH)
553 1.1 takemura reg |= mask2; /* high */
554 1.1 takemura else
555 1.1 takemura reg &= ~mask2; /* low */
556 1.1 takemura }
557 1.1 takemura write_4(sc, intlv_reg, reg);
558 1.1 takemura
559 1.1 takemura #ifdef VRC2GPIODEBUG
560 1.1 takemura if (DBG(DBG_INFO)) {
561 1.1 takemura vrc4172gpio_intr_dump(sc, port);
562 1.1 takemura printf("\n");
563 1.1 takemura }
564 1.1 takemura #endif
565 1.1 takemura
566 1.1 takemura /* XXX, Vrc4172 doesn't have register to set hold or through */
567 1.1 takemura
568 1.1 takemura /*
569 1.1 takemura * clear interrupt status and enable interrupt
570 1.1 takemura */
571 1.1 takemura vrc4172gpio_intr_clear(&sc->sc_iochip, ih);
572 1.1 takemura sc->sc_intr_mask |= mask;
573 1.1 takemura write_4(sc, VRC2_EXGPINTEN, sc->sc_intr_mask);
574 1.1 takemura
575 1.1 takemura splx(s);
576 1.1 takemura
577 1.1 takemura DPRINTF(DBG_INFO, "\n");
578 1.1 takemura
579 1.1 takemura return (ih);
580 1.1 takemura }
581 1.1 takemura
582 1.1 takemura void
583 1.1 takemura vrc4172gpio_intr_disestablish(hpcio_chip_t hc, void *arg)
584 1.1 takemura {
585 1.1 takemura struct vrc4172gpio_intr_entry *ihe = arg;
586 1.1 takemura struct vrc4172gpio_softc *sc = hc->hc_sc;
587 1.1 takemura int port = ihe->ih_port;
588 1.1 takemura struct vrc4172gpio_intr_entry *ih;
589 1.1 takemura int s;
590 1.1 takemura
591 1.1 takemura s = splhigh();
592 1.1 takemura TAILQ_FOREACH(ih, &sc->sc_intr_head[port], ih_link) {
593 1.1 takemura if (ih == ihe) {
594 1.1 takemura TAILQ_REMOVE(&sc->sc_intr_head[port], ih, ih_link);
595 1.1 takemura free(ih, M_DEVBUF);
596 1.1 takemura if (TAILQ_EMPTY(&sc->sc_intr_head[port])) {
597 1.1 takemura /* disable interrupt */
598 1.1 takemura sc->sc_intr_mask &= ~(1<<port);
599 1.1 takemura write_4(sc, VRC2_EXGPINTEN,
600 1.1 takemura sc->sc_intr_mask);
601 1.1 takemura }
602 1.1 takemura splx(s);
603 1.1 takemura return;
604 1.1 takemura }
605 1.1 takemura }
606 1.1 takemura panic(__FUNCTION__": no such a handle.");
607 1.1 takemura /* NOTREACHED */
608 1.1 takemura }
609 1.1 takemura
610 1.1 takemura /* Clear interrupt */
611 1.1 takemura void
612 1.1 takemura vrc4172gpio_intr_clear(hpcio_chip_t hc, void *arg)
613 1.1 takemura {
614 1.1 takemura struct vrc4172gpio_softc *sc = hc->hc_sc;
615 1.1 takemura struct vrc4172gpio_intr_entry *ihe = arg;
616 1.1 takemura
617 1.1 takemura write_4(sc, VRC2_EXGPINTST, 1 << ihe->ih_port);
618 1.1 takemura write_4(sc, VRC2_EXGPINTST, 0);
619 1.1 takemura }
620 1.1 takemura
621 1.1 takemura void
622 1.1 takemura vrc4172gpio_register_iochip(hpcio_chip_t hc, hpcio_chip_t iochip)
623 1.1 takemura {
624 1.1 takemura struct vrc4172gpio_softc *sc = hc->hc_sc;
625 1.1 takemura
626 1.1 takemura hpcio_register_iochip(sc->sc_hc, iochip);
627 1.1 takemura }
628 1.1 takemura
629 1.1 takemura /* interrupt handler */
630 1.1 takemura int
631 1.1 takemura vrc4172gpio_intr(void *arg)
632 1.1 takemura {
633 1.1 takemura struct vrc4172gpio_softc *sc = arg;
634 1.1 takemura int i;
635 1.1 takemura u_int32_t reg;
636 1.1 takemura
637 1.1 takemura /* dispatch handler */
638 1.1 takemura reg = read_4(sc, VRC2_EXGPINTST);
639 1.1 takemura DPRINTF(DBG_INTR, "%s: EXGPINTST=%06x\n", __FUNCTION__, reg);
640 1.1 takemura for (i = 0; i < VRC2_EXGP_NPORTS; i++) {
641 1.1 takemura if (reg & (1 << i)) {
642 1.1 takemura register struct vrc4172gpio_intr_entry *ih;
643 1.1 takemura
644 1.1 takemura /*
645 1.1 takemura * call interrupt handler
646 1.1 takemura */
647 1.1 takemura TAILQ_FOREACH(ih, &sc->sc_intr_head[i], ih_link) {
648 1.1 takemura ih->ih_fun(ih->ih_arg);
649 1.1 takemura }
650 1.1 takemura
651 1.1 takemura /*
652 1.1 takemura * disable interrupt if no handler is installed
653 1.1 takemura */
654 1.1 takemura if (TAILQ_EMPTY(&sc->sc_intr_head[i])) {
655 1.1 takemura sc->sc_intr_mask &= ~(1 << i);
656 1.1 takemura write_2(sc, VRC2_EXGPINTEN, sc->sc_intr_mask);
657 1.1 takemura
658 1.1 takemura /* dump EXGPDATA bits which changed */
659 1.1 takemura if (bootverbose || DBG(DBG_INFO))
660 1.1 takemura vrc4172gpio_diffport(sc);
661 1.1 takemura }
662 1.1 takemura }
663 1.1 takemura }
664 1.1 takemura
665 1.1 takemura return (0);
666 1.1 takemura }
667