|
@@ -10,26 +10,78 @@
|
|
|
#include <linux/interrupt.h>
|
|
|
#include <linux/init.h>
|
|
|
#include <linux/delay.h>
|
|
|
+#include <linux/gpio.h>
|
|
|
|
|
|
#include <mach/hardware.h>
|
|
|
#include <asm/irq.h>
|
|
|
#include <asm/mach-types.h>
|
|
|
#include <mach/h3600.h>
|
|
|
+#include <mach/h3600_gpio.h>
|
|
|
|
|
|
#include "sa1100_generic.h"
|
|
|
|
|
|
static struct pcmcia_irqs irqs[] = {
|
|
|
- { 0, IRQ_GPIO_H3600_PCMCIA_CD0, "PCMCIA CD0" },
|
|
|
- { 1, IRQ_GPIO_H3600_PCMCIA_CD1, "PCMCIA CD1" }
|
|
|
+ { .sock = 0, .str = "PCMCIA CD0" }, /* .irq will be filled later */
|
|
|
+ { .sock = 1, .str = "PCMCIA CD1" }
|
|
|
};
|
|
|
|
|
|
static int h3600_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
|
|
|
{
|
|
|
- skt->socket.pci_irq = skt->nr ? IRQ_GPIO_H3600_PCMCIA_IRQ1
|
|
|
- : IRQ_GPIO_H3600_PCMCIA_IRQ0;
|
|
|
+ int err;
|
|
|
|
|
|
+ switch (skt->nr) {
|
|
|
+ case 0:
|
|
|
+ err = gpio_request(H3XXX_GPIO_PCMCIA_IRQ0, "PCMCIA IRQ0");
|
|
|
+ if (err)
|
|
|
+ goto err00;
|
|
|
+ err = gpio_direction_input(H3XXX_GPIO_PCMCIA_IRQ0);
|
|
|
+ if (err)
|
|
|
+ goto err01;
|
|
|
+ skt->socket.pci_irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_IRQ0);
|
|
|
+
|
|
|
+ err = gpio_request(H3XXX_GPIO_PCMCIA_CD0, "PCMCIA CD0");
|
|
|
+ if (err)
|
|
|
+ goto err01;
|
|
|
+ err = gpio_direction_input(H3XXX_GPIO_PCMCIA_CD0);
|
|
|
+ if (err)
|
|
|
+ goto err02;
|
|
|
+ irqs[0].irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_CD0);
|
|
|
+
|
|
|
+ err = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
|
|
|
+ if (err)
|
|
|
+ goto err02;
|
|
|
+ break;
|
|
|
+ case 1:
|
|
|
+ err = gpio_request(H3XXX_GPIO_PCMCIA_IRQ1, "PCMCIA IRQ1");
|
|
|
+ if (err)
|
|
|
+ goto err10;
|
|
|
+ err = gpio_direction_input(H3XXX_GPIO_PCMCIA_IRQ1);
|
|
|
+ if (err)
|
|
|
+ goto err11;
|
|
|
+ skt->socket.pci_irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_IRQ1);
|
|
|
+
|
|
|
+ err = gpio_request(H3XXX_GPIO_PCMCIA_CD1, "PCMCIA CD1");
|
|
|
+ if (err)
|
|
|
+ goto err11;
|
|
|
+ err = gpio_direction_input(H3XXX_GPIO_PCMCIA_CD1);
|
|
|
+ if (err)
|
|
|
+ goto err12;
|
|
|
+ irqs[1].irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_CD1);
|
|
|
+
|
|
|
+ err = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
|
|
|
+ if (err)
|
|
|
+ goto err12;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+
|
|
|
+err02: gpio_free(H3XXX_GPIO_PCMCIA_CD0);
|
|
|
+err01: gpio_free(H3XXX_GPIO_PCMCIA_IRQ0);
|
|
|
+err00: return err;
|
|
|
|
|
|
- return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
|
|
|
+err12: gpio_free(H3XXX_GPIO_PCMCIA_CD0);
|
|
|
+err11: gpio_free(H3XXX_GPIO_PCMCIA_IRQ0);
|
|
|
+err10: return err;
|
|
|
}
|
|
|
|
|
|
static void h3600_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
|
|
@@ -40,17 +92,25 @@ static void h3600_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
|
|
|
assign_h3600_egpio(IPAQ_EGPIO_OPT_NVRAM_ON, 0);
|
|
|
assign_h3600_egpio(IPAQ_EGPIO_OPT_ON, 0);
|
|
|
assign_h3600_egpio(IPAQ_EGPIO_OPT_RESET, 1);
|
|
|
+ switch (skt->nr) {
|
|
|
+ case 0:
|
|
|
+ gpio_free(H3XXX_GPIO_PCMCIA_CD0);
|
|
|
+ gpio_free(H3XXX_GPIO_PCMCIA_IRQ0);
|
|
|
+ break;
|
|
|
+ case 1:
|
|
|
+ gpio_free(H3XXX_GPIO_PCMCIA_CD1);
|
|
|
+ gpio_free(H3XXX_GPIO_PCMCIA_IRQ1);
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
static void
|
|
|
h3600_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
|
|
|
{
|
|
|
- unsigned long levels = GPLR;
|
|
|
-
|
|
|
switch (skt->nr) {
|
|
|
case 0:
|
|
|
- state->detect = levels & GPIO_H3600_PCMCIA_CD0 ? 0 : 1;
|
|
|
- state->ready = levels & GPIO_H3600_PCMCIA_IRQ0 ? 1 : 0;
|
|
|
+ state->detect = !gpio_get_value(H3XXX_GPIO_PCMCIA_CD0);
|
|
|
+ state->ready = !!gpio_get_value(H3XXX_GPIO_PCMCIA_IRQ0);
|
|
|
state->bvd1 = 0;
|
|
|
state->bvd2 = 0;
|
|
|
state->wrprot = 0; /* Not available on H3600. */
|
|
@@ -59,8 +119,8 @@ h3600_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *st
|
|
|
break;
|
|
|
|
|
|
case 1:
|
|
|
- state->detect = levels & GPIO_H3600_PCMCIA_CD1 ? 0 : 1;
|
|
|
- state->ready = levels & GPIO_H3600_PCMCIA_IRQ1 ? 1 : 0;
|
|
|
+ state->detect = !gpio_get_value(H3XXX_GPIO_PCMCIA_CD1);
|
|
|
+ state->ready = !!gpio_get_value(H3XXX_GPIO_PCMCIA_IRQ1);
|
|
|
state->bvd1 = 0;
|
|
|
state->bvd2 = 0;
|
|
|
state->wrprot = 0; /* Not available on H3600. */
|