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>
30 #include "sa1100_generic.h"
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 sa1100_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 sa11xx_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
49 static void stork_pcmcia_hw_shutdown(struct sa1100_pcmcia_socket *skt)
53 printk("%s\n", __FUNCTION__);
56 sa11xx_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
59 storkClearLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);
60 storkClearLatchA(STORK_PCMCIA_A_POWER_ON);
61 storkClearLatchA(STORK_PCMCIA_B_POWER_ON);
65 stork_pcmcia_socket_state(struct sa1100_pcmcia_socket *skt,
66 struct pcmcia_state *state)
68 unsigned long levels = GPLR;
71 printk("%s GPLR=%x IRQ[1:0]=%x\n", __FUNCTION__, levels,
72 (levels & (GPIO_STORK_PCMCIA_A_RDY|GPIO_STORK_PCMCIA_B_RDY)));
76 state->detect=((levels & GPIO_STORK_PCMCIA_A_CARD_DETECT)==0)?1:0;
77 state->ready=(levels & GPIO_STORK_PCMCIA_A_RDY)?1:0;
86 state->detect=((levels & GPIO_STORK_PCMCIA_B_CARD_DETECT)==0)?1:0;
87 state->ready=(levels & GPIO_STORK_PCMCIA_B_RDY)?1:0;
98 stork_pcmcia_configure_socket(struct sa1100_pcmcia_socket *skt,
99 const socket_state_t *state)
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);
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;
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) {
128 /* storkClearLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON); */
129 storkClearLatchA(POWER);
134 storkSetLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);
135 storkSetLatchA(POWER);
139 printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
141 local_irq_restore(flags);
145 if (state->flags & SS_RESET)
146 storkSetLatchB(RESET);
148 storkClearLatchB(RESET);
150 local_irq_restore(flags);
152 /* silently ignore vpp and speaker enables. */
154 printk("%s: finished\n", __FUNCTION__);
159 static void stork_pcmcia_socket_init(struct sa1100_pcmcia_socket *skt)
161 storkSetLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);
163 sa11xx_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
166 static void stork_pcmcia_socket_suspend(struct sa1100_pcmcia_socket *skt)
168 sa11xx_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
174 storkClearLatchA(STORK_PCMCIA_PULL_UPS_POWER_ON);
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)
194 if (machine_is_stork())
195 ret = sa11xx_drv_pcmcia_probe(dev, &stork_pcmcia_ops, 0, 2);