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