sync hh.org
[hh.org.git] / arch / arm / mach-pxa / eseries / e750_pcmcia.c
blob54bf7b4a4f5541416acd9a65b6c5b05d8e1891d9
1 /*
2 * arch/arm/mach-pxa/e750_pcmcia.c
4 * Toshiba E-750 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-gpio.h>
31 #include "soc_common.h"
33 static struct pcmcia_irqs cd_irqs[] = {
34 { 0, IRQ_GPIO(GPIO_E750_PCMCIA_CD0), "CF card detect" },
37 static int e750_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
39 skt->irq = IRQ_GPIO(GPIO_E750_PCMCIA_RDY0);
41 return soc_pcmcia_request_irqs(skt, cd_irqs, ARRAY_SIZE(cd_irqs));
45 * Release all resources.
47 static void e750_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
49 soc_pcmcia_free_irqs(skt, cd_irqs, ARRAY_SIZE(cd_irqs));
52 #define GPLR_BIT(n) (GPLR((n)) & GPIO_bit((n)))
54 static void e750_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
56 // unsigned long gplr0 = GPLR0; FIXME - this really ought to be atomic
57 // unsigned long gplr1 = GPLR1;
59 state->detect = GPLR_BIT(GPIO_E740_PCMCIA_CD0) ? 0 : 1;
60 state->ready = GPLR_BIT(GPIO_E740_PCMCIA_RDY0) ? 1 : 0;
62 state->vs_3v = 1; //FIXME - is it right?
64 state->bvd1 = 1;
65 state->bvd2 = 1;
66 state->wrprot = 0;
67 state->vs_Xv = 0;
70 #define GPSR_BIT(n) (GPSR((n)) = GPIO_bit((n)))
71 #define GPCR_BIT(n) (GPCR((n)) = GPIO_bit((n)))
73 static int e750_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
75 /* reset it? */
76 if(state->flags & SS_RESET)
77 GPSR_BIT(GPIO_E740_PCMCIA_RST0);
78 else
79 GPCR_BIT(GPIO_E740_PCMCIA_RST0);
82 /* Apply socket voltage */
83 switch (state->Vcc) {
84 case 0:
85 GPCR_BIT(GPIO_E740_PCMCIA_PWR0);
86 break;
87 case 50:
88 case 33:
89 /* Apply power to socket */
90 GPSR_BIT(GPIO_E740_PCMCIA_PWR0);
91 break;
92 default:
93 printk (KERN_ERR "%s: Unsupported Vcc:%d\n", __FUNCTION__, state->Vcc);
96 return 0;
100 * Enable card status IRQs on (re-)initialisation. This can
101 * be called at initialisation, power management event, or
102 * pcmcia event.
104 static void e750_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
106 soc_pcmcia_enable_irqs(skt, cd_irqs, ARRAY_SIZE(cd_irqs));
110 * Disable card status IRQs on suspend.
112 static void e750_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
114 soc_pcmcia_disable_irqs(skt, cd_irqs, ARRAY_SIZE(cd_irqs));
117 static struct pcmcia_low_level e750_pcmcia_ops = {
118 .owner = THIS_MODULE,
119 .hw_init = e750_pcmcia_hw_init,
120 .hw_shutdown = e750_pcmcia_hw_shutdown,
121 .socket_state = e750_pcmcia_socket_state,
122 .configure_socket = e750_pcmcia_configure_socket,
123 .socket_init = e750_pcmcia_socket_init,
124 .socket_suspend = e750_pcmcia_socket_suspend,
125 .nr = 1,
128 static struct platform_device e750_pcmcia_device = {
129 .name = "pxa2xx-pcmcia",
130 .dev = {
131 .platform_data = &e750_pcmcia_ops,
135 static int __init e750_pcmcia_init(void)
137 int ret = 0;
139 if(!machine_is_e750())
140 return -ENODEV;
142 printk("pcmcia: e750 detected.\n");
144 ret = platform_device_register(&e750_pcmcia_device);
146 return ret;
149 static void __exit e750_pcmcia_exit(void)
152 * This call is supposed to free our e750_pcmcia_device.
153 * Unfortunately platform_device don't have a free method, and
154 * we can't assume it's free of any reference at this point so we
155 * can't free it either.
157 //platform_device_unregister(&e750_pcmcia_device);
160 module_init(e750_pcmcia_init);
161 module_exit(e750_pcmcia_exit);
163 MODULE_LICENSE("GPL");