patch-2_6_7-vs1_9_1_12
[linux-2.6.git] / drivers / pcmcia / sa1100_yopy.c
1 /*
2  * drivers/pcmcia/sa1100_yopy.c
3  *
4  * PCMCIA implementation routines for Yopy
5  *
6  */
7 #include <linux/module.h>
8 #include <linux/kernel.h>
9 #include <linux/sched.h>
10 #include <linux/device.h>
11 #include <linux/init.h>
12
13 #include <asm/hardware.h>
14 #include <asm/mach-types.h>
15 #include <asm/irq.h>
16 #include "sa1100_generic.h"
17
18
19 static inline void pcmcia_power(int on) {
20         /* high for power up */
21         yopy_gpio_set(GPIO_CF_POWER, on);
22 }
23
24 static inline void pcmcia_reset(int reset)
25 {
26         /* high for reset */
27         yopy_gpio_set(GPIO_CF_RESET, reset);
28 }
29
30 static struct pcmcia_irqs irqs[] = {
31         { 0, IRQ_CF_CD,   "CF_CD"   },
32         { 0, IRQ_CF_BVD2, "CF_BVD2" },
33         { 0, IRQ_CF_BVD1, "CF_BVD1" },
34 };
35
36 static int yopy_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
37 {
38         skt->irq = IRQ_CF_IREQ;
39
40         pcmcia_power(0);
41         pcmcia_reset(1);
42
43         return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
44 }
45
46 static void yopy_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
47 {
48         soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
49
50         /* Disable CF */
51         pcmcia_reset(1);
52         pcmcia_power(0);
53 }
54
55 static void
56 yopy_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
57                          struct pcmcia_state_array *state)
58 {
59         unsigned long levels = GPLR;
60
61         state->detect = (levels & GPIO_CF_CD)    ? 0 : 1;
62         state->ready  = (levels & GPIO_CF_READY) ? 1 : 0;
63         state->bvd1   = (levels & GPIO_CF_BVD1)  ? 1 : 0;
64         state->bvd2   = (levels & GPIO_CF_BVD2)  ? 1 : 0;
65         state->wrprot = 0; /* Not available on Yopy. */
66         state->vs_3v  = 0; /* FIXME Can only apply 3.3V on Yopy. */
67         state->vs_Xv  = 0;
68 }
69
70 static int
71 yopy_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
72                              const socket_state_t *state)
73 {
74         switch (state->Vcc) {
75         case 0: /* power off */
76                 pcmcia_power(0);
77                 break;
78         case 50:
79                 printk(KERN_WARNING "%s(): CS asked for 5V, applying 3.3V..\n", __FUNCTION__);
80         case 33:
81                 pcmcia_power(1);
82                 break;
83         default:
84                 printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
85                        __FUNCTION__, state->Vcc);
86                 return -1;
87         }
88
89         pcmcia_reset(state->flags & SS_RESET ? 1 : 0);
90
91         /* Silently ignore Vpp, output enable, speaker enable. */
92
93         return 0;
94 }
95
96 static void yopy_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
97 {
98         soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
99 }
100
101 static void yopy_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
102 {
103         soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
104 }
105
106 static struct pcmcia_low_level yopy_pcmcia_ops = {
107         .owner                  = THIS_MODULE,
108         .init                   = yopy_pcmcia_init,
109         .shutdown               = yopy_pcmcia_shutdown,
110         .socket_state           = yopy_pcmcia_socket_state,
111         .configure_socket       = yopy_pcmcia_configure_socket,
112
113         .socket_init            = yopy_pcmcia_socket_init,
114         .socket_suspend         = yopy_pcmcia_socket_suspend,
115 };
116
117 int __init pcmcia_yopy_init(struct device *dev)
118 {
119         int ret = -ENODEV;
120
121         if (machine_is_yopy())
122                 ret = sa11xx_drv_pcmcia_probe(dev, &yopy_pcmcia_ops, 0, 1);
123
124         return ret;
125 }