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

Subversion Repositories or1k

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

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

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * drivers/pcmcia/sa1100_assabet.c
3
 *
4
 * PCMCIA implementation routines for Assabet
5
 *
6
 */
7
#include <linux/kernel.h>
8
#include <linux/sched.h>
9
 
10
#include <asm/hardware.h>
11
#include <asm/irq.h>
12
#include <asm/arch/assabet.h>
13
 
14
#include "sa1100_generic.h"
15
 
16
static struct irqs {
17
        int irq;
18
        unsigned int gpio;
19
        const char *str;
20
} irqs[] = {
21
        { ASSABET_IRQ_GPIO_CF_CD,   ASSABET_GPIO_CF_CD,   "CF_CD"   },
22
        { ASSABET_IRQ_GPIO_CF_BVD2, ASSABET_GPIO_CF_BVD2, "CF_BVD2" },
23
        { ASSABET_IRQ_GPIO_CF_BVD1, ASSABET_GPIO_CF_BVD1, "CF_BVD1" },
24
};
25
 
26
static int assabet_pcmcia_init(struct pcmcia_init *init)
27
{
28
        int i, res;
29
 
30
        /* Set transition detect */
31
        set_GPIO_IRQ_edge(ASSABET_GPIO_CF_IRQ, GPIO_FALLING_EDGE);
32
 
33
        /* Register interrupts */
34
        for (i = 0; i < ARRAY_SIZE(irqs); i++) {
35
                set_GPIO_IRQ_edge(irqs[i].gpio, GPIO_NO_EDGES);
36
                res = request_irq(irqs[i].irq, init->handler, SA_INTERRUPT,
37
                                  irqs[i].str, NULL);
38
                if (res)
39
                        goto irq_err;
40
        }
41
 
42
        /* There's only one slot, but it's "Slot 1": */
43
        return 2;
44
 
45
 irq_err:
46
        printk(KERN_ERR "%s: request for IRQ%d failed\n",
47
                __FUNCTION__, irqs[i].irq);
48
 
49
        while (i--)
50
                free_irq(irqs[i].irq, NULL);
51
 
52
        return -1;
53
}
54
 
55
/*
56
 * Release all resources.
57
 */
58
static int assabet_pcmcia_shutdown(void)
59
{
60
        int i;
61
 
62
        for (i = 0; i < ARRAY_SIZE(irqs); i++)
63
                free_irq(irqs[i].irq, NULL);
64
 
65
        return 0;
66
}
67
 
68
static int
69
assabet_pcmcia_socket_state(struct pcmcia_state_array *state_array)
70
{
71
        unsigned long levels;
72
 
73
        if (state_array->size < 2)
74
                return -1;
75
 
76
        levels = GPLR;
77
 
78
        state_array->state[1].detect = (levels & ASSABET_GPIO_CF_CD) ? 0 : 1;
79
        state_array->state[1].ready  = (levels & ASSABET_GPIO_CF_IRQ) ? 1 : 0;
80
        state_array->state[1].bvd1   = (levels & ASSABET_GPIO_CF_BVD1) ? 1 : 0;
81
        state_array->state[1].bvd2   = (levels & ASSABET_GPIO_CF_BVD2) ? 1 : 0;
82
        state_array->state[1].wrprot = 0; /* Not available on Assabet. */
83
        state_array->state[1].vs_3v  = 1; /* Can only apply 3.3V on Assabet. */
84
        state_array->state[1].vs_Xv  = 0;
85
 
86
        return 1;
87
}
88
 
89
static int assabet_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
90
{
91
        if (info->sock > 1)
92
                return -1;
93
 
94
        if (info->sock == 1)
95
                info->irq = ASSABET_IRQ_GPIO_CF_IRQ;
96
 
97
        return 0;
98
}
99
 
100
static int
101
assabet_pcmcia_configure_socket(const struct pcmcia_configure *configure)
102
{
103
        unsigned int mask;
104
 
105
        if (configure->sock > 1)
106
                return -1;
107
 
108
        if (configure->sock == 0)
109
                return 0;
110
 
111
        switch (configure->vcc) {
112
        case 0:
113
                mask = 0;
114
                break;
115
 
116
        case 50:
117
                printk(KERN_WARNING "%s(): CS asked for 5V, applying 3.3V...\n",
118
                        __FUNCTION__);
119
 
120
        case 33:  /* Can only apply 3.3V to the CF slot. */
121
                mask = ASSABET_BCR_CF_PWR;
122
                break;
123
 
124
        default:
125
                printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
126
                        configure->vcc);
127
                return -1;
128
        }
129
 
130
        /* Silently ignore Vpp, output enable, speaker enable. */
131
 
132
        if (configure->reset)
133
                mask |= ASSABET_BCR_CF_RST;
134
 
135
        ASSABET_BCR_frob(ASSABET_BCR_CF_RST | ASSABET_BCR_CF_PWR, mask);
136
 
137
        /*
138
         * Handle suspend mode properly.  This prevents a
139
         * flood of IRQs from the CF device.
140
         */
141
        if (configure->irq)
142
                enable_irq(ASSABET_IRQ_GPIO_CF_IRQ);
143
        else
144
                disable_irq(ASSABET_IRQ_GPIO_CF_IRQ);
145
 
146
        return 0;
147
}
148
 
149
/*
150
 * Enable card status IRQs on (re-)initialisation.  This can
151
 * be called at initialisation, power management event, or
152
 * pcmcia event.
153
 */
154
static int assabet_pcmcia_socket_init(int sock)
155
{
156
        int i;
157
 
158
        if (sock == 1) {
159
                /*
160
                 * Enable CF bus
161
                 */
162
                ASSABET_BCR_clear(ASSABET_BCR_CF_BUS_OFF);
163
 
164
                for (i = 0; i < ARRAY_SIZE(irqs); i++)
165
                        set_GPIO_IRQ_edge(irqs[i].gpio, GPIO_BOTH_EDGES);
166
        }
167
 
168
        return 0;
169
}
170
 
171
/*
172
 * Disable card status IRQs on suspend.
173
 */
174
static int assabet_pcmcia_socket_suspend(int sock)
175
{
176
        int i;
177
 
178
        if (sock == 1) {
179
                for (i = 0; i < ARRAY_SIZE(irqs); i++)
180
                        set_GPIO_IRQ_edge(irqs[i].gpio, GPIO_NO_EDGES);
181
 
182
                /*
183
                 * Tristate the CF bus signals.  Also assert CF
184
                 * reset as per user guide page 4-11.
185
                 */
186
                ASSABET_BCR_set(ASSABET_BCR_CF_BUS_OFF | ASSABET_BCR_CF_RST);
187
        }
188
 
189
        return 0;
190
}
191
 
192
struct pcmcia_low_level assabet_pcmcia_ops = {
193
        init:                   assabet_pcmcia_init,
194
        shutdown:               assabet_pcmcia_shutdown,
195
        socket_state:           assabet_pcmcia_socket_state,
196
        get_irq_info:           assabet_pcmcia_get_irq_info,
197
        configure_socket:       assabet_pcmcia_configure_socket,
198
 
199
        socket_init:            assabet_pcmcia_socket_init,
200
        socket_suspend:         assabet_pcmcia_socket_suspend,
201
};
202
 

powered by: WebSVN 2.1.0

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