Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / drivers / pcmcia / au1000_db1x00.c
1 /*
2  *
3  * Alchemy Semi Db1x00 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  * Copyright 2004 Pete Popov, updated the driver to 2.6.
10  * Followed the sa11xx API and largely copied many of the hardware
11  * independent functions.
12  *
13  * ########################################################################
14  *
15  *  This program is free software; you can distribute it and/or modify it
16  *  under the terms of the GNU General Public License (Version 2) as
17  *  published by the Free Software Foundation.
18  *
19  *  This program is distributed in the hope it will be useful, but WITHOUT
20  *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
22  *  for more details.
23  *
24  *  You should have received a copy of the GNU General Public License along
25  *  with this program; if not, write to the Free Software Foundation, Inc.,
26  *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
27  *
28  * ########################################################################
29  *
30  *
31  */
32
33 #include <linux/config.h>
34 #include <linux/module.h>
35 #include <linux/kernel.h>
36 #include <linux/errno.h>
37 #include <linux/interrupt.h>
38 #include <linux/device.h>
39 #include <linux/init.h>
40
41 #include <asm/irq.h>
42 #include <asm/signal.h>
43 #include <asm/mach-au1x00/au1000.h>
44
45 #if defined(CONFIG_MIPS_DB1200)
46         #include <db1200.h>
47 #elif defined(CONFIG_MIPS_PB1200)
48         #include <pb1200.h>
49 #else
50         #include <asm/mach-db1x00/db1x00.h>
51         static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
52 #endif
53
54 #include "au1000_generic.h"
55
56 #if 0
57 #define debug(x,args...) printk(KERN_DEBUG "%s: " x, __func__ , ##args)
58 #else
59 #define debug(x,args...)
60 #endif
61
62
63 struct au1000_pcmcia_socket au1000_pcmcia_socket[PCMCIA_NUM_SOCKS];
64 extern int au1x00_pcmcia_socket_probe(struct device *, struct pcmcia_low_level *, int, int);
65
66 static int db1x00_pcmcia_hw_init(struct au1000_pcmcia_socket *skt)
67 {
68 #ifdef CONFIG_MIPS_DB1550
69         skt->irq = skt->nr ? AU1000_GPIO_5 : AU1000_GPIO_3;
70 #elif defined(CONFIG_MIPS_DB1200) || defined(CONFIG_MIPS_PB1200)
71         skt->irq = skt->nr ? BOARD_PC1_INT : BOARD_PC0_INT;
72 #else
73         skt->irq = skt->nr ? AU1000_GPIO_5 : AU1000_GPIO_2;
74 #endif
75         return 0;
76 }
77
78 static void db1x00_pcmcia_shutdown(struct au1000_pcmcia_socket *skt)
79 {
80         bcsr->pcmcia = 0; /* turn off power */
81         au_sync_delay(2);
82 }
83
84 static void
85 db1x00_pcmcia_socket_state(struct au1000_pcmcia_socket *skt, struct pcmcia_state *state)
86 {
87         u32 inserted;
88         unsigned char vs;
89
90         state->ready = 0;
91         state->vs_Xv = 0;
92         state->vs_3v = 0;
93         state->detect = 0;
94
95         switch (skt->nr) {
96         case 0:
97                 vs = bcsr->status & 0x3;
98 #if defined(CONFIG_MIPS_DB1200) || defined(CONFIG_MIPS_PB1200)
99                 inserted = BOARD_CARD_INSERTED(0);
100 #else
101                 inserted = !(bcsr->status & (1<<4));
102 #endif
103                 break;
104         case 1:
105                 vs = (bcsr->status & 0xC)>>2;
106 #if defined(CONFIG_MIPS_DB1200) || defined(CONFIG_MIPS_PB1200)
107                 inserted = BOARD_CARD_INSERTED(1);
108 #else
109                 inserted = !(bcsr->status & (1<<5));
110 #endif
111                 break;
112         default:/* should never happen */
113                 return;
114         }
115
116         if (inserted)
117                 debug("db1x00 socket %d: inserted %d, vs %d pcmcia %x\n",
118                                 skt->nr, inserted, vs, bcsr->pcmcia);
119
120         if (inserted) {
121                 switch (vs) {
122                         case 0:
123                         case 2:
124                                 state->vs_3v=1;
125                                 break;
126                         case 3: /* 5V */
127                                 break;
128                         default:
129                                 /* return without setting 'detect' */
130                                 printk(KERN_ERR "db1x00 bad VS (%d)\n",
131                                                 vs);
132                 }
133                 state->detect = 1;
134                 state->ready = 1;
135         }
136         else {
137                 /* if the card was previously inserted and then ejected,
138                  * we should turn off power to it
139                  */
140                 if ((skt->nr == 0) && (bcsr->pcmcia & BCSR_PCMCIA_PC0RST)) {
141                         bcsr->pcmcia &= ~(BCSR_PCMCIA_PC0RST |
142                                         BCSR_PCMCIA_PC0DRVEN |
143                                         BCSR_PCMCIA_PC0VPP |
144                                         BCSR_PCMCIA_PC0VCC);
145                         au_sync_delay(10);
146                 }
147                 else if ((skt->nr == 1) && bcsr->pcmcia & BCSR_PCMCIA_PC1RST) {
148                         bcsr->pcmcia &= ~(BCSR_PCMCIA_PC1RST |
149                                         BCSR_PCMCIA_PC1DRVEN |
150                                         BCSR_PCMCIA_PC1VPP |
151                                         BCSR_PCMCIA_PC1VCC);
152                         au_sync_delay(10);
153                 }
154         }
155
156         state->bvd1=1;
157         state->bvd2=1;
158         state->wrprot=0;
159 }
160
161 static int
162 db1x00_pcmcia_configure_socket(struct au1000_pcmcia_socket *skt, struct socket_state_t *state)
163 {
164         u16 pwr;
165         int sock = skt->nr;
166
167         debug("config_skt %d Vcc %dV Vpp %dV, reset %d\n",
168                         sock, state->Vcc, state->Vpp,
169                         state->flags & SS_RESET);
170
171         /* pcmcia reg was set to zero at init time. Be careful when
172          * initializing a socket not to wipe out the settings of the
173          * other socket.
174          */
175         pwr = bcsr->pcmcia;
176         pwr &= ~(0xf << sock*8); /* clear voltage settings */
177
178         state->Vpp = 0;
179         switch(state->Vcc){
180                 case 0:  /* Vcc 0 */
181                         pwr |= SET_VCC_VPP(0,0,sock);
182                         break;
183                 case 50: /* Vcc 5V */
184                         switch(state->Vpp) {
185                                 case 0:
186                                         pwr |= SET_VCC_VPP(2,0,sock);
187                                         break;
188                                 case 50:
189                                         pwr |= SET_VCC_VPP(2,1,sock);
190                                         break;
191                                 case 12:
192                                         pwr |= SET_VCC_VPP(2,2,sock);
193                                         break;
194                                 case 33:
195                                 default:
196                                         pwr |= SET_VCC_VPP(0,0,sock);
197                                         printk("%s: bad Vcc/Vpp (%d:%d)\n",
198                                                         __FUNCTION__,
199                                                         state->Vcc,
200                                                         state->Vpp);
201                                         break;
202                         }
203                         break;
204                 case 33: /* Vcc 3.3V */
205                         switch(state->Vpp) {
206                                 case 0:
207                                         pwr |= SET_VCC_VPP(1,0,sock);
208                                         break;
209                                 case 12:
210                                         pwr |= SET_VCC_VPP(1,2,sock);
211                                         break;
212                                 case 33:
213                                         pwr |= SET_VCC_VPP(1,1,sock);
214                                         break;
215                                 case 50:
216                                 default:
217                                         pwr |= SET_VCC_VPP(0,0,sock);
218                                         printk("%s: bad Vcc/Vpp (%d:%d)\n",
219                                                         __FUNCTION__,
220                                                         state->Vcc,
221                                                         state->Vpp);
222                                         break;
223                         }
224                         break;
225                 default: /* what's this ? */
226                         pwr |= SET_VCC_VPP(0,0,sock);
227                         printk(KERN_ERR "%s: bad Vcc %d\n",
228                                         __FUNCTION__, state->Vcc);
229                         break;
230         }
231
232         bcsr->pcmcia = pwr;
233         au_sync_delay(300);
234
235         if (sock == 0) {
236                 if (!(state->flags & SS_RESET)) {
237                         pwr |= BCSR_PCMCIA_PC0DRVEN;
238                         bcsr->pcmcia = pwr;
239                         au_sync_delay(300);
240                         pwr |= BCSR_PCMCIA_PC0RST;
241                         bcsr->pcmcia = pwr;
242                         au_sync_delay(100);
243                 }
244                 else {
245                         pwr &= ~(BCSR_PCMCIA_PC0RST | BCSR_PCMCIA_PC0DRVEN);
246                         bcsr->pcmcia = pwr;
247                         au_sync_delay(100);
248                 }
249         }
250         else {
251                 if (!(state->flags & SS_RESET)) {
252                         pwr |= BCSR_PCMCIA_PC1DRVEN;
253                         bcsr->pcmcia = pwr;
254                         au_sync_delay(300);
255                         pwr |= BCSR_PCMCIA_PC1RST;
256                         bcsr->pcmcia = pwr;
257                         au_sync_delay(100);
258                 }
259                 else {
260                         pwr &= ~(BCSR_PCMCIA_PC1RST | BCSR_PCMCIA_PC1DRVEN);
261                         bcsr->pcmcia = pwr;
262                         au_sync_delay(100);
263                 }
264         }
265         return 0;
266 }
267
268 /*
269  * Enable card status IRQs on (re-)initialisation.  This can
270  * be called at initialisation, power management event, or
271  * pcmcia event.
272  */
273 void db1x00_socket_init(struct au1000_pcmcia_socket *skt)
274 {
275         /* nothing to do for now */
276 }
277
278 /*
279  * Disable card status IRQs and PCMCIA bus on suspend.
280  */
281 void db1x00_socket_suspend(struct au1000_pcmcia_socket *skt)
282 {
283         /* nothing to do for now */
284 }
285
286 struct pcmcia_low_level db1x00_pcmcia_ops = {
287         .owner                  = THIS_MODULE,
288
289         .hw_init                = db1x00_pcmcia_hw_init,
290         .hw_shutdown            = db1x00_pcmcia_shutdown,
291
292         .socket_state           = db1x00_pcmcia_socket_state,
293         .configure_socket       = db1x00_pcmcia_configure_socket,
294
295         .socket_init            = db1x00_socket_init,
296         .socket_suspend         = db1x00_socket_suspend
297 };
298
299 int __init au1x_board_init(struct device *dev)
300 {
301         int ret = -ENODEV;
302         bcsr->pcmcia = 0; /* turn off power, if it's not already off */
303         au_sync_delay(2);
304         ret = au1x00_pcmcia_socket_probe(dev, &db1x00_pcmcia_ops, 0, 2);
305         return ret;
306 }