2 * iPAQ h2200 PCMCIA support
4 * Copyright (c) 2004 Koen Kooi <koen@handhelds.org>
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/init.h>
16 #include <linux/platform_device.h>
17 #include <linux/delay.h>
18 #include <linux/soc-old.h>
20 #include <asm/hardware.h>
23 #include <asm/arch/pxa-regs.h>
24 #include <asm/arch/h2200-gpio.h>
26 #include "soc_common.h"
30 # define _debug(s, args...) printk (KERN_INFO s, ##args)
32 # define _debug(s, args...)
34 #define _debug_func(s, args...) _debug ("%s: " s, __FUNCTION__, ##args)
36 static struct pcmcia_irqs h2200_cd_irq
[] = {
37 { 0, H2200_IRQ (CF_DETECT_N
), "PCMCIA CD" }
40 static void h2200_cf_rst (int state
)
44 SET_H2200_GPIO (CF_RESET
, state
);
47 static int h2200_pcmcia_hw_init (struct soc_pcmcia_socket
*skt
)
53 skt
->irq
= H2200_IRQ (CF_INT_N
);
55 // This must go away as we'll fill h2200-init.h
56 local_irq_save (flags
);
57 pxa_gpio_mode (GPIO_NR_H2200_CF_RESET
| GPIO_OUT
);
58 pxa_gpio_mode (GPIO_NR_H2200_CF_ADD_EN_N
| GPIO_OUT
);
59 pxa_gpio_mode (GPIO_NR_H2200_CF_POWER_EN
| GPIO_OUT
);
60 pxa_gpio_mode (GPIO_NR_H2200_CF_BUFF_EN
| GPIO_OUT
);
61 pxa_gpio_mode (GPIO_NR_H2200_CF_DETECT_N
| GPIO_IN
);
62 pxa_gpio_mode (GPIO_NR_H2200_CF_INT_N
| GPIO_IN
);
63 local_irq_restore (flags
);
65 return soc_pcmcia_request_irqs(skt
, h2200_cd_irq
, ARRAY_SIZE(h2200_cd_irq
));
69 * Release all resources.
71 static void h2200_pcmcia_hw_shutdown (struct soc_pcmcia_socket
*skt
)
74 soc_pcmcia_free_irqs(skt
, h2200_cd_irq
, ARRAY_SIZE(h2200_cd_irq
));
77 static void h2200_pcmcia_socket_state (struct soc_pcmcia_socket
*skt
, struct pcmcia_state
*state
)
79 state
->detect
= GET_H2200_GPIO (CF_DETECT_N
) ? 0 : 1;
80 state
->ready
= GET_H2200_GPIO (CF_INT_N
) ? 1 : 0;
84 state
->vs_3v
= GET_H2200_GPIO (CF_POWER_EN
) ? 1 : 0;
87 _debug ("detect:%d ready:%d vcc:%d\n",
88 state
->detect
, state
->ready
, state
->vs_3v
);
91 static int h2200_pcmcia_configure_socket (struct soc_pcmcia_socket
*skt
, const socket_state_t
*state
)
93 /* Silently ignore Vpp, output enable, speaker enable. */
94 _debug_func ("Reset:%d Vcc:%d\n", (state
->flags
& SS_RESET
) ? 1 : 0,
97 h2200_cf_rst (state
->flags
& SS_RESET
);
99 /* Apply socket voltage */
100 switch (state
->Vcc
) {
102 SET_H2200_GPIO (CF_POWER_EN
, 0);
103 SET_H2200_GPIO_N (CF_ADD_EN
, 0);
104 SET_H2200_GPIO (CF_BUFF_EN
, 0);
108 /* Apply power to socket */
109 SET_H2200_GPIO (CF_POWER_EN
, 1);
110 SET_H2200_GPIO_N (CF_ADD_EN
, 1);
111 SET_H2200_GPIO (CF_BUFF_EN
, 1);
114 printk (KERN_ERR
"%s: Unsupported Vcc:%d\n",
115 __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 h2200_pcmcia_socket_init(struct soc_pcmcia_socket
*skt
)
132 * Disable card status IRQs on suspend.
134 static void h2200_pcmcia_socket_suspend (struct soc_pcmcia_socket
*skt
)
140 static struct pcmcia_low_level h2200_pcmcia_ops
= {
141 .owner
= THIS_MODULE
,
146 .hw_init
= h2200_pcmcia_hw_init
,
147 .hw_shutdown
= h2200_pcmcia_hw_shutdown
,
149 .socket_state
= h2200_pcmcia_socket_state
,
150 .configure_socket
= h2200_pcmcia_configure_socket
,
152 .socket_init
= h2200_pcmcia_socket_init
,
153 .socket_suspend
= h2200_pcmcia_socket_suspend
,
156 static struct platform_device h2200_pcmcia_device
= {
157 .name
= "pxa2xx-pcmcia",
159 .platform_data
= &h2200_pcmcia_ops
,
163 static int __init
h2200_pcmcia_init (void)
166 return platform_device_register (&h2200_pcmcia_device
);
170 h2200_pcmcia_exit(void)
172 platform_device_unregister (&h2200_pcmcia_device
);
175 module_init(h2200_pcmcia_init
);
176 module_exit(h2200_pcmcia_exit
);
178 MODULE_AUTHOR("Koen Kooi <koen@handhelds.org>");
179 MODULE_DESCRIPTION("HP iPAQ h2200 PCMCIA/CF platform-specific driver");
180 MODULE_LICENSE("GPL");