sync hh.org
[hh.org.git] / arch / arm / mach-pxa / eseries / e800_pcmcia.c
blob14b4aff9b7180bf3d835dbdbf09e95015032aa1a
1 /*
2 * arch/arm/mach-pxa/e800_pcmcia.c
4 * Toshiba E-800 PCMCIA specific routines.
6 * Created: 20040704
7 * Author: Ian Molton
8 * Copyright: Ian Molton
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
15 #include <linux/module.h>
16 #include <linux/init.h>
17 #include <linux/kernel.h>
18 #include <linux/errno.h>
19 #include <linux/interrupt.h>
20 #include <linux/platform_device.h>
22 #include <pcmcia/ss.h>
24 #include <asm/hardware.h>
25 #include <asm/irq.h>
27 #include <asm/mach-types.h>
28 #include <asm/arch/pxa-regs.h>
29 #include <asm/arch/eseries-irq.h>
30 #include <asm/arch/eseries-gpio.h>
32 #include "soc_common.h"
34 static struct pcmcia_irqs cd_irqs[] = {
35 { 0, ANGELX_CD0_IRQ, "CF card detect" },
36 { 1, ANGELX_CD1_IRQ, "Wifi switch" },
37 { 0, ANGELX_ST0_IRQ, "ST0" },
38 { 1, ANGELX_ST1_IRQ, "ST1" },
41 static int e800_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
43 skt->irq = skt->nr == 0 ? ANGELX_RDY0_IRQ : ANGELX_RDY1_IRQ;
45 return soc_pcmcia_request_irqs(skt, cd_irqs, ARRAY_SIZE(cd_irqs));
49 * Release all resources.
51 static void e800_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
53 soc_pcmcia_free_irqs(skt, cd_irqs, ARRAY_SIZE(cd_irqs));
56 #define GPLR_BIT(n) (GPLR((n)) & GPIO_bit((n)))
58 extern unsigned char angelx_get_state(int skt);
59 static void e800_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
61 unsigned char socket_state = angelx_get_state(skt->nr);
62 unsigned long gplr0 = GPLR0; // FIXME - this really ought to be atomic
63 unsigned long gplr2 = GPLR2;
66 if(skt->nr == 0){
67 printk("pcmaia state: %d %02x\n", skt->nr, socket_state);
68 state->vs_3v = gplr0 & GPIO_bit(20) ? 1 : 0;
70 else{
71 state->vs_3v = gplr2 & GPIO_bit(73) ? 1 : 0;
74 state->vs_3v = 1; //FIXME - is it right?
76 state->detect = socket_state & 0x04 ? 0 : 1;
77 state->ready = socket_state & 0x10 ? 0 : 1;
78 state->bvd1 = 1;
79 state->bvd2 = 1;
80 state->wrprot = 0;
81 state->vs_Xv = 0;
84 #define GPSR_BIT(n) (GPSR((n)) = GPIO_bit((n)))
85 #define GPCR_BIT(n) (GPCR((n)) = GPIO_bit((n)))
87 static int e800_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
89 /* reset it? */
90 printk("pcmcia reset state %d %s\n", skt->nr, state->flags & SS_RESET ? "asserted" : "deasserted");
91 #if 0
92 if(state->flags & SS_RESET) {
93 if(skt->nr == 0)
94 GPSR_BIT(GPIO_E800_PCMCIA_RST0);
95 else
96 GPSR_BIT(GPIO_E800_PCMCIA_RST1);
97 } else {
98 if(skt->nr == 0)
99 GPCR_BIT(GPIO_E800_PCMCIA_RST0);
100 else
101 GPSR_BIT(GPIO_E800_PCMCIA_RST1);
103 #endif
105 /* Apply socket voltage */
106 switch (state->Vcc) {
107 case 0:
108 if(skt->nr == 0)
109 GPCR_BIT(GPIO_E800_PCMCIA_PWR0);
110 else
111 GPCR_BIT(GPIO_E800_PCMCIA_PWR1);
112 break;
113 case 50:
114 case 33:
115 /* Apply power to socket */
116 if(skt->nr == 0)
117 GPSR_BIT(GPIO_E800_PCMCIA_PWR0);
118 else
119 GPSR_BIT(GPIO_E800_PCMCIA_PWR1);
120 break;
121 default:
122 printk (KERN_ERR "%s: Unsupported Vcc:%d\n", __FUNCTION__, state->Vcc);
125 return 0;
129 * Enable card status IRQs on (re-)initialisation. This can
130 * be called at initialisation, power management event, or
131 * pcmcia event.
133 static void e800_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
135 soc_pcmcia_enable_irqs(skt, cd_irqs, ARRAY_SIZE(cd_irqs));
139 * Disable card status IRQs on suspend.
141 static void e800_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
143 soc_pcmcia_disable_irqs(skt, cd_irqs, ARRAY_SIZE(cd_irqs));
146 static struct pcmcia_low_level e800_pcmcia_ops = {
147 .owner = THIS_MODULE,
148 .hw_init = e800_pcmcia_hw_init,
149 .hw_shutdown = e800_pcmcia_hw_shutdown,
150 .socket_state = e800_pcmcia_socket_state,
151 .configure_socket = e800_pcmcia_configure_socket,
152 .socket_init = e800_pcmcia_socket_init,
153 .socket_suspend = e800_pcmcia_socket_suspend,
154 .nr = 2,
157 static struct platform_device e800_pcmcia_device = {
158 .name = "pxa2xx-pcmcia",
159 .dev = {
160 .platform_data = &e800_pcmcia_ops,
164 static int __init e800_pcmcia_init(void)
166 int ret = 0;
168 if(!machine_is_e800())
169 return -ENODEV;
171 angelx_init_irq(IRQ_GPIO(GPIO_E800_ANGELX_IRQ), PXA_CS5_PHYS);
173 //return -ENODEV;
174 printk("pcmcia: e800 detected.\n");
176 ret = platform_device_register(&e800_pcmcia_device);
178 return ret;
181 static void __exit e800_pcmcia_exit(void)
184 * This call is supposed to free our e800_pcmcia_device.
185 * Unfortunately platform_device don't have a free method, and
186 * we can't assume it's free of any reference at this point so we
187 * can't free it either.
189 //platform_device_unregister(&e800_pcmcia_device);
192 module_init(e800_pcmcia_init);
193 module_exit(e800_pcmcia_exit);
195 MODULE_LICENSE("GPL");