0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/gpio.h>
0011 #include <linux/module.h>
0012 #include <linux/platform_device.h>
0013
0014 #include <asm/mach-types.h>
0015
0016 #include "vpac270.h"
0017
0018 #include <pcmcia/soc_common.h>
0019
0020 static struct gpio vpac270_pcmcia_gpios[] = {
0021 { GPIO107_VPAC270_PCMCIA_PPEN, GPIOF_INIT_LOW, "PCMCIA PPEN" },
0022 { GPIO11_VPAC270_PCMCIA_RESET, GPIOF_INIT_LOW, "PCMCIA Reset" },
0023 };
0024
0025 static struct gpio vpac270_cf_gpios[] = {
0026 { GPIO16_VPAC270_CF_RESET, GPIOF_INIT_LOW, "CF Reset" },
0027 };
0028
0029 static int vpac270_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
0030 {
0031 int ret;
0032
0033 if (skt->nr == 0) {
0034 ret = gpio_request_array(vpac270_pcmcia_gpios,
0035 ARRAY_SIZE(vpac270_pcmcia_gpios));
0036
0037 skt->stat[SOC_STAT_CD].gpio = GPIO84_VPAC270_PCMCIA_CD;
0038 skt->stat[SOC_STAT_CD].name = "PCMCIA CD";
0039 skt->stat[SOC_STAT_RDY].gpio = GPIO35_VPAC270_PCMCIA_RDY;
0040 skt->stat[SOC_STAT_RDY].name = "PCMCIA Ready";
0041 } else {
0042 ret = gpio_request_array(vpac270_cf_gpios,
0043 ARRAY_SIZE(vpac270_cf_gpios));
0044
0045 skt->stat[SOC_STAT_CD].gpio = GPIO17_VPAC270_CF_CD;
0046 skt->stat[SOC_STAT_CD].name = "CF CD";
0047 skt->stat[SOC_STAT_RDY].gpio = GPIO12_VPAC270_CF_RDY;
0048 skt->stat[SOC_STAT_RDY].name = "CF Ready";
0049 }
0050
0051 return ret;
0052 }
0053
0054 static void vpac270_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
0055 {
0056 if (skt->nr == 0)
0057 gpio_free_array(vpac270_pcmcia_gpios,
0058 ARRAY_SIZE(vpac270_pcmcia_gpios));
0059 else
0060 gpio_free_array(vpac270_cf_gpios,
0061 ARRAY_SIZE(vpac270_cf_gpios));
0062 }
0063
0064 static void vpac270_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
0065 struct pcmcia_state *state)
0066 {
0067 state->vs_3v = 1;
0068 state->vs_Xv = 0;
0069 }
0070
0071 static int
0072 vpac270_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
0073 const socket_state_t *state)
0074 {
0075 if (skt->nr == 0) {
0076 gpio_set_value(GPIO11_VPAC270_PCMCIA_RESET,
0077 (state->flags & SS_RESET));
0078 gpio_set_value(GPIO107_VPAC270_PCMCIA_PPEN,
0079 !(state->Vcc == 33 || state->Vcc == 50));
0080 } else {
0081 gpio_set_value(GPIO16_VPAC270_CF_RESET,
0082 (state->flags & SS_RESET));
0083 }
0084
0085 return 0;
0086 }
0087
0088 static struct pcmcia_low_level vpac270_pcmcia_ops = {
0089 .owner = THIS_MODULE,
0090
0091 .first = 0,
0092 .nr = 2,
0093
0094 .hw_init = vpac270_pcmcia_hw_init,
0095 .hw_shutdown = vpac270_pcmcia_hw_shutdown,
0096
0097 .socket_state = vpac270_pcmcia_socket_state,
0098 .configure_socket = vpac270_pcmcia_configure_socket,
0099 };
0100
0101 static struct platform_device *vpac270_pcmcia_device;
0102
0103 static int __init vpac270_pcmcia_init(void)
0104 {
0105 int ret;
0106
0107 if (!machine_is_vpac270())
0108 return -ENODEV;
0109
0110 vpac270_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
0111 if (!vpac270_pcmcia_device)
0112 return -ENOMEM;
0113
0114 ret = platform_device_add_data(vpac270_pcmcia_device,
0115 &vpac270_pcmcia_ops, sizeof(vpac270_pcmcia_ops));
0116
0117 if (!ret)
0118 ret = platform_device_add(vpac270_pcmcia_device);
0119
0120 if (ret)
0121 platform_device_put(vpac270_pcmcia_device);
0122
0123 return ret;
0124 }
0125
0126 static void __exit vpac270_pcmcia_exit(void)
0127 {
0128 platform_device_unregister(vpac270_pcmcia_device);
0129 }
0130
0131 module_init(vpac270_pcmcia_init);
0132 module_exit(vpac270_pcmcia_exit);
0133
0134 MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
0135 MODULE_DESCRIPTION("PCMCIA support for Voipac PXA270");
0136 MODULE_ALIAS("platform:pxa2xx-pcmcia");
0137 MODULE_LICENSE("GPL");