0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/init.h>
0009 #include <linux/module.h>
0010 #include <linux/kernel.h>
0011 #include <linux/errno.h>
0012 #include <linux/gpio.h>
0013 #include <linux/interrupt.h>
0014 #include <linux/platform_device.h>
0015
0016 #include "eseries-gpio.h"
0017
0018 #include <asm/irq.h>
0019 #include <asm/mach-types.h>
0020
0021 #include <pcmcia/soc_common.h>
0022
0023 static int e740_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
0024 {
0025 if (skt->nr == 0) {
0026 skt->stat[SOC_STAT_CD].gpio = GPIO_E740_PCMCIA_CD0;
0027 skt->stat[SOC_STAT_CD].name = "CF card detect";
0028 skt->stat[SOC_STAT_RDY].gpio = GPIO_E740_PCMCIA_RDY0;
0029 skt->stat[SOC_STAT_RDY].name = "CF ready";
0030 } else {
0031 skt->stat[SOC_STAT_CD].gpio = GPIO_E740_PCMCIA_CD1;
0032 skt->stat[SOC_STAT_CD].name = "Wifi switch";
0033 skt->stat[SOC_STAT_RDY].gpio = GPIO_E740_PCMCIA_RDY1;
0034 skt->stat[SOC_STAT_RDY].name = "Wifi ready";
0035 }
0036
0037 return 0;
0038 }
0039
0040 static void e740_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
0041 struct pcmcia_state *state)
0042 {
0043 state->vs_3v = 1;
0044 state->vs_Xv = 0;
0045 }
0046
0047 static int e740_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
0048 const socket_state_t *state)
0049 {
0050 if (state->flags & SS_RESET) {
0051 if (skt->nr == 0)
0052 gpio_set_value(GPIO_E740_PCMCIA_RST0, 1);
0053 else
0054 gpio_set_value(GPIO_E740_PCMCIA_RST1, 1);
0055 } else {
0056 if (skt->nr == 0)
0057 gpio_set_value(GPIO_E740_PCMCIA_RST0, 0);
0058 else
0059 gpio_set_value(GPIO_E740_PCMCIA_RST1, 0);
0060 }
0061
0062 switch (state->Vcc) {
0063 case 0:
0064 if (skt->nr == 0)
0065 gpio_set_value(GPIO_E740_PCMCIA_PWR0, 0);
0066 else
0067 gpio_set_value(GPIO_E740_PCMCIA_PWR1, 1);
0068 break;
0069 case 50:
0070 case 33:
0071 if (skt->nr == 0)
0072 gpio_set_value(GPIO_E740_PCMCIA_PWR0, 1);
0073 else
0074 gpio_set_value(GPIO_E740_PCMCIA_PWR1, 0);
0075 break;
0076 default:
0077 printk(KERN_ERR "e740_cs: Unsupported Vcc: %d\n", state->Vcc);
0078 }
0079
0080 return 0;
0081 }
0082
0083 static struct pcmcia_low_level e740_pcmcia_ops = {
0084 .owner = THIS_MODULE,
0085 .hw_init = e740_pcmcia_hw_init,
0086 .socket_state = e740_pcmcia_socket_state,
0087 .configure_socket = e740_pcmcia_configure_socket,
0088 .nr = 2,
0089 };
0090
0091 static struct platform_device *e740_pcmcia_device;
0092
0093 static int __init e740_pcmcia_init(void)
0094 {
0095 int ret;
0096
0097 if (!machine_is_e740())
0098 return -ENODEV;
0099
0100 e740_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
0101 if (!e740_pcmcia_device)
0102 return -ENOMEM;
0103
0104 ret = platform_device_add_data(e740_pcmcia_device, &e740_pcmcia_ops,
0105 sizeof(e740_pcmcia_ops));
0106
0107 if (!ret)
0108 ret = platform_device_add(e740_pcmcia_device);
0109
0110 if (ret)
0111 platform_device_put(e740_pcmcia_device);
0112
0113 return ret;
0114 }
0115
0116 static void __exit e740_pcmcia_exit(void)
0117 {
0118 platform_device_unregister(e740_pcmcia_device);
0119 }
0120
0121 module_init(e740_pcmcia_init);
0122 module_exit(e740_pcmcia_exit);
0123
0124 MODULE_LICENSE("GPL v2");
0125 MODULE_AUTHOR("Ian Molton <spyro@f2s.com>");
0126 MODULE_ALIAS("platform:pxa2xx-pcmcia");
0127 MODULE_DESCRIPTION("e740 PCMCIA platform support");