diff options
author | Uwe Stuehler <uwe@cvs.openbsd.org> | 2005-07-01 23:51:56 +0000 |
---|---|---|
committer | Uwe Stuehler <uwe@cvs.openbsd.org> | 2005-07-01 23:51:56 +0000 |
commit | 420968103d6f70617afff7176732e5a22c1e80f2 (patch) | |
tree | 88731b79b91f3c44cbaec77833a1068040792ec3 /sys | |
parent | fcfbf526bc30d43ed9ab3d24457e6abc683e9443 (diff) |
Move all zaurus specific code from pxa2x0_pcic.c into scoop_pcic.c
without affecting the way the driver works.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/arm/xscale/files.pxa2x0 | 3 | ||||
-rw-r--r-- | sys/arch/arm/xscale/pxa2x0_pcic.c | 591 | ||||
-rw-r--r-- | sys/arch/arm/xscale/pxapcicvar.h | 82 | ||||
-rw-r--r-- | sys/arch/zaurus/conf/files.zaurus | 10 | ||||
-rw-r--r-- | sys/arch/zaurus/dev/scoop_pcic.c | 252 | ||||
-rw-r--r-- | sys/arch/zaurus/dev/zaurus_scoop.c | 18 | ||||
-rw-r--r-- | sys/arch/zaurus/dev/zaurus_scoopreg.h | 53 |
7 files changed, 521 insertions, 488 deletions
diff --git a/sys/arch/arm/xscale/files.pxa2x0 b/sys/arch/arm/xscale/files.pxa2x0 index 76ddf18fc2b..b416567cead 100644 --- a/sys/arch/arm/xscale/files.pxa2x0 +++ b/sys/arch/arm/xscale/files.pxa2x0 @@ -1,4 +1,4 @@ -# $OpenBSD: files.pxa2x0,v 1.15 2005/06/16 21:30:11 uwe Exp $ +# $OpenBSD: files.pxa2x0,v 1.16 2005/07/01 23:51:55 uwe Exp $ # $NetBSD: files.pxa2x0,v 1.6 2004/05/01 19:09:14 thorpej Exp $ # # Configuration info for Intel PXA2[51]0 CPU support @@ -76,7 +76,6 @@ include "dev/pcmcia/files.pcmcia" # PCMCIA controller device pxapcic: pcmciabus -attach pxapcic at pxaip file arch/arm/xscale/pxa2x0_pcic.c pxapcic # XXX this is a hack to use dev/pcmcia without fdc.c diff --git a/sys/arch/arm/xscale/pxa2x0_pcic.c b/sys/arch/arm/xscale/pxa2x0_pcic.c index bd3b5bd073e..944b7599913 100644 --- a/sys/arch/arm/xscale/pxa2x0_pcic.c +++ b/sys/arch/arm/xscale/pxa2x0_pcic.c @@ -1,4 +1,5 @@ -/* $OpenBSD: pxa2x0_pcic.c,v 1.13 2005/04/11 03:38:03 uwe Exp $ */ +/* $OpenBSD: pxa2x0_pcic.c,v 1.14 2005/07/01 23:51:55 uwe Exp $ */ + /* * Copyright (c) 2005 Dale Rahn <drahn@openbsd.org> * @@ -15,7 +16,6 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <sys/types.h> #include <sys/param.h> #include <sys/systm.h> #include <sys/device.h> @@ -36,6 +36,16 @@ #include <arm/xscale/pxa2x0_gpio.h> #include <arm/xscale/pxapcicvar.h> +int pxapcic_print(void *, const char *); +int pxapcic_submatch(struct device *, void *, void *); + +void pxapcic_create_event_thread(void *); +void pxapcic_event_thread(void *); +void pxapcic_event_process(struct pxapcic_socket *); +void pxapcic_attach_card(struct pxapcic_socket *); +void pxapcic_detach_card(struct pxapcic_socket *, int); +int pxapcic_intr(void *); + int pxapcic_mem_alloc(pcmcia_chipset_handle_t, bus_size_t, struct pcmcia_mem_handle *); void pxapcic_mem_free(pcmcia_chipset_handle_t, @@ -43,6 +53,7 @@ void pxapcic_mem_free(pcmcia_chipset_handle_t, int pxapcic_mem_map(pcmcia_chipset_handle_t, int, bus_addr_t, bus_size_t, struct pcmcia_mem_handle *, bus_addr_t *, int *); void pxapcic_mem_unmap(pcmcia_chipset_handle_t, int); + int pxapcic_io_alloc(pcmcia_chipset_handle_t, bus_addr_t, bus_size_t, bus_size_t, struct pcmcia_io_handle *); void pxapcic_io_free(pcmcia_chipset_handle_t, @@ -50,43 +61,23 @@ void pxapcic_io_free(pcmcia_chipset_handle_t, int pxapcic_io_map(pcmcia_chipset_handle_t, int, bus_addr_t, bus_size_t, struct pcmcia_io_handle *, int *); void pxapcic_io_unmap(pcmcia_chipset_handle_t, int); + void *pxapcic_intr_establish(pcmcia_chipset_handle_t, struct pcmcia_function *, int, int (*)(void *), void *, char *); void pxapcic_intr_disestablish(pcmcia_chipset_handle_t, void *); const char *pxapcic_intr_string(pcmcia_chipset_handle_t, void *); -void pxapcic_wait_ready(struct pxapcic_socket *); + +void pxapcic_socket_setup(struct pxapcic_socket *); void pxapcic_socket_enable(pcmcia_chipset_handle_t); void pxapcic_socket_disable(pcmcia_chipset_handle_t); -void pxapcic_event_thread(void *); - -void pxapcic_delay(int, const char *); - -int pxapcic_match(struct device *, void *, void *); -void pxapcic_attach(struct device *, struct device *, void *); -void pxapcic_create_event_thread(void *arg); -int pxapcic_submatch(struct device *parent, void *, void *aux); -int pxapcic_print(void *aux, const char *name); -int pxapcic_intr(void *arg); - -void pxapcic_event_process(struct pxapcic_socket *); - -void pxapcic_attach_card(struct pxapcic_socket *h); -void pxapcic_detach_card(struct pxapcic_socket *h, int flags); - -int pxapcic_intr_detect(void *arg); - -/* DON'T CONFIGURE CF slot 1 for now */ -#define NUM_CF_CARDS 2 - -struct cfattach pxapcic_ca = { - sizeof(struct pxapcic_softc), pxapcic_match, pxapcic_attach -}; - struct cfdriver pxapcic_cd = { NULL, "pxapcic", DV_DULL }; +/* + * PCMCIA chipset methods + */ struct pcmcia_chip_functions pxapcic_pcmcia_functions = { pxapcic_mem_alloc, pxapcic_mem_free, @@ -106,13 +97,13 @@ struct pcmcia_chip_functions pxapcic_pcmcia_functions = { pxapcic_socket_disable, }; - +/* + * PCMCIA Helpers + */ int -pxapcic_mem_alloc(pch, size, pmh) - pcmcia_chipset_handle_t pch; - bus_size_t size; - struct pcmcia_mem_handle *pmh; +pxapcic_mem_alloc(pcmcia_chipset_handle_t pch, bus_size_t size, + struct pcmcia_mem_handle *pmh) { struct pxapcic_socket *so = pch; @@ -123,21 +114,14 @@ pxapcic_mem_alloc(pch, size, pmh) } void -pxapcic_mem_free(pch, pmh) - pcmcia_chipset_handle_t pch; - struct pcmcia_mem_handle *pmh; +pxapcic_mem_free(pcmcia_chipset_handle_t pch, struct pcmcia_mem_handle *pmh) { } int -pxapcic_mem_map(pch, kind, card_addr, size, pmh, offsetp, windowp) - pcmcia_chipset_handle_t pch; - int kind; - bus_addr_t card_addr; - bus_size_t size; - struct pcmcia_mem_handle *pmh; - bus_addr_t *offsetp; - int *windowp; +pxapcic_mem_map(pcmcia_chipset_handle_t pch, int kind, bus_addr_t card_addr, + bus_size_t size, struct pcmcia_mem_handle *pmh, bus_addr_t *offsetp, + int *windowp) { struct pxapcic_socket *so = pch; int error; @@ -173,9 +157,7 @@ pxapcic_mem_map(pch, kind, card_addr, size, pmh, offsetp, windowp) } void -pxapcic_mem_unmap(pch, window) - pcmcia_chipset_handle_t pch; - int window; +pxapcic_mem_unmap(pcmcia_chipset_handle_t pch, int window) { struct pxapcic_socket *so = pch; @@ -183,12 +165,8 @@ pxapcic_mem_unmap(pch, window) } int -pxapcic_io_alloc(pch, start, size, align, pih) - pcmcia_chipset_handle_t pch; - bus_addr_t start; - bus_size_t size; - bus_size_t align; - struct pcmcia_io_handle *pih; +pxapcic_io_alloc(pcmcia_chipset_handle_t pch, bus_addr_t start, + bus_size_t size, bus_size_t align, struct pcmcia_io_handle *pih) { struct pxapcic_socket *so = pch; int error; @@ -214,9 +192,7 @@ pxapcic_io_alloc(pch, start, size, align, pih) } void -pxapcic_io_free(pch, pih) - pcmcia_chipset_handle_t pch; - struct pcmcia_io_handle *pih; +pxapcic_io_free(pcmcia_chipset_handle_t pch, struct pcmcia_io_handle *pih) { struct pxapcic_socket *so = pch; @@ -224,216 +200,219 @@ pxapcic_io_free(pch, pih) } int -pxapcic_io_map(pch, width, offset, size, pih, windowp) - pcmcia_chipset_handle_t pch; - int width; - bus_addr_t offset; - bus_size_t size; - struct pcmcia_io_handle *pih; - int *windowp; +pxapcic_io_map(pcmcia_chipset_handle_t pch, int width, bus_addr_t offset, + bus_size_t size, struct pcmcia_io_handle *pih, int *windowp) { return (0); } -void pxapcic_io_unmap(pch, window) - pcmcia_chipset_handle_t pch; - int window; +void pxapcic_io_unmap(pcmcia_chipset_handle_t pch, int window) { } void * -pxapcic_intr_establish(pch, pf, ipl, fct, arg, name) - pcmcia_chipset_handle_t pch; - struct pcmcia_function *pf; - int ipl; - int (*fct)(void *); - void *arg; - char *name; +pxapcic_intr_establish(pcmcia_chipset_handle_t pch, + struct pcmcia_function *pf, int ipl, int (*fct)(void *), void *arg, + char *name) { struct pxapcic_socket *so = pch; /* XXX need to check if something should be done here */ - return pxa2x0_gpio_intr_establish(so->irqpin, IST_EDGE_FALLING, - ipl, fct, arg, name); + return (pxa2x0_gpio_intr_establish(so->irqpin, IST_EDGE_FALLING, + ipl, fct, arg, name)); } void -pxapcic_intr_disestablish(pch, ih) - pcmcia_chipset_handle_t pch; - void *ih; +pxapcic_intr_disestablish(pcmcia_chipset_handle_t pch, void *ih) { pxa2x0_gpio_intr_disestablish(ih); } const char * -pxapcic_intr_string(pch, ih) - pcmcia_chipset_handle_t pch; - void *ih; -{ - return pxa2x0_gpio_intr_string(ih); -} - -void -pxapcic_wait_ready(so) - struct pxapcic_socket *so; +pxapcic_intr_string(pcmcia_chipset_handle_t pch, void *ih) { - bus_space_tag_t iot = so->sc->sc_iot; - int i; - - for (i = 0; i < 10000; i++) { - if (bus_space_read_2(iot, so->scooph, SCOOP_REG_CSR) & - SCP_CSR_READY) - return; - delay(500); -#ifdef PCICDEBUG - if ((i>5000) && (i%100 == 99)) - printf("."); -#endif - } - -#ifdef DIAGNOSTIC - printf("pxapcic_wait_ready: ready never happened, status = %02x\n", - bus_space_read_2(iot, so->scooph, SCOOP_REG_CSR)); -#endif + return (pxa2x0_gpio_intr_string(ih)); } void -pxapcic_socket_enable(pch) - pcmcia_chipset_handle_t pch; +pxapcic_socket_enable(pcmcia_chipset_handle_t pch) { struct pxapcic_socket *so = pch; - bus_space_tag_t iot = so->sc->sc_iot; - u_int16_t reg; - -#ifdef PCICDEBUG - printf("pxapcic_socket_enable: socket %d\n", so->socket); -#endif - - /* XXX fix scoop1 base address before trying that. */ - if (so->socket == 1) - return; - - /* XXX bit 2 was clear on boot with card preconfigured. */ - reg = bus_space_read_2(iot, so->scooph, SCOOP_REG_IRM); - bus_space_write_2(iot, so->scooph, SCOOP_REG_IRM, reg & ~0x0004); - - /* Enable CF socket 0 power. */ - if (so->socket == 0) { - reg = bus_space_read_2(iot, so->scooph, SCOOP_REG_GPWR); - bus_space_write_2(iot, so->scooph, SCOOP_REG_GPWR, - reg | (1<<6)); /* SCOOP0_CF_POWER_C3000 */ - } + int i; - /* XXX */ - reg = bus_space_read_2(iot, so->scooph, SCOOP_REG_CPR); - reg = reg & ~(SCP_CPR_PWR|SCP_CPR_5V|SCP_CPR_3V); - bus_space_write_2(iot, so->scooph, SCOOP_REG_CPR, reg); + /* Power down the card and socket before setting the voltage. */ + so->pcictag->write(so, PXAPCIC_CARD_POWER, PXAPCIC_POWER_OFF); + so->pcictag->set_power(so, PXAPCIC_POWER_OFF); /* - * wait 300ms until power fails (Tpf). Then, wait 100ms since + * Wait 300ms until power fails (Tpf). Then, wait 100ms since * we are changing Vcc (Toff). */ delay((300 + 100) * 1000); - /* Socket 1 supports only 5 V (which really is 3.3) for C3000? */ - reg = reg | (SCP_CPR_PWR|SCP_CPR_5V); - bus_space_write_2(iot, so->scooph, SCOOP_REG_CPR, reg); + /* Power up the socket and card at appropriate voltage. */ + if (so->power_capability & PXAPCIC_POWER_5V) { + so->pcictag->set_power(so, PXAPCIC_POWER_5V); + so->pcictag->write(so, PXAPCIC_CARD_POWER, + PXAPCIC_POWER_5V); + } else { + so->pcictag->set_power(so, PXAPCIC_POWER_3V); + so->pcictag->write(so, PXAPCIC_CARD_POWER, + PXAPCIC_POWER_3V); + } /* - * wait 100ms until power raise (Tpr) and 20ms to become + * Wait 100ms until power raise (Tpr) and 20ms to become * stable (Tsu(Vcc)). * - * some machines require some more time to be settled + * Some machines require some more time to be settled * (another 200ms is added here). */ delay((100 + 20 + 200) * 1000); - bus_space_write_2(iot, so->scooph, SCOOP_REG_CCR, SCP_CCR_RESET); + /* Hold RESET at least 10us. */ + so->pcictag->write(so, PXAPCIC_CARD_RESET, 1); delay(10); - bus_space_write_2(iot, so->scooph, SCOOP_REG_CCR, 0); - + so->pcictag->write(so, PXAPCIC_CARD_RESET, 0); - /* wait 20ms as per pc card standard (r2.01) section 4.3.6 */ - + /* Wait 20ms as per PC Card standard (r2.01) section 4.3.6. */ delay(20000); - pxapcic_wait_ready(so); - -#if 0 - printf("cardtype %d\n", h->pcmcia); + /* Wait for the card to become ready. */ + for (i = 0; i < 10000; i++) { + if (so->pcictag->read(so, PXAPCIC_CARD_READY)) + break; + delay(500); +#ifdef PCICDEBUG + if ((i>5000) && (i%100 == 99)) + printf("."); #endif + } } void -pxapcic_socket_disable(pch) - pcmcia_chipset_handle_t pch; +pxapcic_socket_disable(pcmcia_chipset_handle_t pch) { struct pxapcic_socket *so = pch; - bus_space_tag_t iot = so->sc->sc_iot; - u_int16_t reg; #ifdef PCICDEBUG printf("pxapcic_socket_disable: socket %d\n", so->socket); #endif - /* XXX fix scoop1 base address before trying that. */ - if (so->socket == 1) - return; + /* Power down the card and socket. */ + so->pcictag->write(so, PXAPCIC_CARD_POWER, PXAPCIC_POWER_OFF); + so->pcictag->set_power(so, PXAPCIC_POWER_OFF); +} - /* XXX */ - reg = bus_space_read_2(iot, so->scooph, SCOOP_REG_CPR); - reg = reg & ~(SCP_CPR_PWR|SCP_CPR_5V|SCP_CPR_3V); - bus_space_write_2(iot, so->scooph, SCOOP_REG_CPR, reg); +/* + * Attachment and initialization + */ - /* Disable CF socket 0 power. */ - if (so->socket == 0) { - reg = bus_space_read_2(iot, so->scooph, SCOOP_REG_GPWR); - bus_space_write_2(iot, so->scooph, SCOOP_REG_GPWR, - reg & ~(1<<6)); /* SCOOP0_CF_POWER_C3000 */ - } +int +pxapcic_print(void *aux, const char *name) +{ + return (UNCONF); } -#if 0 -void -pxapcic_socket_settype(pch, type) - pcmcia_chipset_handle_t pch; - int type; +int +pxapcic_submatch(struct device *parent, void *match, void *aux) { + struct cfdata *cf = match; - /* XXX */ + return ((*cf->cf_attach->ca_match)(parent, cf, aux)); } -#endif -#if 0 void -pxapcic_socket_setup(struct pxapcic_socket *sp) +pxapcic_attach(struct pxapcic_softc *sc, + void (*socket_setup_hook)(struct pxapcic_socket *)) { - /* - sp->power_capability = PXAPCIC_POWER_3V; - */ - sp->pcictag = &pxapcic_sacpcic_functions; -} -#endif + struct pcmciabus_attach_args paa; + struct pxapcic_socket *so; + int i; -#if 0 -void -pxapcic_set_power(struct pxapcic_socket *so, int arg) -{ - /* 3 volt only, not supported - XXX */ -} + printf(": %d slot%s\n", sc->sc_nslots, sc->sc_nslots==1 ? "" : "s"); + + /* zaurus: configure slot 1 first to make internal drive be wd0. */ + for (i = sc->sc_nslots-1; i >= 0; i--) { + so = &sc->sc_socket[i]; + so->sc = sc; + so->socket = i; + so->flags = 0; + + socket_setup_hook(so); + paa.paa_busname = "pcmcia"; + paa.pct = (pcmcia_chipset_tag_t)&pxapcic_pcmcia_functions; + paa.pch = (pcmcia_chipset_handle_t)so; + paa.iobase = 0; + paa.iosize = 0x4000000; + + so->pcmcia = config_found_sm(&sc->sc_dev, &paa, + pxapcic_print, pxapcic_submatch); + + pxa2x0_gpio_set_function(sc->sc_irqpin[i], GPIO_IN); + pxa2x0_gpio_set_function(sc->sc_irqcfpin[i], GPIO_IN); + + /* Card slot interrupt */ + so->irq = pxa2x0_gpio_intr_establish(sc->sc_irqcfpin[i], + IST_EDGE_BOTH, IPL_BIO /* XXX */, pxapcic_intr, so, + sc->sc_dev.dv_xname); + + /* GPIO pin for interrupt */ + so->irqpin = sc->sc_irqpin[i]; + +#ifdef DO_CONFIG_PENDING + config_pending_incr(); #endif + kthread_create_deferred(pxapcic_create_event_thread, so); + } +} + +/* + * Card slot interrupt handling + */ + int -pxapcic_match(struct device *parent, void *v, void *aux) +pxapcic_intr(void *arg) { + struct pxapcic_socket *so = arg; + + so->pcictag->clear_intr(so); + wakeup(so); return (1); -} +} + +/* + * Event management + */ + +void +pxapcic_create_event_thread(void *arg) +{ + struct pxapcic_socket *sock = arg; + struct pxapcic_softc *sc = sock->sc; + u_int cs; + + /* If there's a card there, attach it. */ + cs = sock->pcictag->read(sock, PXAPCIC_CARD_STATUS); + if (cs == PXAPCIC_CARD_VALID) + pxapcic_attach_card(sock); + + if (kthread_create(pxapcic_event_thread, sock, &sock->event_thread, + sc->sc_dev.dv_xname, sock->socket ? "1" : "0")) { + printf("%s: unable to create event thread for %s\n", + sc->sc_dev.dv_xname, sock->socket ? "1" : "0"); + } +#ifdef DO_CONFIG_PENDING + config_pending_decr(); +#endif +} void pxapcic_event_thread(void *arg) { struct pxapcic_socket *sock = arg; - u_int16_t csr; + u_int cs; int present; while (sock->sc->sc_shutdown == 0) { @@ -444,12 +423,11 @@ pxapcic_event_thread(void *arg) (void) tsleep((caddr_t)sock, PWAIT, "pxapcicss", hz/4); - csr = bus_space_read_2(sock->sc->sc_iot, sock->scooph, - SCOOP_REG_CSR); + cs = sock->pcictag->read(sock, PXAPCIC_CARD_STATUS); present = sock->flags & PXAPCIC_FLAG_CARDP; - if (((csr & SCP_CSR_MISSING) == 0) == (present == 1)) + if ((cs == PXAPCIC_CARD_VALID) == (present == 1)) continue; /* state unchanged */ /* XXX Do both? */ @@ -465,6 +443,22 @@ pxapcic_event_thread(void *arg) } void +pxapcic_event_process(struct pxapcic_socket *sock) +{ + u_int cs; + + cs = sock->pcictag->read(sock, PXAPCIC_CARD_STATUS); + + if (cs == PXAPCIC_CARD_VALID) { + if (!(sock->flags & PXAPCIC_FLAG_CARDP)) + pxapcic_attach_card(sock); + } else { + if ((sock->flags & PXAPCIC_FLAG_CARDP)) + pxapcic_detach_card(sock, DETACH_FORCE); + } +} + +void pxapcic_attach_card(struct pxapcic_socket *h) { if (h->flags & PXAPCIC_FLAG_CARDP) @@ -483,218 +477,5 @@ pxapcic_detach_card(struct pxapcic_socket *h, int flags) /* call the MI detach function */ pcmcia_card_detach(h->pcmcia, flags); - } else { - //DPRINTF(("pcic_detach_card: already detached")); - } -} - - -void pxapcic_event_process_st(void *h); -void -pxapcic_event_process_st(void *v) -{ - struct pxapcic_socket *h = v; - pxapcic_event_process(h); -} -void -pxapcic_event_process(sock) - struct pxapcic_socket *sock; -{ - struct pxapcic_softc *sc = sock->sc; - u_int16_t csr; - - csr = bus_space_read_2(sc->sc_iot, sock->scooph, SCOOP_REG_CSR); - - switch (csr & SCP_CSR_MISSING) { - case 0: /* PRESENT */ - //DPRINTF(("%s: insertion event\n", sock->sc->dv_xname)); - if (!(sock->flags & PXAPCIC_FLAG_CARDP)) - pxapcic_attach_card(sock); - break; - - case SCP_CSR_MISSING: - //DPRINTF(("%s: removal event\n", sock->sc->dv_xname)); - if ((sock->flags & PXAPCIC_FLAG_CARDP)) - pxapcic_detach_card(sock, DETACH_FORCE); - break; - } -} - -void -pxapcic_create_event_thread(void *arg) -{ - struct pxapcic_socket *sock = arg; - struct pxapcic_softc *sc = sock->sc; - u_int16_t csr; - - csr = bus_space_read_2(sc->sc_iot, sock->scooph, SCOOP_REG_CSR); - - /* if there's a card there, attach it */ - - switch (csr & SCP_CSR_MISSING) { - case 0: /* PRESENT */ - pxapcic_attach_card(sock); - break; - default: - ; - } - - if (kthread_create(pxapcic_event_thread, sock, &sock->event_thread, - sc->sc_dev.dv_xname, sock->socket ? "1" : "0")) { - printf("%s: unable to create event thread for %s\n", - sc->sc_dev.dv_xname, sock->socket ? "1" : "0"); - } -#ifdef DO_CONFIG_PENDING - config_pending_decr(); -#endif -} - -int -pxapcic_submatch(struct device *parent, void *match, void *aux) -{ - struct cfdata *cf = match; - - return ((*cf->cf_attach->ca_match)(parent, cf, aux)); - -} - -int -pxapcic_print(void *aux, const char *name) -{ - return (UNCONF); -} - - -void -pxapcic_attach(struct device *parent, struct device *self, void *aux) -{ - struct pcmciabus_attach_args paa; - struct pxapcic_softc *sc = (struct pxapcic_softc *)self; - struct pxaip_attach_args *pxa = aux; - struct pxapcic_socket *so; - bus_space_tag_t iot; - bus_space_handle_t scooph; - int i; - int error; - bus_addr_t pa; - bus_size_t size = 0x100; - - iot = sc->sc_iot = pxa->pxa_iot; - - sc->sc_shutdown = 0; - - printf("\n"); - - /* - * should be model based not processor based, and in zaurus/... - * not arm/xscale - */ - if ((cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA27X) { -#define C3000_CF0_IRQ 105 -#define C3000_CF1_IRQ 106 -#define C3000_CF0_CD 94 -#define C3000_CF1_CD 93 - sc->sc_nslots = 2; - sc->sc_irqpin[0] = C3000_CF0_IRQ; - sc->sc_irqcfpin[0] = C3000_CF0_CD; - sc->sc_irqpin[1] = C3000_CF1_IRQ; - sc->sc_irqcfpin[1] = C3000_CF1_CD; - } else { -#define C860_CF0_IRQ 17 -#define C860_CF0_CD 14 - /* C860 */ - sc->sc_nslots = 1; - sc->sc_irqpin[0] = C860_CF0_IRQ; - sc->sc_irqcfpin[0] = C860_CF0_CD; } - - for(i = 0; i < NUM_CF_CARDS; i++) { - so = &sc->sc_socket[i]; - so->sc = sc; - so->socket = i; - so->flags = 0; - - /* scoop? */ - if (so->socket == 0) - pa = 0x10800000; - else if (so->socket == 1) - pa = 0x14800000; /* 0x08800040 */ - else { - printf ("%s: invalid CF slot %d\n", sc->sc_dev.dv_xname, - i); - continue; - } - error = bus_space_map(iot, pa, size, 0, &scooph); - if (error) { - printf ("%s%d: failed to map memory %x for scoop\n", - sc->sc_dev.dv_xname, i, pa); - continue; - } - so->scooph = scooph; - - bus_space_write_2(iot, scooph, SCOOP_REG_IMR, 0x00c0); - - /* setup */ - bus_space_write_2(iot, scooph, SCOOP_REG_MCR, 0x0100); - bus_space_write_2(iot, scooph, SCOOP_REG_CDR, 0x0000); - bus_space_write_2(iot, scooph, SCOOP_REG_CPR, 0x0000); - bus_space_write_2(iot, scooph, SCOOP_REG_IMR, 0x0000); - bus_space_write_2(iot, scooph, SCOOP_REG_IRM, 0x00ff); - bus_space_write_2(iot, scooph, SCOOP_REG_ISR, 0x0000); - bus_space_write_2(iot, scooph, SCOOP_REG_IRM, 0x0000); - - bus_space_write_2(iot, scooph, SCOOP_REG_CPR, - SCP_CPR_PWR|SCP_CPR_5V); /* 5 V for 3000? */ - - - paa.paa_busname = "pcmcia"; - paa.pct = (pcmcia_chipset_tag_t) &pxapcic_pcmcia_functions; - paa.pch = (pcmcia_chipset_handle_t)&sc->sc_socket[i]; - paa.iobase = 0; - paa.iosize = 0x4000000; - - so->pcmcia = config_found_sm(&sc->sc_dev, &paa, pxapcic_print, - pxapcic_submatch); - } - - /* configure slot 1 first to make internal drive be wd0 */ - for (i = sc->sc_nslots-1; i >= 0; i--) { - so = &sc->sc_socket[i]; - pxa2x0_gpio_set_function(sc->sc_irqpin[i], GPIO_IN); - pxa2x0_gpio_set_function(sc->sc_irqcfpin[i], GPIO_IN); - - sc->sc_socket[i].irq = pxa2x0_gpio_intr_establish( - sc->sc_irqcfpin[i], - IST_EDGE_BOTH, IPL_BIO /* XXX */, pxapcic_intr_detect, - so, sc->sc_dev.dv_xname); - - /* GPIO pin for interrupt */ - sc->sc_socket[i].irqpin = sc->sc_irqpin[i]; - - bus_space_write_2(iot, so->scooph, SCOOP_REG_IMR, 0x00ce); - bus_space_write_2(iot, so->scooph, SCOOP_REG_MCR, 0x0111); - -#ifdef DO_CONFIG_PENDING - config_pending_incr(); -#endif - kthread_create_deferred(pxapcic_create_event_thread, so); - } -} - -int -pxapcic_intr_detect(void *arg) -{ - struct pxapcic_socket *so = arg; - bus_space_tag_t iot; - - iot = so->sc->sc_iot; - - /* - (so->pcictag->clear_intr)(so->socket); - */ - bus_space_write_2(iot, so->scooph, SCOOP_REG_IRM, 0x00ff); - bus_space_write_2(iot, so->scooph, SCOOP_REG_ISR, 0x0000); - bus_space_write_2(iot, so->scooph, SCOOP_REG_IRM, 0x0000); - wakeup(so); - return 1; } diff --git a/sys/arch/arm/xscale/pxapcicvar.h b/sys/arch/arm/xscale/pxapcicvar.h index d1f8654b02e..fc7e9a78591 100644 --- a/sys/arch/arm/xscale/pxapcicvar.h +++ b/sys/arch/arm/xscale/pxapcicvar.h @@ -1,4 +1,5 @@ -/* $OpenBSD: pxapcicvar.h,v 1.5 2005/02/23 00:08:16 drahn Exp $ */ +/* $OpenBSD: pxapcicvar.h,v 1.6 2005/07/01 23:51:55 uwe Exp $ */ + /* * Copyright (c) 2005 Dale Rahn <drahn@openbsd.org> * @@ -17,39 +18,49 @@ struct pxapcic_socket { struct pxapcic_softc *sc; - int socket; /* socket number */ + int socket; /* socket number */ struct device *pcmcia; struct proc *event_thread; - bus_space_handle_t scooph; - int flags; + int power_capability; /* PXAPCIC_POWER_3V | PXAPCIC_POWER_5V */ - int power_capability; int irqpin; void *irq; - void *pcictag_cookie; /* opaque data for pcictag functions */ + void *pcictag_cookie; /* opaque data for pcictag functions */ + struct pxapcic_tag *pcictag; }; /* event */ -#define PXAPCIC_EVENT_INSERTION 0 -#define PXAPCIC_EVENT_REMOVAL 1 +#define PXAPCIC_EVENT_INSERTION 0 +#define PXAPCIC_EVENT_REMOVAL 1 -/* laststatus */ -#define PXAPCIC_FLAG_CARDD 0 -#define PXAPCIC_FLAG_CARDP 1 +/* flags */ +#define PXAPCIC_FLAG_CARDD 0 +#define PXAPCIC_FLAG_CARDP 1 struct pxapcic_tag { - int (*read)(struct pxapcic_socket *, int); - void (*write)(struct pxapcic_socket *, int, int); + u_int (*read)(struct pxapcic_socket *, int); + void (*write)(struct pxapcic_socket *, int, u_int); void (*set_power)(struct pxapcic_socket *, int); - void (*clear_intr)(int); + void (*clear_intr)(struct pxapcic_socket *); void *(*intr_establish)(struct pxapcic_socket *, int, int (*)(void *), void *); void (*intr_disestablish)(struct pxapcic_socket *, void *); + const char *(*intr_string)(struct pxapcic_socket *); }; +/* pcictag registers and their values */ +#define PXAPCIC_CARD_STATUS 0 +#define PXAPCIC_CARD_INVALID 0 +#define PXAPCIC_CARD_VALID 1 +#define PXAPCIC_CARD_READY 1 +#define PXAPCIC_CARD_POWER 2 +#define PXAPCIC_POWER_OFF 0 +#define PXAPCIC_POWER_3V 1 +#define PXAPCIC_POWER_5V 2 +#define PXAPCIC_CARD_RESET 3 struct pxapcic_softc { struct device sc_dev; @@ -64,43 +75,6 @@ struct pxapcic_softc { int sc_irqcfpin[2]; }; - -#define SCOOP_REG_MCR 0x00 -#define SCOOP_REG_CDR 0x04 -#define SCOOP_REG_CSR 0x08 -#define SCOOP_REG_CPR 0x0C -#define SCOOP_REG_CCR 0x10 -#define SCOOP_REG_IRR 0x14 -#define SCOOP_REG_IRM 0x14 -#define SCOOP_REG_IMR 0x18 -#define SCOOP_REG_ISR 0x1C -#define SCOOP_REG_GPCR 0x20 -#define SCOOP_REG_GPWR 0x24 -#define SCOOP_REG_GPRR 0x28 - -#define SCP_CDR_DETECT 0x0002 - -#define SCP_CSR_READY 0x0002 -#define SCP_CSR_MISSING 0x0004 -#define SCP_CSR_WPROT 0x0008 -#define SCP_CSR_BVD1 0x0010 -#define SCP_CSR_BVD2 0x0020 -#define SCP_CSR_3V 0x0040 -#define SCP_CSR_PWR 0x0080 - -#define SCP_CPR_OFF 0x0000 -#define SCP_CPR_3V 0x0001 -#define SCP_CPR_5V 0x0002 -#define SCP_CPR_PWR 0x0080 - - -#define SCP_MCR_IOCARD 0x0010 -#define SCP_CCR_RESET 0x0080 - -#define SCP_IMR_READY 0x0002 -#define SCP_IMR_DETECT 0x0004 -#define SCP_IMR_WRPROT 0x0008 -#define SCP_IMR_STSCHG 0x0010 -#define SCP_IMR_BATWARN 0x0020 -#define SCP_IMR_UNKN0 0x0040 -#define SCP_IMR_UNKN1 0x0080 +void pxapcic_attach(struct pxapcic_softc *, + void (*socket_setup_hook)(struct pxapcic_socket *)); +int pxapcic_intr(void *); diff --git a/sys/arch/zaurus/conf/files.zaurus b/sys/arch/zaurus/conf/files.zaurus index b235e85dfa1..5257b66812a 100644 --- a/sys/arch/zaurus/conf/files.zaurus +++ b/sys/arch/zaurus/conf/files.zaurus @@ -1,4 +1,4 @@ -# $OpenBSD: files.zaurus,v 1.19 2005/06/16 21:30:12 uwe Exp $ +# $OpenBSD: files.zaurus,v 1.20 2005/07/01 23:51:55 uwe Exp $ # # First try for arm-specific configuration info # @@ -33,11 +33,15 @@ device zkbd: wskbddev attach zkbd at pxaip file arch/zaurus/dev/zaurus_kbd.c zkbd -# Onboard peripheral and GPIO controller +# 16-bit GPIO controller device scoop -attach scoop at pxaip with scoop_pxaip +attach scoop at pxaip file arch/zaurus/dev/zaurus_scoop.c scoop +# PCMCIA/CF socket controller +attach pxapcic at pxaip with pxapcic_scoop +file arch/zaurus/dev/scoop_pcic.c pxapcic_scoop + # Dedicated SSP unit for ADC, touch screen, and backlight device zssp attach zssp at pxaip diff --git a/sys/arch/zaurus/dev/scoop_pcic.c b/sys/arch/zaurus/dev/scoop_pcic.c new file mode 100644 index 00000000000..b663fc567a4 --- /dev/null +++ b/sys/arch/zaurus/dev/scoop_pcic.c @@ -0,0 +1,252 @@ +/* $OpenBSD: scoop_pcic.c,v 1.1 2005/07/01 23:51:55 uwe Exp $ */ + +/* + * Copyright (c) 2005 Uwe Stuehler <uwe@bsdx.de> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <uvm/uvm.h> + +#include <arch/arm/xscale/pxa2x0var.h> +#include <arch/arm/xscale/pxapcicvar.h> + +#include <machine/zaurus_reg.h> +#include <machine/zaurus_var.h> + +#include <zaurus/dev/zaurus_scoopreg.h> + +int scoop_pcic_match(struct device *, void *, void *); +void scoop_pcic_attach(struct device *, struct device *, void *); +void scoop_pcic_socket_setup(struct pxapcic_socket *); + +struct cfattach pxapcic_scoop_ca = { + sizeof(struct pxapcic_softc), scoop_pcic_match, + scoop_pcic_attach +}; + +u_int scoop_pcic_read(struct pxapcic_socket *, int); +void scoop_pcic_write(struct pxapcic_socket *, int, u_int); +void scoop_pcic_set_power(struct pxapcic_socket *, int); +void scoop_pcic_clear_intr(struct pxapcic_socket *); + +struct pxapcic_tag scoop_pcic_functions = { + scoop_pcic_read, + scoop_pcic_write, + scoop_pcic_set_power, + scoop_pcic_clear_intr, + 0, /* intr_establish */ + 0, /* intr_disestablish */ + 0 /* intr_string */ +}; + +int +scoop_pcic_match(struct device *parent, void *cf, void *aux) +{ + return (ZAURUS_ISC860 || ZAURUS_ISC3000); +} + +void +scoop_pcic_attach(struct device *parent, struct device *self, void *aux) +{ + struct pxapcic_softc *sc = (struct pxapcic_softc *)self; + struct pxaip_attach_args *pxa = aux; + + sc->sc_iot = pxa->pxa_iot; + + if (ZAURUS_ISC860) { + sc->sc_nslots = 1; + sc->sc_irqpin[0] = C860_CF0_IRQ; + sc->sc_irqcfpin[0] = C860_CF0_IRQ_PIN; + } else if (ZAURUS_ISC3000) { + sc->sc_nslots = 2; + sc->sc_irqpin[0] = C3000_CF0_IRQ; + sc->sc_irqcfpin[0] = C3000_CF0_IRQ_PIN; + sc->sc_irqpin[1] = C3000_CF1_IRQ; + sc->sc_irqcfpin[1] = C3000_CF1_IRQ_PIN; + } + + pxapcic_attach(sc, &scoop_pcic_socket_setup); +} + +void +scoop_pcic_socket_setup(struct pxapcic_socket *so) +{ + struct pxapcic_softc *sc; + bus_addr_t pa; + bus_size_t size = SCOOP_SIZE; + bus_space_tag_t iot; + bus_space_handle_t scooph; + int error; + + sc = so->sc; + iot = sc->sc_iot; + + if (so->socket == 0) + pa = C3000_SCOOP0_BASE; + else if (so->socket == 1) + pa = C3000_SCOOP1_BASE; + else + panic("%s: invalid CF slot %d", sc->sc_dev.dv_xname, + so->socket); + error = bus_space_map(iot, trunc_page(pa), round_page(size), + 0, &scooph); + if (error) + panic("%s: failed to map memory %x for scoop", + sc->sc_dev.dv_xname, pa); + scooph += pa - trunc_page(pa); + + bus_space_write_2(iot, scooph, SCOOP_IMR, + SCP_IMR_UNKN0 | SCP_IMR_UNKN1); + + /* setup */ + bus_space_write_2(iot, scooph, SCOOP_MCR, 0x0100); + bus_space_write_2(iot, scooph, SCOOP_CDR, 0x0000); + bus_space_write_2(iot, scooph, SCOOP_CPR, 0x0000); + bus_space_write_2(iot, scooph, SCOOP_IMR, 0x0000); + bus_space_write_2(iot, scooph, SCOOP_IRM, 0x00ff); + bus_space_write_2(iot, scooph, SCOOP_ISR, 0x0000); + bus_space_write_2(iot, scooph, SCOOP_IRM, 0x0000); + + /* C3000 */ + if (so->socket == 1) { + bus_space_write_2(iot, scooph, SCOOP_CPR, 0x80c1); + bus_space_write_2(iot, scooph, SCOOP_IMR, 0x00c4); + bus_space_write_2(iot, scooph, SCOOP_MCR, 0x0111); + } else { + bus_space_write_2(iot, scooph, SCOOP_CPR, + SCP_CPR_PWR|SCP_CPR_5V); + } + + bus_space_write_2(iot, scooph, SCOOP_IMR, 0x00ce); + bus_space_write_2(iot, scooph, SCOOP_MCR, 0x0111); + + /* C3000 */ + so->power_capability = PXAPCIC_POWER_3V; + if (so->socket == 0) + so->power_capability |= PXAPCIC_POWER_5V; + + so->pcictag_cookie = (void *)scooph; + so->pcictag = &scoop_pcic_functions; +} + +u_int +scoop_pcic_read(struct pxapcic_socket *so, int reg) +{ + bus_space_tag_t iot = so->sc->sc_iot; + bus_space_handle_t ioh = (bus_space_handle_t)so->pcictag_cookie; + u_int16_t csr; + + csr = bus_space_read_2(iot, ioh, SCOOP_CSR); + + switch (reg) { + case PXAPCIC_CARD_STATUS: + if (csr & SCP_CSR_MISSING) + return (PXAPCIC_CARD_INVALID); + else + return (PXAPCIC_CARD_VALID); + + case PXAPCIC_CARD_READY: + return ((bus_space_read_2(iot, ioh, SCOOP_CSR) & + SCP_CSR_READY) != 0); + + default: + panic("scoop_pcic_read: bogus register"); + } +} + +void +scoop_pcic_write(struct pxapcic_socket *so, int reg, u_int val) +{ + bus_space_tag_t iot = so->sc->sc_iot; + bus_space_handle_t ioh = (bus_space_handle_t)so->pcictag_cookie; + u_int16_t newval; + int s; + + s = splhigh(); + + switch (reg) { + case PXAPCIC_CARD_POWER: + newval = bus_space_read_2(iot, ioh, SCOOP_CPR); + newval &= ~(SCP_CPR_PWR | SCP_CPR_3V | SCP_CPR_5V); + + if (val == PXAPCIC_POWER_3V) + newval |= (SCP_CPR_PWR | SCP_CPR_3V); + else if (val == PXAPCIC_POWER_5V) + newval |= (SCP_CPR_PWR | SCP_CPR_5V); + + bus_space_write_2(iot, ioh, SCOOP_CPR, newval); + break; + + case PXAPCIC_CARD_RESET: + bus_space_write_2(iot, ioh, SCOOP_CCR, + val ? SCP_CCR_RESET : 0); + break; + + default: + panic("scoop_pcic_write: bogus register"); + } + + splx(s); +} + +void +scoop_pcic_set_power(struct pxapcic_socket *so, int pwr) +{ + bus_space_tag_t iot = so->sc->sc_iot; + bus_space_handle_t ioh = (bus_space_handle_t)so->pcictag_cookie; + u_int16_t reg; + int s; + + s = splhigh(); + + switch (pwr) { + case PXAPCIC_POWER_OFF: +#if 0 + /* XXX does this disable power to both sockets? */ + reg = bus_space_read_2(iot, ioh, SCOOP_GPWR); + bus_space_write_2(iot, ioh, SCOOP_GPWR, + reg & ~(1 << SCOOP0_CF_POWER_C3000)); +#endif + break; + + case PXAPCIC_POWER_3V: + case PXAPCIC_POWER_5V: + /* XXX */ + if (so->socket == 0) { + reg = bus_space_read_2(iot, ioh, SCOOP_GPWR); + bus_space_write_2(iot, ioh, SCOOP_GPWR, + reg | (1 << SCOOP0_CF_POWER_C3000)); + } + break; + + default: + splx(s); + panic("scoop_pcic_set_power: bogus power state"); + } + + splx(s); +} + +void +scoop_pcic_clear_intr(struct pxapcic_socket *so) +{ + bus_space_tag_t iot = so->sc->sc_iot; + bus_space_handle_t ioh = (bus_space_handle_t)so->pcictag_cookie; + + bus_space_write_2(iot, ioh, SCOOP_IRM, 0x00ff); + bus_space_write_2(iot, ioh, SCOOP_ISR, 0x0000); + bus_space_write_2(iot, ioh, SCOOP_IRM, 0x0000); +} diff --git a/sys/arch/zaurus/dev/zaurus_scoop.c b/sys/arch/zaurus/dev/zaurus_scoop.c index 60347e5c1ad..197a74020d3 100644 --- a/sys/arch/zaurus/dev/zaurus_scoop.c +++ b/sys/arch/zaurus/dev/zaurus_scoop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: zaurus_scoop.c,v 1.10 2005/05/23 22:44:57 pascoe Exp $ */ +/* $OpenBSD: zaurus_scoop.c,v 1.11 2005/07/01 23:51:55 uwe Exp $ */ /* * Copyright (c) 2005 Uwe Stuehler <uwe@bsdx.de> @@ -25,6 +25,9 @@ #include <arm/xscale/pxa2x0var.h> +#include <machine/zaurus_reg.h> +#include <machine/zaurus_var.h> + #include <zaurus/dev/zaurus_scoopreg.h> #include <zaurus/dev/zaurus_scoopvar.h> @@ -38,7 +41,7 @@ struct scoop_softc { int scoopmatch(struct device *, void *, void *); void scoopattach(struct device *, struct device *, void *); -struct cfattach scoop_pxaip_ca = { +struct cfattach scoop_ca = { sizeof (struct scoop_softc), scoopmatch, scoopattach }; @@ -57,10 +60,9 @@ scoopmatch(struct device *parent, void *match, void *aux) struct cfdata *cf = match; /* - * Only the C3000 models (pxa270) are known to have two SCOOPs, - * on other models we only find the first one. + * Only C3000-like models are known to have two SCOOPs. */ - if ((cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA27X) + if (ZAURUS_ISC3000) return (cf->cf_unit < 2); return (cf->cf_unit == 0); @@ -79,9 +81,9 @@ scoopattach(struct device *parent, struct device *self, void *aux) if (pxa->pxa_addr != -1) addr = pxa->pxa_addr; else if (sc->sc_dev.dv_unit == 0) - addr = SCOOP0_BASE; + addr = C3000_SCOOP0_BASE; else - addr = SCOOP1_BASE; + addr = C3000_SCOOP1_BASE; size = pxa->pxa_size < SCOOP_SIZE ? SCOOP_SIZE : pxa->pxa_size; @@ -90,7 +92,7 @@ scoopattach(struct device *parent, struct device *self, void *aux) return; } - printf(": Onboard Peripheral Controller\n"); + printf(": PCMCIA/GPIO controller\n"); } int diff --git a/sys/arch/zaurus/dev/zaurus_scoopreg.h b/sys/arch/zaurus/dev/zaurus_scoopreg.h index e430f99f9fd..c2aa000147a 100644 --- a/sys/arch/zaurus/dev/zaurus_scoopreg.h +++ b/sys/arch/zaurus/dev/zaurus_scoopreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: zaurus_scoopreg.h,v 1.6 2005/03/08 23:29:06 uwe Exp $ */ +/* $OpenBSD: zaurus_scoopreg.h,v 1.7 2005/07/01 23:51:55 uwe Exp $ */ /* * Copyright (c) 2005 Uwe Stuehler <uwe@bsdx.de> @@ -16,22 +16,43 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#define SCOOP0_BASE 0x10800000 -#define SCOOP1_BASE 0x08800040 -#define SCOOP_SIZE 0x2c +#define SCOOP_SIZE 0x2c -#define SCOOP_MCR 0x00 /* (R/W) */ -#define SCOOP_CDR 0x04 /* (R?/W) */ -#define SCOOP_CSR 0x08 /* card status register (R) */ -#define SCOOP_CPR 0x0c /* card power register (R/W) */ -#define SCOOP_CCR 0x10 /* card configuration reg.? (R/W) */ -#define SCOOP_IRR 0x14 /* XXX for pcic: bit 0x4 role is? */ -#define SCOOP_IRM 0x14 -#define SCOOP_IMR 0x18 /* (R/W) */ -#define SCOOP_ISR 0x1c -#define SCOOP_GPCR 0x20 /* GPIO pin direction (R/W) */ -#define SCOOP_GPWR 0x24 /* GPIO pin output level (R/W) */ -#define SCOOP_GPRR 0x28 +/* registers and values */ + +#define SCOOP_MCR 0x00 +#define SCP_MCR_IOCARD 0x0010 +#define SCOOP_CDR 0x04 /* card detect register */ +#define SCP_CDR_DETECT 0x0002 +#define SCOOP_CSR 0x08 /* card status register */ +#define SCP_CSR_READY 0x0002 +#define SCP_CSR_MISSING 0x0004 +#define SCP_CSR_WPROT 0x0008 +#define SCP_CSR_BVD1 0x0010 +#define SCP_CSR_BVD2 0x0020 +#define SCP_CSR_3V 0x0040 +#define SCP_CSR_PWR 0x0080 +#define SCOOP_CPR 0x0c /* card power register */ +#define SCP_CPR_OFF 0x0000 +#define SCP_CPR_3V 0x0001 +#define SCP_CPR_5V 0x0002 +#define SCP_CPR_PWR 0x0080 +#define SCOOP_CCR 0x10 /* card control register */ +#define SCP_CCR_RESET 0x0080 +#define SCOOP_IRR 0x14 /* XXX for pcic: bit 0x4 role is? */ +#define SCOOP_IRM 0x14 +#define SCOOP_IMR 0x18 +#define SCP_IMR_READY 0x0002 +#define SCP_IMR_DETECT 0x0004 +#define SCP_IMR_WRPROT 0x0008 +#define SCP_IMR_STSCHG 0x0010 +#define SCP_IMR_BATWARN 0x0020 +#define SCP_IMR_UNKN0 0x0040 +#define SCP_IMR_UNKN1 0x0080 +#define SCOOP_ISR 0x1c +#define SCOOP_GPCR 0x20 /* GPIO pin direction (R/W) */ +#define SCOOP_GPWR 0x24 /* GPIO pin output level (R/W) */ +#define SCOOP_GPRR 0x28 /* GPIO pin input level (R) */ /* GPIO bits */ |