2 * device.c -- common ColdFire SoC device support
4 * (C) Copyright 2011, Greg Ungerer <gerg@uclinux.org>
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
11 #include <linux/kernel.h>
12 #include <linux/init.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>
24 * All current ColdFire parts contain from 2, 3, 4 or 10 UARTS.
26 static struct mcf_platform_uart mcf_uart_platform_data
[] = {
28 .mapbase
= MCFUART_BASE0
,
32 .mapbase
= MCFUART_BASE1
,
37 .mapbase
= MCFUART_BASE2
,
43 .mapbase
= MCFUART_BASE3
,
49 .mapbase
= MCFUART_BASE4
,
55 .mapbase
= MCFUART_BASE5
,
61 .mapbase
= MCFUART_BASE6
,
67 .mapbase
= MCFUART_BASE7
,
73 .mapbase
= MCFUART_BASE8
,
79 .mapbase
= MCFUART_BASE9
,
86 static struct platform_device mcf_uart
= {
89 .dev
.platform_data
= mcf_uart_platform_data
,
92 #if IS_ENABLED(CONFIG_FEC)
95 #define FEC_NAME "enet-fec"
96 static struct fec_platform_data fec_pdata
= {
97 .phy
= PHY_INTERFACE_MODE_RMII
,
99 #define FEC_PDATA (&fec_pdata)
101 #define FEC_NAME "fec"
102 #define FEC_PDATA NULL
106 * Some ColdFire cores contain the Fast Ethernet Controller (FEC)
107 * block. It is Freescale's own hardware block. Some ColdFires
110 static struct resource mcf_fec0_resources
[] = {
112 .start
= MCFFEC_BASE0
,
113 .end
= MCFFEC_BASE0
+ MCFFEC_SIZE0
- 1,
114 .flags
= IORESOURCE_MEM
,
117 .start
= MCF_IRQ_FECRX0
,
118 .end
= MCF_IRQ_FECRX0
,
119 .flags
= IORESOURCE_IRQ
,
122 .start
= MCF_IRQ_FECTX0
,
123 .end
= MCF_IRQ_FECTX0
,
124 .flags
= IORESOURCE_IRQ
,
127 .start
= MCF_IRQ_FECENTC0
,
128 .end
= MCF_IRQ_FECENTC0
,
129 .flags
= IORESOURCE_IRQ
,
133 static struct platform_device mcf_fec0
= {
136 .num_resources
= ARRAY_SIZE(mcf_fec0_resources
),
137 .resource
= mcf_fec0_resources
,
139 .dma_mask
= &mcf_fec0
.dev
.coherent_dma_mask
,
140 .coherent_dma_mask
= DMA_BIT_MASK(32),
141 .platform_data
= FEC_PDATA
,
146 static struct resource mcf_fec1_resources
[] = {
148 .start
= MCFFEC_BASE1
,
149 .end
= MCFFEC_BASE1
+ MCFFEC_SIZE1
- 1,
150 .flags
= IORESOURCE_MEM
,
153 .start
= MCF_IRQ_FECRX1
,
154 .end
= MCF_IRQ_FECRX1
,
155 .flags
= IORESOURCE_IRQ
,
158 .start
= MCF_IRQ_FECTX1
,
159 .end
= MCF_IRQ_FECTX1
,
160 .flags
= IORESOURCE_IRQ
,
163 .start
= MCF_IRQ_FECENTC1
,
164 .end
= MCF_IRQ_FECENTC1
,
165 .flags
= IORESOURCE_IRQ
,
169 static struct platform_device mcf_fec1
= {
172 .num_resources
= ARRAY_SIZE(mcf_fec1_resources
),
173 .resource
= mcf_fec1_resources
,
175 .dma_mask
= &mcf_fec1
.dev
.coherent_dma_mask
,
176 .coherent_dma_mask
= DMA_BIT_MASK(32),
177 .platform_data
= FEC_PDATA
,
180 #endif /* MCFFEC_BASE1 */
181 #endif /* CONFIG_FEC */
183 #if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
185 * The ColdFire QSPI module is an SPI protocol hardware block used
186 * on a number of different ColdFire CPUs.
188 static struct resource mcf_qspi_resources
[] = {
190 .start
= MCFQSPI_BASE
,
191 .end
= MCFQSPI_BASE
+ MCFQSPI_SIZE
- 1,
192 .flags
= IORESOURCE_MEM
,
195 .start
= MCF_IRQ_QSPI
,
197 .flags
= IORESOURCE_IRQ
,
201 static int mcf_cs_setup(struct mcfqspi_cs_control
*cs_control
)
205 status
= gpio_request(MCFQSPI_CS0
, "MCFQSPI_CS0");
207 pr_debug("gpio_request for MCFQSPI_CS0 failed\n");
210 status
= gpio_direction_output(MCFQSPI_CS0
, 1);
212 pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");
216 status
= gpio_request(MCFQSPI_CS1
, "MCFQSPI_CS1");
218 pr_debug("gpio_request for MCFQSPI_CS1 failed\n");
221 status
= gpio_direction_output(MCFQSPI_CS1
, 1);
223 pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");
227 status
= gpio_request(MCFQSPI_CS2
, "MCFQSPI_CS2");
229 pr_debug("gpio_request for MCFQSPI_CS2 failed\n");
232 status
= gpio_direction_output(MCFQSPI_CS2
, 1);
234 pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");
239 status
= gpio_request(MCFQSPI_CS3
, "MCFQSPI_CS3");
241 pr_debug("gpio_request for MCFQSPI_CS3 failed\n");
244 status
= gpio_direction_output(MCFQSPI_CS3
, 1);
246 pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n");
247 gpio_free(MCFQSPI_CS3
);
255 gpio_free(MCFQSPI_CS2
);
257 gpio_free(MCFQSPI_CS1
);
259 gpio_free(MCFQSPI_CS0
);
264 static void mcf_cs_teardown(struct mcfqspi_cs_control
*cs_control
)
267 gpio_free(MCFQSPI_CS3
);
269 gpio_free(MCFQSPI_CS2
);
270 gpio_free(MCFQSPI_CS1
);
271 gpio_free(MCFQSPI_CS0
);
274 static void mcf_cs_select(struct mcfqspi_cs_control
*cs_control
,
275 u8 chip_select
, bool cs_high
)
277 switch (chip_select
) {
279 gpio_set_value(MCFQSPI_CS0
, cs_high
);
282 gpio_set_value(MCFQSPI_CS1
, cs_high
);
285 gpio_set_value(MCFQSPI_CS2
, cs_high
);
289 gpio_set_value(MCFQSPI_CS3
, cs_high
);
295 static void mcf_cs_deselect(struct mcfqspi_cs_control
*cs_control
,
296 u8 chip_select
, bool cs_high
)
298 switch (chip_select
) {
300 gpio_set_value(MCFQSPI_CS0
, !cs_high
);
303 gpio_set_value(MCFQSPI_CS1
, !cs_high
);
306 gpio_set_value(MCFQSPI_CS2
, !cs_high
);
310 gpio_set_value(MCFQSPI_CS3
, !cs_high
);
316 static struct mcfqspi_cs_control mcf_cs_control
= {
317 .setup
= mcf_cs_setup
,
318 .teardown
= mcf_cs_teardown
,
319 .select
= mcf_cs_select
,
320 .deselect
= mcf_cs_deselect
,
323 static struct mcfqspi_platform_data mcf_qspi_data
= {
326 .cs_control
= &mcf_cs_control
,
329 static struct platform_device mcf_qspi
= {
332 .num_resources
= ARRAY_SIZE(mcf_qspi_resources
),
333 .resource
= mcf_qspi_resources
,
334 .dev
.platform_data
= &mcf_qspi_data
,
336 #endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */
338 #if IS_ENABLED(CONFIG_I2C_IMX)
339 static struct resource mcf_i2c0_resources
[] = {
341 .start
= MCFI2C_BASE0
,
342 .end
= MCFI2C_BASE0
+ MCFI2C_SIZE0
- 1,
343 .flags
= IORESOURCE_MEM
,
346 .start
= MCF_IRQ_I2C0
,
348 .flags
= IORESOURCE_IRQ
,
352 static struct platform_device mcf_i2c0
= {
355 .num_resources
= ARRAY_SIZE(mcf_i2c0_resources
),
356 .resource
= mcf_i2c0_resources
,
360 static struct resource mcf_i2c1_resources
[] = {
362 .start
= MCFI2C_BASE1
,
363 .end
= MCFI2C_BASE1
+ MCFI2C_SIZE1
- 1,
364 .flags
= IORESOURCE_MEM
,
367 .start
= MCF_IRQ_I2C1
,
369 .flags
= IORESOURCE_IRQ
,
373 static struct platform_device mcf_i2c1
= {
376 .num_resources
= ARRAY_SIZE(mcf_i2c1_resources
),
377 .resource
= mcf_i2c1_resources
,
380 #endif /* MCFI2C_BASE1 */
384 static struct resource mcf_i2c2_resources
[] = {
386 .start
= MCFI2C_BASE2
,
387 .end
= MCFI2C_BASE2
+ MCFI2C_SIZE2
- 1,
388 .flags
= IORESOURCE_MEM
,
391 .start
= MCF_IRQ_I2C2
,
393 .flags
= IORESOURCE_IRQ
,
397 static struct platform_device mcf_i2c2
= {
400 .num_resources
= ARRAY_SIZE(mcf_i2c2_resources
),
401 .resource
= mcf_i2c2_resources
,
404 #endif /* MCFI2C_BASE2 */
408 static struct resource mcf_i2c3_resources
[] = {
410 .start
= MCFI2C_BASE3
,
411 .end
= MCFI2C_BASE3
+ MCFI2C_SIZE3
- 1,
412 .flags
= IORESOURCE_MEM
,
415 .start
= MCF_IRQ_I2C3
,
417 .flags
= IORESOURCE_IRQ
,
421 static struct platform_device mcf_i2c3
= {
424 .num_resources
= ARRAY_SIZE(mcf_i2c3_resources
),
425 .resource
= mcf_i2c3_resources
,
428 #endif /* MCFI2C_BASE3 */
432 static struct resource mcf_i2c4_resources
[] = {
434 .start
= MCFI2C_BASE4
,
435 .end
= MCFI2C_BASE4
+ MCFI2C_SIZE4
- 1,
436 .flags
= IORESOURCE_MEM
,
439 .start
= MCF_IRQ_I2C4
,
441 .flags
= IORESOURCE_IRQ
,
445 static struct platform_device mcf_i2c4
= {
448 .num_resources
= ARRAY_SIZE(mcf_i2c4_resources
),
449 .resource
= mcf_i2c4_resources
,
452 #endif /* MCFI2C_BASE4 */
456 static struct resource mcf_i2c5_resources
[] = {
458 .start
= MCFI2C_BASE5
,
459 .end
= MCFI2C_BASE5
+ MCFI2C_SIZE5
- 1,
460 .flags
= IORESOURCE_MEM
,
463 .start
= MCF_IRQ_I2C5
,
465 .flags
= IORESOURCE_IRQ
,
469 static struct platform_device mcf_i2c5
= {
472 .num_resources
= ARRAY_SIZE(mcf_i2c5_resources
),
473 .resource
= mcf_i2c5_resources
,
476 #endif /* MCFI2C_BASE5 */
477 #endif /* IS_ENABLED(CONFIG_I2C_IMX) */
479 static struct platform_device
*mcf_devices
[] __initdata
= {
481 #if IS_ENABLED(CONFIG_FEC)
487 #if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
490 #if IS_ENABLED(CONFIG_I2C_IMX)
511 * Some ColdFire UARTs let you set the IRQ line to use.
513 static void __init
mcf_uart_set_irq(void)
516 /* UART0 interrupt setup */
517 writeb(MCFSIM_ICR_LEVEL6
| MCFSIM_ICR_PRI1
, MCFSIM_UART1ICR
);
518 writeb(MCF_IRQ_UART0
, MCFUART_BASE0
+ MCFUART_UIVR
);
519 mcf_mapirq2imr(MCF_IRQ_UART0
, MCFINTC_UART0
);
521 /* UART1 interrupt setup */
522 writeb(MCFSIM_ICR_LEVEL6
| MCFSIM_ICR_PRI2
, MCFSIM_UART2ICR
);
523 writeb(MCF_IRQ_UART1
, MCFUART_BASE1
+ MCFUART_UIVR
);
524 mcf_mapirq2imr(MCF_IRQ_UART1
, MCFINTC_UART1
);
528 static int __init
mcf_init_devices(void)
531 platform_add_devices(mcf_devices
, ARRAY_SIZE(mcf_devices
));
535 arch_initcall(mcf_init_devices
);