aboutsummaryrefslogtreecommitdiffstats
path: root/arch/m68k/platform/coldfire
diff options
context:
space:
mode:
Diffstat (limited to 'arch/m68k/platform/coldfire')
-rw-r--r--arch/m68k/platform/coldfire/device.c162
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 */
129static 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
142static 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
195fail3:
196 gpio_free(MCFQSPI_CS2);
197fail2:
198 gpio_free(MCFQSPI_CS1);
199fail1:
200 gpio_free(MCFQSPI_CS0);
201fail0:
202 return status;
203}
204
205static 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
215static 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
236static 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
257static 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
264static struct mcfqspi_platform_data mcf_qspi_data = {
265 .bus_num = 0,
266 .num_chipselect = 4,
267 .cs_control = &mcf_cs_control,
268};
269
270static 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
121static struct platform_device *mcf_devices[] __initdata = { 279static 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 */