patch-2_6_7-vs1_9_1_12
[linux-2.6.git] / drivers / pcmcia / sa1100_pangolin.c
1 /*
2  * drivers/pcmcia/sa1100_pangolin.c
3  *
4  * PCMCIA implementation routines for Pangolin
5  *
6  */
7 #include <linux/config.h>
8 #include <linux/module.h>
9 #include <linux/kernel.h>
10 #include <linux/sched.h>
11 #include <linux/device.h>
12 #include <linux/init.h>
13
14 #include <asm/hardware.h>
15 #include <asm/mach-types.h>
16 #include <asm/irq.h>
17 #include "sa1100_generic.h"
18
19 #ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
20 #define PANGOLIN_SOCK   1
21 #else
22 #define PANGOLIN_SOCK   0
23 #endif
24
25 static struct pcmcia_irqs irqs[] = {
26         { PANGOLIN_SOCK, IRQ_PCMCIA_CD, "PCMCIA CD" },
27 };
28
29 static int pangolin_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
30 {
31         int res;
32
33 #ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
34         /* Enable PCMCIA bus: */
35         GPCR = GPIO_PCMCIA_BUS_ON;
36 #endif
37
38         skt->irq = IRQ_PCMCIA_IRQ;
39
40         return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
41 }
42
43 static void pangolin_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
44 {
45         soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
46
47 #ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
48         /* Disable PCMCIA bus: */
49         GPSR = GPIO_PCMCIA_BUS_ON;
50 #endif
51 }
52
53 static void
54 pangolin_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
55                              struct pcmcia_state *state)
56 {
57         unsigned long levels = GPLR;
58
59         state->detect=((levels & GPIO_PCMCIA_CD)==0)?1:0;
60         state->ready=(levels & GPIO_PCMCIA_IRQ)?1:0;
61         state->bvd1=1; /* Not available on Pangolin. */
62         state->bvd2=1; /* Not available on Pangolin. */
63         state->wrprot=0; /* Not available on Pangolin. */
64         state->vs_3v=1;  /* Can only apply 3.3V on Pangolin. */
65         state->vs_Xv=0;
66 }
67
68 static int
69 pangolin_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
70                                  const socket_state_t *state)
71 {
72         unsigned long value, flags;
73
74         local_irq_save(flags);
75
76         /* Murphy: BUS_ON different from POWER ? */
77
78         switch (state->Vcc) {
79         case 0:
80                 break;
81 #ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
82         case 50:
83                 printk(KERN_WARNING "%s(): CS asked for 5V, applying 3.3V...\n",
84                         __FUNCTION__);
85         case 33:  /* Can only apply 3.3V to the CF slot. */
86                 break;
87 #else
88         case 50:
89                 printk(KERN_WARNING "%s(): CS asked for 5V, determinded by "
90                         "jumper setting...\n", __FUNCTION__);
91                 break;
92         case 33:
93                 printk(KERN_WARNING "%s(): CS asked for 3.3V, determined by "
94                         "jumper setting...\n", __FUNCTION__);
95                 break;
96 #endif
97         default:
98                 printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
99                         __FUNCTION__, state->Vcc);
100                 local_irq_restore(flags);
101                 return -1;
102         }
103 #ifdef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
104         /* reset & unreset request */
105         if (skt->nr == 0) {
106                 if (state->flags & SS_RESET) {
107                         GPSR = GPIO_PCMCIA_RESET;
108                 } else {
109                         GPCR = GPIO_PCMCIA_RESET;
110                 }
111         }
112 #endif
113         /* Silently ignore Vpp, output enable, speaker enable. */
114         local_irq_restore(flags);
115         return 0;
116 }
117
118 static void pangolin_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
119 {
120         soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
121 }
122
123 static void pangolin_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
124 {
125         soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
126 }
127
128 static struct pcmcia_low_level pangolin_pcmcia_ops = { 
129         .owner                  = THIS_MODULE,
130         .hw_init                = pangolin_pcmcia_hw_init,
131         .hw_shutdown            = pangolin_pcmcia_hw_shutdown,
132         .socket_state           = pangolin_pcmcia_socket_state,
133         .configure_socket       = pangolin_pcmcia_configure_socket,
134
135         .socket_init            = pangolin_pcmcia_socket_init,
136         .socket_suspend         = pangolin_pcmcia_socket_suspend,
137 };
138
139 int __init pcmcia_pangolin_init(struct device *dev)
140 {
141         int ret = -ENODEV;
142
143         if (machine_is_pangolin())
144                 ret = sa11xx_drv_pcmcia_probe(dev, &pangolin_pcmcia_ops, PANGOLIN_SOCK, 1);
145
146         return ret;
147 }