2 * arch/arm/mach-pxa/e740_pcmcia.c
4 * Toshiba E-740 PCMCIA specific routines.
8 * Copyright: Ian Molton
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
15 #include <linux/module.h>
16 #include <linux/init.h>
17 #include <linux/kernel.h>
18 #include <linux/errno.h>
19 #include <linux/interrupt.h>
20 #include <linux/device.h>
22 #include <pcmcia/ss.h>
23 #include <linux/platform_device.h>
26 #include <asm/hardware.h>
29 #include <asm/mach-types.h>
30 #include <asm/arch/pxa-regs.h>
31 #include <asm/arch/eseries-gpio.h>
33 #include "soc_common.h"
35 static struct pcmcia_irqs cd_irqs
[] = {
36 { 0, IRQ_GPIO(GPIO_E740_PCMCIA_CD0
), "CF card detect" },
37 { 1, IRQ_GPIO(GPIO_E740_PCMCIA_CD1
), "Wifi switch" },
40 static int e740_pcmcia_hw_init(struct soc_pcmcia_socket
*skt
)
42 skt
->irq
= skt
->nr
== 0 ? IRQ_GPIO(GPIO_E740_PCMCIA_RDY0
):
43 IRQ_GPIO(GPIO_E740_PCMCIA_RDY1
);
45 return soc_pcmcia_request_irqs(skt
, cd_irqs
, ARRAY_SIZE(cd_irqs
));
49 * Release all resources.
51 static void e740_pcmcia_hw_shutdown(struct soc_pcmcia_socket
*skt
)
53 soc_pcmcia_free_irqs(skt
, cd_irqs
, ARRAY_SIZE(cd_irqs
));
56 #define GPLR_BIT(n) (GPLR((n)) & GPIO_bit((n)))
58 static void e740_pcmcia_socket_state(struct soc_pcmcia_socket
*skt
, struct pcmcia_state
*state
)
60 // unsigned long gplr0 = GPLR0; FIXME - this really ought to be atomic
61 // unsigned long gplr1 = GPLR1;
64 state
->detect
= GPLR_BIT(GPIO_E740_PCMCIA_CD0
) ? 0 : 1;
65 state
->ready
= GPLR_BIT(GPIO_E740_PCMCIA_RDY0
) ? 1 : 0;
68 state
->detect
= GPLR_BIT(GPIO_E740_PCMCIA_CD1
) ? 0 : 1;
69 state
->ready
= GPLR_BIT(GPIO_E740_PCMCIA_RDY1
) ? 1 : 0;
72 state
->vs_3v
= 1; //FIXME - is it right?
80 #define GPSR_BIT(n) (GPSR((n)) = GPIO_bit((n)))
81 #define GPCR_BIT(n) (GPCR((n)) = GPIO_bit((n)))
83 static int e740_pcmcia_configure_socket(struct soc_pcmcia_socket
*skt
, const socket_state_t
*state
)
86 if(state
->flags
& SS_RESET
) {
88 GPSR_BIT(GPIO_E740_PCMCIA_RST0
);
90 GPSR_BIT(GPIO_E740_PCMCIA_RST1
);
93 GPCR_BIT(GPIO_E740_PCMCIA_RST0
);
95 GPCR_BIT(GPIO_E740_PCMCIA_RST1
);
98 /* Apply socket voltage */
102 GPCR_BIT(GPIO_E740_PCMCIA_PWR0
);
104 GPSR_BIT(GPIO_E740_PCMCIA_PWR1
);
108 /* Apply power to socket */
110 GPSR_BIT(GPIO_E740_PCMCIA_PWR0
);
112 GPCR_BIT(GPIO_E740_PCMCIA_PWR1
);
115 printk (KERN_ERR
"%s: Unsupported Vcc:%d\n", __FUNCTION__
, state
->Vcc
);
122 * Enable card status IRQs on (re-)initialisation. This can
123 * be called at initialisation, power management event, or
126 static void e740_pcmcia_socket_init(struct soc_pcmcia_socket
*skt
)
128 soc_pcmcia_enable_irqs(skt
, cd_irqs
, ARRAY_SIZE(cd_irqs
));
132 * Disable card status IRQs on suspend.
134 static void e740_pcmcia_socket_suspend(struct soc_pcmcia_socket
*skt
)
136 soc_pcmcia_disable_irqs(skt
, cd_irqs
, ARRAY_SIZE(cd_irqs
));
139 static struct pcmcia_low_level e740_pcmcia_ops
= {
140 .owner
= THIS_MODULE
,
141 .hw_init
= e740_pcmcia_hw_init
,
142 .hw_shutdown
= e740_pcmcia_hw_shutdown
,
143 .socket_state
= e740_pcmcia_socket_state
,
144 .configure_socket
= e740_pcmcia_configure_socket
,
145 .socket_init
= e740_pcmcia_socket_init
,
146 .socket_suspend
= e740_pcmcia_socket_suspend
,
150 static struct platform_device e740_pcmcia_device
= {
151 .name
= "pxa2xx-pcmcia",
153 .platform_data
= &e740_pcmcia_ops
,
157 static int __init
e740_pcmcia_init(void)
161 if(!machine_is_e740())
164 printk("pcmcia: e740 detected.\n");
166 ret
= platform_device_register(&e740_pcmcia_device
);
171 static void __exit
e740_pcmcia_exit(void)
174 * This call is supposed to free our e740_pcmcia_device.
175 * Unfortunately platform_device don't have a free method, and
176 * we can't assume it's free of any reference at this point so we
177 * can't free it either.
179 //platform_device_unregister(&e740_pcmcia_device);
182 module_init(e740_pcmcia_init
);
183 module_exit(e740_pcmcia_exit
);
185 MODULE_LICENSE("GPL");