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