xref: /linux/arch/m68k/coldfire/device.c (revision e5c86679d5e864947a52fb31e45a425dea3e7fa9)
1 /*
2  * device.c  -- common ColdFire SoC device support
3  *
4  * (C) Copyright 2011, Greg Ungerer <gerg@uclinux.org>
5  *
6  * This file is subject to the terms and conditions of the GNU General Public
7  * License.  See the file COPYING in the main directory of this archive
8  * for more details.
9  */
10 
11 #include <linux/kernel.h>
12 #include <linux/init.h>
13 #include <linux/io.h>
14 #include <linux/spi/spi.h>
15 #include <linux/gpio.h>
16 #include <linux/fec.h>
17 #include <asm/traps.h>
18 #include <asm/coldfire.h>
19 #include <asm/mcfsim.h>
20 #include <asm/mcfuart.h>
21 #include <asm/mcfqspi.h>
22 
23 /*
24  *	All current ColdFire parts contain from 2, 3, 4 or 10 UARTS.
25  */
26 static struct mcf_platform_uart mcf_uart_platform_data[] = {
27 	{
28 		.mapbase	= MCFUART_BASE0,
29 		.irq		= MCF_IRQ_UART0,
30 	},
31 	{
32 		.mapbase	= MCFUART_BASE1,
33 		.irq		= MCF_IRQ_UART1,
34 	},
35 #ifdef MCFUART_BASE2
36 	{
37 		.mapbase	= MCFUART_BASE2,
38 		.irq		= MCF_IRQ_UART2,
39 	},
40 #endif
41 #ifdef MCFUART_BASE3
42 	{
43 		.mapbase	= MCFUART_BASE3,
44 		.irq		= MCF_IRQ_UART3,
45 	},
46 #endif
47 #ifdef MCFUART_BASE4
48 	{
49 		.mapbase	= MCFUART_BASE4,
50 		.irq		= MCF_IRQ_UART4,
51 	},
52 #endif
53 #ifdef MCFUART_BASE5
54 	{
55 		.mapbase	= MCFUART_BASE5,
56 		.irq		= MCF_IRQ_UART5,
57 	},
58 #endif
59 #ifdef MCFUART_BASE6
60 	{
61 		.mapbase	= MCFUART_BASE6,
62 		.irq		= MCF_IRQ_UART6,
63 	},
64 #endif
65 #ifdef MCFUART_BASE7
66 	{
67 		.mapbase	= MCFUART_BASE7,
68 		.irq		= MCF_IRQ_UART7,
69 	},
70 #endif
71 #ifdef MCFUART_BASE8
72 	{
73 		.mapbase	= MCFUART_BASE8,
74 		.irq		= MCF_IRQ_UART8,
75 	},
76 #endif
77 #ifdef MCFUART_BASE9
78 	{
79 		.mapbase	= MCFUART_BASE9,
80 		.irq		= MCF_IRQ_UART9,
81 	},
82 #endif
83 	{ },
84 };
85 
86 static struct platform_device mcf_uart = {
87 	.name			= "mcfuart",
88 	.id			= 0,
89 	.dev.platform_data	= mcf_uart_platform_data,
90 };
91 
92 #if IS_ENABLED(CONFIG_FEC)
93 
94 #ifdef CONFIG_M5441x
95 #define FEC_NAME	"enet-fec"
96 static struct fec_platform_data fec_pdata = {
97 	.phy		= PHY_INTERFACE_MODE_RMII,
98 };
99 #define FEC_PDATA	(&fec_pdata)
100 #else
101 #define FEC_NAME	"fec"
102 #define FEC_PDATA	NULL
103 #endif
104 
105 /*
106  *	Some ColdFire cores contain the Fast Ethernet Controller (FEC)
107  *	block. It is Freescale's own hardware block. Some ColdFires
108  *	have 2 of these.
109  */
110 static struct resource mcf_fec0_resources[] = {
111 	{
112 		.start		= MCFFEC_BASE0,
113 		.end		= MCFFEC_BASE0 + MCFFEC_SIZE0 - 1,
114 		.flags		= IORESOURCE_MEM,
115 	},
116 	{
117 		.start		= MCF_IRQ_FECRX0,
118 		.end		= MCF_IRQ_FECRX0,
119 		.flags		= IORESOURCE_IRQ,
120 	},
121 	{
122 		.start		= MCF_IRQ_FECTX0,
123 		.end		= MCF_IRQ_FECTX0,
124 		.flags		= IORESOURCE_IRQ,
125 	},
126 	{
127 		.start		= MCF_IRQ_FECENTC0,
128 		.end		= MCF_IRQ_FECENTC0,
129 		.flags		= IORESOURCE_IRQ,
130 	},
131 };
132 
133 static struct platform_device mcf_fec0 = {
134 	.name			= FEC_NAME,
135 	.id			= 0,
136 	.num_resources		= ARRAY_SIZE(mcf_fec0_resources),
137 	.resource		= mcf_fec0_resources,
138 	.dev.platform_data	= FEC_PDATA,
139 };
140 
141 #ifdef MCFFEC_BASE1
142 static struct resource mcf_fec1_resources[] = {
143 	{
144 		.start		= MCFFEC_BASE1,
145 		.end		= MCFFEC_BASE1 + MCFFEC_SIZE1 - 1,
146 		.flags		= IORESOURCE_MEM,
147 	},
148 	{
149 		.start		= MCF_IRQ_FECRX1,
150 		.end		= MCF_IRQ_FECRX1,
151 		.flags		= IORESOURCE_IRQ,
152 	},
153 	{
154 		.start		= MCF_IRQ_FECTX1,
155 		.end		= MCF_IRQ_FECTX1,
156 		.flags		= IORESOURCE_IRQ,
157 	},
158 	{
159 		.start		= MCF_IRQ_FECENTC1,
160 		.end		= MCF_IRQ_FECENTC1,
161 		.flags		= IORESOURCE_IRQ,
162 	},
163 };
164 
165 static struct platform_device mcf_fec1 = {
166 	.name			= FEC_NAME,
167 	.id			= 1,
168 	.num_resources		= ARRAY_SIZE(mcf_fec1_resources),
169 	.resource		= mcf_fec1_resources,
170 	.dev.platform_data	= FEC_PDATA,
171 };
172 #endif /* MCFFEC_BASE1 */
173 #endif /* CONFIG_FEC */
174 
175 #if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
176 /*
177  *	The ColdFire QSPI module is an SPI protocol hardware block used
178  *	on a number of different ColdFire CPUs.
179  */
180 static struct resource mcf_qspi_resources[] = {
181 	{
182 		.start		= MCFQSPI_BASE,
183 		.end		= MCFQSPI_BASE + MCFQSPI_SIZE - 1,
184 		.flags		= IORESOURCE_MEM,
185 	},
186 	{
187 		.start		= MCF_IRQ_QSPI,
188 		.end		= MCF_IRQ_QSPI,
189 		.flags		= IORESOURCE_IRQ,
190 	},
191 };
192 
193 static int mcf_cs_setup(struct mcfqspi_cs_control *cs_control)
194 {
195 	int status;
196 
197 	status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0");
198 	if (status) {
199 		pr_debug("gpio_request for MCFQSPI_CS0 failed\n");
200 		goto fail0;
201 	}
202 	status = gpio_direction_output(MCFQSPI_CS0, 1);
203 	if (status) {
204 		pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");
205 		goto fail1;
206 	}
207 
208 	status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1");
209 	if (status) {
210 		pr_debug("gpio_request for MCFQSPI_CS1 failed\n");
211 		goto fail1;
212 	}
213 	status = gpio_direction_output(MCFQSPI_CS1, 1);
214 	if (status) {
215 		pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");
216 		goto fail2;
217 	}
218 
219 	status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2");
220 	if (status) {
221 		pr_debug("gpio_request for MCFQSPI_CS2 failed\n");
222 		goto fail2;
223 	}
224 	status = gpio_direction_output(MCFQSPI_CS2, 1);
225 	if (status) {
226 		pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");
227 		goto fail3;
228 	}
229 
230 #ifdef MCFQSPI_CS3
231 	status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3");
232 	if (status) {
233 		pr_debug("gpio_request for MCFQSPI_CS3 failed\n");
234 		goto fail3;
235 	}
236 	status = gpio_direction_output(MCFQSPI_CS3, 1);
237 	if (status) {
238 		pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n");
239 		gpio_free(MCFQSPI_CS3);
240 		goto fail3;
241 	}
242 #endif
243 
244 	return 0;
245 
246 fail3:
247 	gpio_free(MCFQSPI_CS2);
248 fail2:
249 	gpio_free(MCFQSPI_CS1);
250 fail1:
251 	gpio_free(MCFQSPI_CS0);
252 fail0:
253 	return status;
254 }
255 
256 static void mcf_cs_teardown(struct mcfqspi_cs_control *cs_control)
257 {
258 #ifdef MCFQSPI_CS3
259 	gpio_free(MCFQSPI_CS3);
260 #endif
261 	gpio_free(MCFQSPI_CS2);
262 	gpio_free(MCFQSPI_CS1);
263 	gpio_free(MCFQSPI_CS0);
264 }
265 
266 static void mcf_cs_select(struct mcfqspi_cs_control *cs_control,
267 			  u8 chip_select, bool cs_high)
268 {
269 	switch (chip_select) {
270 	case 0:
271 		gpio_set_value(MCFQSPI_CS0, cs_high);
272 		break;
273 	case 1:
274 		gpio_set_value(MCFQSPI_CS1, cs_high);
275 		break;
276 	case 2:
277 		gpio_set_value(MCFQSPI_CS2, cs_high);
278 		break;
279 #ifdef MCFQSPI_CS3
280 	case 3:
281 		gpio_set_value(MCFQSPI_CS3, cs_high);
282 		break;
283 #endif
284 	}
285 }
286 
287 static void mcf_cs_deselect(struct mcfqspi_cs_control *cs_control,
288 			    u8 chip_select, bool cs_high)
289 {
290 	switch (chip_select) {
291 	case 0:
292 		gpio_set_value(MCFQSPI_CS0, !cs_high);
293 		break;
294 	case 1:
295 		gpio_set_value(MCFQSPI_CS1, !cs_high);
296 		break;
297 	case 2:
298 		gpio_set_value(MCFQSPI_CS2, !cs_high);
299 		break;
300 #ifdef MCFQSPI_CS3
301 	case 3:
302 		gpio_set_value(MCFQSPI_CS3, !cs_high);
303 		break;
304 #endif
305 	}
306 }
307 
308 static struct mcfqspi_cs_control mcf_cs_control = {
309 	.setup			= mcf_cs_setup,
310 	.teardown		= mcf_cs_teardown,
311 	.select			= mcf_cs_select,
312 	.deselect		= mcf_cs_deselect,
313 };
314 
315 static struct mcfqspi_platform_data mcf_qspi_data = {
316 	.bus_num		= 0,
317 	.num_chipselect		= 4,
318 	.cs_control		= &mcf_cs_control,
319 };
320 
321 static struct platform_device mcf_qspi = {
322 	.name			= "mcfqspi",
323 	.id			= 0,
324 	.num_resources		= ARRAY_SIZE(mcf_qspi_resources),
325 	.resource		= mcf_qspi_resources,
326 	.dev.platform_data	= &mcf_qspi_data,
327 };
328 #endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */
329 
330 #if IS_ENABLED(CONFIG_I2C_IMX)
331 static struct resource mcf_i2c0_resources[] = {
332 	{
333 		.start          = MCFI2C_BASE0,
334 		.end            = MCFI2C_BASE0 + MCFI2C_SIZE0 - 1,
335 		.flags          = IORESOURCE_MEM,
336 	},
337 	{
338 		.start          = MCF_IRQ_I2C0,
339 		.end            = MCF_IRQ_I2C0,
340 		.flags          = IORESOURCE_IRQ,
341 	},
342 };
343 
344 static struct platform_device mcf_i2c0 = {
345 	.name                   = "imx1-i2c",
346 	.id                     = 0,
347 	.num_resources          = ARRAY_SIZE(mcf_i2c0_resources),
348 	.resource               = mcf_i2c0_resources,
349 };
350 #ifdef MCFI2C_BASE1
351 
352 static struct resource mcf_i2c1_resources[] = {
353 	{
354 		.start          = MCFI2C_BASE1,
355 		.end            = MCFI2C_BASE1 + MCFI2C_SIZE1 - 1,
356 		.flags          = IORESOURCE_MEM,
357 	},
358 	{
359 		.start          = MCF_IRQ_I2C1,
360 		.end            = MCF_IRQ_I2C1,
361 		.flags          = IORESOURCE_IRQ,
362 	},
363 };
364 
365 static struct platform_device mcf_i2c1 = {
366 	.name                   = "imx1-i2c",
367 	.id                     = 1,
368 	.num_resources          = ARRAY_SIZE(mcf_i2c1_resources),
369 	.resource               = mcf_i2c1_resources,
370 };
371 
372 #endif /* MCFI2C_BASE1 */
373 
374 #ifdef MCFI2C_BASE2
375 
376 static struct resource mcf_i2c2_resources[] = {
377 	{
378 		.start          = MCFI2C_BASE2,
379 		.end            = MCFI2C_BASE2 + MCFI2C_SIZE2 - 1,
380 		.flags          = IORESOURCE_MEM,
381 	},
382 	{
383 		.start          = MCF_IRQ_I2C2,
384 		.end            = MCF_IRQ_I2C2,
385 		.flags          = IORESOURCE_IRQ,
386 	},
387 };
388 
389 static struct platform_device mcf_i2c2 = {
390 	.name                   = "imx1-i2c",
391 	.id                     = 2,
392 	.num_resources          = ARRAY_SIZE(mcf_i2c2_resources),
393 	.resource               = mcf_i2c2_resources,
394 };
395 
396 #endif /* MCFI2C_BASE2 */
397 
398 #ifdef MCFI2C_BASE3
399 
400 static struct resource mcf_i2c3_resources[] = {
401 	{
402 		.start          = MCFI2C_BASE3,
403 		.end            = MCFI2C_BASE3 + MCFI2C_SIZE3 - 1,
404 		.flags          = IORESOURCE_MEM,
405 	},
406 	{
407 		.start          = MCF_IRQ_I2C3,
408 		.end            = MCF_IRQ_I2C3,
409 		.flags          = IORESOURCE_IRQ,
410 	},
411 };
412 
413 static struct platform_device mcf_i2c3 = {
414 	.name                   = "imx1-i2c",
415 	.id                     = 3,
416 	.num_resources          = ARRAY_SIZE(mcf_i2c3_resources),
417 	.resource               = mcf_i2c3_resources,
418 };
419 
420 #endif /* MCFI2C_BASE3 */
421 
422 #ifdef MCFI2C_BASE4
423 
424 static struct resource mcf_i2c4_resources[] = {
425 	{
426 		.start          = MCFI2C_BASE4,
427 		.end            = MCFI2C_BASE4 + MCFI2C_SIZE4 - 1,
428 		.flags          = IORESOURCE_MEM,
429 	},
430 	{
431 		.start          = MCF_IRQ_I2C4,
432 		.end            = MCF_IRQ_I2C4,
433 		.flags          = IORESOURCE_IRQ,
434 	},
435 };
436 
437 static struct platform_device mcf_i2c4 = {
438 	.name                   = "imx1-i2c",
439 	.id                     = 4,
440 	.num_resources          = ARRAY_SIZE(mcf_i2c4_resources),
441 	.resource               = mcf_i2c4_resources,
442 };
443 
444 #endif /* MCFI2C_BASE4 */
445 
446 #ifdef MCFI2C_BASE5
447 
448 static struct resource mcf_i2c5_resources[] = {
449 	{
450 		.start          = MCFI2C_BASE5,
451 		.end            = MCFI2C_BASE5 + MCFI2C_SIZE5 - 1,
452 		.flags          = IORESOURCE_MEM,
453 	},
454 	{
455 		.start          = MCF_IRQ_I2C5,
456 		.end            = MCF_IRQ_I2C5,
457 		.flags          = IORESOURCE_IRQ,
458 	},
459 };
460 
461 static struct platform_device mcf_i2c5 = {
462 	.name                   = "imx1-i2c",
463 	.id                     = 5,
464 	.num_resources          = ARRAY_SIZE(mcf_i2c5_resources),
465 	.resource               = mcf_i2c5_resources,
466 };
467 
468 #endif /* MCFI2C_BASE5 */
469 #endif /* IS_ENABLED(CONFIG_I2C_IMX) */
470 
471 static struct platform_device *mcf_devices[] __initdata = {
472 	&mcf_uart,
473 #if IS_ENABLED(CONFIG_FEC)
474 	&mcf_fec0,
475 #ifdef MCFFEC_BASE1
476 	&mcf_fec1,
477 #endif
478 #endif
479 #if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
480 	&mcf_qspi,
481 #endif
482 #if IS_ENABLED(CONFIG_I2C_IMX)
483 	&mcf_i2c0,
484 #ifdef MCFI2C_BASE1
485 	&mcf_i2c1,
486 #endif
487 #ifdef MCFI2C_BASE2
488 	&mcf_i2c2,
489 #endif
490 #ifdef MCFI2C_BASE3
491 	&mcf_i2c3,
492 #endif
493 #ifdef MCFI2C_BASE4
494 	&mcf_i2c4,
495 #endif
496 #ifdef MCFI2C_BASE5
497 	&mcf_i2c5,
498 #endif
499 #endif
500 };
501 
502 /*
503  *	Some ColdFire UARTs let you set the IRQ line to use.
504  */
505 static void __init mcf_uart_set_irq(void)
506 {
507 #ifdef MCFUART_UIVR
508 	/* UART0 interrupt setup */
509 	writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCFSIM_UART1ICR);
510 	writeb(MCF_IRQ_UART0, MCFUART_BASE0 + MCFUART_UIVR);
511 	mcf_mapirq2imr(MCF_IRQ_UART0, MCFINTC_UART0);
512 
513 	/* UART1 interrupt setup */
514 	writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCFSIM_UART2ICR);
515 	writeb(MCF_IRQ_UART1, MCFUART_BASE1 + MCFUART_UIVR);
516 	mcf_mapirq2imr(MCF_IRQ_UART1, MCFINTC_UART1);
517 #endif
518 }
519 
520 static int __init mcf_init_devices(void)
521 {
522 	mcf_uart_set_irq();
523 	platform_add_devices(mcf_devices, ARRAY_SIZE(mcf_devices));
524 	return 0;
525 }
526 
527 arch_initcall(mcf_init_devices);
528 
529