ARM: 5814/1: SA1100: h3100/h3600: convert all users of assign_h3600_egpio to gpiolib
[linux-2.6.git] / drivers / pcmcia / sa1100_h3600.c
1 /*
2  * drivers/pcmcia/sa1100_h3600.c
3  *
4  * PCMCIA implementation routines for H3600
5  *
6  */
7 #include <linux/module.h>
8 #include <linux/kernel.h>
9 #include <linux/device.h>
10 #include <linux/interrupt.h>
11 #include <linux/init.h>
12 #include <linux/delay.h>
13 #include <linux/gpio.h>
14
15 #include <mach/hardware.h>
16 #include <asm/irq.h>
17 #include <asm/mach-types.h>
18 #include <mach/h3600.h>
19 #include <mach/h3600_gpio.h>
20
21 #include "sa1100_generic.h"
22
23 static struct pcmcia_irqs irqs[] = {
24         { .sock = 0, .str = "PCMCIA CD0" }, /* .irq will be filled later */
25         { .sock = 1, .str = "PCMCIA CD1" }
26 };
27
28 static int h3600_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
29 {
30         int err;
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 = gpio_request(H3XXX_EGPIO_OPT_NVRAM_ON, "OPT NVRAM ON");
51                 if (err)
52                         goto err02;
53                 err = gpio_direction_output(H3XXX_EGPIO_OPT_NVRAM_ON, 0);
54                 if (err)
55                         goto err03;
56                 err = gpio_request(H3XXX_EGPIO_OPT_ON, "OPT ON");
57                 if (err)
58                         goto err03;
59                 err = gpio_direction_output(H3XXX_EGPIO_OPT_ON, 0);
60                 if (err)
61                         goto err04;
62                 err = gpio_request(H3XXX_EGPIO_OPT_RESET, "OPT RESET");
63                 if (err)
64                         goto err04;
65                 err = gpio_direction_output(H3XXX_EGPIO_OPT_RESET, 0);
66                 if (err)
67                         goto err05;
68                 err = gpio_request(H3XXX_EGPIO_CARD_RESET, "PCMCIA CARD RESET");
69                 if (err)
70                         goto err05;
71                 err = gpio_direction_output(H3XXX_EGPIO_CARD_RESET, 0);
72                 if (err)
73                         goto err06;
74                 err = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
75                 if (err)
76                         goto err06;
77                 break;
78         case 1:
79                 err = gpio_request(H3XXX_GPIO_PCMCIA_IRQ1, "PCMCIA IRQ1");
80                 if (err)
81                         goto err10;
82                 err = gpio_direction_input(H3XXX_GPIO_PCMCIA_IRQ1);
83                 if (err)
84                         goto err11;
85                 skt->socket.pci_irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_IRQ1);
86
87                 err = gpio_request(H3XXX_GPIO_PCMCIA_CD1, "PCMCIA CD1");
88                 if (err)
89                         goto err11;
90                 err = gpio_direction_input(H3XXX_GPIO_PCMCIA_CD1);
91                 if (err)
92                         goto err12;
93                 irqs[1].irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_CD1);
94
95                 err = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
96                 if (err)
97                         goto err12;
98                 break;
99         }
100         return 0;
101
102 err06:  gpio_free(H3XXX_EGPIO_CARD_RESET);
103 err05:  gpio_free(H3XXX_EGPIO_OPT_RESET);
104 err04:  gpio_free(H3XXX_EGPIO_OPT_ON);
105 err03:  gpio_free(H3XXX_EGPIO_OPT_NVRAM_ON);
106 err02:  gpio_free(H3XXX_GPIO_PCMCIA_CD0);
107 err01:  gpio_free(H3XXX_GPIO_PCMCIA_IRQ0);
108 err00:  return err;
109
110 err12:  gpio_free(H3XXX_GPIO_PCMCIA_CD0);
111 err11:  gpio_free(H3XXX_GPIO_PCMCIA_IRQ0);
112 err10:  return err;
113 }
114
115 static void h3600_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
116 {
117         soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
118   
119         switch (skt->nr) {
120         case 0:
121                 /* Disable CF bus: */
122                 gpio_set_value(H3XXX_EGPIO_OPT_NVRAM_ON, 0);
123                 gpio_set_value(H3XXX_EGPIO_OPT_ON, 0);
124                 gpio_set_value(H3XXX_EGPIO_OPT_RESET, 1);
125
126                 gpio_free(H3XXX_EGPIO_CARD_RESET);
127                 gpio_free(H3XXX_EGPIO_OPT_RESET);
128                 gpio_free(H3XXX_EGPIO_OPT_ON);
129                 gpio_free(H3XXX_EGPIO_OPT_NVRAM_ON);
130                 gpio_free(H3XXX_GPIO_PCMCIA_CD0);
131                 gpio_free(H3XXX_GPIO_PCMCIA_IRQ0);
132                 break;
133         case 1:
134                 gpio_free(H3XXX_GPIO_PCMCIA_CD1);
135                 gpio_free(H3XXX_GPIO_PCMCIA_IRQ1);
136                 break;
137         }
138 }
139
140 static void
141 h3600_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
142 {
143         switch (skt->nr) {
144         case 0:
145                 state->detect = !gpio_get_value(H3XXX_GPIO_PCMCIA_CD0);
146                 state->ready = !!gpio_get_value(H3XXX_GPIO_PCMCIA_IRQ0);
147                 state->bvd1 = 0;
148                 state->bvd2 = 0;
149                 state->wrprot = 0; /* Not available on H3600. */
150                 state->vs_3v = 0;
151                 state->vs_Xv = 0;
152                 break;
153
154         case 1:
155                 state->detect = !gpio_get_value(H3XXX_GPIO_PCMCIA_CD1);
156                 state->ready = !!gpio_get_value(H3XXX_GPIO_PCMCIA_IRQ1);
157                 state->bvd1 = 0;
158                 state->bvd2 = 0;
159                 state->wrprot = 0; /* Not available on H3600. */
160                 state->vs_3v = 0;
161                 state->vs_Xv = 0;
162                 break;
163         }
164 }
165
166 static int
167 h3600_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
168 {
169         if (state->Vcc != 0 && state->Vcc != 33 && state->Vcc != 50) {
170                 printk(KERN_ERR "h3600_pcmcia: unrecognized Vcc %u.%uV\n",
171                        state->Vcc / 10, state->Vcc % 10);
172                 return -1;
173         }
174
175         gpio_set_value(H3XXX_EGPIO_CARD_RESET, !!(state->flags & SS_RESET));
176
177         /* Silently ignore Vpp, output enable, speaker enable. */
178
179         return 0;
180 }
181
182 static void h3600_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
183 {
184         /* Enable CF bus: */
185         gpio_set_value(H3XXX_EGPIO_OPT_NVRAM_ON, 1);
186         gpio_set_value(H3XXX_EGPIO_OPT_ON, 1);
187         gpio_set_value(H3XXX_EGPIO_OPT_RESET, 0);
188
189         msleep(10);
190
191         soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
192 }
193
194 static void h3600_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
195 {
196         soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
197
198         /*
199          * FIXME:  This doesn't fit well.  We don't have the mechanism in
200          * the generic PCMCIA layer to deal with the idea of two sockets
201          * on one bus.  We rely on the cs.c behaviour shutting down
202          * socket 0 then socket 1.
203          */
204         if (skt->nr == 1) {
205                 gpio_set_value(H3XXX_EGPIO_OPT_ON, 0);
206                 gpio_set_value(H3XXX_EGPIO_OPT_NVRAM_ON, 0);
207                 /* hmm, does this suck power? */
208                 gpio_set_value(H3XXX_EGPIO_OPT_RESET, 1);
209         }
210 }
211
212 struct pcmcia_low_level h3600_pcmcia_ops = { 
213         .owner                  = THIS_MODULE,
214         .hw_init                = h3600_pcmcia_hw_init,
215         .hw_shutdown            = h3600_pcmcia_hw_shutdown,
216         .socket_state           = h3600_pcmcia_socket_state,
217         .configure_socket       = h3600_pcmcia_configure_socket,
218
219         .socket_init            = h3600_pcmcia_socket_init,
220         .socket_suspend         = h3600_pcmcia_socket_suspend,
221 };
222
223 int __init pcmcia_h3600_init(struct device *dev)
224 {
225         int ret = -ENODEV;
226
227         if (machine_is_h3600())
228                 ret = sa11xx_drv_pcmcia_probe(dev, &h3600_pcmcia_ops, 0, 2);
229
230         return ret;
231 }