[brcm63xx] also supports pcmcia
[openwrt.git] / target / linux / pxa / patches-2.6.21 / 018-modular-init-smc91x.patch
1 --- a/drivers/net/Kconfig
2 +++ b/drivers/net/Kconfig
3 @@ -959,6 +959,12 @@ config SMC91X
4 module, say M here and read <file:Documentation/modules.txt> as well
5 as <file:Documentation/networking/net-modules.txt>.
6
7 +config SMC91X_GUMSTIX
8 + tristate
9 + default m if SMC91X=m
10 + default y if SMC91X=y
11 + depends on SMC91X && ARCH_GUMSTIX
12 +
13 config SMC9194
14 tristate "SMC 9194 support"
15 depends on NET_VENDOR_SMC && (ISA || MAC && BROKEN)
16 --- a/drivers/net/Makefile
17 +++ b/drivers/net/Makefile
18 @@ -201,6 +201,7 @@ obj-$(CONFIG_PASEMI_MAC) += pasemi_mac.o
19
20 obj-$(CONFIG_MACB) += macb.o
21
22 +obj-$(CONFIG_SMC91X_GUMSTIX) += gumstix-smc91x.o
23 obj-$(CONFIG_ARM) += arm/
24 obj-$(CONFIG_DEV_APPLETALK) += appletalk/
25 obj-$(CONFIG_TR) += tokenring/
26 --- a/drivers/net/smc91x.c
27 +++ b/drivers/net/smc91x.c
28 @@ -2373,6 +2373,10 @@ static struct platform_driver smc_driver
29 },
30 };
31
32 +#ifdef CONFIG_ARCH_GUMSTIX
33 +extern void gumstix_smc91x_load(void);
34 +#endif
35 +
36 static int __init smc_init(void)
37 {
38 #ifdef MODULE
39 @@ -2384,6 +2388,10 @@ static int __init smc_init(void)
40 #endif
41 #endif
42
43 +#ifdef CONFIG_ARCH_GUMSTIX
44 + gumstix_smc91x_load();
45 +#endif
46 +
47 return platform_driver_register(&smc_driver);
48 }
49
50 --- /dev/null
51 +++ b/drivers/net/gumstix-smc91x.c
52 @@ -0,0 +1,143 @@
53 +/*
54 + * Gumstix SMC91C111 chip intialization driver
55 + *
56 + * Author: Craig Hughes
57 + * Created: December 9, 2004
58 + * Copyright: (C) 2004 Craig Hughes
59 + *
60 + * This program is free software; you can redistribute it and/or modify
61 + * it under the terms of the GNU General Public License as published by
62 + * the Free Software Foundation; either version 2 of the License, or
63 + * (at your option) any later version.
64 + *
65 + */
66 +
67 +#include <linux/module.h>
68 +#include <linux/ioport.h>
69 +#include <linux/device.h>
70 +#include <linux/platform_device.h>
71 +#include <linux/delay.h>
72 +
73 +#include <asm/hardware.h>
74 +#include <asm/arch/pxa-regs.h>
75 +#include <asm/delay.h>
76 +
77 +#include <asm/arch/gumstix.h>
78 +
79 +#define SMC_DEBUG 0
80 +#include <asm/io.h>
81 +#include "smc91x.h"
82 +
83 +static struct resource gumstix_smc91x0_resources[] = {
84 + [0] = {
85 + .name = "smc91x-regs",
86 + .start = PXA_CS1_PHYS + 0x00000300,
87 + .end = PXA_CS1_PHYS + 0x000fffff,
88 + .flags = IORESOURCE_MEM,
89 + },
90 + [1] = {
91 + .start = GUMSTIX_ETH0_IRQ,
92 + .end = GUMSTIX_ETH0_IRQ,
93 + .flags = IORESOURCE_IRQ,
94 + },
95 +};
96 +
97 +static struct resource gumstix_smc91x1_resources[] = {
98 + [0] = {
99 + .name = "smc91x-regs",
100 + .start = PXA_CS2_PHYS + 0x00000300,
101 + .end = PXA_CS2_PHYS + 0x000fffff,
102 + .flags = IORESOURCE_MEM,
103 + },
104 + [1] = {
105 + .start = GUMSTIX_ETH1_IRQ,
106 + .end = GUMSTIX_ETH1_IRQ,
107 + .flags = IORESOURCE_IRQ,
108 + },
109 +};
110 +
111 +static struct platform_device gumstix_smc91x0_device = {
112 + .name = "smc91x",
113 + .id = 0,
114 + .num_resources = ARRAY_SIZE(gumstix_smc91x0_resources),
115 + .resource = gumstix_smc91x0_resources,
116 +};
117 +
118 +static struct platform_device gumstix_smc91x1_device = {
119 + .name = "smc91x",
120 + .id = 1,
121 + .num_resources = ARRAY_SIZE(gumstix_smc91x1_resources),
122 + .resource = gumstix_smc91x1_resources,
123 +};
124 +
125 +static struct platform_device *smc91x_devices[] = {
126 + &gumstix_smc91x0_device,
127 + &gumstix_smc91x1_device,
128 +};
129 +
130 +/* First we're going to test if there's a 2nd SMC91C111, and if not, then we'll free up those resources and the GPIO lines
131 + * that it would otherwise use. We have no choice but to probe by doing:
132 + * Set nCS2 to CS2 mode
133 + * Set the reset line to GPIO out mode, and pull it high, then drop it low (to trigger reset)
134 + * Read from the memory space to check for the sentinel sequence identifying a likely SMC91C111 device
135 + */
136 +int __init gumstix_smc91x_init(void)
137 +{
138 + unsigned int val, num_devices=ARRAY_SIZE(smc91x_devices);
139 + void *ioaddr;
140 +
141 + /* Set up nPWE */
142 + pxa_gpio_mode(GPIO49_nPWE_MD);
143 +
144 + pxa_gpio_mode(GPIO78_nCS_2_MD);
145 + // If either if statement fails, then we'll drop out and turn_off_eth1,
146 + // if both succeed, then we'll skip that and just proceed with 2 cards
147 + if(request_mem_region(gumstix_smc91x1_resources[0].start, SMC_IO_EXTENT, "smc91x probe"))
148 + {
149 + ioaddr = ioremap(gumstix_smc91x1_resources[0].start, SMC_IO_EXTENT);
150 + val = ioread16(ioaddr + BANK_SELECT);
151 + iounmap(ioaddr);
152 + release_mem_region(gumstix_smc91x1_resources[0].start, SMC_IO_EXTENT);
153 + if ((val & 0xFF00) == 0x3300) {
154 + goto proceed;
155 + }
156 + }
157 +
158 +turn_off_eth1:
159 + // This is apparently not an SMC91C111
160 + // So, let's decrement the number of devices to request, and reset the GPIO lines to GPIO IN mode
161 + num_devices--;
162 + smc91x_devices[1] = NULL;
163 + pxa_gpio_mode(78 | GPIO_IN);
164 +
165 +proceed:
166 + pxa_gpio_mode(GPIO15_nCS_1_MD);
167 +
168 + if(smc91x_devices[1]) pxa_gpio_mode(GPIO_GUMSTIX_ETH1_RST_MD);
169 + pxa_gpio_mode(GPIO_GUMSTIX_ETH0_RST_MD);
170 + if(smc91x_devices[1]) GPSR(GPIO_GUMSTIX_ETH1_RST) = GPIO_bit(GPIO_GUMSTIX_ETH1_RST);
171 + GPSR(GPIO_GUMSTIX_ETH0_RST) = GPIO_bit(GPIO_GUMSTIX_ETH0_RST);
172 + udelay(1); // Hold RESET for at least 100ns
173 + if(smc91x_devices[1]) GPCR(GPIO_GUMSTIX_ETH1_RST) = GPIO_bit(GPIO_GUMSTIX_ETH1_RST);
174 + GPCR(GPIO_GUMSTIX_ETH0_RST) = GPIO_bit(GPIO_GUMSTIX_ETH0_RST);
175 + msleep(50);
176 +
177 + return platform_add_devices(smc91x_devices, num_devices);
178 +}
179 +
180 +void __exit gumstix_smc91x_exit(void)
181 +{
182 + if(smc91x_devices[1] != NULL) platform_device_unregister(&gumstix_smc91x1_device);
183 + platform_device_unregister(&gumstix_smc91x0_device);
184 +}
185 +
186 +void gumstix_smc91x_load(void) {}
187 +EXPORT_SYMBOL(gumstix_smc91x_load);
188 +
189 +module_init(gumstix_smc91x_init);
190 +module_exit(gumstix_smc91x_exit);
191 +
192 +MODULE_LICENSE("GPL");
193 +MODULE_AUTHOR("Craig Hughes <craig@gumstix.com>");
194 +MODULE_DESCRIPTION("Gumstix board SMC91C111 chip initialization driver");
195 +MODULE_VERSION("1:0.1");
This page took 0.053597 seconds and 5 git commands to generate.