Commit 0960a1f6 authored by Russell King's avatar Russell King

[ARM] SA11x0 PCMCIA 3

Make low level socket_status() method take the socket index as an
argument in the same way that our other methods do.  socket_status()
now only returns the status of the requested socket, not all sockets.
parent 44760e52
...@@ -69,25 +69,20 @@ static int assabet_pcmcia_shutdown(void) ...@@ -69,25 +69,20 @@ static int assabet_pcmcia_shutdown(void)
return 0; return 0;
} }
static int static void
assabet_pcmcia_socket_state(struct pcmcia_state_array *state_array) assabet_pcmcia_socket_state(int sock, struct pcmcia_state *state)
{ {
unsigned long levels; unsigned long levels = GPLR;
if (state_array->size < 2)
return -1;
levels = GPLR;
state_array->state[1].detect = (levels & ASSABET_GPIO_CF_CD) ? 0 : 1; if (sock == 1) {
state_array->state[1].ready = (levels & ASSABET_GPIO_CF_IRQ) ? 1 : 0; state->detect = (levels & ASSABET_GPIO_CF_CD) ? 0 : 1;
state_array->state[1].bvd1 = (levels & ASSABET_GPIO_CF_BVD1) ? 1 : 0; state->ready = (levels & ASSABET_GPIO_CF_IRQ) ? 1 : 0;
state_array->state[1].bvd2 = (levels & ASSABET_GPIO_CF_BVD2) ? 1 : 0; state->bvd1 = (levels & ASSABET_GPIO_CF_BVD1) ? 1 : 0;
state_array->state[1].wrprot = 0; /* Not available on Assabet. */ state->bvd2 = (levels & ASSABET_GPIO_CF_BVD2) ? 1 : 0;
state_array->state[1].vs_3v = 1; /* Can only apply 3.3V on Assabet. */ state->wrprot = 0; /* Not available on Assabet. */
state_array->state[1].vs_Xv = 0; state->vs_3v = 1; /* Can only apply 3.3V on Assabet. */
state->vs_Xv = 0;
return 1; }
} }
static int assabet_pcmcia_get_irq_info(struct pcmcia_irq_info *info) static int assabet_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
......
...@@ -66,24 +66,19 @@ static int cerf_pcmcia_shutdown(void) ...@@ -66,24 +66,19 @@ static int cerf_pcmcia_shutdown(void)
return 0; return 0;
} }
static int cerf_pcmcia_socket_state(struct pcmcia_state_array static void cerf_pcmcia_socket_state(int sock, struct pcmcia_state *state)
*state_array){ {
unsigned long levels; unsigned long levels=GPLR;
int i = CERF_SOCKET;
if (sock == CERF_SOCKET) {
if(state_array->size<2) return -1; state->detect=((levels & GPIO_CF_CD)==0)?1:0;
state->ready=(levels & GPIO_CF_IRQ)?1:0;
levels=GPLR; state->bvd1=(levels & GPIO_CF_BVD1)?1:0;
state->bvd2=(levels & GPIO_CF_BVD2)?1:0;
state_array->state[i].detect=((levels & GPIO_CF_CD)==0)?1:0; state->wrprot=0;
state_array->state[i].ready=(levels & GPIO_CF_IRQ)?1:0; state->vs_3v=1;
state_array->state[i].bvd1=(levels & GPIO_CF_BVD1)?1:0; state->vs_Xv=0;
state_array->state[i].bvd2=(levels & GPIO_CF_BVD2)?1:0; }
state_array->state[i].wrprot=0;
state_array->state[i].vs_3v=1;
state_array->state[i].vs_Xv=0;
return 1;
} }
static int cerf_pcmcia_get_irq_info(struct pcmcia_irq_info *info){ static int cerf_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
......
...@@ -88,35 +88,31 @@ static int flexanet_pcmcia_shutdown(void) ...@@ -88,35 +88,31 @@ static int flexanet_pcmcia_shutdown(void)
* Sockets in Flexanet are 3.3V only, without BVD2. * Sockets in Flexanet are 3.3V only, without BVD2.
* *
*/ */
static int flexanet_pcmcia_socket_state(struct pcmcia_state_array static void flexanet_pcmcia_socket_state(int sock, struct pcmcia_state *state)
*state_array){ {
unsigned long levels; unsigned long levels = GPLR; /* Sense the GPIOs, asynchronously */
if (state_array->size < 2) switch (sock) {
return -1; case 0: /* Socket 0 */
state->detect = ((levels & GPIO_CF1_NCD)==0)?1:0;
state->ready = (levels & GPIO_CF1_IRQ)?1:0;
state->bvd1 = (levels & GPIO_CF1_BVD1)?1:0;
state->bvd2 = 1;
state->wrprot = 0;
state->vs_3v = 1;
state->vs_Xv = 0;
break;
/* Sense the GPIOs, asynchronously */ case 1: /* Socket 1 */
levels = GPLR; state->detect = ((levels & GPIO_CF2_NCD)==0)?1:0;
state->ready = (levels & GPIO_CF2_IRQ)?1:0;
/* Socket 0 */ state->bvd1 = (levels & GPIO_CF2_BVD1)?1:0;
state_array->state[0].detect = ((levels & GPIO_CF1_NCD)==0)?1:0; state->bvd2 = 1;
state_array->state[0].ready = (levels & GPIO_CF1_IRQ)?1:0; state->wrprot = 0;
state_array->state[0].bvd1 = (levels & GPIO_CF1_BVD1)?1:0; state->vs_3v = 1;
state_array->state[0].bvd2 = 1; state->vs_Xv = 0;
state_array->state[0].wrprot = 0; break;
state_array->state[0].vs_3v = 1; }
state_array->state[0].vs_Xv = 0;
/* Socket 1 */
state_array->state[1].detect = ((levels & GPIO_CF2_NCD)==0)?1:0;
state_array->state[1].ready = (levels & GPIO_CF2_IRQ)?1:0;
state_array->state[1].bvd1 = (levels & GPIO_CF2_BVD1)?1:0;
state_array->state[1].bvd2 = 1;
state_array->state[1].wrprot = 0;
state_array->state[1].vs_3v = 1;
state_array->state[1].vs_Xv = 0;
return 1;
} }
......
...@@ -75,34 +75,20 @@ static int freebird_pcmcia_shutdown(void) ...@@ -75,34 +75,20 @@ static int freebird_pcmcia_shutdown(void)
return 0; return 0;
} }
static int freebird_pcmcia_socket_state(struct pcmcia_state_array static void freebird_pcmcia_socket_state(int sock, struct pcmcia_state *state)
*state_array){ {
unsigned long levels; unsigned long levels = LINKUP_PRS;
if(state_array->size<2) return -1;
memset(state_array->state, 0,
(state_array->size)*sizeof(struct pcmcia_state));
levels = LINKUP_PRS;
//printk("LINKUP_PRS=%x\n",levels); //printk("LINKUP_PRS=%x\n",levels);
state_array->state[0].detect= if (sock == 0) {
((levels & (LINKUP_CD1 | LINKUP_CD2))==0)?1:0; state->detect = ((levels & (LINKUP_CD1 | LINKUP_CD2))==0)?1:0;
state->ready = (levels & LINKUP_RDY)?1:0;
state_array->state[0].ready=(levels & LINKUP_RDY)?1:0; state->bvd1 = (levels & LINKUP_BVD1)?1:0;
state->bvd2 = (levels & LINKUP_BVD2)?1:0;
state_array->state[0].bvd1=(levels & LINKUP_BVD1)?1:0; state->wrprot = 0; /* Not available on Assabet. */
state->vs_3v = 1; /* Can only apply 3.3V on Assabet. */
state_array->state[0].bvd2=(levels & LINKUP_BVD2)?1:0; state->vs_Xv = 0;
}
state_array->state[0].wrprot=0; /* Not available on Assabet. */
state_array->state[0].vs_3v=1; /* Can only apply 3.3V on Assabet. */
state_array->state[0].vs_Xv=0;
return 1;
} }
static int freebird_pcmcia_get_irq_info(struct pcmcia_irq_info *info){ static int freebird_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
......
...@@ -292,40 +292,33 @@ sa1100_pcmcia_events(struct pcmcia_state *state, ...@@ -292,40 +292,33 @@ sa1100_pcmcia_events(struct pcmcia_state *state,
*/ */
static void sa1100_pcmcia_task_handler(void *data) static void sa1100_pcmcia_task_handler(void *data)
{ {
struct pcmcia_state state[SA1100_PCMCIA_MAX_SOCK]; struct pcmcia_state state;
struct pcmcia_state_array state_array;
unsigned int all_events; unsigned int all_events;
DEBUG(4, "%s(): entering PCMCIA monitoring thread\n", __FUNCTION__); DEBUG(4, "%s(): entering PCMCIA monitoring thread\n", __FUNCTION__);
state_array.size = sa1100_pcmcia_socket_count;
state_array.state = state;
do { do {
unsigned int events; unsigned int events;
int ret, i; int i;
memset(state, 0, sizeof(state));
DEBUG(4, "%s(): interrogating low-level PCMCIA service\n", __FUNCTION__); DEBUG(4, "%s(): interrogating low-level PCMCIA service\n", __FUNCTION__);
ret = pcmcia_low_level->socket_state(&state_array);
if (ret < 0) {
printk(KERN_ERR "sa1100_pcmcia: unable to read socket status\n");
break;
}
all_events = 0; all_events = 0;
for (i = 0; i < state_array.size; i++, all_events |= events) { for (i = 0; i < sa1100_pcmcia_socket_count; i++) {
struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(i); struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(i);
events = sa1100_pcmcia_events(&state[i], &skt->k_state, memset(&state, 0, sizeof(state));
skt->ops->socket_state(skt->nr, &state);
events = sa1100_pcmcia_events(&state, &skt->k_state,
skt->cs_state.csc_mask, skt->cs_state.csc_mask,
skt->cs_state.flags); skt->cs_state.flags);
if (events && sa1100_pcmcia_socket[i].handler != NULL) if (events && skt->handler != NULL)
skt->handler(skt->handler_info, events); skt->handler(skt->handler_info, events);
all_events |= events;
} }
} while(all_events); } while(all_events);
} /* sa1100_pcmcia_task_handler() */ } /* sa1100_pcmcia_task_handler() */
...@@ -469,28 +462,20 @@ static int ...@@ -469,28 +462,20 @@ static int
sa1100_pcmcia_get_status(unsigned int sock, unsigned int *status) sa1100_pcmcia_get_status(unsigned int sock, unsigned int *status)
{ {
struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock); struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
struct pcmcia_state state[SA1100_PCMCIA_MAX_SOCK]; struct pcmcia_state state;
struct pcmcia_state_array state_array;
unsigned int stat; unsigned int stat;
DEBUG(2, "%s() for sock %u\n", __FUNCTION__, skt->nr); DEBUG(2, "%s() for sock %u\n", __FUNCTION__, skt->nr);
state_array.size = sa1100_pcmcia_socket_count; memset(&state, 0, sizeof(state));
state_array.state = state;
memset(state, 0, sizeof(state)); skt->ops->socket_state(skt->nr, &state);
skt->k_state = state;
if ((pcmcia_low_level->socket_state(&state_array)) < 0) {
printk(KERN_ERR "sa1100_pcmcia: unable to get socket status\n");
return -1;
}
skt->k_state = state[sock]; stat = state.detect ? SS_DETECT : 0;
stat |= state.ready ? SS_READY : 0;
stat = state[sock].detect ? SS_DETECT : 0; stat |= state.vs_3v ? SS_3VCARD : 0;
stat |= state[sock].ready ? SS_READY : 0; stat |= state.vs_Xv ? SS_XVCARD : 0;
stat |= state[sock].vs_3v ? SS_3VCARD : 0;
stat |= state[sock].vs_Xv ? SS_XVCARD : 0;
/* The power status of individual sockets is not available /* The power status of individual sockets is not available
* explicitly from the hardware, so we just remember the state * explicitly from the hardware, so we just remember the state
...@@ -499,11 +484,11 @@ sa1100_pcmcia_get_status(unsigned int sock, unsigned int *status) ...@@ -499,11 +484,11 @@ sa1100_pcmcia_get_status(unsigned int sock, unsigned int *status)
stat |= skt->cs_state.Vcc ? SS_POWERON : 0; stat |= skt->cs_state.Vcc ? SS_POWERON : 0;
if (skt->cs_state.flags & SS_IOCARD) if (skt->cs_state.flags & SS_IOCARD)
stat |= state[sock].bvd1 ? SS_STSCHG : 0; stat |= state.bvd1 ? SS_STSCHG : 0;
else { else {
if (state[sock].bvd1 == 0) if (state.bvd1 == 0)
stat |= SS_BATDEAD; stat |= SS_BATDEAD;
else if (state[sock].bvd2 == 0) else if (state.bvd2 == 0)
stat |= SS_BATWARN; stat |= SS_BATWARN;
} }
...@@ -960,24 +945,11 @@ int sa1100_register_pcmcia(struct pcmcia_low_level *ops) ...@@ -960,24 +945,11 @@ int sa1100_register_pcmcia(struct pcmcia_low_level *ops)
ret = ops->init(&pcmcia_init); ret = ops->init(&pcmcia_init);
if (ret < 0) { if (ret < 0) {
printk(KERN_ERR "Unable to initialize kernel PCMCIA service (%d).\n", ret); printk(KERN_ERR "Unable to initialize kernel PCMCIA service (%d).\n", ret);
if (ret == -1)
ret = -EIO;
goto out; goto out;
} }
sa1100_pcmcia_socket_count = ret; sa1100_pcmcia_socket_count = ret;
state_array.size = ret;
state_array.state = state;
memset(state, 0, sizeof(state));
if (ops->socket_state(&state_array) < 0) {
printk(KERN_ERR "Unable to get PCMCIA status driver.\n");
ret = -EIO;
goto shutdown;
}
cpu_clock = cpufreq_get(0); cpu_clock = cpufreq_get(0);
/* /*
...@@ -1002,7 +974,6 @@ int sa1100_register_pcmcia(struct pcmcia_low_level *ops) ...@@ -1002,7 +974,6 @@ int sa1100_register_pcmcia(struct pcmcia_low_level *ops)
skt->nr = i; skt->nr = i;
skt->ops = ops; skt->ops = ops;
skt->irq = irq_info.irq; skt->irq = irq_info.irq;
skt->k_state = state[i];
skt->speed_io = SA1100_PCMCIA_IO_ACCESS; skt->speed_io = SA1100_PCMCIA_IO_ACCESS;
skt->speed_attr = SA1100_PCMCIA_5V_MEM_ACCESS; skt->speed_attr = SA1100_PCMCIA_5V_MEM_ACCESS;
skt->speed_mem = SA1100_PCMCIA_5V_MEM_ACCESS; skt->speed_mem = SA1100_PCMCIA_5V_MEM_ACCESS;
...@@ -1015,6 +986,7 @@ int sa1100_register_pcmcia(struct pcmcia_low_level *ops) ...@@ -1015,6 +986,7 @@ int sa1100_register_pcmcia(struct pcmcia_low_level *ops)
goto out_err; goto out_err;
} }
ops->socket_state(skt->nr, &skt->k_state);
sa1100_pcmcia_set_mecr(skt, cpu_clock); sa1100_pcmcia_set_mecr(skt, cpu_clock);
} }
......
...@@ -31,11 +31,6 @@ struct pcmcia_state { ...@@ -31,11 +31,6 @@ struct pcmcia_state {
vs_Xv: 1; vs_Xv: 1;
}; };
struct pcmcia_state_array {
unsigned int size;
struct pcmcia_state *state;
};
struct pcmcia_configure { struct pcmcia_configure {
unsigned vcc: 8, unsigned vcc: 8,
vpp: 8, vpp: 8,
...@@ -53,7 +48,7 @@ struct pcmcia_irq_info { ...@@ -53,7 +48,7 @@ struct pcmcia_irq_info {
struct pcmcia_low_level { struct pcmcia_low_level {
int (*init)(struct pcmcia_init *); int (*init)(struct pcmcia_init *);
int (*shutdown)(void); int (*shutdown)(void);
int (*socket_state)(struct pcmcia_state_array *); void (*socket_state)(int sock, struct pcmcia_state *);
int (*get_irq_info)(struct pcmcia_irq_info *); int (*get_irq_info)(struct pcmcia_irq_info *);
int (*configure_socket)(int sock, const struct pcmcia_configure *); int (*configure_socket)(int sock, const struct pcmcia_configure *);
......
...@@ -72,33 +72,31 @@ static int h3600_pcmcia_shutdown(void) ...@@ -72,33 +72,31 @@ static int h3600_pcmcia_shutdown(void)
return 0; return 0;
} }
static int static void h3600_pcmcia_socket_state(int sock, struct pcmcia_state *state)
h3600_pcmcia_socket_state(struct pcmcia_state_array *state)
{ {
unsigned long levels; unsigned long levels = GPLR;
if (state->size < 2) switch (sock) {
return -1; case 0:
state->detect = levels & GPIO_H3600_PCMCIA_CD0 ? 0 : 1;
state->ready = levels & GPIO_H3600_PCMCIA_IRQ0 ? 1 : 0;
state->bvd1 = 0;
state->bvd2 = 0;
state->wrprot = 0; /* Not available on H3600. */
state->vs_3v = 0;
state->vs_Xv = 0;
break;
levels = GPLR; case 1:
state->detect = levels & GPIO_H3600_PCMCIA_CD1 ? 0 : 1;
state->state[0].detect = levels & GPIO_H3600_PCMCIA_CD0 ? 0 : 1; state->ready = levels & GPIO_H3600_PCMCIA_IRQ1 ? 1 : 0;
state->state[0].ready = levels & GPIO_H3600_PCMCIA_IRQ0 ? 1 : 0; state->bvd1 = 0;
state->state[0].bvd1 = 0; state->bvd2 = 0;
state->state[0].bvd2 = 0; state->wrprot = 0; /* Not available on H3600. */
state->state[0].wrprot = 0; /* Not available on H3600. */ state->vs_3v = 0;
state->state[0].vs_3v = 0; state->vs_Xv = 0;
state->state[0].vs_Xv = 0; break;
}
state->state[1].detect = levels & GPIO_H3600_PCMCIA_CD1 ? 0 : 1;
state->state[1].ready = levels & GPIO_H3600_PCMCIA_IRQ1 ? 1 : 0;
state->state[1].bvd1 = 0;
state->state[1].bvd2 = 0;
state->state[1].wrprot = 0; /* Not available on H3600. */
state->state[1].vs_3v = 0;
state->state[1].vs_Xv = 0;
return 1;
} }
static int h3600_pcmcia_get_irq_info(struct pcmcia_irq_info *info) static int h3600_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
......
...@@ -57,34 +57,19 @@ static int pangolin_pcmcia_shutdown(void) ...@@ -57,34 +57,19 @@ static int pangolin_pcmcia_shutdown(void)
return 0; return 0;
} }
static int pangolin_pcmcia_socket_state(struct pcmcia_state_array static void pangolin_pcmcia_socket_state(int sock, struct pcmcia_state *state)
*state_array){ {
unsigned long levels; unsigned long levels = GPLR;;
if(state_array->size<2) return -1; if (sock == PANGOLIN_SOCK) {
state->detect=((levels & GPIO_PCMCIA_CD)==0)?1:0;
memset(state_array->state, 0, state->ready=(levels & GPIO_PCMCIA_IRQ)?1:0;
(state_array->size)*sizeof(struct pcmcia_state)); state->bvd1=1; /* Not available on Pangolin. */
state->bvd2=1; /* Not available on Pangolin. */
levels=GPLR; state->wrprot=0; /* Not available on Pangolin. */
#ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE state->vs_3v=1; /* Can only apply 3.3V on Pangolin. */
state_array->state[1].detect=((levels & GPIO_PCMCIA_CD)==0)?1:0; state->vs_Xv=0;
state_array->state[1].ready=(levels & GPIO_PCMCIA_IRQ)?1:0; }
state_array->state[1].bvd1=1; /* Not available on Pangolin. */
state_array->state[1].bvd2=1; /* Not available on Pangolin. */
state_array->state[1].wrprot=0; /* Not available on Pangolin. */
state_array->state[1].vs_3v=1; /* Can only apply 3.3V on Pangolin. */
state_array->state[1].vs_Xv=0;
#else
state_array->state[0].detect=((levels & GPIO_PCMCIA_CD)==0)?1:0;
state_array->state[0].ready=(levels & GPIO_PCMCIA_IRQ)?1:0;
state_array->state[0].bvd1=1; /* Not available on Pangolin. */
state_array->state[0].bvd2=1; /* Not available on Pangolin. */
state_array->state[0].wrprot=0; /* Not available on Pangolin. */
state_array->state[0].vs_3v=0; /* voltage level is determined by jumper setting */
state_array->state[0].vs_Xv=0;
#endif
return 1;
} }
static int pangolin_pcmcia_get_irq_info(struct pcmcia_irq_info *info){ static int pangolin_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
......
...@@ -68,32 +68,31 @@ static int shannon_pcmcia_shutdown(void) ...@@ -68,32 +68,31 @@ static int shannon_pcmcia_shutdown(void)
return 0; return 0;
} }
static int shannon_pcmcia_socket_state(struct pcmcia_state_array *state_array) static void shannon_pcmcia_socket_state(int sock, struct pcmcia_state *state)
{ {
unsigned long levels; unsigned long levels = GPLR;
memset(state_array->state, 0, switch (sock) {
state_array->size * sizeof(struct pcmcia_state)); case 0:
state->detect = (levels & SHANNON_GPIO_EJECT_0) ? 0 : 1;
levels = GPLR; state->ready = (levels & SHANNON_GPIO_RDY_0) ? 1 : 0;
state->wrprot = 0; /* Not available on Shannon. */
state_array->state[0].detect = (levels & SHANNON_GPIO_EJECT_0) ? 0 : 1; state->bvd1 = 1;
state_array->state[0].ready = (levels & SHANNON_GPIO_RDY_0) ? 1 : 0; state->bvd2 = 1;
state_array->state[0].wrprot = 0; /* Not available on Shannon. */ state->vs_3v = 1; /* FIXME Can only apply 3.3V on Shannon. */
state_array->state[0].bvd1 = 1; state->vs_Xv = 0;
state_array->state[0].bvd2 = 1; break;
state_array->state[0].vs_3v = 1; /* FIXME Can only apply 3.3V on Shannon. */
state_array->state[0].vs_Xv = 0; case 1:
state->detect = (levels & SHANNON_GPIO_EJECT_1) ? 0 : 1;
state_array->state[1].detect = (levels & SHANNON_GPIO_EJECT_1) ? 0 : 1; state->ready = (levels & SHANNON_GPIO_RDY_1) ? 1 : 0;
state_array->state[1].ready = (levels & SHANNON_GPIO_RDY_1) ? 1 : 0; state->wrprot = 0; /* Not available on Shannon. */
state_array->state[1].wrprot = 0; /* Not available on Shannon. */ state->bvd1 = 1;
state_array->state[1].bvd1 = 1; state->bvd2 = 1;
state_array->state[1].bvd2 = 1; state->vs_3v = 1; /* FIXME Can only apply 3.3V on Shannon. */
state_array->state[1].vs_3v = 1; /* FIXME Can only apply 3.3V on Shannon. */ state->vs_Xv = 0;
state_array->state[1].vs_Xv = 0; break;
}
return 1;
} }
static int shannon_pcmcia_get_irq_info(struct pcmcia_irq_info *info) static int shannon_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
......
...@@ -58,39 +58,26 @@ static int simpad_pcmcia_shutdown(void) ...@@ -58,39 +58,26 @@ static int simpad_pcmcia_shutdown(void)
return 0; return 0;
} }
static int simpad_pcmcia_socket_state(struct pcmcia_state_array static void simpad_pcmcia_socket_state(int sock, struct pcmcia_state *state)
*state_array)
{ {
unsigned long levels; if (sock == 1) {
unsigned long levels = GPLR;
unsigned long *cs3reg = CS3_BASE; unsigned long *cs3reg = CS3_BASE;
if(state_array->size<2) return -1; state->detect=((levels & GPIO_CF_CD)==0)?1:0;
state->ready=(levels & GPIO_CF_IRQ)?1:0;
memset(state_array->state, 0, state->bvd1=1; /* Not available on Simpad. */
(state_array->size)*sizeof(struct pcmcia_state)); state->bvd2=1; /* Not available on Simpad. */
state->wrprot=0; /* Not available on Simpad. */
levels=GPLR;
state_array->state[1].detect=((levels & GPIO_CF_CD)==0)?1:0;
state_array->state[1].ready=(levels & GPIO_CF_IRQ)?1:0;
state_array->state[1].bvd1=1; /* Not available on Simpad. */
state_array->state[1].bvd2=1; /* Not available on Simpad. */
state_array->state[1].wrprot=0; /* Not available on Simpad. */
if((*cs3reg & 0x0c) == 0x0c) { if((*cs3reg & 0x0c) == 0x0c) {
state_array->state[1].vs_3v=0; state->vs_3v=0;
state_array->state[1].vs_Xv=0; state->vs_Xv=0;
} else } else {
{ state->vs_3v=1;
state_array->state[1].vs_3v=1; state->vs_Xv=0;
state_array->state[1].vs_Xv=0; }
} }
return 1;
} }
static int simpad_pcmcia_get_irq_info(struct pcmcia_irq_info *info){ static int simpad_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
......
...@@ -87,36 +87,35 @@ static int stork_pcmcia_shutdown(void) ...@@ -87,36 +87,35 @@ static int stork_pcmcia_shutdown(void)
return 0; return 0;
} }
static int stork_pcmcia_socket_state(struct pcmcia_state_array *state_array) static void stork_pcmcia_socket_state(int sock, struct pcmcia_state *state)
{ {
unsigned long levels; unsigned long levels = GPLR;
if(state_array->size<2) return -1; if (debug > 1)
printk(__FUNCTION__ " GPLR=%x IRQ[1:0]=%x\n", levels,
memset(state_array->state, 0, (levels & (GPIO_STORK_PCMCIA_A_RDY|GPIO_STORK_PCMCIA_B_RDY)));
(state_array->size)*sizeof(struct pcmcia_state));
levels=GPLR; switch (sock) {
case 0:
state->detect=((levels & GPIO_STORK_PCMCIA_A_CARD_DETECT)==0)?1:0;
state->ready=(levels & GPIO_STORK_PCMCIA_A_RDY)?1:0;
state->bvd1= 1;
state->bvd2= 1;
state->wrprot=0;
state->vs_3v=1;
state->vs_Xv=0;
break;
if (debug > 1) case 1:
printk(__FUNCTION__ " GPLR=%x IRQ[1:0]=%x\n", GPLR, (GPLR & (GPIO_STORK_PCMCIA_A_RDY|GPIO_STORK_PCMCIA_B_RDY))); state->detect=((levels & GPIO_STORK_PCMCIA_B_CARD_DETECT)==0)?1:0;
state_array->state[0].detect=((levels & GPIO_STORK_PCMCIA_A_CARD_DETECT)==0)?1:0; state->ready=(levels & GPIO_STORK_PCMCIA_B_RDY)?1:0;
state_array->state[0].ready=(levels & GPIO_STORK_PCMCIA_A_RDY)?1:0; state->bvd1=1;
state_array->state[0].bvd1= 1; state->bvd2=1;
state_array->state[0].bvd2= 1; state->wrprot=0;
state_array->state[0].wrprot=0; state->vs_3v=1;
state_array->state[0].vs_3v=1; state->vs_Xv=0;
state_array->state[0].vs_Xv=0; break;
}
state_array->state[1].detect=((levels & GPIO_STORK_PCMCIA_B_CARD_DETECT)==0)?1:0;
state_array->state[1].ready=(levels & GPIO_STORK_PCMCIA_B_RDY)?1:0;
state_array->state[1].bvd1=1;
state_array->state[1].bvd2=1;
state_array->state[1].wrprot=0;
state_array->state[1].vs_3v=1;
state_array->state[1].vs_Xv=0;
return 1;
} }
static int stork_pcmcia_get_irq_info(struct pcmcia_irq_info *info) static int stork_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
......
...@@ -66,40 +66,36 @@ int system3_pcmcia_configure_socket(int sock, const struct pcmcia_configure *con ...@@ -66,40 +66,36 @@ int system3_pcmcia_configure_socket(int sock, const struct pcmcia_configure *con
return sa1111_pcmcia_configure_socket(sock, conf); return sa1111_pcmcia_configure_socket(sock, conf);
} }
static int system3_pcmcia_socket_state(struct pcmcia_state_array static void system3_pcmcia_socket_state(int sock, struct pcmcia_state *state)
*state)
{ {
unsigned long status = 0; unsigned long status = PCSR;
if(state->size<2) return -1;
memset(state->state, 0,
(state->size)*sizeof(struct pcmcia_state));
status=PCSR;
switch (sock) {
#if 0 /* PCMCIA socket not yet connected */ #if 0 /* PCMCIA socket not yet connected */
state->state[0].detect = status & PCSR_S0_DETECT ? 0 : 1; case 0:
state->state[0].ready = status & PCSR_S0_READY ? 1 : 0; state->detect = status & PCSR_S0_DETECT ? 0 : 1;
state->state[0].bvd1 = status & PCSR_S0_BVD1 ? 1 : 0; state->ready = status & PCSR_S0_READY ? 1 : 0;
state->state[0].bvd2 = 1; state->bvd1 = status & PCSR_S0_BVD1 ? 1 : 0;
state->state[0].wrprot = status & PCSR_S0_WP ? 1 : 0; state->bvd2 = 1;
state->state[0].vs_3v = 1; state->wrprot = status & PCSR_S0_WP ? 1 : 0;
state->state[0].vs_Xv = 0; state->vs_3v = 1;
state->vs_Xv = 0;
break;
#endif #endif
state->state[1].detect = status & PCSR_S1_DETECT ? 0 : 1; case 1:
state->state[1].ready = status & PCSR_S1_READY ? 1 : 0; state->detect = status & PCSR_S1_DETECT ? 0 : 1;
state->state[1].bvd1 = status & PCSR_S1_BVD1 ? 1 : 0; state->ready = status & PCSR_S1_READY ? 1 : 0;
state->state[1].bvd2 = 1; state->bvd1 = status & PCSR_S1_BVD1 ? 1 : 0;
state->state[1].wrprot = status & PCSR_S1_WP ? 1 : 0; state->bvd2 = 1;
state->state[1].vs_3v = 1; state->wrprot = status & PCSR_S1_WP ? 1 : 0;
state->state[1].vs_Xv = 0; state->vs_3v = 1;
state->vs_Xv = 0;
DPRINTK( "PCSR=0x%08lx, S1_RDY_nIREQ=%d\n", status, break;
state->state[1].ready ); }
return 1; DPRINTK("Sock %d PCSR=0x%08lx, Sx_RDY_nIREQ=%d\n",
sock, status, state->ready);
} }
struct pcmcia_low_level system3_pcmcia_ops = { struct pcmcia_low_level system3_pcmcia_ops = {
......
...@@ -79,26 +79,19 @@ static int trizeps_pcmcia_shutdown(void) ...@@ -79,26 +79,19 @@ static int trizeps_pcmcia_shutdown(void)
* *
******************************************************/ ******************************************************/
static int trizeps_pcmcia_socket_state(struct pcmcia_state_array static void trizeps_pcmcia_socket_state(int sock, struct pcmcia_state *state_array)
*state_array){ {
unsigned long levels; unsigned long levels = GPLR;
if (state_array->size < NUMBER_OF_TRIZEPS_PCMCIA_SLOTS) return -1; if (sock == 0) {
state->detect = ((levels & GPIO_GPIO(TRIZEPS_GPIO_PCMCIA_CD0)) == 0) ? 1 : 0;
memset(state_array->state, 0, state->ready = ((levels & GPIO_GPIO(TRIZEPS_GPIO_PCMCIA_IRQ0)) != 0) ? 1 : 0;
(state_array->size)*sizeof(struct pcmcia_state)); state->bvd1 = ((TRIZEPS_BCR1 & TRIZEPS_PCM_BVD1) !=0 ) ? 1 : 0;
state->bvd2 = ((TRIZEPS_BCR1 & TRIZEPS_PCM_BVD2) != 0) ? 1 : 0;
levels = GPLR; state->wrprot = 0; // not write protected
state->vs_3v = ((TRIZEPS_BCR1 & TRIZEPS_nPCM_VS1) == 0) ? 1 : 0; //VS1=0 -> vs_3v=1
state_array->state[0].detect = ((levels & GPIO_GPIO(TRIZEPS_GPIO_PCMCIA_CD0)) == 0) ? 1 : 0; state->vs_Xv = ((TRIZEPS_BCR1 & TRIZEPS_nPCM_VS2) == 0) ? 1 : 0; //VS2=0 -> vs_Xv=1
state_array->state[0].ready = ((levels & GPIO_GPIO(TRIZEPS_GPIO_PCMCIA_IRQ0)) != 0) ? 1 : 0; }
state_array->state[0].bvd1 = ((TRIZEPS_BCR1 & TRIZEPS_PCM_BVD1) !=0 ) ? 1 : 0;
state_array->state[0].bvd2 = ((TRIZEPS_BCR1 & TRIZEPS_PCM_BVD2) != 0) ? 1 : 0;
state_array->state[0].wrprot = 0; // not write protected
state_array->state[0].vs_3v = ((TRIZEPS_BCR1 & TRIZEPS_nPCM_VS1) == 0) ? 1 : 0; //VS1=0 -> vs_3v=1
state_array->state[0].vs_Xv = ((TRIZEPS_BCR1 & TRIZEPS_nPCM_VS2) == 0) ? 1 : 0; //VS2=0 -> vs_Xv=1
return 1; // success
} }
/** /**
......
...@@ -80,27 +80,19 @@ static int yopy_pcmcia_shutdown(void) ...@@ -80,27 +80,19 @@ static int yopy_pcmcia_shutdown(void)
return 0; return 0;
} }
static int yopy_pcmcia_socket_state(struct pcmcia_state_array *state_array) static void yopy_pcmcia_socket_state(int sock, struct pcmcia_state_array *state)
{ {
unsigned long levels; unsigned long levels = GPLR;
if (state_array->size != 1) if (sock == 0) {
return -1; state->detect = (levels & GPIO_CF_CD) ? 0 : 1;
state->ready = (levels & GPIO_CF_READY) ? 1 : 0;
memset(state_array->state, 0, state->bvd1 = (levels & GPIO_CF_BVD1) ? 1 : 0;
state_array->size * sizeof(struct pcmcia_state)); state->bvd2 = (levels & GPIO_CF_BVD2) ? 1 : 0;
state->wrprot = 0; /* Not available on Yopy. */
levels = GPLR; state->vs_3v = 0; /* FIXME Can only apply 3.3V on Yopy. */
state->vs_Xv = 0;
state_array->state[0].detect = (levels & GPIO_CF_CD) ? 0 : 1; }
state_array->state[0].ready = (levels & GPIO_CF_READY) ? 1 : 0;
state_array->state[0].bvd1 = (levels & GPIO_CF_BVD1) ? 1 : 0;
state_array->state[0].bvd2 = (levels & GPIO_CF_BVD2) ? 1 : 0;
state_array->state[0].wrprot = 0; /* Not available on Yopy. */
state_array->state[0].vs_3v = 0; /* FIXME Can only apply 3.3V on Yopy. */
state_array->state[0].vs_Xv = 0;
return 1;
} }
static int yopy_pcmcia_get_irq_info(struct pcmcia_irq_info *info) static int yopy_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
......
...@@ -63,32 +63,31 @@ int sa1111_pcmcia_shutdown(void) ...@@ -63,32 +63,31 @@ int sa1111_pcmcia_shutdown(void)
return 0; return 0;
} }
int sa1111_pcmcia_socket_state(struct pcmcia_state_array *state) void sa1111_pcmcia_socket_state(int sock, struct pcmcia_state *state)
{ {
unsigned long status; unsigned long status = sa1111_readl(pcmcia->mapbase + SA1111_PCSR);
if (state->size < 2) switch (sock) {
return -1; case 0:
state->detect = status & PCSR_S0_DETECT ? 0 : 1;
state->ready = status & PCSR_S0_READY ? 1 : 0;
state->bvd1 = status & PCSR_S0_BVD1 ? 1 : 0;
state->bvd2 = status & PCSR_S0_BVD2 ? 1 : 0;
state->wrprot = status & PCSR_S0_WP ? 1 : 0;
state->vs_3v = status & PCSR_S0_VS1 ? 0 : 1;
state->vs_Xv = status & PCSR_S0_VS2 ? 0 : 1;
break;
status = sa1111_readl(pcmcia->mapbase + SA1111_PCSR); case 1:
state->detect = status & PCSR_S1_DETECT ? 0 : 1;
state->state[0].detect = status & PCSR_S0_DETECT ? 0 : 1; state->ready = status & PCSR_S1_READY ? 1 : 0;
state->state[0].ready = status & PCSR_S0_READY ? 1 : 0; state->bvd1 = status & PCSR_S1_BVD1 ? 1 : 0;
state->state[0].bvd1 = status & PCSR_S0_BVD1 ? 1 : 0; state->bvd2 = status & PCSR_S1_BVD2 ? 1 : 0;
state->state[0].bvd2 = status & PCSR_S0_BVD2 ? 1 : 0; state->wrprot = status & PCSR_S1_WP ? 1 : 0;
state->state[0].wrprot = status & PCSR_S0_WP ? 1 : 0; state->vs_3v = status & PCSR_S1_VS1 ? 0 : 1;
state->state[0].vs_3v = status & PCSR_S0_VS1 ? 0 : 1; state->vs_Xv = status & PCSR_S1_VS2 ? 0 : 1;
state->state[0].vs_Xv = status & PCSR_S0_VS2 ? 0 : 1; break;
}
state->state[1].detect = status & PCSR_S1_DETECT ? 0 : 1;
state->state[1].ready = status & PCSR_S1_READY ? 1 : 0;
state->state[1].bvd1 = status & PCSR_S1_BVD1 ? 1 : 0;
state->state[1].bvd2 = status & PCSR_S1_BVD2 ? 1 : 0;
state->state[1].wrprot = status & PCSR_S1_WP ? 1 : 0;
state->state[1].vs_3v = status & PCSR_S1_VS1 ? 0 : 1;
state->state[1].vs_Xv = status & PCSR_S1_VS2 ? 0 : 1;
return 1;
} }
int sa1111_pcmcia_get_irq_info(struct pcmcia_irq_info *info) int sa1111_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
......
extern int sa1111_pcmcia_init(struct pcmcia_init *); extern int sa1111_pcmcia_init(struct pcmcia_init *);
extern int sa1111_pcmcia_shutdown(void); extern int sa1111_pcmcia_shutdown(void);
extern int sa1111_pcmcia_socket_state(struct pcmcia_state_array *); extern void sa1111_pcmcia_socket_state(int sock, struct pcmcia_state *);
extern int sa1111_pcmcia_get_irq_info(struct pcmcia_irq_info *); extern int sa1111_pcmcia_get_irq_info(struct pcmcia_irq_info *);
extern int sa1111_pcmcia_configure_socket(int sock, const struct pcmcia_configure *); extern int sa1111_pcmcia_configure_socket(int sock, const struct pcmcia_configure *);
extern int sa1111_pcmcia_socket_init(int); extern int sa1111_pcmcia_socket_init(int);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment