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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [pcmcia/] [sa1100_stork.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * drivers/pcmcia/sa1100_stork.c
3
 *
4
    Copyright 2001 (C) Ken Gordon
5
 
6
    This is derived from pre-existing drivers/pcmcia/sa1100_?????.c
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 as published by
10
    the Free Software Foundation; either version 2 of the License.
11
 
12
    This program is distributed in the hope that it will be useful,
13
    but WITHOUT ANY WARRANTY; without even the implied warranty of
14
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
    GNU General Public License for more details.
16
 
17
 *
18
 * PCMCIA implementation routines for stork
19
 *
20
 */
21
 
22
#include <linux/config.h>
23
#include <linux/module.h>
24
#include <linux/init.h>
25
#include <linux/kernel.h>
26
#include <linux/sched.h>
27
 
28
#include <asm/hardware.h>
29
#include <asm/irq.h>
30
#include "sa1100_generic.h"
31
 
32
static int debug = 0;
33
 
34
static struct pcmcia_init sa1100_stork_pcmcia_init;
35
 
36
static int stork_pcmcia_init(struct pcmcia_init *init)
37
{
38
        int irq, res;
39
        printk("in stork_pcmcia_init\n");
40
 
41
        sa1100_stork_pcmcia_init = *init;
42
 
43
        /* Set transition detect */
44
        set_GPIO_IRQ_edge( GPIO_STORK_PCMCIA_A_CARD_DETECT | GPIO_STORK_PCMCIA_B_CARD_DETECT, GPIO_NO_EDGES );
45
        set_GPIO_IRQ_edge( GPIO_STORK_PCMCIA_A_RDY| GPIO_STORK_PCMCIA_B_RDY, GPIO_FALLING_EDGE );
46
 
47
        /* Register interrupts */
48
        irq = IRQ_GPIO_STORK_PCMCIA_A_CARD_DETECT;
49
        res = request_irq( irq, init->handler, SA_INTERRUPT, "PCMCIA_CD0", NULL );
50
        if( res < 0 ) goto irq_err;
51
        irq = IRQ_GPIO_STORK_PCMCIA_B_CARD_DETECT;
52
        res = request_irq( irq, init->handler, SA_INTERRUPT, "PCMCIA_CD1", NULL );
53
        if( res < 0 ) goto irq_err;
54
 
55
        return 2;
56
 
57
 irq_err:
58
        printk( KERN_ERR __FUNCTION__ ": Request for IRQ %u failed\n", irq );
59
        return -1;
60
}
61
 
62
static int stork_pcmcia_shutdown(void)
63
{
64
        printk(__FUNCTION__ "\n");
65
        /* disable IRQs */
66
        free_irq( IRQ_GPIO_STORK_PCMCIA_A_CARD_DETECT, NULL );
67
        free_irq( IRQ_GPIO_STORK_PCMCIA_B_CARD_DETECT, NULL );
68
 
69
        /* Disable CF bus: */
70
        storkClearLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);
71
        storkClearLatchA(STORK_PCMCIA_A_POWER_ON);
72
        storkClearLatchA(STORK_PCMCIA_B_POWER_ON);
73
        return 0;
74
}
75
 
76
static int stork_pcmcia_socket_state(struct pcmcia_state_array *state_array)
77
{
78
        unsigned long levels;
79
 
80
        if(state_array->size<2) return -1;
81
 
82
        memset(state_array->state, 0,
83
               (state_array->size)*sizeof(struct pcmcia_state));
84
 
85
        levels=GPLR;
86
 
87
        if (debug > 1)
88
                printk(__FUNCTION__ " GPLR=%x IRQ[1:0]=%x\n", GPLR, (GPLR & (GPIO_STORK_PCMCIA_A_RDY|GPIO_STORK_PCMCIA_B_RDY)));
89
        state_array->state[0].detect=((levels & GPIO_STORK_PCMCIA_A_CARD_DETECT)==0)?1:0;
90
        state_array->state[0].ready=(levels & GPIO_STORK_PCMCIA_A_RDY)?1:0;
91
        state_array->state[0].bvd1= 1;
92
        state_array->state[0].bvd2= 1;
93
        state_array->state[0].wrprot=0;
94
        state_array->state[0].vs_3v=1;
95
        state_array->state[0].vs_Xv=0;
96
 
97
        state_array->state[1].detect=((levels & GPIO_STORK_PCMCIA_B_CARD_DETECT)==0)?1:0;
98
        state_array->state[1].ready=(levels & GPIO_STORK_PCMCIA_B_RDY)?1:0;
99
        state_array->state[1].bvd1=1;
100
        state_array->state[1].bvd2=1;
101
        state_array->state[1].wrprot=0;
102
        state_array->state[1].vs_3v=1;
103
        state_array->state[1].vs_Xv=0;
104
 
105
        return 1;
106
}
107
 
108
static int stork_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
109
{
110
 
111
        switch (info->sock) {
112
        case 0:
113
                info->irq=IRQ_GPIO_STORK_PCMCIA_A_RDY;
114
                break;
115
        case 1:
116
                info->irq=IRQ_GPIO_STORK_PCMCIA_B_RDY;
117
                break;
118
        default:
119
                return -1;
120
        }
121
        return 0;
122
}
123
 
124
static int stork_pcmcia_configure_socket(const struct pcmcia_configure *configure)
125
{
126
        int card = configure->sock;
127
        unsigned long flags;
128
 
129
        int DETECT, RDY, POWER, RESET;
130
 
131
        if (card > 1) return -1;
132
 
133
        printk(__FUNCTION__ ": socket=%d vcc=%d vpp=%d reset=%d\n",
134
                       card, configure->vcc, configure->vpp, configure->reset);
135
 
136
        save_flags_cli(flags);
137
 
138
        if (card == 0) {
139
            DETECT = GPIO_STORK_PCMCIA_A_CARD_DETECT;
140
            RDY = GPIO_STORK_PCMCIA_A_RDY;
141
            POWER = STORK_PCMCIA_A_POWER_ON;
142
            RESET = STORK_PCMCIA_A_RESET;
143
        } else {
144
            DETECT = GPIO_STORK_PCMCIA_B_CARD_DETECT;
145
            RDY = GPIO_STORK_PCMCIA_B_RDY;
146
            POWER = STORK_PCMCIA_B_POWER_ON;
147
            RESET = STORK_PCMCIA_B_RESET;
148
        }
149
 
150
/*
151
        if (storkTestGPIO(DETECT)) {
152
           printk("no card detected - but resetting anyway\r\n");
153
        }
154
*/
155
        switch (configure->vcc) {
156
        case 0:
157
/*              storkClearLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON); */
158
                storkClearLatchA(POWER);
159
                break;
160
 
161
        case 50:
162
        case 33:
163
                storkSetLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);
164
                storkSetLatchA(POWER);
165
                break;
166
 
167
        default:
168
                printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
169
                       configure->vcc);
170
                restore_flags(flags);
171
                return -1;
172
        }
173
 
174
        if (configure->reset)
175
                storkSetLatchB(RESET);
176
        else
177
                storkClearLatchB(RESET);
178
 
179
        restore_flags(flags);
180
 
181
        /* silently ignore vpp and speaker enables. */
182
 
183
        printk(__FUNCTION__ ": finished\n");
184
 
185
        return 0;
186
}
187
 
188
static int stork_pcmcia_socket_init(int sock)
189
{
190
        storkSetLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);
191
 
192
        if (sock == 0)
193
                set_GPIO_IRQ_edge(GPIO_STORK_PCMCIA_A_CARD_DETECT, GPIO_BOTH_EDGES);
194
        else if (sock == 1)
195
                set_GPIO_IRQ_edge(GPIO_STORK_PCMCIA_B_CARD_DETECT, GPIO_BOTH_EDGES);
196
 
197
        return 0;
198
}
199
 
200
static int stork_pcmcia_socket_suspend(int sock)
201
{
202
        if (sock == 0)
203
                set_GPIO_IRQ_edge(GPIO_STORK_PCMCIA_A_CARD_DETECT, GPIO_NO_EDGES);
204
        else if (sock == 1) {
205
                set_GPIO_IRQ_edge(GPIO_STORK_PCMCIA_B_CARD_DETECT, GPIO_NO_EDGES);
206
 
207
                /*
208
                 * Hack!
209
                 */
210
                storkClearLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);
211
        }
212
 
213
        return 0;
214
}
215
 
216
struct pcmcia_low_level stork_pcmcia_ops = {
217
        init:                   stork_pcmcia_init,
218
        shutdown:               stork_pcmcia_shutdown,
219
        socket_state:           stork_pcmcia_socket_state,
220
        get_irq_info:           stork_pcmcia_get_irq_info,
221
        configure_socket:       stork_pcmcia_configure_socket,
222
 
223
        socket_init:            stork_pcmcia_socket_init,
224
        socket_suspend:         stork_pcmcia_socket_suspend,
225
};

powered by: WebSVN 2.1.0

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