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