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