2 * Rover P5+ PCMCIA support
4 * Konstantine A. Beklemishev <konstantine@r66.ru>
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive for
11 #include <linux/module.h>
12 #include <linux/kernel.h>
13 #include <linux/errno.h>
14 #include <linux/interrupt.h>
15 #include <linux/device.h>
16 #include <linux/init.h>
18 #include <asm/hardware.h>
19 #include <asm/mach-types.h>
21 #include <asm/signal.h>
23 #include <../drivers/pcmcia/soc_common.h>
24 #include <asm/arch/pxa-regs.h>
25 #include <asm/arch/roverp5p-gpio.h>
28 # define rover_debug(s, args...) printk (KERN_INFO s, ##args)
30 # define rover_debug(s, args...)
32 #define debug_func(s, args...) rover_debug ("%s: " s, __FUNCTION__, ##args)
34 #define GPIO_STATE(x) (GPLR (x) & GPIO_bit (x))
35 #define GPIO_SET(x) (GPSR (x) = GPIO_bit (x))
36 #define GPIO_CLR(x) (GPCR (x) = GPIO_bit (x))
38 static struct pcmcia_irqs cd_irqs
[] = {
39 { 0, IRQ_GPIO(GPIO_NR_ROVERP5P_CF_DETECT
), "PCMCIA CD" },
42 static void roverp5p_pcmcia_hw_rst (int state
)
45 SET_ROVERP5P_GPIO (CF_RESET
, state
);
47 GPIO_SET (GPIO_NR_ROVERP5P_CF_RESET);
49 GPIO_CLR (GPIO_NR_ROVERP5P_CF_RESET);*/
52 static int roverp5p_pcmcia_hw_init(struct soc_pcmcia_socket
*skt
)
56 skt
->irq
= IRQ_GPIO(GPIO_NR_ROVERP5P_PXA_PRDY
);
58 local_irq_save (flags
);
59 pxa_gpio_mode (GPIO_NR_ROVERP5P_CF_RESET
| GPIO_OUT
);
60 pxa_gpio_mode (GPIO_NR_ROVERP5P_CF_PWR_ON
| GPIO_OUT
);
61 pxa_gpio_mode (GPIO_NR_ROVERP5P_CF_BUS_nON
| GPIO_OUT
);
62 pxa_gpio_mode (GPIO_NR_ROVERP5P_CF_DETECT
| GPIO_IN
);
63 pxa_gpio_mode (GPIO_NR_ROVERP5P_PXA_PRDY
| GPIO_IN
);
64 local_irq_restore (flags
);
66 return soc_pcmcia_request_irqs(skt
, cd_irqs
, ARRAY_SIZE(cd_irqs
));
71 * Release all resources.
73 static void roverp5p_pcmcia_hw_shutdown(struct soc_pcmcia_socket
*skt
)
75 soc_pcmcia_free_irqs(skt
, cd_irqs
, ARRAY_SIZE(cd_irqs
));
79 roverp5p_pcmcia_socket_state(struct soc_pcmcia_socket
*skt
, struct pcmcia_state
*state
)
81 state
->detect
= GET_ROVERP5P_GPIO (CF_DETECT
) ? 0 : 1;
82 state
->ready
= GET_ROVERP5P_GPIO (PXA_PRDY
) ? 1 : 0;
86 state
->vs_3v
= GET_ROVERP5P_GPIO (CF_PWR_ON
) ? 0 : 1;
89 rover_debug ("detect:%d ready:%d vcc:%d\n",
90 state
->detect
, state
->ready
, state
->vs_3v
);
94 roverp5p_pcmcia_configure_socket(struct soc_pcmcia_socket
*skt
, const socket_state_t
*state
)
96 /* Silently ignore Vpp, output enable, speaker enable. */
97 debug_func ("Reset:%d Vcc:%d\n", (state
->flags
& SS_RESET
) ? 1 : 0,
100 roverp5p_pcmcia_hw_rst (state
->flags
& SS_RESET
);
102 /* Apply socket voltage */
103 switch (state
->Vcc
) {
105 SET_ROVERP5P_GPIO (CF_PWR_ON
, 1);
106 SET_ROVERP5P_GPIO (CF_BUS_nON
, 1);
107 /*GPIO_CLR (GPIO_NR_ROVERP5P_CF_PWR_ON);
108 GPIO_CLR (GPIO_NR_ROVERP5P_CF_BUS_nON);*/
111 /*GPIO_SET (GPIO_NR_ROVERP5P_CF_PWR_ON);
114 /* Apply power to socket */
115 SET_ROVERP5P_GPIO (CF_PWR_ON
, 0);
116 SET_ROVERP5P_GPIO (CF_BUS_nON
, 0);
117 /*GPIO_SET (GPIO_NR_ROVERP5P_CF_PWR_ON);
118 GPIO_SET (GPIO_NR_ROVERP5P_CF_BUS_nON);*/
121 printk (KERN_ERR
"%s: Unsupported Vcc:%d\n",
122 __FUNCTION__
, state
->Vcc
);
129 * Enable card status IRQs on (re-)initialisation. This can
130 * be called at initialisation, power management event, or
133 static void roverp5p_pcmcia_socket_init(struct soc_pcmcia_socket
*skt
)
136 soc_pcmcia_enable_irqs (skt
, cd_irqs
, ARRAY_SIZE(cd_irqs
));
140 * Disable card status IRQs on suspend.
142 static void roverp5p_pcmcia_socket_suspend(struct soc_pcmcia_socket
*skt
)
145 roverp5p_pcmcia_hw_rst(1);
146 soc_pcmcia_disable_irqs(skt
, cd_irqs
, ARRAY_SIZE(cd_irqs
));
149 static struct pcmcia_low_level roverp5p_pcmcia_ops
= {
150 .owner
= THIS_MODULE
,
155 .hw_init
= roverp5p_pcmcia_hw_init
,
156 .hw_shutdown
= roverp5p_pcmcia_hw_shutdown
,
158 .socket_state
= roverp5p_pcmcia_socket_state
,
159 .configure_socket
= roverp5p_pcmcia_configure_socket
,
161 .socket_init
= roverp5p_pcmcia_socket_init
,
162 .socket_suspend
= roverp5p_pcmcia_socket_suspend
,
165 static struct platform_device roverp5p_pcmcia_device
= {
166 .name
= "pxa2xx-pcmcia",
169 .platform_data
= &roverp5p_pcmcia_ops
173 static int __init
roverp5p_pcmcia_init(void)
175 return platform_device_register(&roverp5p_pcmcia_device
);
178 static void __exit
roverp5p_pcmcia_exit(void)
180 platform_device_unregister (&roverp5p_pcmcia_device
);
183 module_init(roverp5p_pcmcia_init
);
184 module_exit(roverp5p_pcmcia_exit
);
186 MODULE_AUTHOR("Konstantine A. Beklemishev");
187 MODULE_DESCRIPTION("Rover P5+ PCMCIA driver");
188 MODULE_LICENSE("GPL");