setup enviroment for compilation
[linux-2.4.21-pre4.git] / drivers / pcmcia / sa1100_stork.c
1 /* 
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 #include <linux/i2c.h>
28
29 #include <asm/hardware.h>
30 #include <asm/irq.h>
31 #include "sa1100_generic.h"
32
33 static int debug = 0;
34
35 static struct pcmcia_init sa1100_stork_pcmcia_init;
36
37 static int stork_pcmcia_init(struct pcmcia_init *init)
38 {
39         int irq, res;
40         printk("in stork_pcmcia_init\n");
41
42         sa1100_stork_pcmcia_init = *init;
43
44         /* Set transition detect */
45         set_GPIO_IRQ_edge( GPIO_STORK_PCMCIA_A_CARD_DETECT | GPIO_STORK_PCMCIA_B_CARD_DETECT, GPIO_NO_EDGES );
46         set_GPIO_IRQ_edge( GPIO_STORK_PCMCIA_A_RDY| GPIO_STORK_PCMCIA_B_RDY, GPIO_FALLING_EDGE );
47
48         /* Register interrupts */
49         irq = IRQ_GPIO_STORK_PCMCIA_A_CARD_DETECT;
50         res = request_irq( irq, init->handler, SA_INTERRUPT, "PCMCIA_CD0", NULL );
51         if( res < 0 ) goto irq_err;
52         irq = IRQ_GPIO_STORK_PCMCIA_B_CARD_DETECT;
53         res = request_irq( irq, init->handler, SA_INTERRUPT, "PCMCIA_CD1", NULL );
54         if( res < 0 ) goto irq_err;
55
56         return 2;
57
58  irq_err:
59         printk( KERN_ERR __FUNCTION__ ": Request for IRQ %u failed\n", irq );
60         return -1;
61 }
62
63 static int stork_pcmcia_shutdown(void)
64 {
65         printk(__FUNCTION__ "\n");
66         /* disable IRQs */
67         free_irq( IRQ_GPIO_STORK_PCMCIA_A_CARD_DETECT, NULL );
68         free_irq( IRQ_GPIO_STORK_PCMCIA_B_CARD_DETECT, NULL );
69   
70         /* Disable CF bus: */
71         storkClearLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);
72         storkClearLatchA(STORK_PCMCIA_A_POWER_ON);
73         storkClearLatchA(STORK_PCMCIA_B_POWER_ON);
74         return 0;
75 }
76
77 static int stork_pcmcia_socket_state(struct pcmcia_state_array *state_array)
78 {
79         unsigned long levels;
80
81         if(state_array->size<2) return -1;
82
83         memset(state_array->state, 0, 
84                (state_array->size)*sizeof(struct pcmcia_state));
85
86         levels=GPLR;
87
88         if (debug > 1)
89                 printk(__FUNCTION__ " GPLR=%x IRQ[1:0]=%x\n", GPLR, (GPLR & (GPIO_STORK_PCMCIA_A_RDY|GPIO_STORK_PCMCIA_B_RDY)));
90         state_array->state[0].detect=((levels & GPIO_STORK_PCMCIA_A_CARD_DETECT)==0)?1:0;
91         state_array->state[0].ready=(levels & GPIO_STORK_PCMCIA_A_RDY)?1:0;
92         state_array->state[0].bvd1= 1;
93         state_array->state[0].bvd2= 1;
94         state_array->state[0].wrprot=0;
95         state_array->state[0].vs_3v=1;
96         state_array->state[0].vs_Xv=0;
97
98         state_array->state[1].detect=((levels & GPIO_STORK_PCMCIA_B_CARD_DETECT)==0)?1:0;
99         state_array->state[1].ready=(levels & GPIO_STORK_PCMCIA_B_RDY)?1:0;
100         state_array->state[1].bvd1=1;
101         state_array->state[1].bvd2=1;
102         state_array->state[1].wrprot=0;
103         state_array->state[1].vs_3v=1;
104         state_array->state[1].vs_Xv=0;
105
106         return 1;
107 }
108
109 static int stork_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
110 {
111
112         switch (info->sock) {
113         case 0:
114                 info->irq=IRQ_GPIO_STORK_PCMCIA_A_RDY;
115                 break;
116         case 1:
117                 info->irq=IRQ_GPIO_STORK_PCMCIA_B_RDY;
118                 break;
119         default:
120                 return -1;
121         }
122         return 0;
123 }
124
125 static int stork_pcmcia_configure_socket(const struct pcmcia_configure *configure)
126 {
127         int card = configure->sock;
128         unsigned long flags;
129
130         int DETECT, RDY, POWER, RESET;
131
132         if (card > 1) return -1;
133
134         printk(__FUNCTION__ ": socket=%d vcc=%d vpp=%d reset=%d\n", 
135                        card, configure->vcc, configure->vpp, configure->reset);
136
137         save_flags_cli(flags);
138
139         if (card == 0) {
140             DETECT = GPIO_STORK_PCMCIA_A_CARD_DETECT;
141             RDY = GPIO_STORK_PCMCIA_A_RDY;
142             POWER = STORK_PCMCIA_A_POWER_ON;
143             RESET = STORK_PCMCIA_A_RESET;
144         } else {
145             DETECT = GPIO_STORK_PCMCIA_B_CARD_DETECT;
146             RDY = GPIO_STORK_PCMCIA_B_RDY;
147             POWER = STORK_PCMCIA_B_POWER_ON;
148             RESET = STORK_PCMCIA_B_RESET;
149         }
150     
151 /*
152         if (storkTestGPIO(DETECT)) {
153            printk("no card detected - but resetting anyway\r\n");
154         }
155 */
156         switch (configure->vcc) {
157         case 0:
158 /*              storkClearLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON); */
159                 storkClearLatchA(POWER);
160                 break;
161
162         case 50:
163         case 33:
164                 storkSetLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);
165                 storkSetLatchA(POWER);
166                 break;
167
168         default:
169                 printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
170                        configure->vcc);
171                 restore_flags(flags);
172                 return -1;
173         }
174
175         if (configure->reset)
176                 storkSetLatchB(RESET);
177         else
178                 storkClearLatchB(RESET);
179
180         restore_flags(flags);
181
182         /* silently ignore vpp and speaker enables. */
183
184         printk(__FUNCTION__ ": finished\n");
185
186         return 0;
187 }
188
189 static int stork_pcmcia_socket_init(int sock)
190 {
191         storkSetLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);
192
193         if (sock == 0)
194                 set_GPIO_IRQ_edge(GPIO_STORK_PCMCIA_A_CARD_DETECT, GPIO_BOTH_EDGES);
195         else if (sock == 1)
196                 set_GPIO_IRQ_edge(GPIO_STORK_PCMCIA_B_CARD_DETECT, GPIO_BOTH_EDGES);
197
198         return 0;
199 }
200
201 static int stork_pcmcia_socket_suspend(int sock)
202 {
203         if (sock == 0)
204                 set_GPIO_IRQ_edge(GPIO_STORK_PCMCIA_A_CARD_DETECT, GPIO_NO_EDGES);
205         else if (sock == 1) {
206                 set_GPIO_IRQ_edge(GPIO_STORK_PCMCIA_B_CARD_DETECT, GPIO_NO_EDGES);
207
208                 /*
209                  * Hack!
210                  */
211                 storkClearLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);
212         }
213
214         return 0;
215 }
216
217 struct pcmcia_low_level stork_pcmcia_ops = { 
218         init:                   stork_pcmcia_init,
219         shutdown:               stork_pcmcia_shutdown,
220         socket_state:           stork_pcmcia_socket_state,
221         get_irq_info:           stork_pcmcia_get_irq_info,
222         configure_socket:       stork_pcmcia_configure_socket,
223
224         socket_init:            stork_pcmcia_socket_init,
225         socket_suspend:         stork_pcmcia_socket_suspend,
226 };