0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <linux/module.h>
0016 #include <linux/gpio.h>
0017 #include <linux/errno.h>
0018 #include <linux/interrupt.h>
0019 #include <linux/platform_device.h>
0020 #include <linux/irq.h>
0021 #include <linux/io.h>
0022
0023 #include "balloon3.h"
0024
0025 #include <asm/mach-types.h>
0026
0027 #include <pcmcia/soc_common.h>
0028
0029 static int balloon3_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
0030 {
0031 uint16_t ver;
0032
0033 ver = __raw_readw(BALLOON3_FPGA_VER);
0034 if (ver < 0x4f08)
0035 pr_warn("The FPGA code, version 0x%04x, is too old. "
0036 "PCMCIA/CF support might be broken in this version!",
0037 ver);
0038
0039 skt->socket.pci_irq = BALLOON3_BP_CF_NRDY_IRQ;
0040 skt->stat[SOC_STAT_CD].gpio = BALLOON3_GPIO_S0_CD;
0041 skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD";
0042 skt->stat[SOC_STAT_BVD1].irq = BALLOON3_BP_NSTSCHG_IRQ;
0043 skt->stat[SOC_STAT_BVD1].name = "PCMCIA0 STSCHG";
0044
0045 return 0;
0046 }
0047
0048 static unsigned long balloon3_pcmcia_status[2] = {
0049 BALLOON3_CF_nSTSCHG_BVD1,
0050 BALLOON3_CF_nSTSCHG_BVD1
0051 };
0052
0053 static void balloon3_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
0054 struct pcmcia_state *state)
0055 {
0056 uint16_t status;
0057 int flip;
0058
0059
0060 status = __raw_readw(BALLOON3_CF_STATUS_REG);
0061 flip = (status ^ balloon3_pcmcia_status[skt->nr])
0062 & BALLOON3_CF_nSTSCHG_BVD1;
0063
0064
0065
0066
0067
0068 if (flip) {
0069 balloon3_pcmcia_status[skt->nr] = status;
0070 if (status & BALLOON3_CF_nSTSCHG_BVD1)
0071 enable_irq(BALLOON3_BP_NSTSCHG_IRQ);
0072 else
0073 disable_irq(BALLOON3_BP_NSTSCHG_IRQ);
0074 }
0075
0076 state->ready = !!(status & BALLOON3_CF_nIRQ);
0077 state->bvd1 = !!(status & BALLOON3_CF_nSTSCHG_BVD1);
0078 state->bvd2 = 0;
0079 state->vs_3v = 1;
0080 state->vs_Xv = 0;
0081 }
0082
0083 static int balloon3_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
0084 const socket_state_t *state)
0085 {
0086 __raw_writew(BALLOON3_CF_RESET, BALLOON3_CF_CONTROL_REG +
0087 ((state->flags & SS_RESET) ?
0088 BALLOON3_FPGA_SETnCLR : 0));
0089 return 0;
0090 }
0091
0092 static struct pcmcia_low_level balloon3_pcmcia_ops = {
0093 .owner = THIS_MODULE,
0094 .hw_init = balloon3_pcmcia_hw_init,
0095 .socket_state = balloon3_pcmcia_socket_state,
0096 .configure_socket = balloon3_pcmcia_configure_socket,
0097 .first = 0,
0098 .nr = 1,
0099 };
0100
0101 static struct platform_device *balloon3_pcmcia_device;
0102
0103 static int __init balloon3_pcmcia_init(void)
0104 {
0105 int ret;
0106
0107 if (!machine_is_balloon3())
0108 return -ENODEV;
0109
0110 balloon3_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
0111 if (!balloon3_pcmcia_device)
0112 return -ENOMEM;
0113
0114 ret = platform_device_add_data(balloon3_pcmcia_device,
0115 &balloon3_pcmcia_ops, sizeof(balloon3_pcmcia_ops));
0116
0117 if (!ret)
0118 ret = platform_device_add(balloon3_pcmcia_device);
0119
0120 if (ret)
0121 platform_device_put(balloon3_pcmcia_device);
0122
0123 return ret;
0124 }
0125
0126 static void __exit balloon3_pcmcia_exit(void)
0127 {
0128 platform_device_unregister(balloon3_pcmcia_device);
0129 }
0130
0131 module_init(balloon3_pcmcia_init);
0132 module_exit(balloon3_pcmcia_exit);
0133
0134 MODULE_LICENSE("GPL");
0135 MODULE_AUTHOR("Nick Bane <nick@cecomputing.co.uk>");
0136 MODULE_ALIAS("platform:pxa2xx-pcmcia");
0137 MODULE_DESCRIPTION("Balloon3 board CF/PCMCIA driver");