xref: /netbsd-src/sys/arch/hpcmips/dev/it8368.c (revision 4472dbe5e3bd91ef2540bada7a7ca7384627ff9b)
1 /*	$NetBSD: it8368.c,v 1.8 2000/03/12 15:35:29 uch Exp $ */
2 
3 /*
4  * Copyright (c) 1999, 2000, 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 #undef WINCE_DEFAULT_SETTING /* for debug */
29 #undef IT8368DEBUG
30 #include "opt_tx39_debug.h"
31 
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/device.h>
35 
36 #include <machine/bus.h>
37 
38 #include <dev/pcmcia/pcmciareg.h>
39 #include <dev/pcmcia/pcmciavar.h>
40 #include <dev/pcmcia/pcmciachip.h>
41 
42 #include <hpcmips/tx/tx39var.h>
43 #include <hpcmips/tx/txcsbusvar.h>
44 #include <hpcmips/tx/tx39biureg.h> /* legacy mode requires BIU access */
45 #include <hpcmips/dev/it8368var.h>
46 #include <hpcmips/dev/it8368reg.h>
47 
48 #ifdef IT8368DEBUG
49 int	it8368debug = 1;
50 #define	DPRINTF(arg) if (it8368debug) printf arg;
51 #define	DPRINTFN(n, arg) if (it8368debug > (n)) printf arg;
52 #else
53 #define	DPRINTF(arg)
54 #define DPRINTFN(n, arg)
55 #endif
56 
57 int	it8368e_match __P((struct device*, struct cfdata*, void*));
58 void	it8368e_attach __P((struct device*, struct device*, void*));
59 int	it8368_print __P((void*, const char*));
60 int	it8368_submatch __P((struct device*, struct cfdata*, void*));
61 
62 #define IT8368_LASTSTATE_PRESENT	0x0002
63 #define IT8368_LASTSTATE_HALF		0x0001
64 #define IT8368_LASTSTATE_EMPTY		0x0000
65 
66 struct it8368e_softc {
67 	struct device	sc_dev;
68 	struct device	*sc_pcmcia;
69 	tx_chipset_tag_t sc_tc;
70 
71 	/* Register space */
72 	bus_space_tag_t		sc_csregt;
73 	bus_space_handle_t	sc_csregh;
74 	/* I/O, attribute space */
75 	bus_space_tag_t		sc_csiot;
76 	bus_addr_t		sc_csiobase;
77 	bus_size_t		sc_csiosize;
78 	/*
79 	 *  XXX theses means attribute memory. not memory space.
80 	 *	memory space is 0x64000000.
81 	 */
82 	bus_space_tag_t		sc_csmemt;
83 	bus_addr_t		sc_csmembase;
84 	bus_size_t		sc_csmemsize;
85 
86 	/* Separate I/O and attribute space mode */
87 	int sc_fixattr;
88 
89 	/* Card interrupt handler */
90 	int	(*sc_card_fun) __P((void*));
91 	void	*sc_card_arg;
92 	void	*sc_card_ih;
93 	int	sc_card_irq;
94 
95 	/* Card status change */
96 	int	sc_irq;
97 	void	*sc_ih;
98 	int	sc_laststate;
99 };
100 
101 void	it8368_init_socket __P((struct it8368e_softc*));
102 void	it8368_attach_socket __P((struct it8368e_softc*));
103 int	it8368_intr __P((void*));
104 int	it8368_chip_mem_alloc __P((pcmcia_chipset_handle_t, bus_size_t,
105 				   struct pcmcia_mem_handle*));
106 void	it8368_chip_mem_free __P((pcmcia_chipset_handle_t,
107 				  struct pcmcia_mem_handle*));
108 int	it8368_chip_mem_map __P((pcmcia_chipset_handle_t, int, bus_addr_t,
109 				 bus_size_t, struct pcmcia_mem_handle*,
110 				 bus_addr_t*, int*));
111 void	it8368_chip_mem_unmap __P((pcmcia_chipset_handle_t, int));
112 int	it8368_chip_io_alloc __P((pcmcia_chipset_handle_t, bus_addr_t,
113 				  bus_size_t, bus_size_t,
114 				  struct pcmcia_io_handle*));
115 void	it8368_chip_io_free __P((pcmcia_chipset_handle_t,
116 				 struct pcmcia_io_handle*));
117 int	it8368_chip_io_map __P((pcmcia_chipset_handle_t, int, bus_addr_t,
118 				bus_size_t, struct pcmcia_io_handle*,
119 				int*));
120 void	it8368_chip_io_unmap __P((pcmcia_chipset_handle_t, int));
121 void	it8368_chip_socket_enable __P((pcmcia_chipset_handle_t));
122 void	it8368_chip_socket_disable __P((pcmcia_chipset_handle_t));
123 void	*it8368_chip_intr_establish __P((pcmcia_chipset_handle_t,
124 					 struct pcmcia_function*, int,
125 					 int (*) (void*), void*));
126 void	it8368_chip_intr_disestablish __P((pcmcia_chipset_handle_t, void*));
127 
128 #ifdef IT8368DEBUG
129 void	it8368_dump __P((struct it8368e_softc*));
130 #endif
131 
132 static struct pcmcia_chip_functions it8368_functions = {
133 	it8368_chip_mem_alloc,
134 	it8368_chip_mem_free,
135 	it8368_chip_mem_map,
136 	it8368_chip_mem_unmap,
137 	it8368_chip_io_alloc,
138 	it8368_chip_io_free,
139 	it8368_chip_io_map,
140 	it8368_chip_io_unmap,
141 	it8368_chip_intr_establish,
142 	it8368_chip_intr_disestablish,
143 	it8368_chip_socket_enable,
144 	it8368_chip_socket_disable
145 };
146 
147 struct cfattach it8368e_ca = {
148 	sizeof(struct it8368e_softc), it8368e_match, it8368e_attach
149 };
150 
151 /*
152  *	IT8368 configuration register is big-endian.
153  */
154 __inline__ u_int16_t	it8368_reg_read __P((bus_space_tag_t,
155 					     bus_space_handle_t, int));
156 __inline__ void		it8368_reg_write __P((bus_space_tag_t,
157 					      bus_space_handle_t, int,
158 					      u_int16_t));
159 
160 #ifdef IT8368E_DESTRUCTIVE_CHECK
161 int	it8368e_id_check __P((void *));
162 
163 /*
164  *	IT8368E don't have identification method. this is destructive check.
165  */
166 int
167 it8368e_id_check(aux)
168 	void *aux;
169 {
170 	struct cs_attach_args *ca = aux;
171 	tx_chipset_tag_t tc;
172 	bus_space_tag_t csregt;
173 	bus_space_handle_t csregh;
174 	u_int16_t oreg, reg;
175 	int match = 0;
176 
177 	tc = ca->ca_tc;
178 	csregt = ca->ca_csreg.cstag;
179 
180 	bus_space_map(csregt, ca->ca_csreg.csbase, ca->ca_csreg.cssize,
181 		      0, &csregh);
182 	reg = it8368_reg_read(csregt, csregh, IT8368_CTRL_REG);
183 	oreg = reg;
184 	bitdisp(reg);
185 
186 	reg &= ~IT8368_CTRL_BYTESWAP;
187 	it8368_reg_write(csregt, csregh, IT8368_CTRL_REG, reg);
188 	reg = it8368_reg_read(csregt, csregh, IT8368_CTRL_REG);
189 	if (reg & IT8368_CTRL_BYTESWAP)
190 		goto nomatch;
191 
192 	reg |= IT8368_CTRL_BYTESWAP;
193 	it8368_reg_write(csregt, csregh, IT8368_CTRL_REG, reg);
194 	reg = it8368_reg_read(csregt, csregh, IT8368_CTRL_REG);
195 	if (!(reg & IT8368_CTRL_BYTESWAP))
196 		goto nomatch;
197 
198 	match = 1;
199  nomatch:
200 	it8368_reg_write(csregt, csregh, IT8368_CTRL_REG, oreg);
201 	bus_space_unmap(csregt, csregh, ca->ca_csreg.cssize);
202 
203 	return (match);
204 }
205 #endif /* IT8368E_DESTRUCTIVE_CHECK */
206 
207 int
208 it8368e_match(parent, cf, aux)
209 	struct device *parent;
210 	struct cfdata *cf;
211 	void *aux;
212 {
213 #ifdef IT8368E_DESTRUCTIVE_CHECK
214 	return (it8368e_id_check(aux));
215 #else
216 	return (1);
217 #endif
218 }
219 
220 void
221 it8368e_attach(parent, self, aux)
222 	struct device *parent;
223 	struct device *self;
224 	void *aux;
225 {
226 	struct cs_attach_args *ca = aux;
227 	struct it8368e_softc *sc = (void*)self;
228 	tx_chipset_tag_t tc;
229 	bus_space_tag_t csregt;
230 	bus_space_handle_t csregh;
231 	u_int16_t reg;
232 
233 	sc->sc_tc = tc = ca->ca_tc;
234 	sc->sc_csregt = csregt = ca->ca_csreg.cstag;
235 
236 	bus_space_map(csregt, ca->ca_csreg.csbase, ca->ca_csreg.cssize,
237 		      0, &sc->sc_csregh);
238 	csregh = sc->sc_csregh;
239 	sc->sc_csiot = ca->ca_csio.cstag;
240 	sc->sc_csiobase = ca->ca_csio.csbase;
241 	sc->sc_csiosize = ca->ca_csio.cssize;
242 
243 #ifdef IT8368DEBUG
244 	printf("\n\t[Windows CE setting]\n");
245 	it8368_dump(sc); /* print WindowsCE setting */
246 #endif
247 	/* LHA[14:13] <= HA[14:13]	*/
248 	reg = it8368_reg_read(csregt, csregh, IT8368_CTRL_REG);
249 	reg &= ~IT8368_CTRL_ADDRSEL;
250 	it8368_reg_write(csregt, csregh, IT8368_CTRL_REG, reg);
251 
252 	/* Set all MFIO direction as LHA[23:13] output pins */
253 	reg = it8368_reg_read(csregt, csregh, IT8368_MFIODIR_REG);
254 	reg |= IT8368_MFIODIR_MASK;
255 	it8368_reg_write(csregt, csregh, IT8368_MFIODIR_REG, reg);
256 
257 	/* Set all MFIO functions as LHA */
258 	reg = it8368_reg_read(csregt, csregh, IT8368_MFIOSEL_REG);
259 	reg &= ~IT8368_MFIOSEL_MASK;
260 	it8368_reg_write(csregt, csregh, IT8368_MFIOSEL_REG, reg);
261 
262 	/* Disable MFIO interrupt */
263 	reg = it8368_reg_read(csregt, csregh, IT8368_MFIOPOSINTEN_REG);
264 	reg &= ~IT8368_MFIOPOSINTEN_MASK;
265 	it8368_reg_write(csregt, csregh, IT8368_MFIOPOSINTEN_REG, reg);
266 	reg = it8368_reg_read(csregt, csregh, IT8368_MFIONEGINTEN_REG);
267 	reg &= ~IT8368_MFIONEGINTEN_MASK;
268 	it8368_reg_write(csregt, csregh, IT8368_MFIONEGINTEN_REG, reg);
269 
270 	/* Port direction */
271 	reg = IT8368_PIN_CRDVCCON1 | IT8368_PIN_CRDVCCON0 |
272 		IT8368_PIN_CRDVPPON1 | IT8368_PIN_CRDVPPON0 |
273 		IT8368_PIN_BCRDRST;
274 	it8368_reg_write(csregt, csregh, IT8368_GPIODIR_REG, reg);
275 	printf("\n");
276 
277 	/*
278 	 *	Separate I/O and attribute memory region
279 	 */
280 	reg = it8368_reg_read(csregt, csregh, IT8368_CTRL_REG);
281 
282 	reg |= IT8368_CTRL_FIXATTRIO;
283 	it8368_reg_write(csregt, csregh, IT8368_CTRL_REG, reg);
284 
285 	if (IT8368_CTRL_FIXATTRIO &
286 	    it8368_reg_read(csregt, csregh, IT8368_CTRL_REG)) {
287 		sc->sc_fixattr = 1;
288 		printf("%s: fix attr mode\n", sc->sc_dev.dv_xname);
289 	} else {
290 		sc->sc_fixattr = 0;
291 		printf("%s: legacy attr mode\n", sc->sc_dev.dv_xname);
292 	}
293 
294 	sc->sc_csmemt = sc->sc_csiot;
295 	sc->sc_csiosize /= 2;
296 	sc->sc_csmemsize = sc->sc_csiosize;
297 	sc->sc_csmembase = sc->sc_csiosize;
298 
299 #ifdef IT8368DEBUG
300 	it8368_dump(sc);
301 #endif
302 	/* Enable card and interrupt driving. */
303 	reg = it8368_reg_read(csregt, csregh, IT8368_CTRL_REG);
304 	reg |= (IT8368_CTRL_GLOBALEN | IT8368_CTRL_CARDEN);
305 	if (sc->sc_fixattr)
306 		reg |= IT8368_CTRL_FIXATTRIO;
307 	it8368_reg_write(csregt, csregh, IT8368_CTRL_REG, reg);
308 
309 	sc->sc_irq = ca->ca_irq1;
310 	sc->sc_card_irq = ca->ca_irq3;
311 
312 	it8368_attach_socket(sc);
313 }
314 
315 __inline__ u_int16_t
316 it8368_reg_read(t, h, ofs)
317 	bus_space_tag_t t;
318 	bus_space_handle_t h;
319 	int ofs;
320 {
321 	u_int16_t val;
322 
323 	val = bus_space_read_2(t, h, ofs);
324 	return 0xffff & (((val >> 8) & 0xff)|((val << 8) & 0xff00));
325 }
326 
327 __inline__ void
328 it8368_reg_write(t, h, ofs, v)
329 	bus_space_tag_t t;
330 	bus_space_handle_t h;
331 	int ofs;
332 	u_int16_t v;
333 {
334 	u_int16_t val;
335 
336 	val = 0xffff & (((v >> 8) & 0xff)|((v << 8) & 0xff00));
337 	bus_space_write_2(t, h, ofs, val);
338 }
339 
340 int
341 it8368_intr(arg)
342  	void *arg;
343 {
344 	struct it8368e_softc *sc = arg;
345 	bus_space_tag_t csregt = sc->sc_csregt;
346 	bus_space_handle_t csregh = sc->sc_csregh;
347 	u_int16_t reg;
348 
349 	reg = it8368_reg_read(csregt, csregh, IT8368_GPIONEGINTSTAT_REG);
350 
351 	if (reg & IT8368_PIN_BCRDRDY) {
352 		if (sc->sc_card_fun) {
353 			/* clear interrupt */
354 			it8368_reg_write(csregt, csregh,
355 					 IT8368_GPIONEGINTSTAT_REG,
356 					 IT8368_PIN_BCRDRDY);
357 
358 			/* Dispatch card interrupt handler */
359 			(*sc->sc_card_fun)(sc->sc_card_arg);
360 		}
361 	} else if (reg & IT8368_PIN_CRDDET2) {
362 		it8368_reg_write(csregt, csregh, IT8368_GPIONEGINTSTAT_REG,
363 				 IT8368_PIN_CRDDET2);
364 		printf("[CSC]\n");
365 #ifdef IT8368DEBUG
366 		it8368_dump(sc);
367 #endif
368 		it8368_chip_socket_disable(sc);
369 	} else {
370 #ifdef IT8368DEBUG
371 		u_int16_t reg2;
372 		reg2 = reg & ~(IT8368_PIN_BCRDRDY|IT8368_PIN_CRDDET2);
373 		printf("unknown it8368 interrupt: ");
374 		bitdisp(reg2);
375 		it8368_reg_write(csregt, csregh, IT8368_GPIONEGINTSTAT_REG,
376 				 reg);
377 #endif
378 	}
379 
380 	return 0;
381 }
382 
383 int
384 it8368_print(arg, pnp)
385 	void *arg;
386 	const char *pnp;
387 {
388 	if (pnp)
389 		printf("pcmcia at %s", pnp);
390 
391 	return UNCONF;
392 }
393 
394 int
395 it8368_submatch(parent, cf, aux)
396 	struct device *parent;
397 	struct cfdata *cf;
398 	void *aux;
399 {
400 	return ((*cf->cf_attach->ca_match)(parent, cf, aux));
401 }
402 
403 void
404 it8368_attach_socket(sc)
405 	struct it8368e_softc *sc;
406 {
407 	struct pcmciabus_attach_args paa;
408 
409 	paa.paa_busname = "pcmcia";
410 	paa.pct = (pcmcia_chipset_tag_t)&it8368_functions;
411 	paa.pch = (pcmcia_chipset_handle_t)sc;
412 	paa.iobase = 0;		/* I don't use them */
413 	paa.iosize = 0;
414 
415 	if ((sc->sc_pcmcia = config_found_sm((void*)sc, &paa, it8368_print,
416  					     it8368_submatch))) {
417 
418 		it8368_init_socket(sc);
419 	}
420 }
421 
422 void
423 it8368_init_socket(sc)
424 	struct it8368e_softc *sc;
425 {
426 	bus_space_tag_t csregt = sc->sc_csregt;
427 	bus_space_handle_t csregh = sc->sc_csregh;
428 	u_int16_t reg;
429 
430 	/*
431 	 *  set up the card to interrupt on card detect
432 	 */
433 	reg = IT8368_PIN_CRDDET2; /* CSC */
434 	/* enable negative edge */
435 	it8368_reg_write(csregt, csregh, IT8368_GPIONEGINTEN_REG, reg);
436 	/* disable positive edge */
437 	it8368_reg_write(csregt, csregh, IT8368_GPIOPOSINTEN_REG, 0);
438 
439 	sc->sc_ih = tx_intr_establish(sc->sc_tc, sc->sc_irq,
440 				      IST_EDGE, IPL_BIO, it8368_intr, sc);
441 	if (sc->sc_ih == NULL) {
442 		printf("%s: can't establish interrupt\n",
443 		       sc->sc_dev.dv_xname);
444 		return;
445 	}
446 
447 	/*
448 	 *  if there's a card there, then attach it.
449 	 */
450 	reg = it8368_reg_read(csregt, csregh, IT8368_GPIODATAIN_REG);
451 
452 	if (reg & (IT8368_PIN_CRDDET2|IT8368_PIN_CRDDET1)) {
453 		sc->sc_laststate = IT8368_LASTSTATE_EMPTY;
454 	} else {
455 		pcmcia_card_attach(sc->sc_pcmcia);
456 		sc->sc_laststate = IT8368_LASTSTATE_PRESENT;
457 	}
458 }
459 
460 void *
461 it8368_chip_intr_establish(pch, pf, ipl, ih_fun, ih_arg)
462 	pcmcia_chipset_handle_t pch;
463 	struct pcmcia_function *pf;
464 	int ipl;
465 	int (*ih_fun) __P((void *));
466 	void *ih_arg;
467 {
468 	struct it8368e_softc *sc = (struct it8368e_softc*) pch;
469 	bus_space_tag_t csregt = sc->sc_csregt;
470 	bus_space_handle_t csregh = sc->sc_csregh;
471 	u_int16_t reg;
472 
473 	if (sc->sc_card_fun)
474 		panic("it8368_chip_intr_establish: "
475 		      "duplicate card interrupt handler.");
476 
477 	sc->sc_card_fun = ih_fun;
478 	sc->sc_card_arg = ih_arg;
479 
480 	sc->sc_card_ih = tx_intr_establish(sc->sc_tc, sc->sc_card_irq,
481 					   IST_EDGE, IPL_BIO, it8368_intr,
482 					   sc);
483 
484 	/* enable card interrupt */
485 	reg = it8368_reg_read(csregt, csregh, IT8368_GPIONEGINTEN_REG);
486 	reg |= IT8368_PIN_BCRDRDY;
487 	it8368_reg_write(csregt, csregh, IT8368_GPIONEGINTEN_REG, reg);
488 
489 	return sc->sc_card_ih;
490 }
491 
492 void
493 it8368_chip_intr_disestablish(pch, ih)
494 	pcmcia_chipset_handle_t pch;
495 	void *ih;
496 {
497 	struct it8368e_softc *sc = (struct it8368e_softc*) pch;
498 	bus_space_tag_t csregt = sc->sc_csregt;
499 	bus_space_handle_t csregh = sc->sc_csregh;
500 	u_int16_t reg;
501 
502 	if (!sc->sc_card_fun)
503 		panic("it8368_chip_intr_disestablish:"
504 		      "no handler established.");
505 	assert(ih == sc->sc_card_ih);
506 
507 	sc->sc_card_fun = 0;
508 	sc->sc_card_arg = 0;
509 
510 	/* disable card interrupt */
511 	reg = it8368_reg_read(csregt, csregh, IT8368_GPIONEGINTEN_REG);
512 	reg &= ~IT8368_PIN_BCRDRDY;
513 	it8368_reg_write(csregt, csregh, IT8368_GPIONEGINTEN_REG, reg);
514 
515 	tx_intr_disestablish(sc->sc_tc, ih);
516 }
517 
518 int
519 it8368_chip_mem_alloc(pch, size, pcmhp)
520 	pcmcia_chipset_handle_t pch;
521 	bus_size_t size;
522 	struct pcmcia_mem_handle *pcmhp;
523 {
524 	struct it8368e_softc *sc = (struct it8368e_softc*) pch;
525 
526 	if (bus_space_alloc(sc->sc_csmemt, sc->sc_csmembase,
527 			    sc->sc_csmembase + sc->sc_csmemsize, size,
528 			    size, 0, 0, 0, &pcmhp->memh)) {
529 		DPRINTF(("it8368_chip_mem_alloc: failed\n"));
530 		return 1;
531 	}
532 
533 	if (!sc->sc_fixattr) /* XXX IT8368 brain damaged spec */
534 		pcmhp->memh -= sc->sc_csmembase;
535 
536 	pcmhp->memt = sc->sc_csmemt;
537 	pcmhp->addr = pcmhp->memh;
538 	pcmhp->size = size;
539 	pcmhp->realsize = size;
540 
541 	DPRINTF(("it8368_chip_mem_alloc: %#x+%#x\n",
542 		 (unsigned)pcmhp->memh, (unsigned)size));
543 
544 	return 0;
545 }
546 
547 void
548 it8368_chip_mem_free(pch, pcmhp)
549 	pcmcia_chipset_handle_t pch;
550 	struct pcmcia_mem_handle *pcmhp;
551 {
552 	struct it8368e_softc *sc = (struct it8368e_softc*) pch;
553 
554 	DPRINTF(("it8368_chip_mem_free: %#x+%#x\n",
555 		 (unsigned)pcmhp->memh, (unsigned)pcmhp->size));
556 
557 	if (!sc->sc_fixattr) /* XXX IT8368 brain damaged spec */
558 		pcmhp->memh += sc->sc_csmembase;
559 
560 	bus_space_unmap(pcmhp->memt, pcmhp->memh, pcmhp->size);
561 }
562 
563 int
564 it8368_chip_mem_map(pch, kind, card_addr, size, pcmhp, offsetp, windowp)
565 	pcmcia_chipset_handle_t pch;
566 	int kind;
567 	bus_addr_t card_addr;
568 	bus_size_t size;
569 	struct pcmcia_mem_handle *pcmhp;
570 	bus_addr_t *offsetp;
571 	int *windowp;
572 {
573 	/* attribute mode */
574 	it8368_mode(pch, IT8368_ATTR_MODE, IT8368_WIDTH_16);
575 
576 	*offsetp = card_addr;
577 	DPRINTF(("it8368_chip_mem_map %#x+%#x\n",
578 		 (unsigned)pcmhp->memh, (unsigned)size));
579 
580 	return 0;
581 }
582 
583 void
584 it8368_chip_mem_unmap(pch, window)
585 	pcmcia_chipset_handle_t pch;
586 	int window;
587 {
588 	/* return to I/O mode */
589 	it8368_mode(pch, IT8368_IO_MODE, IT8368_WIDTH_16);
590 }
591 
592 void
593 it8368_mode(pch, io, width)
594 	pcmcia_chipset_handle_t pch;
595 	int io;
596 	int width;
597 {
598 	struct it8368e_softc *sc = (struct it8368e_softc*) pch;
599 	txreg_t reg32;
600 
601 	DPRINTF(("it8368_mode: change access space to "));
602 	DPRINTF((io ? "I/O (%dbit)\n" : "attribute (%dbit)...\n",
603 		 width == IT8368_WIDTH_8 ? 8 : 16));
604 
605 	reg32 = tx_conf_read(sc->sc_tc, TX39_MEMCONFIG3_REG);
606 
607 	if (io) {
608 		if (width == IT8368_WIDTH_8)
609 			reg32 |= TX39_MEMCONFIG3_PORT8SEL;
610 		else
611 			reg32 &= ~TX39_MEMCONFIG3_PORT8SEL;
612 	}
613 
614 	if (!sc->sc_fixattr) {
615 		if (io)
616 			reg32 |= TX39_MEMCONFIG3_CARD1IOEN;
617 		else
618 			reg32 &= ~TX39_MEMCONFIG3_CARD1IOEN;
619 	}
620 	tx_conf_write(sc->sc_tc, TX39_MEMCONFIG3_REG, reg32);
621 
622 #ifdef IT8368DEBUG
623 	if (sc->sc_fixattr)
624 		return; /* No need to report BIU status */
625 
626 	/* check BIU status */
627 	reg32 = tx_conf_read(sc->sc_tc, TX39_MEMCONFIG3_REG);
628 	if (reg32 & TX39_MEMCONFIG3_CARD1IOEN) {
629 		DPRINTF(("it8368_mode: I/O space (%dbit) enabled\n",
630 			 reg32 & TX39_MEMCONFIG3_PORT8SEL ? 8 : 16));
631 	} else {
632 		DPRINTF(("it8368_mode: atttribute space enabled\n"));
633 	}
634 #endif /* IT8368DEBUG */
635 }
636 
637 int
638 it8368_chip_io_alloc(pch, start, size, align, pcihp)
639 	pcmcia_chipset_handle_t pch;
640 	bus_addr_t start;
641 	bus_size_t size;
642 	bus_size_t align;
643 	struct pcmcia_io_handle *pcihp;
644 {
645 	struct it8368e_softc *sc = (struct it8368e_softc*) pch;
646 
647 	if (start) {
648 		if (bus_space_map(sc->sc_csiot, start, size, 0,
649 				  &pcihp->ioh)) {
650 			return 1;
651 		}
652 		DPRINTF(("it8368_chip_io_alloc map port %#x+%#x\n",
653 			 (unsigned)start, (unsigned)size));
654 	} else {
655 		if (bus_space_alloc(sc->sc_csiot, sc->sc_csiobase,
656 				    sc->sc_csiobase + sc->sc_csiosize,
657 				    size, align, 0, 0, &pcihp->addr,
658 				    &pcihp->ioh)) {
659 
660 			return 1;
661 		}
662 		pcihp->flags = PCMCIA_IO_ALLOCATED;
663 		DPRINTF(("it8368_chip_io_alloc alloc %#x from %#x\n",
664 			 (unsigned)size, (unsigned)pcihp->addr));
665 	}
666 
667 	pcihp->iot = sc->sc_csiot;
668 	pcihp->size = size;
669 
670 	return 0;
671 }
672 
673 int
674 it8368_chip_io_map(pch, width, offset, size, pcihp, windowp)
675 	pcmcia_chipset_handle_t pch;
676 	int width;
677 	bus_addr_t offset;
678 	bus_size_t size;
679 	struct pcmcia_io_handle *pcihp;
680 	int *windowp;
681 {
682 	/* I/O mode */
683 	it8368_mode(pch, IT8368_IO_MODE, IT8368_WIDTH_16);
684 
685 	DPRINTF(("it8368_chip_io_map %#x:%#x+%#x\n",
686 		 (unsigned)pcihp->ioh, (unsigned)offset, (unsigned)size));
687 
688 	return 0;
689 }
690 
691 void
692 it8368_chip_io_free(pch, pcihp)
693 	pcmcia_chipset_handle_t pch;
694 	struct pcmcia_io_handle *pcihp;
695 {
696 	if (pcihp->flags & PCMCIA_IO_ALLOCATED)
697 		bus_space_free(pcihp->iot, pcihp->ioh, pcihp->size);
698 	else
699 		bus_space_unmap(pcihp->iot, pcihp->ioh, pcihp->size);
700 
701 	DPRINTF(("it8368_chip_io_free %#x+%#x\n",
702 		 (unsigned)pcihp->ioh, (unsigned)pcihp->size));
703 }
704 
705 void
706 it8368_chip_io_unmap(pch, window)
707 	pcmcia_chipset_handle_t pch;
708 	int window;
709 {
710 }
711 
712 void
713 it8368_chip_socket_enable(pch)
714 	pcmcia_chipset_handle_t pch;
715 {
716 #ifndef WINCE_DEFAULT_SETTING
717 	struct it8368e_softc *sc = (struct it8368e_softc*)pch;
718 	bus_space_tag_t csregt = sc->sc_csregt;
719 	bus_space_handle_t csregh = sc->sc_csregh;
720 	volatile u_int16_t reg;
721 
722 	/* Power off */
723 	reg = it8368_reg_read(csregt, csregh, IT8368_GPIODATAOUT_REG);
724 	reg &= ~(IT8368_PIN_CRDVCCMASK | IT8368_PIN_CRDVPPMASK);
725 	reg |= (IT8368_PIN_CRDVCC_0V | IT8368_PIN_CRDVPP_0V);
726 	it8368_reg_write(csregt, csregh, IT8368_GPIODATAOUT_REG, reg);
727 	delay(20000);
728 
729 	/*
730 	 * wait 300ms until power fails (Tpf).  Then, wait 100ms since
731 	 * we are changing Vcc (Toff).
732 	 */
733 	delay((300 + 100) * 1000);
734 
735 	/* Supply Vcc */
736 	reg = it8368_reg_read(csregt, csregh, IT8368_GPIODATAOUT_REG);
737 	reg &= ~(IT8368_PIN_CRDVCCMASK | IT8368_PIN_CRDVPPMASK);
738 	reg |= IT8368_PIN_CRDVCC_5V; /* XXX */
739 	it8368_reg_write(csregt, csregh, IT8368_GPIODATAOUT_REG, reg);
740 
741 	/*
742 	 * wait 100ms until power raise (Tpr) and 20ms to become
743 	 * stable (Tsu(Vcc)).
744 	 *
745 	 * some machines require some more time to be settled
746 	 * (300ms is added here).
747 	 */
748 	delay((100 + 20 + 300) * 1000);
749 
750 	/* Assert reset signal */
751 	reg = it8368_reg_read(csregt, csregh, IT8368_GPIODATAOUT_REG);
752 	reg |= IT8368_PIN_BCRDRST;
753 	it8368_reg_write(csregt, csregh, IT8368_GPIODATAOUT_REG, reg);
754 
755 	/*
756 	 * hold RESET at least 10us.
757 	 */
758 	delay(10);
759 
760 	/* deassert reset signal */
761 	reg = it8368_reg_read(csregt, csregh, IT8368_GPIODATAOUT_REG);
762 	reg &= ~IT8368_PIN_BCRDRST;
763 	it8368_reg_write(csregt, csregh, IT8368_GPIODATAOUT_REG, reg);
764 	delay(20000);
765 
766 	DPRINTF(("it8368_chip_socket_enable: socket enabled\n"));
767 #endif /* !WINCE_DEFAULT_SETTING */
768 }
769 
770 void
771 it8368_chip_socket_disable(pch)
772 	pcmcia_chipset_handle_t pch;
773 {
774 #ifndef WINCE_DEFAULT_SETTING
775 	struct it8368e_softc *sc = (struct it8368e_softc*) pch;
776 	bus_space_tag_t csregt = sc->sc_csregt;
777 	bus_space_handle_t csregh = sc->sc_csregh;
778 	u_int16_t reg;
779 
780 	/* Power down */
781 	reg = it8368_reg_read(csregt, csregh, IT8368_GPIODATAOUT_REG);
782 	reg &= ~(IT8368_PIN_CRDVCCMASK | IT8368_PIN_CRDVPPMASK);
783 	reg |= (IT8368_PIN_CRDVCC_0V | IT8368_PIN_CRDVPP_0V);
784 	it8368_reg_write(csregt, csregh, IT8368_GPIODATAOUT_REG, reg);
785 	delay(20000);
786 
787 	/*
788 	 * wait 300ms until power fails (Tpf).
789 	 */
790 	delay(300 * 1000);
791 
792 	DPRINTF(("it8368_chip_socket_disable: socket disabled\n"));
793 #endif /* !WINCE_DEFAULT_SETTING */
794 }
795 
796 #ifdef IT8368DEBUG
797 #define PRINTGPIO(m) __bitdisp(it8368_reg_read(csregt, csregh,		\
798 	IT8368_GPIO##m##_REG), 0, IT8368_GPIO_MAX, #m, 1)
799 #define PRINTMFIO(m) __bitdisp(it8368_reg_read(csregt, csregh,		\
800 	IT8368_MFIO##m##_REG), 0, IT8368_MFIO_MAX, #m, 1)
801 void
802 it8368_dump(sc)
803 	struct it8368e_softc *sc;
804 {
805 	bus_space_tag_t csregt = sc->sc_csregt;
806 	bus_space_handle_t csregh = sc->sc_csregh;
807 
808 	printf("[GPIO]\n");
809 	PRINTGPIO(DIR);
810 	PRINTGPIO(DATAIN);
811 	PRINTGPIO(DATAOUT);
812 	PRINTGPIO(POSINTEN);
813 	PRINTGPIO(NEGINTEN);
814 	PRINTGPIO(POSINTSTAT);
815 	PRINTGPIO(NEGINTSTAT);
816 	printf("[MFIO]\n");
817 	PRINTMFIO(SEL);
818 	PRINTMFIO(DIR);
819 	PRINTMFIO(DATAIN);
820 	PRINTMFIO(DATAOUT);
821 	PRINTMFIO(POSINTEN);
822 	PRINTMFIO(NEGINTEN);
823 	PRINTMFIO(POSINTSTAT);
824 	PRINTMFIO(NEGINTSTAT);
825 	__bitdisp(it8368_reg_read(csregt, csregh, IT8368_CTRL_REG), 0, 15,
826 		  "CTRL", 1);
827 	__bitdisp(it8368_reg_read(csregt, csregh, IT8368_GPIODATAIN_REG),
828 		  8, 11, "]CRDDET/SENSE[", 1);
829 }
830 #endif /* IT8368DEBUG */
831