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