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