initial commit with v2.6.9
[linux-2.6.9-moxart.git] / drivers / pcmcia / sa1100_stork.c
blob1110e63abf9771aef7e9c4ca29acc1d7a4863faf
1 /*
2 * drivers/pcmcia/sa1100_stork.c
4 Copyright 2001 (C) Ken Gordon
6 This is derived from pre-existing drivers/pcmcia/sa1100_?????.c
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.
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.
18 * PCMCIA implementation routines for stork
21 #include <linux/module.h>
22 #include <linux/init.h>
23 #include <linux/kernel.h>
24 #include <linux/sched.h>
25 #include <linux/device.h>
27 #include <asm/hardware.h>
28 #include <asm/mach-types.h>
29 #include <asm/irq.h>
30 #include "sa1100_generic.h"
32 static int debug = 0;
34 static struct pcmcia_irqs irqs[] = {
35 { 0, IRQ_GPIO_STORK_PCMCIA_A_CARD_DETECT, "PCMCIA_CD0" },
36 { 1, IRQ_GPIO_STORK_PCMCIA_B_CARD_DETECT, "PCMCIA_CD1" },
39 static int stork_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
41 printk("in stork_pcmcia_init\n");
43 skt->irq = skt->nr ? IRQ_GPIO_STORK_PCMCIA_B_RDY
44 : IRQ_GPIO_STORK_PCMCIA_A_RDY;
46 return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
49 static void stork_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
51 int i;
53 printk("%s\n", __FUNCTION__);
55 /* disable IRQs */
56 soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
58 /* Disable CF bus: */
59 storkClearLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);
60 storkClearLatchA(STORK_PCMCIA_A_POWER_ON);
61 storkClearLatchA(STORK_PCMCIA_B_POWER_ON);
64 static void
65 stork_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
66 struct pcmcia_state *state)
68 unsigned long levels = GPLR;
70 if (debug > 1)
71 printk("%s GPLR=%x IRQ[1:0]=%x\n", __FUNCTION__, levels,
72 (levels & (GPIO_STORK_PCMCIA_A_RDY|GPIO_STORK_PCMCIA_B_RDY)));
74 switch (skt->nr) {
75 case 0:
76 state->detect=((levels & GPIO_STORK_PCMCIA_A_CARD_DETECT)==0)?1:0;
77 state->ready=(levels & GPIO_STORK_PCMCIA_A_RDY)?1:0;
78 state->bvd1= 1;
79 state->bvd2= 1;
80 state->wrprot=0;
81 state->vs_3v=1;
82 state->vs_Xv=0;
83 break;
85 case 1:
86 state->detect=((levels & GPIO_STORK_PCMCIA_B_CARD_DETECT)==0)?1:0;
87 state->ready=(levels & GPIO_STORK_PCMCIA_B_RDY)?1:0;
88 state->bvd1=1;
89 state->bvd2=1;
90 state->wrprot=0;
91 state->vs_3v=1;
92 state->vs_Xv=0;
93 break;
97 static int
98 stork_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
99 const socket_state_t *state)
101 unsigned long flags;
102 int DETECT, RDY, POWER, RESET;
104 printk("%s: socket=%d vcc=%d vpp=%d reset=%d\n", __FUNCTION__,
105 skt->nr, state->Vcc, state->Vpp, state->flags & SS_RESET ? 1 : 0);
107 local_irq_save(flags);
109 if (skt->nr == 0) {
110 DETECT = GPIO_STORK_PCMCIA_A_CARD_DETECT;
111 RDY = GPIO_STORK_PCMCIA_A_RDY;
112 POWER = STORK_PCMCIA_A_POWER_ON;
113 RESET = STORK_PCMCIA_A_RESET;
114 } else {
115 DETECT = GPIO_STORK_PCMCIA_B_CARD_DETECT;
116 RDY = GPIO_STORK_PCMCIA_B_RDY;
117 POWER = STORK_PCMCIA_B_POWER_ON;
118 RESET = STORK_PCMCIA_B_RESET;
122 if (storkTestGPIO(DETECT)) {
123 printk("no card detected - but resetting anyway\r\n");
126 switch (state->Vcc) {
127 case 0:
128 /* storkClearLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON); */
129 storkClearLatchA(POWER);
130 break;
132 case 50:
133 case 33:
134 storkSetLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);
135 storkSetLatchA(POWER);
136 break;
138 default:
139 printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
140 state->Vcc);
141 local_irq_restore(flags);
142 return -1;
145 if (state->flags & SS_RESET)
146 storkSetLatchB(RESET);
147 else
148 storkClearLatchB(RESET);
150 local_irq_restore(flags);
152 /* silently ignore vpp and speaker enables. */
154 printk("%s: finished\n", __FUNCTION__);
156 return 0;
159 static void stork_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
161 storkSetLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);
163 soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
166 static void stork_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
168 soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
171 * Hack!
173 if (skt->nr == 1)
174 storkClearLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);
176 return 0;
179 static struct pcmcia_low_level stork_pcmcia_ops = {
180 .owner = THIS_MODULE,
181 .hw_init = stork_pcmcia_hw_init,
182 .hw_shutdown = stork_pcmcia_hw_shutdown,
183 .socket_state = stork_pcmcia_socket_state,
184 .configure_socket = stork_pcmcia_configure_socket,
186 .socket_init = stork_pcmcia_socket_init,
187 .socket_suspend = stork_pcmcia_socket_suspend,
190 int __init pcmcia_stork_init(struct device *dev)
192 int ret = -ENODEV;
194 if (machine_is_stork())
195 ret = sa11xx_drv_pcmcia_probe(dev, &stork_pcmcia_ops, 0, 2);
197 return ret;