diff options
Diffstat (limited to 'drivers/pcmcia/au1000_pb1x00.c')
-rw-r--r-- | drivers/pcmcia/au1000_pb1x00.c | 294 |
1 files changed, 0 insertions, 294 deletions
diff --git a/drivers/pcmcia/au1000_pb1x00.c b/drivers/pcmcia/au1000_pb1x00.c deleted file mode 100644 index b2396647a165..000000000000 --- a/drivers/pcmcia/au1000_pb1x00.c +++ /dev/null | |||
@@ -1,294 +0,0 @@ | |||
1 | /* | ||
2 | * | ||
3 | * Alchemy Semi Pb1000 boards specific pcmcia routines. | ||
4 | * | ||
5 | * Copyright 2002 MontaVista Software Inc. | ||
6 | * Author: MontaVista Software, Inc. | ||
7 | * ppopov@mvista.com or source@mvista.com | ||
8 | * | ||
9 | * ######################################################################## | ||
10 | * | ||
11 | * This program is free software; you can distribute it and/or modify it | ||
12 | * under the terms of the GNU General Public License (Version 2) as | ||
13 | * published by the Free Software Foundation. | ||
14 | * | ||
15 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
16 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
17 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
18 | * for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License along | ||
21 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
22 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
23 | */ | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/delay.h> | ||
27 | #include <linux/ioport.h> | ||
28 | #include <linux/kernel.h> | ||
29 | #include <linux/timer.h> | ||
30 | #include <linux/mm.h> | ||
31 | #include <linux/proc_fs.h> | ||
32 | #include <linux/types.h> | ||
33 | |||
34 | #include <pcmcia/ss.h> | ||
35 | #include <pcmcia/cistpl.h> | ||
36 | |||
37 | #include <asm/io.h> | ||
38 | #include <asm/irq.h> | ||
39 | #include <asm/system.h> | ||
40 | |||
41 | #include <asm/au1000.h> | ||
42 | #include <asm/au1000_pcmcia.h> | ||
43 | |||
44 | #define debug(fmt, arg...) do { } while (0) | ||
45 | |||
46 | #include <asm/pb1000.h> | ||
47 | #define PCMCIA_IRQ AU1000_GPIO_15 | ||
48 | |||
49 | static int pb1x00_pcmcia_init(struct pcmcia_init *init) | ||
50 | { | ||
51 | u16 pcr; | ||
52 | pcr = PCR_SLOT_0_RST | PCR_SLOT_1_RST; | ||
53 | |||
54 | au_writel(0x8000, PB1000_MDR); /* clear pcmcia interrupt */ | ||
55 | au_sync_delay(100); | ||
56 | au_writel(0x4000, PB1000_MDR); /* enable pcmcia interrupt */ | ||
57 | au_sync(); | ||
58 | |||
59 | pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,0); | ||
60 | pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,1); | ||
61 | au_writel(pcr, PB1000_PCR); | ||
62 | au_sync_delay(20); | ||
63 | |||
64 | return PCMCIA_NUM_SOCKS; | ||
65 | } | ||
66 | |||
67 | static int pb1x00_pcmcia_shutdown(void) | ||
68 | { | ||
69 | u16 pcr; | ||
70 | pcr = PCR_SLOT_0_RST | PCR_SLOT_1_RST; | ||
71 | pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,0); | ||
72 | pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,1); | ||
73 | au_writel(pcr, PB1000_PCR); | ||
74 | au_sync_delay(20); | ||
75 | return 0; | ||
76 | } | ||
77 | |||
78 | static int | ||
79 | pb1x00_pcmcia_socket_state(unsigned sock, struct pcmcia_state *state) | ||
80 | { | ||
81 | u32 inserted0, inserted1; | ||
82 | u16 vs0, vs1; | ||
83 | |||
84 | vs0 = vs1 = (u16)au_readl(PB1000_ACR1); | ||
85 | inserted0 = !(vs0 & (ACR1_SLOT_0_CD1 | ACR1_SLOT_0_CD2)); | ||
86 | inserted1 = !(vs1 & (ACR1_SLOT_1_CD1 | ACR1_SLOT_1_CD2)); | ||
87 | vs0 = (vs0 >> 4) & 0x3; | ||
88 | vs1 = (vs1 >> 12) & 0x3; | ||
89 | |||
90 | state->ready = 0; | ||
91 | state->vs_Xv = 0; | ||
92 | state->vs_3v = 0; | ||
93 | state->detect = 0; | ||
94 | |||
95 | if (sock == 0) { | ||
96 | if (inserted0) { | ||
97 | switch (vs0) { | ||
98 | case 0: | ||
99 | case 2: | ||
100 | state->vs_3v=1; | ||
101 | break; | ||
102 | case 3: /* 5V */ | ||
103 | break; | ||
104 | default: | ||
105 | /* return without setting 'detect' */ | ||
106 | printk(KERN_ERR "pb1x00 bad VS (%d)\n", | ||
107 | vs0); | ||
108 | return 0; | ||
109 | } | ||
110 | state->detect = 1; | ||
111 | } | ||
112 | } | ||
113 | else { | ||
114 | if (inserted1) { | ||
115 | switch (vs1) { | ||
116 | case 0: | ||
117 | case 2: | ||
118 | state->vs_3v=1; | ||
119 | break; | ||
120 | case 3: /* 5V */ | ||
121 | break; | ||
122 | default: | ||
123 | /* return without setting 'detect' */ | ||
124 | printk(KERN_ERR "pb1x00 bad VS (%d)\n", | ||
125 | vs1); | ||
126 | return 0; | ||
127 | } | ||
128 | state->detect = 1; | ||
129 | } | ||
130 | } | ||
131 | |||
132 | if (state->detect) { | ||
133 | state->ready = 1; | ||
134 | } | ||
135 | |||
136 | state->bvd1=1; | ||
137 | state->bvd2=1; | ||
138 | state->wrprot=0; | ||
139 | return 1; | ||
140 | } | ||
141 | |||
142 | |||
143 | static int pb1x00_pcmcia_get_irq_info(struct pcmcia_irq_info *info) | ||
144 | { | ||
145 | |||
146 | if(info->sock > PCMCIA_MAX_SOCK) return -1; | ||
147 | |||
148 | /* | ||
149 | * Even in the case of the Pb1000, both sockets are connected | ||
150 | * to the same irq line. | ||
151 | */ | ||
152 | info->irq = PCMCIA_IRQ; | ||
153 | |||
154 | return 0; | ||
155 | } | ||
156 | |||
157 | |||
158 | static int | ||
159 | pb1x00_pcmcia_configure_socket(const struct pcmcia_configure *configure) | ||
160 | { | ||
161 | u16 pcr; | ||
162 | |||
163 | if(configure->sock > PCMCIA_MAX_SOCK) return -1; | ||
164 | |||
165 | pcr = au_readl(PB1000_PCR); | ||
166 | |||
167 | if (configure->sock == 0) { | ||
168 | pcr &= ~(PCR_SLOT_0_VCC0 | PCR_SLOT_0_VCC1 | | ||
169 | PCR_SLOT_0_VPP0 | PCR_SLOT_0_VPP1); | ||
170 | } | ||
171 | else { | ||
172 | pcr &= ~(PCR_SLOT_1_VCC0 | PCR_SLOT_1_VCC1 | | ||
173 | PCR_SLOT_1_VPP0 | PCR_SLOT_1_VPP1); | ||
174 | } | ||
175 | |||
176 | pcr &= ~PCR_SLOT_0_RST; | ||
177 | debug("Vcc %dV Vpp %dV, pcr %x\n", | ||
178 | configure->vcc, configure->vpp, pcr); | ||
179 | switch(configure->vcc){ | ||
180 | case 0: /* Vcc 0 */ | ||
181 | switch(configure->vpp) { | ||
182 | case 0: | ||
183 | pcr |= SET_VCC_VPP(VCC_HIZ,VPP_GND, | ||
184 | configure->sock); | ||
185 | break; | ||
186 | case 12: | ||
187 | pcr |= SET_VCC_VPP(VCC_HIZ,VPP_12V, | ||
188 | configure->sock); | ||
189 | break; | ||
190 | case 50: | ||
191 | pcr |= SET_VCC_VPP(VCC_HIZ,VPP_5V, | ||
192 | configure->sock); | ||
193 | break; | ||
194 | case 33: | ||
195 | pcr |= SET_VCC_VPP(VCC_HIZ,VPP_3V, | ||
196 | configure->sock); | ||
197 | break; | ||
198 | default: | ||
199 | pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ, | ||
200 | configure->sock); | ||
201 | printk("%s: bad Vcc/Vpp (%d:%d)\n", | ||
202 | __func__, | ||
203 | configure->vcc, | ||
204 | configure->vpp); | ||
205 | break; | ||
206 | } | ||
207 | break; | ||
208 | case 50: /* Vcc 5V */ | ||
209 | switch(configure->vpp) { | ||
210 | case 0: | ||
211 | pcr |= SET_VCC_VPP(VCC_5V,VPP_GND, | ||
212 | configure->sock); | ||
213 | break; | ||
214 | case 50: | ||
215 | pcr |= SET_VCC_VPP(VCC_5V,VPP_5V, | ||
216 | configure->sock); | ||
217 | break; | ||
218 | case 12: | ||
219 | pcr |= SET_VCC_VPP(VCC_5V,VPP_12V, | ||
220 | configure->sock); | ||
221 | break; | ||
222 | case 33: | ||
223 | pcr |= SET_VCC_VPP(VCC_5V,VPP_3V, | ||
224 | configure->sock); | ||
225 | break; | ||
226 | default: | ||
227 | pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ, | ||
228 | configure->sock); | ||
229 | printk("%s: bad Vcc/Vpp (%d:%d)\n", | ||
230 | __func__, | ||
231 | configure->vcc, | ||
232 | configure->vpp); | ||
233 | break; | ||
234 | } | ||
235 | break; | ||
236 | case 33: /* Vcc 3.3V */ | ||
237 | switch(configure->vpp) { | ||
238 | case 0: | ||
239 | pcr |= SET_VCC_VPP(VCC_3V,VPP_GND, | ||
240 | configure->sock); | ||
241 | break; | ||
242 | case 50: | ||
243 | pcr |= SET_VCC_VPP(VCC_3V,VPP_5V, | ||
244 | configure->sock); | ||
245 | break; | ||
246 | case 12: | ||
247 | pcr |= SET_VCC_VPP(VCC_3V,VPP_12V, | ||
248 | configure->sock); | ||
249 | break; | ||
250 | case 33: | ||
251 | pcr |= SET_VCC_VPP(VCC_3V,VPP_3V, | ||
252 | configure->sock); | ||
253 | break; | ||
254 | default: | ||
255 | pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ, | ||
256 | configure->sock); | ||
257 | printk("%s: bad Vcc/Vpp (%d:%d)\n", | ||
258 | __func__, | ||
259 | configure->vcc, | ||
260 | configure->vpp); | ||
261 | break; | ||
262 | } | ||
263 | break; | ||
264 | default: /* what's this ? */ | ||
265 | pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,configure->sock); | ||
266 | printk(KERN_ERR "%s: bad Vcc %d\n", | ||
267 | __func__, configure->vcc); | ||
268 | break; | ||
269 | } | ||
270 | |||
271 | if (configure->sock == 0) { | ||
272 | pcr &= ~(PCR_SLOT_0_RST); | ||
273 | if (configure->reset) | ||
274 | pcr |= PCR_SLOT_0_RST; | ||
275 | } | ||
276 | else { | ||
277 | pcr &= ~(PCR_SLOT_1_RST); | ||
278 | if (configure->reset) | ||
279 | pcr |= PCR_SLOT_1_RST; | ||
280 | } | ||
281 | au_writel(pcr, PB1000_PCR); | ||
282 | au_sync_delay(300); | ||
283 | |||
284 | return 0; | ||
285 | } | ||
286 | |||
287 | |||
288 | struct pcmcia_low_level pb1x00_pcmcia_ops = { | ||
289 | pb1x00_pcmcia_init, | ||
290 | pb1x00_pcmcia_shutdown, | ||
291 | pb1x00_pcmcia_socket_state, | ||
292 | pb1x00_pcmcia_get_irq_info, | ||
293 | pb1x00_pcmcia_configure_socket | ||
294 | }; | ||