aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia/au1000_db1x00.c
diff options
context:
space:
mode:
authorManuel Lauss <manuel.lauss@googlemail.com>2009-10-04 08:55:27 -0400
committerRalf Baechle <ralf@linux-mips.org>2010-02-27 06:52:51 -0500
commit66213b3ccfc770704025ce9465fa3aaedde21b55 (patch)
tree2f74c1819b371926952c9c5b8f98ae808588e728 /drivers/pcmcia/au1000_db1x00.c
parent7e50b2b741bb4f9dbddc9f56972ef82a7d4b33ed (diff)
MIPS: PCMCIA: new socket driver for Au1000 demoboards.
New PCMCIA socket driver for all Db/Pb1xxx boards (except Pb1000), which replaces au1000_db1x00.c and (most of) au1000_pb1x00.c. Notable improvements: - supports Db1000, DB/PB1100/1500/1550/1200. - support for carddetect and statuschange IRQs. - pcmcia socket mem/io/attr areas and irqs passed through platform resource information. - doesn't freeze system during card insertion/ejection like the one it replaces. - boardtype is automatically detected using BCSR ID register. Run-tested on the DB1200. Cc: Linux-PCMCIA <linux-pcmcia@lists.infradead.org> Signed-off-by: Manuel Lauss <manuel.lauss@gmail.com> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'drivers/pcmcia/au1000_db1x00.c')
-rw-r--r--drivers/pcmcia/au1000_db1x00.c307
1 files changed, 0 insertions, 307 deletions
diff --git a/drivers/pcmcia/au1000_db1x00.c b/drivers/pcmcia/au1000_db1x00.c
deleted file mode 100644
index 3fdd664e41c6..000000000000
--- a/drivers/pcmcia/au1000_db1x00.c
+++ /dev/null
@@ -1,307 +0,0 @@
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#endif
51
52#include <asm/mach-db1x00/bcsr.h>
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
62struct au1000_pcmcia_socket au1000_pcmcia_socket[PCMCIA_NUM_SOCKS];
63extern int au1x00_pcmcia_socket_probe(struct device *, struct pcmcia_low_level *, int, int);
64
65static 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
77static void db1x00_pcmcia_shutdown(struct au1000_pcmcia_socket *skt)
78{
79 bcsr_write(BCSR_PCMCIA, 0); /* turn off power */
80 msleep(2);
81}
82
83static void
84db1x00_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_read(BCSR_STATUS) & 0x3;
97#if defined(CONFIG_MIPS_DB1200) || defined(CONFIG_MIPS_PB1200)
98 inserted = BOARD_CARD_INSERTED(0);
99#else
100 inserted = !(bcsr_read(BCSR_STATUS) & (1 << 4));
101#endif
102 break;
103 case 1:
104 vs = (bcsr_read(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_read(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_read(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) &&
140 (bcsr_read(BCSR_PCMCIA) & BCSR_PCMCIA_PC0RST)) {
141 bcsr_mod(BCSR_PCMCIA, BCSR_PCMCIA_PC0RST |
142 BCSR_PCMCIA_PC0DRVEN |
143 BCSR_PCMCIA_PC0VPP |
144 BCSR_PCMCIA_PC0VCC, 0);
145 msleep(10);
146 }
147 else if ((skt->nr == 1) &&
148 (bcsr_read(BCSR_PCMCIA) & BCSR_PCMCIA_PC1RST)) {
149 bcsr_mod(BCSR_PCMCIA, BCSR_PCMCIA_PC1RST |
150 BCSR_PCMCIA_PC1DRVEN |
151 BCSR_PCMCIA_PC1VPP |
152 BCSR_PCMCIA_PC1VCC, 0);
153 msleep(10);
154 }
155 }
156
157 state->bvd1=1;
158 state->bvd2=1;
159 state->wrprot=0;
160}
161
162static int
163db1x00_pcmcia_configure_socket(struct au1000_pcmcia_socket *skt, struct socket_state_t *state)
164{
165 u16 pwr;
166 int sock = skt->nr;
167
168 debug("config_skt %d Vcc %dV Vpp %dV, reset %d\n",
169 sock, state->Vcc, state->Vpp,
170 state->flags & SS_RESET);
171
172 /* pcmcia reg was set to zero at init time. Be careful when
173 * initializing a socket not to wipe out the settings of the
174 * other socket.
175 */
176 pwr = bcsr_read(BCSR_PCMCIA);
177 pwr &= ~(0xf << sock*8); /* clear voltage settings */
178
179 state->Vpp = 0;
180 switch(state->Vcc){
181 case 0: /* Vcc 0 */
182 pwr |= SET_VCC_VPP(0,0,sock);
183 break;
184 case 50: /* Vcc 5V */
185 switch(state->Vpp) {
186 case 0:
187 pwr |= SET_VCC_VPP(2,0,sock);
188 break;
189 case 50:
190 pwr |= SET_VCC_VPP(2,1,sock);
191 break;
192 case 12:
193 pwr |= SET_VCC_VPP(2,2,sock);
194 break;
195 case 33:
196 default:
197 pwr |= SET_VCC_VPP(0,0,sock);
198 printk("%s: bad Vcc/Vpp (%d:%d)\n",
199 __func__,
200 state->Vcc,
201 state->Vpp);
202 break;
203 }
204 break;
205 case 33: /* Vcc 3.3V */
206 switch(state->Vpp) {
207 case 0:
208 pwr |= SET_VCC_VPP(1,0,sock);
209 break;
210 case 12:
211 pwr |= SET_VCC_VPP(1,2,sock);
212 break;
213 case 33:
214 pwr |= SET_VCC_VPP(1,1,sock);
215 break;
216 case 50:
217 default:
218 pwr |= SET_VCC_VPP(0,0,sock);
219 printk("%s: bad Vcc/Vpp (%d:%d)\n",
220 __func__,
221 state->Vcc,
222 state->Vpp);
223 break;
224 }
225 break;
226 default: /* what's this ? */
227 pwr |= SET_VCC_VPP(0,0,sock);
228 printk(KERN_ERR "%s: bad Vcc %d\n",
229 __func__, state->Vcc);
230 break;
231 }
232
233 bcsr_write(BCSR_PCMCIA, pwr);
234 msleep(300);
235
236 if (sock == 0) {
237 if (!(state->flags & SS_RESET)) {
238 pwr |= BCSR_PCMCIA_PC0DRVEN;
239 bcsr_write(BCSR_PCMCIA, pwr);
240 msleep(300);
241 pwr |= BCSR_PCMCIA_PC0RST;
242 bcsr_write(BCSR_PCMCIA, pwr);
243 msleep(100);
244 }
245 else {
246 pwr &= ~(BCSR_PCMCIA_PC0RST | BCSR_PCMCIA_PC0DRVEN);
247 bcsr_write(BCSR_PCMCIA, pwr);
248 msleep(100);
249 }
250 }
251 else {
252 if (!(state->flags & SS_RESET)) {
253 pwr |= BCSR_PCMCIA_PC1DRVEN;
254 bcsr_write(BCSR_PCMCIA, pwr);
255 msleep(300);
256 pwr |= BCSR_PCMCIA_PC1RST;
257 bcsr_write(BCSR_PCMCIA, pwr);
258 msleep(100);
259 }
260 else {
261 pwr &= ~(BCSR_PCMCIA_PC1RST | BCSR_PCMCIA_PC1DRVEN);
262 bcsr_write(BCSR_PCMCIA, pwr);
263 msleep(100);
264 }
265 }
266 return 0;
267}
268
269/*
270 * Enable card status IRQs on (re-)initialisation. This can
271 * be called at initialisation, power management event, or
272 * pcmcia event.
273 */
274void db1x00_socket_init(struct au1000_pcmcia_socket *skt)
275{
276 /* nothing to do for now */
277}
278
279/*
280 * Disable card status IRQs and PCMCIA bus on suspend.
281 */
282void db1x00_socket_suspend(struct au1000_pcmcia_socket *skt)
283{
284 /* nothing to do for now */
285}
286
287struct pcmcia_low_level db1x00_pcmcia_ops = {
288 .owner = THIS_MODULE,
289
290 .hw_init = db1x00_pcmcia_hw_init,
291 .hw_shutdown = db1x00_pcmcia_shutdown,
292
293 .socket_state = db1x00_pcmcia_socket_state,
294 .configure_socket = db1x00_pcmcia_configure_socket,
295
296 .socket_init = db1x00_socket_init,
297 .socket_suspend = db1x00_socket_suspend
298};
299
300int au1x_board_init(struct device *dev)
301{
302 int ret = -ENODEV;
303 bcsr_write(BCSR_PCMCIA, 0); /* turn off power, if it's not already off */
304 msleep(2);
305 ret = au1x00_pcmcia_socket_probe(dev, &db1x00_pcmcia_ops, 0, 2);
306 return ret;
307}