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