6cbb1b1f7cfdf0a2224853f7cda97469b6deeffa
[linux-2.6.git] / drivers / pcmcia / pxa2xx_lubbock.c
1 /*
2  * linux/drivers/pcmcia/pxa2xx_lubbock.c
3  *
4  * Author:      George Davis
5  * Created:     Jan 10, 2002
6  * Copyright:   MontaVista Software Inc.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  *
12  * Originally based upon linux/drivers/pcmcia/sa1100_neponset.c
13  *
14  * Lubbock PCMCIA specific routines.
15  *
16  */
17 #include <linux/module.h>
18 #include <linux/kernel.h>
19 #include <linux/device.h>
20 #include <linux/errno.h>
21 #include <linux/init.h>
22 #include <linux/delay.h>
23
24 #include <mach/hardware.h>
25 #include <asm/hardware/sa1111.h>
26 #include <asm/mach-types.h>
27 #include <mach/lubbock.h>
28
29 #include "sa1111_generic.h"
30
31 static int
32 lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
33                                 const socket_state_t *state)
34 {
35         unsigned int pa_dwr_mask, pa_dwr_set, misc_mask, misc_set;
36         int ret = 0;
37
38         pa_dwr_mask = pa_dwr_set = misc_mask = misc_set = 0;
39
40         /* Lubbock uses the Maxim MAX1602, with the following connections:
41          *
42          * Socket 0 (PCMCIA):
43          *      MAX1602 Lubbock         Register
44          *      Pin     Signal
45          *      -----   -------         ----------------------
46          *      A0VPP   S0_PWR0         SA-1111 GPIO A<0>
47          *      A1VPP   S0_PWR1         SA-1111 GPIO A<1>
48          *      A0VCC   S0_PWR2         SA-1111 GPIO A<2>
49          *      A1VCC   S0_PWR3         SA-1111 GPIO A<3>
50          *      VX      VCC
51          *      VY      +3.3V
52          *      12IN    +12V
53          *      CODE    +3.3V           Cirrus  Code, CODE = High (VY)
54          *
55          * Socket 1 (CF):
56          *      MAX1602 Lubbock         Register
57          *      Pin     Signal
58          *      -----   -------         ----------------------
59          *      A0VPP   GND             VPP is not connected
60          *      A1VPP   GND             VPP is not connected
61          *      A0VCC   S1_PWR0         MISC_WR<14>
62          *      A1VCC   S1_PWR1         MISC_WR<15>
63          *      VX      VCC
64          *      VY      +3.3V
65          *      12IN    GND             VPP is not connected
66          *      CODE    +3.3V           Cirrus  Code, CODE = High (VY)
67          *
68          */
69
70  again:
71         switch (skt->nr) {
72         case 0:
73                 pa_dwr_mask = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3;
74
75                 switch (state->Vcc) {
76                 case 0: /* Hi-Z */
77                         break;
78
79                 case 33: /* VY */
80                         pa_dwr_set |= GPIO_A3;
81                         break;
82
83                 case 50: /* VX */
84                         pa_dwr_set |= GPIO_A2;
85                         break;
86
87                 default:
88                         printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
89                                __func__, state->Vcc);
90                         ret = -1;
91                 }
92
93                 switch (state->Vpp) {
94                 case 0: /* Hi-Z */
95                         break;
96
97                 case 120: /* 12IN */
98                         pa_dwr_set |= GPIO_A1;
99                         break;
100
101                 default: /* VCC */
102                         if (state->Vpp == state->Vcc)
103                                 pa_dwr_set |= GPIO_A0;
104                         else {
105                                 printk(KERN_ERR "%s(): unrecognized Vpp %u\n",
106                                        __func__, state->Vpp);
107                                 ret = -1;
108                                 break;
109                         }
110                 }
111                 break;
112
113         case 1:
114                 misc_mask = (1 << 15) | (1 << 14);
115
116                 switch (state->Vcc) {
117                 case 0: /* Hi-Z */
118                         break;
119
120                 case 33: /* VY */
121                         misc_set |= 1 << 15;
122                         break;
123
124                 case 50: /* VX */
125                         misc_set |= 1 << 14;
126                         break;
127
128                 default:
129                         printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
130                                __func__, state->Vcc);
131                         ret = -1;
132                         break;
133                 }
134
135                 if (state->Vpp != state->Vcc && state->Vpp != 0) {
136                         printk(KERN_ERR "%s(): CF slot cannot support Vpp %u\n",
137                                __func__, state->Vpp);
138                         ret = -1;
139                         break;
140                 }
141                 break;
142
143         default:
144                 ret = -1;
145         }
146
147         if (ret == 0)
148                 ret = sa1111_pcmcia_configure_socket(skt, state);
149
150         if (ret == 0) {
151                 lubbock_set_misc_wr(misc_mask, misc_set);
152                 sa1111_set_io(SA1111_DEV(skt->dev), pa_dwr_mask, pa_dwr_set);
153         }
154
155 #if 1
156         if (ret == 0 && state->Vcc == 33) {
157                 struct pcmcia_state new_state;
158
159                 /*
160                  * HACK ALERT:
161                  * We can't sense the voltage properly on Lubbock before
162                  * actually applying some power to the socket (catch 22).
163                  * Resense the socket Voltage Sense pins after applying
164                  * socket power.
165                  *
166                  * Note: It takes about 2.5ms for the MAX1602 VCC output
167                  * to rise.
168                  */
169                 mdelay(3);
170
171                 sa1111_pcmcia_socket_state(skt, &new_state);
172
173                 if (!new_state.vs_3v && !new_state.vs_Xv) {
174                         /*
175                          * Switch to 5V,  Configure socket with 5V voltage
176                          */
177                         lubbock_set_misc_wr(misc_mask, 0);
178                         sa1111_set_io(SA1111_DEV(skt->dev), pa_dwr_mask, 0);
179
180                         /*
181                          * It takes about 100ms to turn off Vcc.
182                          */
183                         mdelay(100);
184
185                         /*
186                          * We need to hack around the const qualifier as
187                          * well to keep this ugly workaround localized and
188                          * not force it to the rest of the code. Barf bags
189                          * avaliable in the seat pocket in front of you!
190                          */
191                         ((socket_state_t *)state)->Vcc = 50;
192                         ((socket_state_t *)state)->Vpp = 50;
193                         goto again;
194                 }
195         }
196 #endif
197
198         return ret;
199 }
200
201 static struct pcmcia_low_level lubbock_pcmcia_ops = {
202         .owner                  = THIS_MODULE,
203         .hw_init                = sa1111_pcmcia_hw_init,
204         .hw_shutdown            = sa1111_pcmcia_hw_shutdown,
205         .socket_state           = sa1111_pcmcia_socket_state,
206         .configure_socket       = lubbock_pcmcia_configure_socket,
207         .socket_init            = sa1111_pcmcia_socket_init,
208         .socket_suspend         = sa1111_pcmcia_socket_suspend,
209         .first                  = 0,
210         .nr                     = 2,
211 };
212
213 #include "pxa2xx_base.h"
214
215 int pcmcia_lubbock_init(struct sa1111_dev *sadev)
216 {
217         int ret = -ENODEV;
218
219         if (machine_is_lubbock()) {
220                 /*
221                  * Set GPIO_A<3:0> to be outputs for the MAX1600,
222                  * and switch to standby mode.
223                  */
224                 sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0);
225                 sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
226                 sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
227
228                 /* Set CF Socket 1 power to standby mode. */
229                 lubbock_set_misc_wr((1 << 15) | (1 << 14), 0);
230
231                 sadev->dev.platform_data = &lubbock_pcmcia_ops;
232                 ret = __pxa2xx_drv_pcmcia_probe(&sadev->dev);
233         }
234
235         return ret;
236 }
237
238 MODULE_LICENSE("GPL");