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