Root/target/linux/pxa/patches/005-verdex_pcmcia_support.patch

1From 76a102bd5c9d792db19c6c72eafdecea0311a0c9 Mon Sep 17 00:00:00 2001
2From: Craig Hughes <craig@gumstix.com>
3Date: Fri, 30 Oct 2009 14:16:27 -0400
4Subject: [PATCH] [ARM] pxa: Gumstix Verdex PCMCIA support
5
6Needed for the Libertas CS wireless device.
7
8Signed-off-by: Bobby Powers <bobbypowers@gmail.com>
9---
10 drivers/pcmcia/Kconfig | 3 +-
11 drivers/pcmcia/Makefile | 3 +
12 drivers/pcmcia/pxa2xx_gumstix.c | 194 +++++++++++++++++++++++++++++++++++++++
13 3 files changed, 199 insertions(+), 1 deletions(-)
14 create mode 100644 drivers/pcmcia/pxa2xx_gumstix.c
15
16--- a/drivers/pcmcia/Kconfig
17+++ b/drivers/pcmcia/Kconfig
18@@ -215,7 +215,7 @@ config PCMCIA_PXA2XX
19     depends on (ARCH_LUBBOCK || MACH_MAINSTONE || PXA_SHARPSL \
20             || MACH_ARMCORE || ARCH_PXA_PALM || TRIZEPS_PCMCIA \
21             || ARCOM_PCMCIA || ARCH_PXA_ESERIES || MACH_STARGATE2 \
22- || MACH_VPAC270 || MACH_BALLOON3)
23+ || MACH_VPAC270 || MACH_BALLOON3 || ARCH_GUMSTIX)
24     select PCMCIA_SOC_COMMON
25     help
26       Say Y here to include support for the PXA2xx PCMCIA controller
27--- a/drivers/pcmcia/Makefile
28+++ b/drivers/pcmcia/Makefile
29@@ -71,6 +71,9 @@ pxa2xx-obj-$(CONFIG_MACH_STARGATE2) +=
30 pxa2xx-obj-$(CONFIG_MACH_VPAC270) += pxa2xx_vpac270.o
31 pxa2xx-obj-$(CONFIG_MACH_BALLOON3) += pxa2xx_balloon3.o
32 
33+pxa2xx-obj-$(CONFIG_MACH_GUMSTIX_VERDEX) += pxa2xx_cs.o
34+pxa2xx_cs-objs := pxa2xx_gumstix.o
35+
36 obj-$(CONFIG_PCMCIA_PXA2XX) += pxa2xx_base.o $(pxa2xx-obj-y)
37 
38 obj-$(CONFIG_PCMCIA_XXS1500) += xxs1500_ss.o
39--- /dev/null
40+++ b/drivers/pcmcia/pxa2xx_gumstix.c
41@@ -0,0 +1,194 @@
42+/*
43+ * linux/drivers/pcmcia/pxa2xx_gumstix.c
44+ *
45+ * Gumstix PCMCIA specific routines. Based on Mainstone
46+ *
47+ * Copyright 2004, Craig Hughes <craig@gumstix.com>
48+ *
49+ * This program is free software; you can redistribute it and/or modify
50+ * it under the terms of the GNU General Public License version 2 as
51+ * published by the Free Software Foundation.
52+ */
53+
54+#include <linux/module.h>
55+#include <linux/init.h>
56+#include <linux/kernel.h>
57+#include <linux/errno.h>
58+#include <linux/interrupt.h>
59+#include <linux/irq.h>
60+#include <linux/gpio.h>
61+
62+#include <linux/delay.h>
63+#include <linux/platform_device.h>
64+
65+#include <pcmcia/ss.h>
66+
67+#include <mach/hardware.h>
68+#include <asm/mach-types.h>
69+
70+#ifdef CONFIG_MACH_GUMSTIX_VERDEX
71+#include <mach/pxa27x.h>
72+#else
73+#include <mach/pxa27x.h>
74+#endif
75+
76+#include <asm/io.h>
77+#include <mach/gpio.h>
78+#include <mach/gumstix.h>
79+#include "soc_common.h"
80+
81+#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
82+
83+static struct pcmcia_irqs gumstix_pcmcia_irqs0[] = {
84+ { 0, GUMSTIX_S0_nCD_IRQ, "CF0 nCD" },
85+ { 0, GUMSTIX_S0_nSTSCHG_IRQ, "CF0 nSTSCHG" },
86+};
87+
88+static struct pcmcia_irqs gumstix_pcmcia_irqs1[] = {
89+ { 1, GUMSTIX_S1_nCD_IRQ, "CF1 nCD" },
90+ { 1, GUMSTIX_S1_nSTSCHG_IRQ, "CF1 nSTSCHG" },
91+};
92+
93+
94+static int net_cf_vx_mode = 0;
95+
96+static int gumstix_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
97+{
98+/* Note: The verdex_pcmcia_pin_config is moved to gumstix_verdex.c in order to use mfp_pxa2xx_config
99+ for board-specific pin configuration instead of the old deprecated pxa_gpio_mode function. Thus,
100+ only the IRQ init is still needed to be done here. */
101+ 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;
102+
103+ return (skt->nr == 0) ? soc_pcmcia_request_irqs(skt, gumstix_pcmcia_irqs0, ARRAY_SIZE(gumstix_pcmcia_irqs0)) :
104+ soc_pcmcia_request_irqs(skt, gumstix_pcmcia_irqs1, ARRAY_SIZE(gumstix_pcmcia_irqs1));
105+}
106+
107+static void gumstix_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
108+{
109+ if(skt->nr == 0)
110+ {
111+ soc_pcmcia_free_irqs(skt, gumstix_pcmcia_irqs0, ARRAY_SIZE(gumstix_pcmcia_irqs0));
112+ } else {
113+ soc_pcmcia_free_irqs(skt, gumstix_pcmcia_irqs1, ARRAY_SIZE(gumstix_pcmcia_irqs1));
114+ }
115+
116+ if (net_cf_vx_mode) {
117+ gpio_free(GPIO_GUMSTIX_CF_OLD_RESET);
118+ } else {
119+ gpio_free(GPIO_GUMSTIX_CF_RESET);
120+ }
121+
122+}
123+
124+static void gumstix_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
125+ struct pcmcia_state *state)
126+{
127+ unsigned int cd, prdy_nbsy, nbvd1;
128+ if(skt->nr == 0)
129+ {
130+ cd = GPIO_GUMSTIX_nCD_0;
131+ if(net_cf_vx_mode)
132+ prdy_nbsy = GPIO_GUMSTIX_PRDY_nBSY_0_OLD;
133+ else
134+ prdy_nbsy = GPIO_GUMSTIX_PRDY_nBSY_0;
135+ nbvd1 = GPIO_GUMSTIX_nBVD1_0;
136+ } else {
137+ cd = GPIO_GUMSTIX_nCD_1;
138+ prdy_nbsy = GPIO_GUMSTIX_PRDY_nBSY_1;
139+ nbvd1 = GPIO_GUMSTIX_nBVD1_1;
140+ }
141+ state->detect = !(GPLR(cd) & GPIO_bit(cd));
142+ state->ready = !!(GPLR(prdy_nbsy) & GPIO_bit(prdy_nbsy));
143+ state->bvd1 = !!(GPLR(nbvd1) & GPIO_bit(nbvd1));
144+ state->bvd2 = 1;
145+ state->vs_3v = 0;
146+ state->vs_Xv = 0;
147+ state->wrprot = 0;
148+}
149+
150+static int gumstix_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
151+ const socket_state_t *state)
152+{
153+ return 0;
154+}
155+
156+static void gumstix_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
157+{
158+ if(skt->nr) {
159+ soc_pcmcia_enable_irqs(skt, gumstix_pcmcia_irqs0, ARRAY_SIZE(gumstix_pcmcia_irqs0));
160+ } else {
161+ soc_pcmcia_enable_irqs(skt, gumstix_pcmcia_irqs1, ARRAY_SIZE(gumstix_pcmcia_irqs1));
162+ }
163+}
164+
165+static void gumstix_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
166+{
167+ if(skt->nr) {
168+ soc_pcmcia_disable_irqs(skt, gumstix_pcmcia_irqs0, ARRAY_SIZE(gumstix_pcmcia_irqs0));
169+ } else {
170+ soc_pcmcia_disable_irqs(skt, gumstix_pcmcia_irqs1, ARRAY_SIZE(gumstix_pcmcia_irqs1));
171+ }
172+}
173+
174+static struct pcmcia_low_level gumstix_pcmcia_ops = {
175+ .owner = THIS_MODULE,
176+ .hw_init = gumstix_pcmcia_hw_init,
177+ .hw_shutdown = gumstix_pcmcia_hw_shutdown,
178+ .socket_state = gumstix_pcmcia_socket_state,
179+ .configure_socket = gumstix_pcmcia_configure_socket,
180+ .socket_init = gumstix_pcmcia_socket_init,
181+ .socket_suspend = gumstix_pcmcia_socket_suspend,
182+ .nr = 2,
183+};
184+
185+static struct platform_device *gumstix_pcmcia_device;
186+
187+extern int __init gumstix_get_cf_cards(void);
188+
189+#ifdef CONFIG_MACH_GUMSTIX_VERDEX
190+extern int __init gumstix_check_if_netCF_vx(void);
191+#endif
192+
193+static int __init gumstix_pcmcia_init(void)
194+{
195+ int ret;
196+
197+#ifdef CONFIG_MACH_GUMSTIX_VERDEX
198+ net_cf_vx_mode = gumstix_check_if_netCF_vx();
199+#endif
200+
201+ gumstix_pcmcia_ops.nr = gumstix_get_cf_cards();
202+
203+ gumstix_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
204+ if (!gumstix_pcmcia_device)
205+ return -ENOMEM;
206+
207+ ret = platform_device_add_data(gumstix_pcmcia_device, &gumstix_pcmcia_ops,
208+ sizeof(gumstix_pcmcia_ops));
209+
210+ if (ret == 0) {
211+ printk(KERN_INFO "Registering gumstix PCMCIA interface.\n");
212+ ret = platform_device_add(gumstix_pcmcia_device);
213+ }
214+
215+ if (ret)
216+ platform_device_put(gumstix_pcmcia_device);
217+
218+ return ret;
219+}
220+
221+static void __exit gumstix_pcmcia_exit(void)
222+{
223+ /*
224+ * This call is supposed to free our gumstix_pcmcia_device.
225+ * Unfortunately platform_device don't have a free method, and
226+ * we can't assume it's free of any reference at this point so we
227+ * can't free it either.
228+ */
229+ platform_device_unregister(gumstix_pcmcia_device);
230+}
231+
232+fs_initcall(gumstix_pcmcia_init);
233+module_exit(gumstix_pcmcia_exit);
234+
235+MODULE_LICENSE("GPL");
236

Archive Download this file



interactive