pcmcia: setup IRQ to be used by PCMCIA drivers at card insert
[safe/jmp/linux-2.6] / drivers / pcmcia / xxs1500_ss.c
1 /*
2  * PCMCIA socket code for the MyCable XXS1500 system.
3  *
4  * Copyright (c) 2009 Manuel Lauss <manuel.lauss@gmail.com>
5  *
6  */
7
8 #include <linux/delay.h>
9 #include <linux/gpio.h>
10 #include <linux/interrupt.h>
11 #include <linux/io.h>
12 #include <linux/ioport.h>
13 #include <linux/mm.h>
14 #include <linux/platform_device.h>
15 #include <linux/pm.h>
16 #include <linux/resource.h>
17 #include <linux/slab.h>
18 #include <linux/spinlock.h>
19
20 #include <pcmcia/cs_types.h>
21 #include <pcmcia/cs.h>
22 #include <pcmcia/ss.h>
23 #include <pcmcia/cistpl.h>
24
25 #include <asm/irq.h>
26 #include <asm/system.h>
27 #include <asm/mach-au1x00/au1000.h>
28
29 #define MEM_MAP_SIZE    0x400000
30 #define IO_MAP_SIZE     0x1000
31
32
33 /*
34  * 3.3V cards only; all interfacing is done via gpios:
35  *
36  * 0/1:  carddetect (00 = card present, xx = huh)
37  * 4:    card irq
38  * 204:  reset (high-act)
39  * 205:  buffer enable (low-act)
40  * 208/209: card voltage key (00,01,10,11)
41  * 210:  battwarn
42  * 211:  batdead
43  * 214:  power (low-act)
44  */
45 #define GPIO_CDA        0
46 #define GPIO_CDB        1
47 #define GPIO_CARDIRQ    4
48 #define GPIO_RESET      204
49 #define GPIO_OUTEN      205
50 #define GPIO_VSL        208
51 #define GPIO_VSH        209
52 #define GPIO_BATTDEAD   210
53 #define GPIO_BATTWARN   211
54 #define GPIO_POWER      214
55
56 struct xxs1500_pcmcia_sock {
57         struct pcmcia_socket    socket;
58         void            *virt_io;
59
60         phys_addr_t     phys_io;
61         phys_addr_t     phys_attr;
62         phys_addr_t     phys_mem;
63
64         /* previous flags for set_socket() */
65         unsigned int old_flags;
66 };
67
68 #define to_xxs_socket(x) container_of(x, struct xxs1500_pcmcia_sock, socket)
69
70 static irqreturn_t cdirq(int irq, void *data)
71 {
72         struct xxs1500_pcmcia_sock *sock = data;
73
74         pcmcia_parse_events(&sock->socket, SS_DETECT);
75
76         return IRQ_HANDLED;
77 }
78
79 static int xxs1500_pcmcia_configure(struct pcmcia_socket *skt,
80                                     struct socket_state_t *state)
81 {
82         struct xxs1500_pcmcia_sock *sock = to_xxs_socket(skt);
83         unsigned int changed;
84
85         /* power control */
86         switch (state->Vcc) {
87         case 0:
88                 gpio_set_value(GPIO_POWER, 1);  /* power off */
89                 break;
90         case 33:
91                 gpio_set_value(GPIO_POWER, 0);  /* power on */
92                 break;
93         case 50:
94         default:
95                 return -EINVAL;
96         }
97
98         changed = state->flags ^ sock->old_flags;
99
100         if (changed & SS_RESET) {
101                 if (state->flags & SS_RESET) {
102                         gpio_set_value(GPIO_RESET, 1);  /* assert reset */
103                         gpio_set_value(GPIO_OUTEN, 1);  /* buffers off */
104                 } else {
105                         gpio_set_value(GPIO_RESET, 0);  /* deassert reset */
106                         gpio_set_value(GPIO_OUTEN, 0);  /* buffers on */
107                         msleep(500);
108                 }
109         }
110
111         sock->old_flags = state->flags;
112
113         return 0;
114 }
115
116 static int xxs1500_pcmcia_get_status(struct pcmcia_socket *skt,
117                                      unsigned int *value)
118 {
119         unsigned int status;
120         int i;
121
122         status = 0;
123
124         /* check carddetects: GPIO[0:1] must both be low */
125         if (!gpio_get_value(GPIO_CDA) && !gpio_get_value(GPIO_CDB))
126                 status |= SS_DETECT;
127
128         /* determine card voltage: GPIO[208:209] binary value */
129         i = (!!gpio_get_value(GPIO_VSL)) | ((!!gpio_get_value(GPIO_VSH)) << 1);
130
131         switch (i) {
132         case 0:
133         case 1:
134         case 2:
135                 status |= SS_3VCARD;    /* 3V card */
136                 break;
137         case 3:                         /* 5V card, unsupported */
138         default:
139                 status |= SS_XVCARD;    /* treated as unsupported in core */
140         }
141
142         /* GPIO214: low active power switch */
143         status |= gpio_get_value(GPIO_POWER) ? 0 : SS_POWERON;
144
145         /* GPIO204: high-active reset line */
146         status |= gpio_get_value(GPIO_RESET) ? SS_RESET : SS_READY;
147
148         /* other stuff */
149         status |= gpio_get_value(GPIO_BATTDEAD) ? 0 : SS_BATDEAD;
150         status |= gpio_get_value(GPIO_BATTWARN) ? 0 : SS_BATWARN;
151
152         *value = status;
153
154         return 0;
155 }
156
157 static int xxs1500_pcmcia_sock_init(struct pcmcia_socket *skt)
158 {
159         gpio_direction_input(GPIO_CDA);
160         gpio_direction_input(GPIO_CDB);
161         gpio_direction_input(GPIO_VSL);
162         gpio_direction_input(GPIO_VSH);
163         gpio_direction_input(GPIO_BATTDEAD);
164         gpio_direction_input(GPIO_BATTWARN);
165         gpio_direction_output(GPIO_RESET, 1);   /* assert reset */
166         gpio_direction_output(GPIO_OUTEN, 1);   /* disable buffers */
167         gpio_direction_output(GPIO_POWER, 1);   /* power off */
168
169         return 0;
170 }
171
172 static int xxs1500_pcmcia_sock_suspend(struct pcmcia_socket *skt)
173 {
174         return 0;
175 }
176
177 static int au1x00_pcmcia_set_io_map(struct pcmcia_socket *skt,
178                                     struct pccard_io_map *map)
179 {
180         struct xxs1500_pcmcia_sock *sock = to_xxs_socket(skt);
181
182         map->start = (u32)sock->virt_io;
183         map->stop = map->start + IO_MAP_SIZE;
184
185         return 0;
186 }
187
188 static int au1x00_pcmcia_set_mem_map(struct pcmcia_socket *skt,
189                                      struct pccard_mem_map *map)
190 {
191         struct xxs1500_pcmcia_sock *sock = to_xxs_socket(skt);
192
193         if (map->flags & MAP_ATTRIB)
194                 map->static_start = sock->phys_attr + map->card_start;
195         else
196                 map->static_start = sock->phys_mem + map->card_start;
197
198         return 0;
199 }
200
201 static struct pccard_operations xxs1500_pcmcia_operations = {
202         .init                   = xxs1500_pcmcia_sock_init,
203         .suspend                = xxs1500_pcmcia_sock_suspend,
204         .get_status             = xxs1500_pcmcia_get_status,
205         .set_socket             = xxs1500_pcmcia_configure,
206         .set_io_map             = au1x00_pcmcia_set_io_map,
207         .set_mem_map            = au1x00_pcmcia_set_mem_map,
208 };
209
210 static int __devinit xxs1500_pcmcia_probe(struct platform_device *pdev)
211 {
212         struct xxs1500_pcmcia_sock *sock;
213         struct resource *r;
214         int ret, irq;
215
216         sock = kzalloc(sizeof(struct xxs1500_pcmcia_sock), GFP_KERNEL);
217         if (!sock)
218                 return -ENOMEM;
219
220         ret = -ENODEV;
221
222         /* 36bit PCMCIA Attribute area address */
223         r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pcmcia-attr");
224         if (!r) {
225                 dev_err(&pdev->dev, "missing 'pcmcia-attr' resource!\n");
226                 goto out0;
227         }
228         sock->phys_attr = r->start;
229
230         /* 36bit PCMCIA Memory area address */
231         r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pcmcia-mem");
232         if (!r) {
233                 dev_err(&pdev->dev, "missing 'pcmcia-mem' resource!\n");
234                 goto out0;
235         }
236         sock->phys_mem = r->start;
237
238         /* 36bit PCMCIA IO area address */
239         r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pcmcia-io");
240         if (!r) {
241                 dev_err(&pdev->dev, "missing 'pcmcia-io' resource!\n");
242                 goto out0;
243         }
244         sock->phys_io = r->start;
245
246
247         /*
248          * PCMCIA client drivers use the inb/outb macros to access
249          * the IO registers.  Since mips_io_port_base is added
250          * to the access address of the mips implementation of
251          * inb/outb, we need to subtract it here because we want
252          * to access the I/O or MEM address directly, without
253          * going through this "mips_io_port_base" mechanism.
254          */
255         sock->virt_io = (void *)(ioremap(sock->phys_io, IO_MAP_SIZE) -
256                                  mips_io_port_base);
257
258         if (!sock->virt_io) {
259                 dev_err(&pdev->dev, "cannot remap IO area\n");
260                 ret = -ENOMEM;
261                 goto out0;
262         }
263
264         sock->socket.ops        = &xxs1500_pcmcia_operations;
265         sock->socket.owner      = THIS_MODULE;
266         sock->socket.pci_irq    = gpio_to_irq(GPIO_CARDIRQ);
267         sock->socket.features   = SS_CAP_STATIC_MAP | SS_CAP_PCCARD;
268         sock->socket.map_size   = MEM_MAP_SIZE;
269         sock->socket.io_offset  = (unsigned long)sock->virt_io;
270         sock->socket.dev.parent = &pdev->dev;
271         sock->socket.resource_ops = &pccard_static_ops;
272
273         platform_set_drvdata(pdev, sock);
274
275         /* setup carddetect irq: use one of the 2 GPIOs as an
276          * edge detector.
277          */
278         irq = gpio_to_irq(GPIO_CDA);
279         set_irq_type(irq, IRQ_TYPE_EDGE_BOTH);
280         ret = request_irq(irq, cdirq, 0, "pcmcia_carddetect", sock);
281         if (ret) {
282                 dev_err(&pdev->dev, "cannot setup cd irq\n");
283                 goto out1;
284         }
285
286         ret = pcmcia_register_socket(&sock->socket);
287         if (ret) {
288                 dev_err(&pdev->dev, "failed to register\n");
289                 goto out2;
290         }
291
292         printk(KERN_INFO "MyCable XXS1500 PCMCIA socket services\n");
293
294         return 0;
295
296 out2:
297         free_irq(gpio_to_irq(GPIO_CDA), sock);
298 out1:
299         iounmap((void *)(sock->virt_io + (u32)mips_io_port_base));
300 out0:
301         kfree(sock);
302         return ret;
303 }
304
305 static int __devexit xxs1500_pcmcia_remove(struct platform_device *pdev)
306 {
307         struct xxs1500_pcmcia_sock *sock = platform_get_drvdata(pdev);
308
309         pcmcia_unregister_socket(&sock->socket);
310         free_irq(gpio_to_irq(GPIO_CDA), sock);
311         iounmap((void *)(sock->virt_io + (u32)mips_io_port_base));
312         kfree(sock);
313
314         return 0;
315 }
316
317 static struct platform_driver xxs1500_pcmcia_socket_driver = {
318         .driver = {
319                 .name   = "xxs1500_pcmcia",
320                 .owner  = THIS_MODULE,
321         },
322         .probe          = xxs1500_pcmcia_probe,
323         .remove         = __devexit_p(xxs1500_pcmcia_remove),
324 };
325
326 int __init xxs1500_pcmcia_socket_load(void)
327 {
328         return platform_driver_register(&xxs1500_pcmcia_socket_driver);
329 }
330
331 void  __exit xxs1500_pcmcia_socket_unload(void)
332 {
333         platform_driver_unregister(&xxs1500_pcmcia_socket_driver);
334 }
335
336 module_init(xxs1500_pcmcia_socket_load);
337 module_exit(xxs1500_pcmcia_socket_unload);
338
339 MODULE_LICENSE("GPL");
340 MODULE_DESCRIPTION("PCMCIA Socket Services for MyCable XXS1500 systems");
341 MODULE_AUTHOR("Manuel Lauss");