]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/pcmcia/xxs1500_ss.c
MIPS: Alchemy: XXS1500 PCMCIA driver rewrite
[mv-sheeva.git] / 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/spinlock.h>
18
19 #include <pcmcia/cs_types.h>
20 #include <pcmcia/cs.h>
21 #include <pcmcia/ss.h>
22 #include <pcmcia/cistpl.h>
23
24 #include <asm/irq.h>
25 #include <asm/system.h>
26 #include <asm/mach-au1x00/au1000.h>
27
28 #define MEM_MAP_SIZE    0x400000
29 #define IO_MAP_SIZE     0x1000
30
31
32 /*
33  * 3.3V cards only; all interfacing is done via gpios:
34  *
35  * 0/1:  carddetect (00 = card present, xx = huh)
36  * 4:    card irq
37  * 204:  reset (high-act)
38  * 205:  buffer enable (low-act)
39  * 208/209: card voltage key (00,01,10,11)
40  * 210:  battwarn
41  * 211:  batdead
42  * 214:  power (low-act)
43  */
44 #define GPIO_CDA        0
45 #define GPIO_CDB        1
46 #define GPIO_CARDIRQ    4
47 #define GPIO_RESET      204
48 #define GPIO_OUTEN      205
49 #define GPIO_VSL        208
50 #define GPIO_VSH        209
51 #define GPIO_BATTDEAD   210
52 #define GPIO_BATTWARN   211
53 #define GPIO_POWER      214
54
55 struct xxs1500_pcmcia_sock {
56         struct pcmcia_socket    socket;
57         void            *virt_io;
58
59         /* the "pseudo" addresses of the PCMCIA space. */
60         unsigned long   phys_io;
61         unsigned long   phys_attr;
62         unsigned long   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         phys_t physio;
215         int ret, irq;
216
217         sock = kzalloc(sizeof(struct xxs1500_pcmcia_sock), GFP_KERNEL);
218         if (!sock)
219                 return -ENOMEM;
220
221         ret = -ENODEV;
222
223         /*
224          * pseudo-attr:  The 32bit address of the PCMCIA attribute space
225          * for this socket (usually the 36bit address shifted 4 to the
226          * right).
227          */
228         r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pseudo-attr");
229         if (!r) {
230                 dev_err(&pdev->dev, "missing 'pseudo-attr' resource!\n");
231                 goto out0;
232         }
233         sock->phys_attr = r->start;
234
235         /*
236          * pseudo-mem:  The 32bit address of the PCMCIA memory space for
237          * this socket (usually the 36bit address shifted 4 to the right)
238          */
239         r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pseudo-mem");
240         if (!r) {
241                 dev_err(&pdev->dev, "missing 'pseudo-mem' resource!\n");
242                 goto out0;
243         }
244         sock->phys_mem = r->start;
245
246         /*
247          * pseudo-io:  The 32bit address of the PCMCIA IO space for this
248          * socket (usually the 36bit address shifted 4 to the right).
249          */
250         r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pseudo-io");
251         if (!r) {
252                 dev_err(&pdev->dev, "missing 'pseudo-io' resource!\n");
253                 goto out0;
254         }
255         sock->phys_io = r->start;
256
257
258         /* for io must remap the full 36bit address (for reference see
259          * alchemy/common/setup.c::__fixup_bigphys_addr)
260          */
261         physio = ((phys_t)sock->phys_io) << 4;
262
263         /*
264          * PCMCIA client drivers use the inb/outb macros to access
265          * the IO registers.  Since mips_io_port_base is added
266          * to the access address of the mips implementation of
267          * inb/outb, we need to subtract it here because we want
268          * to access the I/O or MEM address directly, without
269          * going through this "mips_io_port_base" mechanism.
270          */
271         sock->virt_io = (void *)(ioremap(physio, IO_MAP_SIZE) -
272                                  mips_io_port_base);
273
274         if (!sock->virt_io) {
275                 dev_err(&pdev->dev, "cannot remap IO area\n");
276                 ret = -ENOMEM;
277                 goto out0;
278         }
279
280         sock->socket.ops        = &xxs1500_pcmcia_operations;
281         sock->socket.owner      = THIS_MODULE;
282         sock->socket.pci_irq    = gpio_to_irq(GPIO_CARDIRQ);
283         sock->socket.features   = SS_CAP_STATIC_MAP | SS_CAP_PCCARD;
284         sock->socket.map_size   = MEM_MAP_SIZE;
285         sock->socket.io_offset  = (unsigned long)sock->virt_io;
286         sock->socket.dev.parent = &pdev->dev;
287         sock->socket.resource_ops = &pccard_static_ops;
288
289         platform_set_drvdata(pdev, sock);
290
291         /* setup carddetect irq: use one of the 2 GPIOs as an
292          * edge detector.
293          */
294         irq = gpio_to_irq(GPIO_CDA);
295         set_irq_type(irq, IRQ_TYPE_EDGE_BOTH);
296         ret = request_irq(irq, cdirq, 0, "pcmcia_carddetect", sock);
297         if (ret) {
298                 dev_err(&pdev->dev, "cannot setup cd irq\n");
299                 goto out1;
300         }
301
302         ret = pcmcia_register_socket(&sock->socket);
303         if (ret) {
304                 dev_err(&pdev->dev, "failed to register\n");
305                 goto out2;
306         }
307
308         printk(KERN_INFO "MyCable XXS1500 PCMCIA socket services\n");
309
310         return 0;
311
312 out2:
313         free_irq(gpio_to_irq(GPIO_CDA), sock);
314 out1:
315         iounmap((void *)(sock->virt_io + (u32)mips_io_port_base));
316 out0:
317         kfree(sock);
318         return ret;
319 }
320
321 static int __devexit xxs1500_pcmcia_remove(struct platform_device *pdev)
322 {
323         struct xxs1500_pcmcia_sock *sock = platform_get_drvdata(pdev);
324
325         pcmcia_unregister_socket(&sock->socket);
326         free_irq(gpio_to_irq(GPIO_CDA), sock);
327         iounmap((void *)(sock->virt_io + (u32)mips_io_port_base));
328         kfree(sock);
329
330         return 0;
331 }
332
333 static struct platform_driver xxs1500_pcmcia_socket_driver = {
334         .driver = {
335                 .name   = "xxs1500_pcmcia",
336                 .owner  = THIS_MODULE,
337         },
338         .probe          = xxs1500_pcmcia_probe,
339         .remove         = __devexit_p(xxs1500_pcmcia_remove),
340 };
341
342 int __init xxs1500_pcmcia_socket_load(void)
343 {
344         return platform_driver_register(&xxs1500_pcmcia_socket_driver);
345 }
346
347 void  __exit xxs1500_pcmcia_socket_unload(void)
348 {
349         platform_driver_unregister(&xxs1500_pcmcia_socket_driver);
350 }
351
352 module_init(xxs1500_pcmcia_socket_load);
353 module_exit(xxs1500_pcmcia_socket_unload);
354
355 MODULE_LICENSE("GPL");
356 MODULE_DESCRIPTION("PCMCIA Socket Services for MyCable XXS1500 systems");
357 MODULE_AUTHOR("Manuel Lauss");