1 /* $NetBSD: it8368.c,v 1.8 2000/03/12 15:35:29 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; /* I don't use them */ 413 paa.iosize = 0; 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