diff options
Diffstat (limited to 'arch/m68k/platform/coldfire')
-rw-r--r-- | arch/m68k/platform/coldfire/device.c | 162 |
1 files changed, 161 insertions, 1 deletions
diff --git a/arch/m68k/platform/coldfire/device.c b/arch/m68k/platform/coldfire/device.c index 24b0d5e5350a..fa50c48292ff 100644 --- a/arch/m68k/platform/coldfire/device.c +++ b/arch/m68k/platform/coldfire/device.c | |||
@@ -11,10 +11,13 @@ | |||
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/io.h> | 13 | #include <linux/io.h> |
14 | #include <linux/spi/spi.h> | ||
15 | #include <linux/gpio.h> | ||
14 | #include <asm/traps.h> | 16 | #include <asm/traps.h> |
15 | #include <asm/coldfire.h> | 17 | #include <asm/coldfire.h> |
16 | #include <asm/mcfsim.h> | 18 | #include <asm/mcfsim.h> |
17 | #include <asm/mcfuart.h> | 19 | #include <asm/mcfuart.h> |
20 | #include <asm/mcfqspi.h> | ||
18 | 21 | ||
19 | /* | 22 | /* |
20 | * All current ColdFire parts contain from 2, 3 or 4 UARTS. | 23 | * All current ColdFire parts contain from 2, 3 or 4 UARTS. |
@@ -118,6 +121,161 @@ static struct platform_device mcf_fec1 = { | |||
118 | #endif /* MCFFEC_BASE1 */ | 121 | #endif /* MCFFEC_BASE1 */ |
119 | #endif /* CONFIG_FEC */ | 122 | #endif /* CONFIG_FEC */ |
120 | 123 | ||
124 | #ifdef CONFIG_SPI_COLDFIRE_QSPI | ||
125 | /* | ||
126 | * The ColdFire QSPI module is an SPI protocol hardware block used | ||
127 | * on a number of different ColdFire CPUs. | ||
128 | */ | ||
129 | static struct resource mcf_qspi_resources[] = { | ||
130 | { | ||
131 | .start = MCFQSPI_BASE, | ||
132 | .end = MCFQSPI_BASE + MCFQSPI_SIZE - 1, | ||
133 | .flags = IORESOURCE_MEM, | ||
134 | }, | ||
135 | { | ||
136 | .start = MCF_IRQ_QSPI, | ||
137 | .end = MCF_IRQ_QSPI, | ||
138 | .flags = IORESOURCE_IRQ, | ||
139 | }, | ||
140 | }; | ||
141 | |||
142 | static int mcf_cs_setup(struct mcfqspi_cs_control *cs_control) | ||
143 | { | ||
144 | int status; | ||
145 | |||
146 | status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0"); | ||
147 | if (status) { | ||
148 | pr_debug("gpio_request for MCFQSPI_CS0 failed\n"); | ||
149 | goto fail0; | ||
150 | } | ||
151 | status = gpio_direction_output(MCFQSPI_CS0, 1); | ||
152 | if (status) { | ||
153 | pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n"); | ||
154 | goto fail1; | ||
155 | } | ||
156 | |||
157 | status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1"); | ||
158 | if (status) { | ||
159 | pr_debug("gpio_request for MCFQSPI_CS1 failed\n"); | ||
160 | goto fail1; | ||
161 | } | ||
162 | status = gpio_direction_output(MCFQSPI_CS1, 1); | ||
163 | if (status) { | ||
164 | pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n"); | ||
165 | goto fail2; | ||
166 | } | ||
167 | |||
168 | status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2"); | ||
169 | if (status) { | ||
170 | pr_debug("gpio_request for MCFQSPI_CS2 failed\n"); | ||
171 | goto fail2; | ||
172 | } | ||
173 | status = gpio_direction_output(MCFQSPI_CS2, 1); | ||
174 | if (status) { | ||
175 | pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n"); | ||
176 | goto fail3; | ||
177 | } | ||
178 | |||
179 | #ifdef MCFQSPI_CS3 | ||
180 | status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3"); | ||
181 | if (status) { | ||
182 | pr_debug("gpio_request for MCFQSPI_CS3 failed\n"); | ||
183 | goto fail3; | ||
184 | } | ||
185 | status = gpio_direction_output(MCFQSPI_CS3, 1); | ||
186 | if (status) { | ||
187 | pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n"); | ||
188 | gpio_free(MCFQSPI_CS3); | ||
189 | goto fail3; | ||
190 | } | ||
191 | #endif | ||
192 | |||
193 | return 0; | ||
194 | |||
195 | fail3: | ||
196 | gpio_free(MCFQSPI_CS2); | ||
197 | fail2: | ||
198 | gpio_free(MCFQSPI_CS1); | ||
199 | fail1: | ||
200 | gpio_free(MCFQSPI_CS0); | ||
201 | fail0: | ||
202 | return status; | ||
203 | } | ||
204 | |||
205 | static void mcf_cs_teardown(struct mcfqspi_cs_control *cs_control) | ||
206 | { | ||
207 | #ifdef MCFQSPI_CS3 | ||
208 | gpio_free(MCFQSPI_CS3); | ||
209 | #endif | ||
210 | gpio_free(MCFQSPI_CS2); | ||
211 | gpio_free(MCFQSPI_CS1); | ||
212 | gpio_free(MCFQSPI_CS0); | ||
213 | } | ||
214 | |||
215 | static void mcf_cs_select(struct mcfqspi_cs_control *cs_control, | ||
216 | u8 chip_select, bool cs_high) | ||
217 | { | ||
218 | switch (chip_select) { | ||
219 | case 0: | ||
220 | gpio_set_value(MCFQSPI_CS0, cs_high); | ||
221 | break; | ||
222 | case 1: | ||
223 | gpio_set_value(MCFQSPI_CS1, cs_high); | ||
224 | break; | ||
225 | case 2: | ||
226 | gpio_set_value(MCFQSPI_CS2, cs_high); | ||
227 | break; | ||
228 | #ifdef MCFQSPI_CS3 | ||
229 | case 3: | ||
230 | gpio_set_value(MCFQSPI_CS3, cs_high); | ||
231 | break; | ||
232 | #endif | ||
233 | } | ||
234 | } | ||
235 | |||
236 | static void mcf_cs_deselect(struct mcfqspi_cs_control *cs_control, | ||
237 | u8 chip_select, bool cs_high) | ||
238 | { | ||
239 | switch (chip_select) { | ||
240 | case 0: | ||
241 | gpio_set_value(MCFQSPI_CS0, !cs_high); | ||
242 | break; | ||
243 | case 1: | ||
244 | gpio_set_value(MCFQSPI_CS1, !cs_high); | ||
245 | break; | ||
246 | case 2: | ||
247 | gpio_set_value(MCFQSPI_CS2, !cs_high); | ||
248 | break; | ||
249 | #ifdef MCFQSPI_CS3 | ||
250 | case 3: | ||
251 | gpio_set_value(MCFQSPI_CS3, !cs_high); | ||
252 | break; | ||
253 | #endif | ||
254 | } | ||
255 | } | ||
256 | |||
257 | static struct mcfqspi_cs_control mcf_cs_control = { | ||
258 | .setup = mcf_cs_setup, | ||
259 | .teardown = mcf_cs_teardown, | ||
260 | .select = mcf_cs_select, | ||
261 | .deselect = mcf_cs_deselect, | ||
262 | }; | ||
263 | |||
264 | static struct mcfqspi_platform_data mcf_qspi_data = { | ||
265 | .bus_num = 0, | ||
266 | .num_chipselect = 4, | ||
267 | .cs_control = &mcf_cs_control, | ||
268 | }; | ||
269 | |||
270 | static struct platform_device mcf_qspi = { | ||
271 | .name = "mcfqspi", | ||
272 | .id = 0, | ||
273 | .num_resources = ARRAY_SIZE(mcf_qspi_resources), | ||
274 | .resource = mcf_qspi_resources, | ||
275 | .dev.platform_data = &mcf_qspi_data, | ||
276 | }; | ||
277 | #endif /* CONFIG_SPI_COLDFIRE_QSPI */ | ||
278 | |||
121 | static struct platform_device *mcf_devices[] __initdata = { | 279 | static struct platform_device *mcf_devices[] __initdata = { |
122 | &mcf_uart, | 280 | &mcf_uart, |
123 | #ifdef CONFIG_FEC | 281 | #ifdef CONFIG_FEC |
@@ -126,9 +284,11 @@ static struct platform_device *mcf_devices[] __initdata = { | |||
126 | &mcf_fec1, | 284 | &mcf_fec1, |
127 | #endif | 285 | #endif |
128 | #endif | 286 | #endif |
287 | #ifdef CONFIG_SPI_COLDFIRE_QSPI | ||
288 | &mcf_qspi, | ||
289 | #endif | ||
129 | }; | 290 | }; |
130 | 291 | ||
131 | |||
132 | /* | 292 | /* |
133 | * Some ColdFire UARTs let you set the IRQ line to use. | 293 | * Some ColdFire UARTs let you set the IRQ line to use. |
134 | */ | 294 | */ |