summaryrefslogtreecommitdiff
path: root/sys/arch/arm
diff options
context:
space:
mode:
authorUwe Stuehler <uwe@cvs.openbsd.org>2005-07-01 23:51:56 +0000
committerUwe Stuehler <uwe@cvs.openbsd.org>2005-07-01 23:51:56 +0000
commit420968103d6f70617afff7176732e5a22c1e80f2 (patch)
tree88731b79b91f3c44cbaec77833a1068040792ec3 /sys/arch/arm
parentfcfbf526bc30d43ed9ab3d24457e6abc683e9443 (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/arch/arm')
-rw-r--r--sys/arch/arm/xscale/files.pxa2x03
-rw-r--r--sys/arch/arm/xscale/pxa2x0_pcic.c591
-rw-r--r--sys/arch/arm/xscale/pxapcicvar.h82
3 files changed, 215 insertions, 461 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 *);