2 * Asus MyPal 730 PCMCIA/CF support. Based on a716_pcmcia.c
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file COPYING in the main directory of this archive for
8 * Copyright (C) 2005 Pawel Kolodziejski
9 * Copyright (C) 2004 Nicolas Pouillon, Vitaliy Sardyko
14 #include <linux/module.h>
15 #include <linux/kernel.h>
16 #include <linux/errno.h>
17 #include <linux/interrupt.h>
18 #include <linux/device.h>
19 #include <linux/init.h>
20 #include <linux/device.h>
21 #include <linux/delay.h>
22 #include <linux/irq.h>
24 #include <asm/hardware.h>
25 #include <asm/mach/arch.h>
26 #include <asm/mach/map.h>
27 #include <asm/mach-types.h>
29 #include <asm/arch/pxa-regs.h>
30 #include <asm/arch/asus730-gpio.h>
32 #include <pcmcia/ss.h>
34 #include <../drivers/pcmcia/soc_common.h>
36 #include <linux/platform_device.h>
40 static int socket0_ready
= 0;
41 #define GPIO_NR_A730_CF_CARD_DETECT_N 38
42 #define GPIO_NR_A730_CF_IN_1 11
43 //#define GPIO_NR_A730_CF_IN_2 14
44 #define GPIO_NR_A730_CF_OUT_3 22
45 #define GPIO_NR_A730_CF_OUT_1 80
46 #define GPIO_NR_A730_CF_OUT_2 91
48 #define GPIO_CLR(nr) (GPCR(nr) = GPIO_bit(nr))
49 #define GPIO_SET(nr) (GPSR(nr) = GPIO_bit(nr))
51 static struct pcmcia_irqs irqs
[] = {
52 { 0, A730_IRQ(CF_CARD_DETECT_N
), "PCMCIA CD" },
55 void a730_pcmcia_restore(void)
59 printk("%s\n",__PRETTY_FUNCTION__
);
60 local_irq_save(flags
);
61 local_irq_restore(flags
);
64 static int a730_pcmcia_hw_init(struct soc_pcmcia_socket
*skt
)
69 skt
->irq
= A730_IRQ(CF_IN_1
);//or _2 or something entirelly different
70 set_irq_type(irqs
->irq
, IRQF_TRIGGER_RISING
| IRQF_TRIGGER_FALLING
);
71 ret
= soc_pcmcia_request_irqs(skt
, irqs
, ARRAY_SIZE(irqs
));
72 //a730_pcmcia_restore();
81 static void a730_pcmcia_hw_shutdown(struct soc_pcmcia_socket
*skt
)
83 //DPRINTK("%s\n",__PRETTY_FUNCTION__);
85 soc_pcmcia_free_irqs(skt
, irqs
, ARRAY_SIZE(irqs
));
88 static void a730_pcmcia_socket_state(struct soc_pcmcia_socket
*skt
, struct pcmcia_state
*state
)
91 state
->detect
= GET_A730_GPIO(CF_CARD_DETECT_N
) ? 0 : 1;//new
92 state
->ready
= socket0_ready
;
93 } else { // disabled fo now
103 // DPRINTK("skt:%d, detect:%d ready:%d 3X:%d%d\n", skt->nr,
104 // state->detect, state->ready, state->vs_3v, state->vs_Xv);
108 Three set_socket_calls
113 static int a730_pcmcia_configure_socket(struct soc_pcmcia_socket
*skt
, const socket_state_t
*state
)
115 printk("%s: reset = %d, snum = %d\n",__PRETTY_FUNCTION__
, (state
->flags
& SS_RESET
? 1 : 0), skt
->nr
);
117 /*if (state->flags & SS_RESET)
119 GPIO_SET(GPIO_NR_A730_CF_OUT_3);
121 GPIO_CLR(GPIO_NR_A730_CF_OUT_3);
122 GPIO_SET(GPIO_NR_A730_CF_OUT_1);
123 GPIO_CLR(GPIO_NR_A730_CF_OUT_2);
129 switch (state
->Vcc
) {
131 printk("%s: vcc=%d\n",__PRETTY_FUNCTION__
, state
->Vcc
);
132 GPIO_SET(GPIO_NR_A730_CF_OUT_1
);
133 GPIO_CLR(GPIO_NR_A730_CF_OUT_2
);
137 printk("%s: vcc=%d\n",__PRETTY_FUNCTION__
, state
->Vcc
);
138 GPIO_CLR(GPIO_NR_A730_CF_OUT_1
);
139 GPIO_SET(GPIO_NR_A730_CF_OUT_2
);
140 GPIO_SET(GPIO_NR_A730_CF_OUT_3
);
142 GPIO_CLR(GPIO_NR_A730_CF_OUT_3
);
146 printk("%s: vcc=%d\n",__PRETTY_FUNCTION__
, state
->Vcc
);
147 GPIO_CLR(GPIO_NR_A730_CF_OUT_1
);
148 GPIO_SET(GPIO_NR_A730_CF_OUT_2
);
149 GPIO_SET(GPIO_NR_A730_CF_OUT_3
);
151 GPIO_CLR(GPIO_NR_A730_CF_OUT_3
);
155 printk (KERN_ERR
"%s: Unsupported Vcc:%d\n", __FUNCTION__
, state
->Vcc
);
158 SET_A730_GPIO(CF_POWER
, !power_en
);
165 static void a730_pcmcia_socket_init(struct soc_pcmcia_socket
*skt
)
167 printk("%s %d\n",__PRETTY_FUNCTION__
,skt
->nr
);
169 if (skt
->nr
== 0) soc_pcmcia_enable_irqs(skt
, irqs
, ARRAY_SIZE(irqs
));
172 static void a730_pcmcia_socket_suspend(struct soc_pcmcia_socket
*skt
)
174 printk("%s %d\n",__PRETTY_FUNCTION__
,skt
->nr
);
177 soc_pcmcia_disable_irqs(skt
, irqs
, ARRAY_SIZE(irqs
));
181 static struct pcmcia_low_level a730_pcmcia_ops
= {
182 .owner
= THIS_MODULE
,
185 .hw_init
= a730_pcmcia_hw_init
,
186 .hw_shutdown
= a730_pcmcia_hw_shutdown
,
187 .socket_state
= a730_pcmcia_socket_state
,
188 .configure_socket
= a730_pcmcia_configure_socket
,
189 .socket_init
= a730_pcmcia_socket_init
,
190 .socket_suspend
= a730_pcmcia_socket_suspend
,
193 static struct platform_device a730_pcmcia_device
= {
194 .name
= "pxa2xx-pcmcia",
197 .platform_data
= &a730_pcmcia_ops
201 static int __init
a730_pcmcia_init(void)
203 printk("%s\n",__PRETTY_FUNCTION__
);
204 if (!machine_is_a730()) return -ENODEV
;
206 return platform_device_register(&a730_pcmcia_device
);
209 static void __exit
a730_pcmcia_exit(void)
211 printk("%s\n",__PRETTY_FUNCTION__
);
212 platform_device_unregister(&a730_pcmcia_device
);
215 module_init(a730_pcmcia_init
);
216 module_exit(a730_pcmcia_exit
);
218 MODULE_AUTHOR("Michal Sroczynski");
219 MODULE_DESCRIPTION("Asus MyPal 730 PCMCIA driver");
220 MODULE_LICENSE("GPL");