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