1 /* $NetBSD: shpcmcia.c,v 1.1 2010/04/06 15:54:29 nonaka Exp $ */ 2 3 /*- 4 * Copyright (c) 2009 NONAKA Kimihiro <nonaka@netbsd.org> 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. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <sys/cdefs.h> 30 __KERNEL_RCSID(0, "$NetBSD: shpcmcia.c,v 1.1 2010/04/06 15:54:29 nonaka Exp $"); 31 32 #include <sys/types.h> 33 #include <sys/param.h> 34 #include <sys/systm.h> 35 #include <sys/device.h> 36 #include <sys/malloc.h> 37 #include <sys/kthread.h> 38 #include <sys/kernel.h> 39 #include <sys/callout.h> 40 #include <sys/bus.h> 41 #include <sys/intr.h> 42 43 #include <dev/pcmcia/pcmciachip.h> 44 #include <dev/pcmcia/pcmciavar.h> 45 46 #include <machine/autoconf.h> 47 48 #include <sh3/devreg.h> 49 #include <sh3/bscreg.h> 50 #include <sh3/pfcreg.h> 51 52 #include <evbsh3/ap_ms104_sh4/ap_ms104_sh4reg.h> 53 #include <evbsh3/ap_ms104_sh4/ap_ms104_sh4var.h> 54 55 #ifdef SHPCMCIA_DEBUG 56 #define DPRINTF(s) printf s 57 #else 58 #define DPRINTF(s) 59 #endif 60 61 static int shpcmcia_chip_mem_alloc(pcmcia_chipset_handle_t, 62 bus_size_t, struct pcmcia_mem_handle *); 63 static void shpcmcia_chip_mem_free(pcmcia_chipset_handle_t, 64 struct pcmcia_mem_handle *); 65 static int shpcmcia_chip_mem_map(pcmcia_chipset_handle_t, int, 66 bus_addr_t, bus_size_t, struct pcmcia_mem_handle *, 67 bus_size_t *, int *); 68 static void shpcmcia_chip_mem_unmap(pcmcia_chipset_handle_t, int); 69 static int shpcmcia_chip_io_alloc(pcmcia_chipset_handle_t, 70 bus_addr_t, bus_size_t, bus_size_t, 71 struct pcmcia_io_handle *); 72 static void shpcmcia_chip_io_free(pcmcia_chipset_handle_t, 73 struct pcmcia_io_handle *); 74 static int shpcmcia_chip_io_map(pcmcia_chipset_handle_t, int, 75 bus_addr_t, bus_size_t, struct pcmcia_io_handle *, int *); 76 static void shpcmcia_chip_io_unmap(pcmcia_chipset_handle_t, int); 77 static void *shpcmcia_chip_intr_establish(pcmcia_chipset_handle_t, 78 struct pcmcia_function *, int, int (*)(void *), void *); 79 static void shpcmcia_chip_intr_disestablish(pcmcia_chipset_handle_t, 80 void *); 81 static void shpcmcia_chip_socket_enable(pcmcia_chipset_handle_t); 82 static void shpcmcia_chip_socket_disable(pcmcia_chipset_handle_t); 83 static void shpcmcia_chip_socket_settype(pcmcia_chipset_handle_t, 84 int); 85 86 static struct pcmcia_chip_functions shpcmcia_chip_functions = { 87 /* memory space allocation */ 88 .mem_alloc = shpcmcia_chip_mem_alloc, 89 .mem_free = shpcmcia_chip_mem_free, 90 91 /* memory space window mapping */ 92 .mem_map = shpcmcia_chip_mem_map, 93 .mem_unmap = shpcmcia_chip_mem_unmap, 94 95 /* I/O space allocation */ 96 .io_alloc = shpcmcia_chip_io_alloc, 97 .io_free = shpcmcia_chip_io_free, 98 99 /* I/O space window mapping */ 100 .io_map = shpcmcia_chip_io_map, 101 .io_unmap = shpcmcia_chip_io_unmap, 102 103 /* interrupt glue */ 104 .intr_establish = shpcmcia_chip_intr_establish, 105 .intr_disestablish = shpcmcia_chip_intr_disestablish, 106 107 /* card enable/disable */ 108 .socket_enable = shpcmcia_chip_socket_enable, 109 .socket_disable = shpcmcia_chip_socket_disable, 110 .socket_settype = shpcmcia_chip_socket_settype, 111 112 /* card detection */ 113 .card_detect = NULL, 114 }; 115 116 /* 117 * event thread 118 */ 119 struct shpcmcia_event { 120 SIMPLEQ_ENTRY(shpcmcia_event) pe_q; 121 int pe_type; 122 }; 123 124 /* pe_type */ 125 #define SHPCMCIA_EVENT_INSERT 0 126 #define SHPCMCIA_EVENT_REMOVE 1 127 128 struct shpcmcia_softc; 129 struct shpcmcia_handle { 130 struct shpcmcia_softc *sc; 131 132 int flags; 133 #define SHPCMCIA_FLAG_SOCKETP 0x0001 134 #define SHPCMCIA_FLAG_CARDP 0x0002 135 int laststate; 136 #define SHPCMCIA_LASTSTATE_EMPTY 0x0000 137 #define SHPCMCIA_LASTSTATE_PRESENT 0x0002 138 139 140 int memalloc; 141 struct { 142 bus_addr_t addr; 143 bus_size_t size; 144 long offset; 145 int kind; 146 #define SHPCMCIA_MEM_WINS 5 147 } mem[SHPCMCIA_MEM_WINS]; 148 149 int ioalloc; 150 struct { 151 bus_addr_t addr; 152 bus_size_t size; 153 int width; 154 #define SHPCMCIA_IO_WINS 2 155 } io[SHPCMCIA_IO_WINS]; 156 157 struct device *pcmcia; 158 159 int shutdown; 160 lwp_t *event_thread; 161 SIMPLEQ_HEAD(, shpcmcia_event) events; 162 }; 163 164 struct shpcmcia_softc { 165 device_t sc_dev; 166 167 bus_space_tag_t sc_iot; 168 bus_space_handle_t sc_ioh; 169 bus_space_tag_t sc_memt; 170 bus_space_handle_t sc_memh; 171 bus_space_tag_t sc_attt; 172 bus_space_handle_t sc_atth; 173 174 pcmcia_chipset_tag_t sc_pct; 175 176 void *sc_ih; 177 #if 0 178 void *sc_detect_ih; 179 #else 180 callout_t sc_detect_ch; 181 #endif 182 183 bus_addr_t sc_membase; 184 #define SHPCMCIA_MAX_MEM_PAGES (8 * sizeof(int)) 185 186 bus_addr_t sc_iobase; 187 bus_size_t sc_iosize; 188 189 #define SHPCMCIA_NSLOTS 1 190 struct shpcmcia_handle sc_handle[SHPCMCIA_NSLOTS]; 191 }; 192 193 static int shpcmcia_probe(device_t, cfdata_t, void *); 194 static void shpcmcia_attach(device_t, device_t, void *); 195 static int shpcmcia_print(void *, const char *); 196 197 CFATTACH_DECL_NEW(shpcmcia, sizeof(struct shpcmcia_softc), 198 shpcmcia_probe, shpcmcia_attach, NULL, NULL); 199 200 #if 0 201 static int shpcmcia_card_detect_intr(void *arg); 202 #else 203 static void shpcmcia_card_detect_poll(void *arg); 204 #endif 205 206 static void shpcmcia_init_socket(struct shpcmcia_handle *); 207 static void shpcmcia_attach_socket(struct shpcmcia_handle *); 208 static void shpcmcia_attach_sockets(struct shpcmcia_softc *); 209 210 static void shpcmcia_event_thread(void *); 211 static void shpcmcia_queue_event(struct shpcmcia_handle *, int); 212 213 static void shpcmcia_attach_card(struct shpcmcia_handle *); 214 static void shpcmcia_detach_card(struct shpcmcia_handle *, int ); 215 static void shpcmcia_deactivate_card(struct shpcmcia_handle *); 216 217 static int 218 shpcmcia_probe(device_t parent, cfdata_t cfp, void *aux) 219 { 220 struct mainbus_attach_args *maa = aux; 221 222 if (strcmp(maa->ma_name, "shpcmcia") != 0) 223 return 0; 224 return 1; 225 } 226 227 static void 228 shpcmcia_attach(device_t parent, device_t self, void *aux) 229 { 230 struct shpcmcia_softc *sc = device_private(self); 231 #if 0 232 uint32_t reg; 233 #endif 234 235 sc->sc_dev = self; 236 237 aprint_naive("\n"); 238 aprint_normal("\n"); 239 240 #if 0 241 /* setup bus controller */ 242 /* max wait */ 243 reg = _reg_read_4(SH4_WCR1); 244 reg |= 0x00700000; 245 _reg_write_4(SH4_WCR1, reg); 246 reg = _reg_read_4(SH4_WCR2); 247 reg |= 0xfff00000; 248 _reg_write_4(SH4_WCR2, reg); 249 reg = _reg_read_4(SH4_WCR3); 250 reg |= 0x07700000; 251 _reg_write_4(SH4_WCR3, reg); 252 reg = _reg_read_4(SH4_PCR); 253 reg |= 0xffffffff; 254 _reg_write_4(SH4_PCR, reg); 255 #endif 256 257 sc->sc_pct = (pcmcia_chipset_tag_t)&shpcmcia_chip_functions; 258 sc->sc_iot = &ap_ms104_sh4_bus_io; 259 sc->sc_memt = &ap_ms104_sh4_bus_mem; 260 sc->sc_attt = &ap_ms104_sh4_bus_att; 261 262 if (bus_space_map(sc->sc_attt, 0x14000000, 4 * 1024, 0, &sc->sc_atth)) 263 panic("%s: couldn't map attribute\n", device_xname(sc->sc_dev)); 264 if (bus_space_map(sc->sc_iot, 0x15000000, 64 * 1024, 0, 265 &sc->sc_ioh)) 266 panic("%s: couldn't map io memory\n", device_xname(sc->sc_dev)); 267 if (bus_space_map(sc->sc_memt, 0x16000000, 32 * 1024 * 1024, 0, 268 &sc->sc_memh)) 269 panic("%s: couldn't map memory\n", device_xname(sc->sc_dev)); 270 271 sc->sc_iobase = sc->sc_ioh; 272 sc->sc_iosize = 64 * 1024; 273 sc->sc_membase = sc->sc_memh; 274 275 sc->sc_handle[0].sc = sc; 276 sc->sc_handle[0].flags = SHPCMCIA_FLAG_SOCKETP; 277 sc->sc_handle[0].laststate = SHPCMCIA_LASTSTATE_EMPTY; 278 SIMPLEQ_INIT(&sc->sc_handle[0].events); 279 280 #if 0 281 sc->sc_detect_ih = gpio_intr_establish(GPIO_PIN_CARD_CD, 282 shpcmcia_card_detect_intr, sc); 283 if (sc->sc_detect_ih == NULL) { 284 aprint_error_dev(self, "couldn't establish detect interrupt\n"); 285 } 286 #else 287 callout_init(&sc->sc_detect_ch, 0); 288 callout_reset(&sc->sc_detect_ch, hz, shpcmcia_card_detect_poll, sc); 289 #endif 290 291 shpcmcia_attach_sockets(sc); 292 } 293 294 static void 295 shpcmcia_attach_sockets(struct shpcmcia_softc *sc) 296 { 297 298 shpcmcia_attach_socket(&sc->sc_handle[0]); 299 } 300 301 static void 302 shpcmcia_attach_socket(struct shpcmcia_handle *h) 303 { 304 struct pcmciabus_attach_args paa; 305 306 /* initialize the rest of the handle */ 307 h->shutdown = 0; 308 h->memalloc = 0; 309 h->ioalloc = 0; 310 311 /* now, config one pcmcia device per socket */ 312 paa.paa_busname = "pcmcia"; 313 paa.pct = (pcmcia_chipset_tag_t)h->sc->sc_pct; 314 paa.pch = (pcmcia_chipset_handle_t)h; 315 paa.iobase = h->sc->sc_iobase; 316 paa.iosize = h->sc->sc_iosize; 317 318 h->pcmcia = config_found_ia(h->sc->sc_dev, "pcmciabus", &paa, 319 shpcmcia_print); 320 321 /* if there's actually a pcmcia device attached, initialize the slot */ 322 if (h->pcmcia) 323 shpcmcia_init_socket(h); 324 } 325 326 /*ARGSUSED*/ 327 static int 328 shpcmcia_print(void *arg, const char *pnp) 329 { 330 331 if (pnp) 332 aprint_normal("pcmcia at %s", pnp); 333 return UNCONF; 334 } 335 336 static void 337 shpcmcia_init_socket(struct shpcmcia_handle *h) 338 { 339 uint16_t reg; 340 341 /* 342 * queue creation of a kernel thread to handle insert/removal events. 343 */ 344 #ifdef DIAGNOSTIC 345 if (h->event_thread != NULL) 346 panic("shpcmcia_attach_socket: event thread"); 347 #endif 348 349 /* if there's a card there, then attach it. */ 350 reg = _reg_read_2(SH4_PDTRA); 351 if (!(reg & (1 << GPIO_PIN_CARD_CD))) { 352 shpcmcia_attach_card(h); 353 h->laststate = SHPCMCIA_LASTSTATE_PRESENT; 354 } else { 355 h->laststate = SHPCMCIA_LASTSTATE_EMPTY; 356 } 357 358 if (kthread_create(PRI_NONE, 0, NULL, shpcmcia_event_thread, h, 359 &h->event_thread, "%s", device_xname(h->sc->sc_dev))) { 360 aprint_error_dev(h->sc->sc_dev, 361 "unable to create event thread\n"); 362 panic("shpcmcia_create_event_thread"); 363 } 364 } 365 366 /* 367 * event thread 368 */ 369 static void 370 shpcmcia_event_thread(void *arg) 371 { 372 struct shpcmcia_handle *h = (struct shpcmcia_handle *)arg; 373 struct shpcmcia_event *pe; 374 int s; 375 376 while (h->shutdown == 0) { 377 s = splhigh(); 378 if ((pe = SIMPLEQ_FIRST(&h->events)) == NULL) { 379 splx(s); 380 (void) tsleep(&h->events, PWAIT, "waitev", 0); 381 continue; 382 } else { 383 splx(s); 384 /* sleep .25s to be enqueued chatterling interrupts */ 385 (void) tsleep((void *)shpcmcia_event_thread, 386 PWAIT, "waitss", hz / 4); 387 } 388 s = splhigh(); 389 SIMPLEQ_REMOVE_HEAD(&h->events, pe_q); 390 splx(s); 391 392 switch (pe->pe_type) { 393 case SHPCMCIA_EVENT_INSERT: 394 s = splhigh(); 395 for (;;) { 396 struct shpcmcia_event *pe1, *pe2; 397 398 if ((pe1 = SIMPLEQ_FIRST(&h->events)) == NULL) 399 break; 400 if (pe1->pe_type != SHPCMCIA_EVENT_REMOVE) 401 break; 402 if ((pe2 = SIMPLEQ_NEXT(pe1, pe_q)) == NULL) 403 break; 404 if (pe2->pe_type == SHPCMCIA_EVENT_INSERT) { 405 SIMPLEQ_REMOVE_HEAD(&h->events, pe_q); 406 free(pe1, M_TEMP); 407 SIMPLEQ_REMOVE_HEAD(&h->events, pe_q); 408 free(pe2, M_TEMP); 409 } 410 } 411 splx(s); 412 413 DPRINTF(("%s: insertion event\n", 414 device_xname(h->sc->sc_dev))); 415 shpcmcia_attach_card(h); 416 break; 417 418 case SHPCMCIA_EVENT_REMOVE: 419 s = splhigh(); 420 for (;;) { 421 struct shpcmcia_event *pe1, *pe2; 422 423 if ((pe1 = SIMPLEQ_FIRST(&h->events)) == NULL) 424 break; 425 if (pe1->pe_type != SHPCMCIA_EVENT_INSERT) 426 break; 427 if ((pe2 = SIMPLEQ_NEXT(pe1, pe_q)) == NULL) 428 break; 429 if (pe2->pe_type == SHPCMCIA_EVENT_REMOVE) { 430 SIMPLEQ_REMOVE_HEAD(&h->events, pe_q); 431 free(pe1, M_TEMP); 432 SIMPLEQ_REMOVE_HEAD(&h->events, pe_q); 433 free(pe2, M_TEMP); 434 } 435 } 436 splx(s); 437 438 DPRINTF(("%s: removal event\n", 439 device_xname(h->sc->sc_dev))); 440 shpcmcia_detach_card(h, DETACH_FORCE); 441 break; 442 443 default: 444 panic("shpcmcia_event_thread: unknown event %d", 445 pe->pe_type); 446 } 447 free(pe, M_TEMP); 448 } 449 450 h->event_thread = NULL; 451 452 /* In case parent is waiting for us to exit. */ 453 wakeup(h->sc); 454 455 kthread_exit(0); 456 } 457 458 static void 459 shpcmcia_queue_event(struct shpcmcia_handle *h, int event) 460 { 461 struct shpcmcia_event *pe; 462 int s; 463 464 pe = malloc(sizeof(*pe), M_TEMP, M_NOWAIT); 465 if (pe == NULL) 466 panic("shpcmcia_queue_event: can't allocate event"); 467 468 pe->pe_type = event; 469 s = splhigh(); 470 SIMPLEQ_INSERT_TAIL(&h->events, pe, pe_q); 471 splx(s); 472 wakeup(&h->events); 473 } 474 475 static void 476 shpcmcia_attach_card(struct shpcmcia_handle *h) 477 { 478 479 DPRINTF(("%s\n", __func__)); 480 481 if (!(h->flags & SHPCMCIA_FLAG_CARDP)) { 482 /* call the MI attach function */ 483 pcmcia_card_attach(h->pcmcia); 484 485 h->flags |= SHPCMCIA_FLAG_CARDP; 486 } else { 487 DPRINTF(("shpcmcia_attach_card: already attached")); 488 } 489 } 490 491 static void 492 shpcmcia_detach_card(struct shpcmcia_handle *h, int flags) 493 { 494 495 DPRINTF(("%s\n", __func__)); 496 497 if (h->flags & SHPCMCIA_FLAG_CARDP) { 498 h->flags &= ~SHPCMCIA_FLAG_CARDP; 499 500 /* call the MI detach function */ 501 pcmcia_card_detach(h->pcmcia, flags); 502 } else { 503 DPRINTF(("shpcmcia_detach_card: already detached")); 504 } 505 } 506 507 static void 508 shpcmcia_deactivate_card(struct shpcmcia_handle *h) 509 { 510 511 DPRINTF(("%s\n", __func__)); 512 513 /* call the MI deactivate function */ 514 pcmcia_card_deactivate(h->pcmcia); 515 516 shpcmcia_chip_socket_disable(h); 517 } 518 519 #if 0 520 /* 521 * interrupt 522 */ 523 static int 524 shpcmcia_card_detect_intr(void *arg) 525 { 526 struct shpcmcia_softc *sc = (struct shpcmcia_softc *)arg; 527 struct shpcmcia_handle *h = &sc->sc_handle[0]; 528 uint16_t reg; 529 530 DPRINTF(("%s\n", __func__)); 531 532 reg = _reg_read_2(SH4_PDTRA); 533 if (reg & (1 << GPIO_PIN_CARD_CD)) { 534 /* remove */ 535 if (h->laststate == SHPCMCIA_LASTSTATE_PRESENT) { 536 /* Deactivate the card now. */ 537 shpcmcia_deactivate_card(h); 538 shpcmcia_queue_event(h, SHPCMCIA_EVENT_REMOVE); 539 } 540 h->laststate = SHPCMCIA_LASTSTATE_EMPTY; 541 } else { 542 /* insert */ 543 if (h->laststate != SHPCMCIA_LASTSTATE_PRESENT) { 544 shpcmcia_queue_event(h, SHPCMCIA_EVENT_INSERT); 545 } 546 h->laststate = SHPCMCIA_LASTSTATE_PRESENT; 547 } 548 return 1; 549 } 550 #else 551 /* 552 * card polling 553 */ 554 static void 555 shpcmcia_card_detect_poll(void *arg) 556 { 557 struct shpcmcia_softc *sc = (struct shpcmcia_softc *)arg; 558 struct shpcmcia_handle *h = &sc->sc_handle[0]; 559 uint16_t reg; 560 561 DPRINTF(("%s\n", __func__)); 562 563 reg = _reg_read_2(SH4_PDTRA); 564 if (reg & (1 << GPIO_PIN_CARD_CD)) { 565 /* remove */ 566 if (h->laststate == SHPCMCIA_LASTSTATE_PRESENT) { 567 /* Deactivate the card now. */ 568 shpcmcia_deactivate_card(h); 569 shpcmcia_queue_event(h, SHPCMCIA_EVENT_REMOVE); 570 } 571 h->laststate = SHPCMCIA_LASTSTATE_EMPTY; 572 } else { 573 /* insert */ 574 if (h->laststate != SHPCMCIA_LASTSTATE_PRESENT) { 575 shpcmcia_queue_event(h, SHPCMCIA_EVENT_INSERT); 576 } 577 h->laststate = SHPCMCIA_LASTSTATE_PRESENT; 578 } 579 580 callout_schedule(&sc->sc_detect_ch, hz); 581 } 582 #endif 583 584 /* 585 * pcmcia chip functions 586 */ 587 /* Memory space functions. */ 588 static int 589 shpcmcia_chip_mem_alloc(pcmcia_chipset_handle_t pch, bus_size_t size, 590 struct pcmcia_mem_handle *pmhp) 591 { 592 struct shpcmcia_handle *h = (struct shpcmcia_handle *)pch; 593 struct shpcmcia_softc *sc = h->sc; 594 595 DPRINTF(("%s: size=%d\n", __func__, (unsigned)size)); 596 597 memset(pmhp, 0, sizeof(*pmhp)); 598 pmhp->memt = sc->sc_memt; 599 pmhp->memh = sc->sc_memh; 600 pmhp->addr = 0; 601 pmhp->size = size; 602 pmhp->realsize = size; 603 604 return 0; 605 } 606 607 /*ARGSUSED*/ 608 static void 609 shpcmcia_chip_mem_free(pcmcia_chipset_handle_t pch, 610 struct pcmcia_mem_handle *pmhp) 611 { 612 613 DPRINTF(("%s\n", __func__)); 614 } 615 616 static int 617 shpcmcia_chip_mem_map(pcmcia_chipset_handle_t pch, int kind, 618 bus_addr_t card_addr, bus_size_t size, struct pcmcia_mem_handle *pmhp, 619 bus_size_t *offsetp, int *windowp) 620 { 621 struct shpcmcia_handle *h = (struct shpcmcia_handle *)pch; 622 struct shpcmcia_softc *sc = h->sc; 623 int win; 624 int i; 625 int s; 626 627 DPRINTF(("%s: kind=%#x, card_addr=%#x, size=%d\n", 628 __func__, kind, (unsigned)card_addr, (unsigned)size)); 629 630 s = splbio(); 631 win = -1; 632 for (i = 0; i < SHPCMCIA_MEM_WINS; i++) { 633 if ((h->memalloc & (1 << i)) == 0) { 634 win = i; 635 h->memalloc |= (1 << i); 636 break; 637 } 638 } 639 splx(s); 640 if (win == -1) 641 return 1; 642 643 *windowp = win; 644 *offsetp = 0; 645 646 h->mem[win].addr = pmhp->addr; 647 h->mem[win].size = size; 648 h->mem[win].offset = (((long)card_addr) - ((long)pmhp->addr)); 649 h->mem[win].kind = kind; 650 651 switch (kind) { 652 case PCMCIA_MEM_ATTR: 653 DPRINTF(("%s:PCMCIA_MEM_ATTR\n",device_xname(sc->sc_dev))); 654 pmhp->memh = sc->sc_atth + card_addr; 655 break; 656 657 default: 658 pmhp->memh = sc->sc_memh + card_addr; 659 break; 660 } 661 662 return 0; 663 } 664 665 /*ARGSUSED*/ 666 static void 667 shpcmcia_chip_mem_unmap(pcmcia_chipset_handle_t pch, int window) 668 { 669 struct shpcmcia_handle *h = (struct shpcmcia_handle *)pch; 670 int s; 671 672 DPRINTF(("%s\n", __func__)); 673 674 s = splbio(); 675 h->memalloc &= ~(1 << window); 676 splx(s); 677 } 678 679 /* I/O space functions. */ 680 static int 681 shpcmcia_chip_io_alloc(pcmcia_chipset_handle_t pch, 682 bus_addr_t start, bus_size_t size, bus_size_t align, 683 struct pcmcia_io_handle *pihp) 684 { 685 struct shpcmcia_handle *h = (struct shpcmcia_handle *)pch; 686 struct shpcmcia_softc *sc = h->sc; 687 688 DPRINTF(("%s\n", __func__)); 689 690 memset(pihp, 0, sizeof(*pihp)); 691 pihp->iot = sc->sc_iot; 692 pihp->ioh = sc->sc_ioh; 693 pihp->addr = start; 694 pihp->size = size; 695 pihp->flags |= PCMCIA_IO_ALLOCATED; 696 697 return 0; 698 } 699 700 /*ARGSUSED*/ 701 static void 702 shpcmcia_chip_io_free(pcmcia_chipset_handle_t pch, 703 struct pcmcia_io_handle *pih) 704 { 705 706 DPRINTF(("%s\n", __func__)); 707 } 708 709 /*ARGSUSED*/ 710 static int 711 shpcmcia_chip_io_map(pcmcia_chipset_handle_t pch, int width, 712 bus_addr_t card_addr, bus_size_t size, struct pcmcia_io_handle *pihp, 713 int *windowp) 714 { 715 struct shpcmcia_handle *h = (struct shpcmcia_handle *)pch; 716 struct shpcmcia_softc *sc = h->sc; 717 bus_addr_t ioaddr = pihp->addr + card_addr; 718 int win; 719 int i; 720 int s; 721 722 DPRINTF(("%s\n", __func__)); 723 724 s = splbio(); 725 win = -1; 726 for (i = 0; i < SHPCMCIA_IO_WINS; i++) { 727 if ((h->ioalloc & (1 << i)) == 0) { 728 win = i; 729 h->ioalloc |= (1 << i); 730 break; 731 } 732 } 733 splx(s); 734 if (win == -1) 735 return 1; 736 737 *windowp = win; 738 739 /* XXX: IOS16 */ 740 741 aprint_normal_dev(sc->sc_dev, "port 0x%0lx", (u_long)ioaddr); 742 if (size > 1) 743 aprint_normal("-0x%lx", (u_long) ioaddr + (u_long) size - 1); 744 aprint_normal("\n"); 745 746 h->io[win].addr = ioaddr; 747 h->io[win].size = size; 748 h->io[win].width = width; 749 750 return 0; 751 } 752 753 /*ARGSUSED*/ 754 static void 755 shpcmcia_chip_io_unmap(pcmcia_chipset_handle_t pch, int window) 756 { 757 struct shpcmcia_handle *h = (struct shpcmcia_handle *)pch; 758 int s; 759 760 DPRINTF(("%s\n", __func__)); 761 762 s = splbio(); 763 h->ioalloc &= ~(1 << window); 764 splx(s); 765 } 766 767 /* Interrupt functions. */ 768 static void * 769 shpcmcia_chip_intr_establish(pcmcia_chipset_handle_t pch, 770 struct pcmcia_function *pf, int ipl, int (*ih_func)(void *), void *ih_arg) 771 { 772 struct shpcmcia_handle *h = (struct shpcmcia_handle *)pch; 773 struct shpcmcia_softc *sc = h->sc; 774 int s; 775 776 KASSERT(sc->sc_ih == NULL); 777 DPRINTF(("%s\n", __func__)); 778 779 s = splhigh(); 780 sc->sc_ih = extintr_establish(EXTINTR_INTR_CFIREQ, IST_LEVEL, ipl, 781 ih_func, ih_arg); 782 if (sc->sc_ih == NULL) { 783 aprint_error_dev(sc->sc_dev, 784 "couldn't establish card interrupt\n"); 785 } 786 splx(s); 787 788 return sc->sc_ih; 789 } 790 791 static void 792 shpcmcia_chip_intr_disestablish(pcmcia_chipset_handle_t pch, void *cookie) 793 { 794 struct shpcmcia_handle *h = (struct shpcmcia_handle *)pch; 795 struct shpcmcia_softc *sc = h->sc; 796 int s; 797 798 KASSERT(sc->sc_ih != NULL); 799 DPRINTF(("%s\n", __func__)); 800 801 s = splhigh(); 802 extintr_disestablish(sc->sc_ih); 803 sc->sc_ih = NULL; 804 splx(s); 805 } 806 807 /* Socket functions. */ 808 static void 809 shpcmcia_chip_socket_enable(pcmcia_chipset_handle_t pch) 810 { 811 uint16_t reg; 812 813 DPRINTF(("%s\n", __func__)); 814 815 /* power on the card */ 816 reg = _reg_read_2(SH4_PDTRA); 817 reg &= ~(1 << GPIO_PIN_CARD_PON); 818 _reg_write_2(SH4_PDTRA, reg); 819 820 /* wait for card ready */ 821 while (_reg_read_1(EXTINTR_STAT1) & MASK1_INT12) 822 continue; 823 824 /* enable bus buffer */ 825 reg = _reg_read_2(SH4_PDTRA); 826 reg &= ~(1 << GPIO_PIN_CARD_ENABLE); 827 _reg_write_2(SH4_PDTRA, reg); 828 829 /* reset the card */ 830 reg = _reg_read_2(SH4_PDTRA); 831 reg &= ~(1 << GPIO_PIN_CARD_RESET); 832 _reg_write_2(SH4_PDTRA, reg); 833 delay(100 * 1000); 834 } 835 836 /*ARGSUSED*/ 837 static void 838 shpcmcia_chip_socket_disable(pcmcia_chipset_handle_t pch) 839 { 840 uint16_t reg; 841 842 DPRINTF(("%s\n", __func__)); 843 844 /* reset the card */ 845 reg = _reg_read_2(SH4_PDTRA); 846 reg |= (1 << GPIO_PIN_CARD_RESET); 847 _reg_write_2(SH4_PDTRA, reg); 848 849 /* power off the card */ 850 reg = _reg_read_2(SH4_PDTRA); 851 reg |= (1 << GPIO_PIN_CARD_PON); 852 _reg_write_2(SH4_PDTRA, reg); 853 854 /* disable bus buffer */ 855 reg = _reg_read_2(SH4_PDTRA); 856 reg |= (1 << GPIO_PIN_CARD_ENABLE); 857 _reg_write_2(SH4_PDTRA, reg); 858 } 859 860 /*ARGSUSED*/ 861 static void 862 shpcmcia_chip_socket_settype(pcmcia_chipset_handle_t pch, int type) 863 { 864 865 DPRINTF(("%s\n", __func__)); 866 } 867