diff options
Diffstat (limited to 'drivers/pcmcia/sa1100_h3600.c')
-rw-r--r-- | drivers/pcmcia/sa1100_h3600.c | 82 |
1 files changed, 71 insertions, 11 deletions
diff --git a/drivers/pcmcia/sa1100_h3600.c b/drivers/pcmcia/sa1100_h3600.c index 3a121ac697d6..97e5667fb2e3 100644 --- a/drivers/pcmcia/sa1100_h3600.c +++ b/drivers/pcmcia/sa1100_h3600.c | |||
@@ -10,26 +10,78 @@ | |||
10 | #include <linux/interrupt.h> | 10 | #include <linux/interrupt.h> |
11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
12 | #include <linux/delay.h> | 12 | #include <linux/delay.h> |
13 | #include <linux/gpio.h> | ||
13 | 14 | ||
14 | #include <mach/hardware.h> | 15 | #include <mach/hardware.h> |
15 | #include <asm/irq.h> | 16 | #include <asm/irq.h> |
16 | #include <asm/mach-types.h> | 17 | #include <asm/mach-types.h> |
17 | #include <mach/h3600.h> | 18 | #include <mach/h3600.h> |
19 | #include <mach/h3600_gpio.h> | ||
18 | 20 | ||
19 | #include "sa1100_generic.h" | 21 | #include "sa1100_generic.h" |
20 | 22 | ||
21 | static struct pcmcia_irqs irqs[] = { | 23 | static struct pcmcia_irqs irqs[] = { |
22 | { 0, IRQ_GPIO_H3600_PCMCIA_CD0, "PCMCIA CD0" }, | 24 | { .sock = 0, .str = "PCMCIA CD0" }, /* .irq will be filled later */ |
23 | { 1, IRQ_GPIO_H3600_PCMCIA_CD1, "PCMCIA CD1" } | 25 | { .sock = 1, .str = "PCMCIA CD1" } |
24 | }; | 26 | }; |
25 | 27 | ||
26 | static int h3600_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 28 | static int h3600_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
27 | { | 29 | { |
28 | skt->socket.pci_irq = skt->nr ? IRQ_GPIO_H3600_PCMCIA_IRQ1 | 30 | int err; |
29 | : IRQ_GPIO_H3600_PCMCIA_IRQ0; | ||
30 | 31 | ||
32 | switch (skt->nr) { | ||
33 | case 0: | ||
34 | err = gpio_request(H3XXX_GPIO_PCMCIA_IRQ0, "PCMCIA IRQ0"); | ||
35 | if (err) | ||
36 | goto err00; | ||
37 | err = gpio_direction_input(H3XXX_GPIO_PCMCIA_IRQ0); | ||
38 | if (err) | ||
39 | goto err01; | ||
40 | skt->socket.pci_irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_IRQ0); | ||
41 | |||
42 | err = gpio_request(H3XXX_GPIO_PCMCIA_CD0, "PCMCIA CD0"); | ||
43 | if (err) | ||
44 | goto err01; | ||
45 | err = gpio_direction_input(H3XXX_GPIO_PCMCIA_CD0); | ||
46 | if (err) | ||
47 | goto err02; | ||
48 | irqs[0].irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_CD0); | ||
49 | |||
50 | err = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
51 | if (err) | ||
52 | goto err02; | ||
53 | break; | ||
54 | case 1: | ||
55 | err = gpio_request(H3XXX_GPIO_PCMCIA_IRQ1, "PCMCIA IRQ1"); | ||
56 | if (err) | ||
57 | goto err10; | ||
58 | err = gpio_direction_input(H3XXX_GPIO_PCMCIA_IRQ1); | ||
59 | if (err) | ||
60 | goto err11; | ||
61 | skt->socket.pci_irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_IRQ1); | ||
62 | |||
63 | err = gpio_request(H3XXX_GPIO_PCMCIA_CD1, "PCMCIA CD1"); | ||
64 | if (err) | ||
65 | goto err11; | ||
66 | err = gpio_direction_input(H3XXX_GPIO_PCMCIA_CD1); | ||
67 | if (err) | ||
68 | goto err12; | ||
69 | irqs[1].irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_CD1); | ||
70 | |||
71 | err = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
72 | if (err) | ||
73 | goto err12; | ||
74 | break; | ||
75 | } | ||
76 | return 0; | ||
77 | |||
78 | err02: gpio_free(H3XXX_GPIO_PCMCIA_CD0); | ||
79 | err01: gpio_free(H3XXX_GPIO_PCMCIA_IRQ0); | ||
80 | err00: return err; | ||
31 | 81 | ||
32 | return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); | 82 | err12: gpio_free(H3XXX_GPIO_PCMCIA_CD0); |
83 | err11: gpio_free(H3XXX_GPIO_PCMCIA_IRQ0); | ||
84 | err10: return err; | ||
33 | } | 85 | } |
34 | 86 | ||
35 | static void h3600_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | 87 | 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) | |||
40 | assign_h3600_egpio(IPAQ_EGPIO_OPT_NVRAM_ON, 0); | 92 | assign_h3600_egpio(IPAQ_EGPIO_OPT_NVRAM_ON, 0); |
41 | assign_h3600_egpio(IPAQ_EGPIO_OPT_ON, 0); | 93 | assign_h3600_egpio(IPAQ_EGPIO_OPT_ON, 0); |
42 | assign_h3600_egpio(IPAQ_EGPIO_OPT_RESET, 1); | 94 | assign_h3600_egpio(IPAQ_EGPIO_OPT_RESET, 1); |
95 | switch (skt->nr) { | ||
96 | case 0: | ||
97 | gpio_free(H3XXX_GPIO_PCMCIA_CD0); | ||
98 | gpio_free(H3XXX_GPIO_PCMCIA_IRQ0); | ||
99 | break; | ||
100 | case 1: | ||
101 | gpio_free(H3XXX_GPIO_PCMCIA_CD1); | ||
102 | gpio_free(H3XXX_GPIO_PCMCIA_IRQ1); | ||
103 | break; | ||
104 | } | ||
43 | } | 105 | } |
44 | 106 | ||
45 | static void | 107 | static void |
46 | h3600_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) | 108 | h3600_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) |
47 | { | 109 | { |
48 | unsigned long levels = GPLR; | ||
49 | |||
50 | switch (skt->nr) { | 110 | switch (skt->nr) { |
51 | case 0: | 111 | case 0: |
52 | state->detect = levels & GPIO_H3600_PCMCIA_CD0 ? 0 : 1; | 112 | state->detect = !gpio_get_value(H3XXX_GPIO_PCMCIA_CD0); |
53 | state->ready = levels & GPIO_H3600_PCMCIA_IRQ0 ? 1 : 0; | 113 | state->ready = !!gpio_get_value(H3XXX_GPIO_PCMCIA_IRQ0); |
54 | state->bvd1 = 0; | 114 | state->bvd1 = 0; |
55 | state->bvd2 = 0; | 115 | state->bvd2 = 0; |
56 | state->wrprot = 0; /* Not available on H3600. */ | 116 | state->wrprot = 0; /* Not available on H3600. */ |
@@ -59,8 +119,8 @@ h3600_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *st | |||
59 | break; | 119 | break; |
60 | 120 | ||
61 | case 1: | 121 | case 1: |
62 | state->detect = levels & GPIO_H3600_PCMCIA_CD1 ? 0 : 1; | 122 | state->detect = !gpio_get_value(H3XXX_GPIO_PCMCIA_CD1); |
63 | state->ready = levels & GPIO_H3600_PCMCIA_IRQ1 ? 1 : 0; | 123 | state->ready = !!gpio_get_value(H3XXX_GPIO_PCMCIA_IRQ1); |
64 | state->bvd1 = 0; | 124 | state->bvd1 = 0; |
65 | state->bvd2 = 0; | 125 | state->bvd2 = 0; |
66 | state->wrprot = 0; /* Not available on H3600. */ | 126 | state->wrprot = 0; /* Not available on H3600. */ |