OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [pcmcia/] [pxa2xx_lubbock.c] - Blame information for rev 78

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.