1 /*
2  *
3  * Alchemy Semi Pb1x00 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/tqueue.h>
30 #include <linux/timer.h>
31 #include <linux/mm.h>
32 #include <linux/proc_fs.h>
33 #include <linux/version.h>
34 #include <linux/types.h>
35 
36 #include <pcmcia/version.h>
37 #include <pcmcia/cs_types.h>
38 #include <pcmcia/cs.h>
39 #include <pcmcia/ss.h>
40 #include <pcmcia/bulkmem.h>
41 #include <pcmcia/cistpl.h>
42 #include <pcmcia/bus_ops.h>
43 #include "cs_internal.h"
44 
45 #include <asm/io.h>
46 #include <asm/irq.h>
47 #include <asm/system.h>
48 
49 #include <asm/au1000.h>
50 #include <asm/au1000_pcmcia.h>
51 
52 #ifdef CONFIG_MIPS_PB1000
53 #include <asm/pb1000.h>
54 #define PCMCIA_IRQ AU1000_GPIO_15
55 #elif defined (CONFIG_MIPS_PB1500)
56 #include <asm/pb1500.h>
57 #define PCMCIA_IRQ AU1500_GPIO_203
58 #elif defined (CONFIG_MIPS_PB1100)
59 #include <asm/pb1100.h>
60 #define PCMCIA_IRQ AU1000_GPIO_11
61 #endif
62 
pb1x00_pcmcia_init(struct pcmcia_init * init)63 static int pb1x00_pcmcia_init(struct pcmcia_init *init)
64 {
65 #ifdef CONFIG_MIPS_PB1000
66 	u16 pcr;
67 	pcr = PCR_SLOT_0_RST | PCR_SLOT_1_RST;
68 
69 	au_writel(0x8000, PB1000_MDR); /* clear pcmcia interrupt */
70 	au_sync_delay(100);
71 	au_writel(0x4000, PB1000_MDR); /* enable pcmcia interrupt */
72 	au_sync();
73 
74 	pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,0);
75 	pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,1);
76 	au_writel(pcr, PB1000_PCR);
77 	au_sync_delay(20);
78 
79 	return PCMCIA_NUM_SOCKS;
80 
81 #else /* fixme -- take care of the Pb1500 at some point */
82 
83 	u16 pcr;
84 	pcr = au_readw(PCMCIA_BOARD_REG) & ~0xf; /* turn off power */
85 	pcr &= ~(PC_DEASSERT_RST | PC_DRV_EN);
86 	au_writew(pcr, PCMCIA_BOARD_REG);
87 	au_sync_delay(500);
88 	return PCMCIA_NUM_SOCKS;
89 #endif
90 }
91 
pb1x00_pcmcia_shutdown(void)92 static int pb1x00_pcmcia_shutdown(void)
93 {
94 #ifdef CONFIG_MIPS_PB1000
95 	u16 pcr;
96 	pcr = PCR_SLOT_0_RST | PCR_SLOT_1_RST;
97 	pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,0);
98 	pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,1);
99 	au_writel(pcr, PB1000_PCR);
100 	au_sync_delay(20);
101 	return 0;
102 #else
103 	u16 pcr;
104 	pcr = au_readw(PCMCIA_BOARD_REG) & ~0xf; /* turn off power */
105 	pcr &= ~(PC_DEASSERT_RST | PC_DRV_EN);
106 	au_writew(pcr, PCMCIA_BOARD_REG);
107 	au_sync_delay(2);
108 	return 0;
109 #endif
110 }
111 
112 static int
pb1x00_pcmcia_socket_state(unsigned sock,struct pcmcia_state * state)113 pb1x00_pcmcia_socket_state(unsigned sock, struct pcmcia_state *state)
114 {
115 	u32 inserted0, inserted1;
116 	u16 vs0, vs1;
117 
118 #ifdef CONFIG_MIPS_PB1000
119 	vs0 = vs1 = (u16)au_readl(PB1000_ACR1);
120 	inserted0 = !(vs0 & (ACR1_SLOT_0_CD1 | ACR1_SLOT_0_CD2));
121 	inserted1 = !(vs1 & (ACR1_SLOT_1_CD1 | ACR1_SLOT_1_CD2));
122 	vs0 = (vs0 >> 4) & 0x3;
123 	vs1 = (vs1 >> 12) & 0x3;
124 #else
125 	vs0 = (au_readw(BOARD_STATUS_REG) >> 4) & 0x3;
126 #ifdef CONFIG_MIPS_PB1500
127 	inserted0 = !((au_readl(GPIO2_PINSTATE) >> 1) & 0x1); /* gpio 201 */
128 #else /* Pb1100 */
129 	inserted0 = !((au_readl(SYS_PINSTATERD) >> 9) & 0x1); /* gpio 9 */
130 #endif
131 	inserted1 = 0;
132 #endif
133 
134 	state->ready = 0;
135 	state->vs_Xv = 0;
136 	state->vs_3v = 0;
137 	state->detect = 0;
138 
139 	if (sock == 0) {
140 		if (inserted0) {
141 			switch (vs0) {
142 				case 0:
143 				case 2:
144 					state->vs_3v=1;
145 					break;
146 				case 3: /* 5V */
147 					break;
148 				default:
149 					/* return without setting 'detect' */
150 					printk(KERN_ERR "pb1x00 bad VS (%d)\n",
151 							vs0);
152 					return 0;
153 			}
154 			state->detect = 1;
155 		}
156 	}
157 	else  {
158 		if (inserted1) {
159 			switch (vs1) {
160 				case 0:
161 				case 2:
162 					state->vs_3v=1;
163 					break;
164 				case 3: /* 5V */
165 					break;
166 				default:
167 					/* return without setting 'detect' */
168 					printk(KERN_ERR "pb1x00 bad VS (%d)\n",
169 							vs1);
170 					return 0;
171 			}
172 			state->detect = 1;
173 		}
174 	}
175 
176 	if (state->detect) {
177 		state->ready = 1;
178 	}
179 
180 	state->bvd1=1;
181 	state->bvd2=1;
182 	state->wrprot=0;
183 	return 1;
184 }
185 
186 
pb1x00_pcmcia_get_irq_info(struct pcmcia_irq_info * info)187 static int pb1x00_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
188 {
189 
190 	if(info->sock > PCMCIA_MAX_SOCK) return -1;
191 
192 	/*
193 	 * Even in the case of the Pb1000, both sockets are connected
194 	 * to the same irq line.
195 	 */
196 	info->irq = PCMCIA_IRQ;
197 
198 	return 0;
199 }
200 
201 
202 static int
pb1x00_pcmcia_configure_socket(const struct pcmcia_configure * configure)203 pb1x00_pcmcia_configure_socket(const struct pcmcia_configure *configure)
204 {
205 	u16 pcr;
206 
207 	if(configure->sock > PCMCIA_MAX_SOCK) return -1;
208 
209 #ifdef CONFIG_MIPS_PB1000
210 	pcr = au_readl(PB1000_PCR);
211 
212 	if (configure->sock == 0) {
213 		pcr &= ~(PCR_SLOT_0_VCC0 | PCR_SLOT_0_VCC1 |
214 				PCR_SLOT_0_VPP0 | PCR_SLOT_0_VPP1);
215 	}
216 	else  {
217 		pcr &= ~(PCR_SLOT_1_VCC0 | PCR_SLOT_1_VCC1 |
218 				PCR_SLOT_1_VPP0 | PCR_SLOT_1_VPP1);
219 	}
220 
221 	pcr &= ~PCR_SLOT_0_RST;
222 	DEBUG(KERN_INFO "Vcc %dV Vpp %dV, pcr %x\n",
223 			configure->vcc, configure->vpp, pcr);
224 	switch(configure->vcc){
225 		case 0:  /* Vcc 0 */
226 			switch(configure->vpp) {
227 				case 0:
228 					pcr |= SET_VCC_VPP(VCC_HIZ,VPP_GND,
229 							configure->sock);
230 					break;
231 				case 12:
232 					pcr |= SET_VCC_VPP(VCC_HIZ,VPP_12V,
233 							configure->sock);
234 					break;
235 				case 50:
236 					pcr |= SET_VCC_VPP(VCC_HIZ,VPP_5V,
237 							configure->sock);
238 					break;
239 				case 33:
240 					pcr |= SET_VCC_VPP(VCC_HIZ,VPP_3V,
241 							configure->sock);
242 					break;
243 				default:
244 					pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,
245 							configure->sock);
246 					printk("%s: bad Vcc/Vpp (%d:%d)\n",
247 							__FUNCTION__,
248 							configure->vcc,
249 							configure->vpp);
250 					break;
251 			}
252 			break;
253 		case 50: /* Vcc 5V */
254 			switch(configure->vpp) {
255 				case 0:
256 					pcr |= SET_VCC_VPP(VCC_5V,VPP_GND,
257 							configure->sock);
258 					break;
259 				case 50:
260 					pcr |= SET_VCC_VPP(VCC_5V,VPP_5V,
261 							configure->sock);
262 					break;
263 				case 12:
264 					pcr |= SET_VCC_VPP(VCC_5V,VPP_12V,
265 							configure->sock);
266 					break;
267 				case 33:
268 					pcr |= SET_VCC_VPP(VCC_5V,VPP_3V,
269 							configure->sock);
270 					break;
271 				default:
272 					pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,
273 							configure->sock);
274 					printk("%s: bad Vcc/Vpp (%d:%d)\n",
275 							__FUNCTION__,
276 							configure->vcc,
277 							configure->vpp);
278 					break;
279 			}
280 			break;
281 		case 33: /* Vcc 3.3V */
282 			switch(configure->vpp) {
283 				case 0:
284 					pcr |= SET_VCC_VPP(VCC_3V,VPP_GND,
285 							configure->sock);
286 					break;
287 				case 50:
288 					pcr |= SET_VCC_VPP(VCC_3V,VPP_5V,
289 							configure->sock);
290 					break;
291 				case 12:
292 					pcr |= SET_VCC_VPP(VCC_3V,VPP_12V,
293 							configure->sock);
294 					break;
295 				case 33:
296 					pcr |= SET_VCC_VPP(VCC_3V,VPP_3V,
297 							configure->sock);
298 					break;
299 				default:
300 					pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,
301 							configure->sock);
302 					printk("%s: bad Vcc/Vpp (%d:%d)\n",
303 							__FUNCTION__,
304 							configure->vcc,
305 							configure->vpp);
306 					break;
307 			}
308 			break;
309 		default: /* what's this ? */
310 			pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,configure->sock);
311 			printk(KERN_ERR "%s: bad Vcc %d\n",
312 					__FUNCTION__, configure->vcc);
313 			break;
314 	}
315 
316 	if (configure->sock == 0) {
317 	pcr &= ~(PCR_SLOT_0_RST);
318 		if (configure->reset)
319 		pcr |= PCR_SLOT_0_RST;
320 	}
321 	else {
322 		pcr &= ~(PCR_SLOT_1_RST);
323 		if (configure->reset)
324 			pcr |= PCR_SLOT_1_RST;
325 	}
326 	au_writel(pcr, PB1000_PCR);
327 	au_sync_delay(300);
328 
329 #else
330 
331 	pcr = au_readw(PCMCIA_BOARD_REG) & ~0xf;
332 
333 	DEBUG(KERN_INFO "Vcc %dV Vpp %dV, pcr %x, reset %d\n",
334 			configure->vcc, configure->vpp, pcr, configure->reset);
335 
336 
337 	switch(configure->vcc){
338 		case 0:  /* Vcc 0 */
339 			pcr |= SET_VCC_VPP(0,0);
340 			break;
341 		case 50: /* Vcc 5V */
342 			switch(configure->vpp) {
343 				case 0:
344 					pcr |= SET_VCC_VPP(2,0);
345 					break;
346 				case 50:
347 					pcr |= SET_VCC_VPP(2,1);
348 					break;
349 				case 12:
350 					pcr |= SET_VCC_VPP(2,2);
351 					break;
352 				case 33:
353 				default:
354 					pcr |= SET_VCC_VPP(0,0);
355 					printk("%s: bad Vcc/Vpp (%d:%d)\n",
356 							__FUNCTION__,
357 							configure->vcc,
358 							configure->vpp);
359 					break;
360 			}
361 			break;
362 		case 33: /* Vcc 3.3V */
363 			switch(configure->vpp) {
364 				case 0:
365 					pcr |= SET_VCC_VPP(1,0);
366 					break;
367 				case 12:
368 					pcr |= SET_VCC_VPP(1,2);
369 					break;
370 				case 33:
371 					pcr |= SET_VCC_VPP(1,1);
372 					break;
373 				case 50:
374 				default:
375 					pcr |= SET_VCC_VPP(0,0);
376 					printk("%s: bad Vcc/Vpp (%d:%d)\n",
377 							__FUNCTION__,
378 							configure->vcc,
379 							configure->vpp);
380 					break;
381 			}
382 			break;
383 		default: /* what's this ? */
384 			pcr |= SET_VCC_VPP(0,0);
385 			printk(KERN_ERR "%s: bad Vcc %d\n",
386 					__FUNCTION__, configure->vcc);
387 			break;
388 	}
389 
390 	au_writew(pcr, PCMCIA_BOARD_REG);
391 	au_sync_delay(300);
392 
393 	if (!configure->reset) {
394 		pcr |= PC_DRV_EN;
395 		au_writew(pcr, PCMCIA_BOARD_REG);
396 		au_sync_delay(100);
397 		pcr |= PC_DEASSERT_RST;
398 		au_writew(pcr, PCMCIA_BOARD_REG);
399 		au_sync_delay(100);
400 	}
401 	else {
402 		pcr &= ~(PC_DEASSERT_RST | PC_DRV_EN);
403 		au_writew(pcr, PCMCIA_BOARD_REG);
404 		au_sync_delay(100);
405 	}
406 #endif
407 	return 0;
408 }
409 
410 
411 struct pcmcia_low_level au1x00_pcmcia_ops = {
412 	pb1x00_pcmcia_init,
413 	pb1x00_pcmcia_shutdown,
414 	pb1x00_pcmcia_socket_state,
415 	pb1x00_pcmcia_get_irq_info,
416 	pb1x00_pcmcia_configure_socket
417 };
418