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