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