2 * linux/drivers/pcmcia/pxa2xx_gumstix.c
4 * Gumstix PCMCIA specific routines. Based on Mainstone
6 * Copyright 2004, Craig Hughes <craig@gumstix.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
13 #include <linux/module.h>
14 #include <linux/init.h>
15 #include <linux/kernel.h>
16 #include <linux/errno.h>
17 #include <linux/interrupt.h>
18 #include <linux/irq.h>
19 #include <linux/gpio.h>
21 #include <linux/delay.h>
22 #include <linux/platform_device.h>
24 #include <pcmcia/ss.h>
26 #include <mach/hardware.h>
27 #include <asm/mach-types.h>
29 #ifdef CONFIG_MACH_GUMSTIX_VERDEX
30 #include <mach/pxa27x.h>
32 #include <mach/pxa27x.h>
36 #include <mach/gpio.h>
37 #include <mach/gumstix.h>
38 #include "soc_common.h"
40 #define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
42 static struct pcmcia_irqs gumstix_pcmcia_irqs0
[] = {
43 { 0, GUMSTIX_S0_nCD_IRQ
, "CF0 nCD" },
44 { 0, GUMSTIX_S0_nSTSCHG_IRQ
, "CF0 nSTSCHG" },
47 static struct pcmcia_irqs gumstix_pcmcia_irqs1
[] = {
48 { 1, GUMSTIX_S1_nCD_IRQ
, "CF1 nCD" },
49 { 1, GUMSTIX_S1_nSTSCHG_IRQ
, "CF1 nSTSCHG" },
53 static int net_cf_vx_mode
= 0;
55 static int gumstix_pcmcia_hw_init(struct soc_pcmcia_socket
*skt
)
57 /* Note: The verdex_pcmcia_pin_config is moved to gumstix_verdex.c in order to use mfp_pxa2xx_config
58 for board-specific pin configuration instead of the old deprecated pxa_gpio_mode function. Thus,
59 only the IRQ init is still needed to be done here. */
60 skt
->irq
= (skt
->nr
== 0) ? ((net_cf_vx_mode
== 0) ? GUMSTIX_S0_PRDY_nBSY_IRQ
: GUMSTIX_S0_PRDY_nBSY_OLD_IRQ
) : GUMSTIX_S1_PRDY_nBSY_IRQ
;
62 return (skt
->nr
== 0) ? soc_pcmcia_request_irqs(skt
, gumstix_pcmcia_irqs0
, ARRAY_SIZE(gumstix_pcmcia_irqs0
)) :
63 soc_pcmcia_request_irqs(skt
, gumstix_pcmcia_irqs1
, ARRAY_SIZE(gumstix_pcmcia_irqs1
));
66 static void gumstix_pcmcia_hw_shutdown(struct soc_pcmcia_socket
*skt
)
70 soc_pcmcia_free_irqs(skt
, gumstix_pcmcia_irqs0
, ARRAY_SIZE(gumstix_pcmcia_irqs0
));
72 soc_pcmcia_free_irqs(skt
, gumstix_pcmcia_irqs1
, ARRAY_SIZE(gumstix_pcmcia_irqs1
));
76 gpio_free(GPIO_GUMSTIX_CF_OLD_RESET
);
78 gpio_free(GPIO_GUMSTIX_CF_RESET
);
83 static void gumstix_pcmcia_socket_state(struct soc_pcmcia_socket
*skt
,
84 struct pcmcia_state
*state
)
86 unsigned int cd
, prdy_nbsy
, nbvd1
;
89 cd
= GPIO_GUMSTIX_nCD_0
;
91 prdy_nbsy
= GPIO_GUMSTIX_PRDY_nBSY_0_OLD
;
93 prdy_nbsy
= GPIO_GUMSTIX_PRDY_nBSY_0
;
94 nbvd1
= GPIO_GUMSTIX_nBVD1_0
;
96 cd
= GPIO_GUMSTIX_nCD_1
;
97 prdy_nbsy
= GPIO_GUMSTIX_PRDY_nBSY_1
;
98 nbvd1
= GPIO_GUMSTIX_nBVD1_1
;
100 state
->detect
= !(GPLR(cd
) & GPIO_bit(cd
));
101 state
->ready
= !!(GPLR(prdy_nbsy
) & GPIO_bit(prdy_nbsy
));
102 state
->bvd1
= !!(GPLR(nbvd1
) & GPIO_bit(nbvd1
));
109 static int gumstix_pcmcia_configure_socket(struct soc_pcmcia_socket
*skt
,
110 const socket_state_t
*state
)
115 static void gumstix_pcmcia_socket_init(struct soc_pcmcia_socket
*skt
)
118 soc_pcmcia_enable_irqs(skt
, gumstix_pcmcia_irqs0
, ARRAY_SIZE(gumstix_pcmcia_irqs0
));
120 soc_pcmcia_enable_irqs(skt
, gumstix_pcmcia_irqs1
, ARRAY_SIZE(gumstix_pcmcia_irqs1
));
124 static void gumstix_pcmcia_socket_suspend(struct soc_pcmcia_socket
*skt
)
127 soc_pcmcia_disable_irqs(skt
, gumstix_pcmcia_irqs0
, ARRAY_SIZE(gumstix_pcmcia_irqs0
));
129 soc_pcmcia_disable_irqs(skt
, gumstix_pcmcia_irqs1
, ARRAY_SIZE(gumstix_pcmcia_irqs1
));
133 static struct pcmcia_low_level gumstix_pcmcia_ops
= {
134 .owner
= THIS_MODULE
,
135 .hw_init
= gumstix_pcmcia_hw_init
,
136 .hw_shutdown
= gumstix_pcmcia_hw_shutdown
,
137 .socket_state
= gumstix_pcmcia_socket_state
,
138 .configure_socket
= gumstix_pcmcia_configure_socket
,
139 .socket_init
= gumstix_pcmcia_socket_init
,
140 .socket_suspend
= gumstix_pcmcia_socket_suspend
,
144 static struct platform_device
*gumstix_pcmcia_device
;
146 extern int __init
gumstix_get_cf_cards(void);
148 #ifdef CONFIG_MACH_GUMSTIX_VERDEX
149 extern int __init
gumstix_check_if_netCF_vx(void);
152 static int __init
gumstix_pcmcia_init(void)
156 #ifdef CONFIG_MACH_GUMSTIX_VERDEX
157 net_cf_vx_mode
= gumstix_check_if_netCF_vx();
160 gumstix_pcmcia_ops
.nr
= gumstix_get_cf_cards();
162 gumstix_pcmcia_device
= platform_device_alloc("pxa2xx-pcmcia", -1);
163 if (!gumstix_pcmcia_device
)
166 ret
= platform_device_add_data(gumstix_pcmcia_device
, &gumstix_pcmcia_ops
,
167 sizeof(gumstix_pcmcia_ops
));
170 printk(KERN_INFO
"Registering gumstix PCMCIA interface.\n");
171 ret
= platform_device_add(gumstix_pcmcia_device
);
175 platform_device_put(gumstix_pcmcia_device
);
180 static void __exit
gumstix_pcmcia_exit(void)
183 * This call is supposed to free our gumstix_pcmcia_device.
184 * Unfortunately platform_device don't have a free method, and
185 * we can't assume it's free of any reference at this point so we
186 * can't free it either.
188 platform_device_unregister(gumstix_pcmcia_device
);
191 fs_initcall(gumstix_pcmcia_init
);
192 module_exit(gumstix_pcmcia_exit
);
194 MODULE_LICENSE("GPL");