1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // Copyright (c) 2011 Samsung Electronics Co., Ltd. 4 // http://www.samsung.com 5 // 6 // Base Samsung platform device definitions 7 8 #include <linux/gpio.h> 9 #include <linux/kernel.h> 10 #include <linux/types.h> 11 #include <linux/interrupt.h> 12 #include <linux/list.h> 13 #include <linux/timer.h> 14 #include <linux/init.h> 15 #include <linux/serial_core.h> 16 #include <linux/serial_s3c.h> 17 #include <linux/platform_device.h> 18 #include <linux/io.h> 19 #include <linux/slab.h> 20 #include <linux/string.h> 21 #include <linux/dma-mapping.h> 22 #include <linux/fb.h> 23 #include <linux/gfp.h> 24 #include <linux/mtd/mtd.h> 25 #include <linux/mtd/onenand.h> 26 #include <linux/mtd/partitions.h> 27 #include <linux/mmc/host.h> 28 #include <linux/ioport.h> 29 #include <linux/sizes.h> 30 #include <linux/platform_data/s3c-hsudc.h> 31 #include <linux/platform_data/s3c-hsotg.h> 32 33 #include <linux/platform_data/media/s5p_hdmi.h> 34 35 #include <asm/irq.h> 36 #include <asm/mach/arch.h> 37 #include <asm/mach/map.h> 38 #include <asm/mach/irq.h> 39 40 #include "irqs.h" 41 #include "map.h" 42 #include "gpio-samsung.h" 43 #include "gpio-cfg.h" 44 45 #ifdef CONFIG_PLAT_S3C24XX 46 #include "regs-s3c2443-clock.h" 47 #endif /* CONFIG_PLAT_S3C24XX */ 48 49 #include "cpu.h" 50 #include "devs.h" 51 #include <linux/soc/samsung/s3c-adc.h> 52 #include <linux/platform_data/ata-samsung_cf.h> 53 #include "fb.h" 54 #include <linux/platform_data/fb-s3c2410.h> 55 #include <linux/platform_data/hwmon-s3c.h> 56 #include <linux/platform_data/i2c-s3c2410.h> 57 #include "keypad.h" 58 #include <linux/platform_data/mmc-s3cmci.h> 59 #include <linux/platform_data/mtd-nand-s3c2410.h> 60 #include "pwm-core.h" 61 #include "sdhci.h" 62 #include <linux/platform_data/touchscreen-s3c2410.h> 63 #include <linux/platform_data/usb-s3c2410_udc.h> 64 #include <linux/platform_data/usb-ohci-s3c2410.h> 65 #include "usb-phy.h" 66 #include <linux/platform_data/asoc-s3c.h> 67 #include <linux/platform_data/spi-s3c64xx.h> 68 69 #define samsung_device_dma_mask (*((u64[]) { DMA_BIT_MASK(32) })) 70 71 /* AC97 */ 72 #ifdef CONFIG_CPU_S3C2440 73 static struct resource s3c_ac97_resource[] = { 74 [0] = DEFINE_RES_MEM(S3C2440_PA_AC97, S3C2440_SZ_AC97), 75 [1] = DEFINE_RES_IRQ(IRQ_S3C244X_AC97), 76 }; 77 78 struct platform_device s3c_device_ac97 = { 79 .name = "samsung-ac97", 80 .id = -1, 81 .num_resources = ARRAY_SIZE(s3c_ac97_resource), 82 .resource = s3c_ac97_resource, 83 .dev = { 84 .dma_mask = &samsung_device_dma_mask, 85 .coherent_dma_mask = DMA_BIT_MASK(32), 86 } 87 }; 88 #endif /* CONFIG_CPU_S3C2440 */ 89 90 /* ADC */ 91 92 #ifdef CONFIG_PLAT_S3C24XX 93 static struct resource s3c_adc_resource[] = { 94 [0] = DEFINE_RES_MEM(S3C24XX_PA_ADC, S3C24XX_SZ_ADC), 95 [1] = DEFINE_RES_IRQ(IRQ_TC), 96 [2] = DEFINE_RES_IRQ(IRQ_ADC), 97 }; 98 99 struct platform_device s3c_device_adc = { 100 .name = "s3c24xx-adc", 101 .id = -1, 102 .num_resources = ARRAY_SIZE(s3c_adc_resource), 103 .resource = s3c_adc_resource, 104 }; 105 #endif /* CONFIG_PLAT_S3C24XX */ 106 107 #if defined(CONFIG_SAMSUNG_DEV_ADC) 108 static struct resource s3c_adc_resource[] = { 109 [0] = DEFINE_RES_MEM(SAMSUNG_PA_ADC, SZ_256), 110 [1] = DEFINE_RES_IRQ(IRQ_ADC), 111 [2] = DEFINE_RES_IRQ(IRQ_TC), 112 }; 113 114 struct platform_device s3c_device_adc = { 115 .name = "exynos-adc", 116 .id = -1, 117 .num_resources = ARRAY_SIZE(s3c_adc_resource), 118 .resource = s3c_adc_resource, 119 }; 120 #endif /* CONFIG_SAMSUNG_DEV_ADC */ 121 122 /* Camif Controller */ 123 124 #ifdef CONFIG_CPU_S3C2440 125 static struct resource s3c_camif_resource[] = { 126 [0] = DEFINE_RES_MEM(S3C2440_PA_CAMIF, S3C2440_SZ_CAMIF), 127 [1] = DEFINE_RES_IRQ(IRQ_S3C2440_CAM_C), 128 [2] = DEFINE_RES_IRQ(IRQ_S3C2440_CAM_P), 129 }; 130 131 struct platform_device s3c_device_camif = { 132 .name = "s3c2440-camif", 133 .id = -1, 134 .num_resources = ARRAY_SIZE(s3c_camif_resource), 135 .resource = s3c_camif_resource, 136 .dev = { 137 .dma_mask = &samsung_device_dma_mask, 138 .coherent_dma_mask = DMA_BIT_MASK(32), 139 } 140 }; 141 #endif /* CONFIG_CPU_S3C2440 */ 142 143 /* FB */ 144 145 #ifdef CONFIG_S3C_DEV_FB 146 static struct resource s3c_fb_resource[] = { 147 [0] = DEFINE_RES_MEM(S3C_PA_FB, SZ_16K), 148 [1] = DEFINE_RES_IRQ(IRQ_LCD_VSYNC), 149 [2] = DEFINE_RES_IRQ(IRQ_LCD_FIFO), 150 [3] = DEFINE_RES_IRQ(IRQ_LCD_SYSTEM), 151 }; 152 153 struct platform_device s3c_device_fb = { 154 .name = "s3c-fb", 155 .id = -1, 156 .num_resources = ARRAY_SIZE(s3c_fb_resource), 157 .resource = s3c_fb_resource, 158 .dev = { 159 .dma_mask = &samsung_device_dma_mask, 160 .coherent_dma_mask = DMA_BIT_MASK(32), 161 }, 162 }; 163 164 void __init s3c_fb_set_platdata(struct s3c_fb_platdata *pd) 165 { 166 s3c_set_platdata(pd, sizeof(struct s3c_fb_platdata), 167 &s3c_device_fb); 168 } 169 #endif /* CONFIG_S3C_DEV_FB */ 170 171 /* HWMON */ 172 173 #ifdef CONFIG_S3C_DEV_HWMON 174 struct platform_device s3c_device_hwmon = { 175 .name = "s3c-hwmon", 176 .id = -1, 177 .dev.parent = &s3c_device_adc.dev, 178 }; 179 180 void __init s3c_hwmon_set_platdata(struct s3c_hwmon_pdata *pd) 181 { 182 s3c_set_platdata(pd, sizeof(struct s3c_hwmon_pdata), 183 &s3c_device_hwmon); 184 } 185 #endif /* CONFIG_S3C_DEV_HWMON */ 186 187 /* HSMMC */ 188 189 #ifdef CONFIG_S3C_DEV_HSMMC 190 static struct resource s3c_hsmmc_resource[] = { 191 [0] = DEFINE_RES_MEM(S3C_PA_HSMMC0, SZ_4K), 192 [1] = DEFINE_RES_IRQ(IRQ_HSMMC0), 193 }; 194 195 struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata = { 196 .max_width = 4, 197 .host_caps = (MMC_CAP_4_BIT_DATA | 198 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), 199 }; 200 201 struct platform_device s3c_device_hsmmc0 = { 202 .name = "s3c-sdhci", 203 .id = 0, 204 .num_resources = ARRAY_SIZE(s3c_hsmmc_resource), 205 .resource = s3c_hsmmc_resource, 206 .dev = { 207 .dma_mask = &samsung_device_dma_mask, 208 .coherent_dma_mask = DMA_BIT_MASK(32), 209 .platform_data = &s3c_hsmmc0_def_platdata, 210 }, 211 }; 212 213 void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd) 214 { 215 s3c_sdhci_set_platdata(pd, &s3c_hsmmc0_def_platdata); 216 } 217 #endif /* CONFIG_S3C_DEV_HSMMC */ 218 219 #ifdef CONFIG_S3C_DEV_HSMMC1 220 static struct resource s3c_hsmmc1_resource[] = { 221 [0] = DEFINE_RES_MEM(S3C_PA_HSMMC1, SZ_4K), 222 [1] = DEFINE_RES_IRQ(IRQ_HSMMC1), 223 }; 224 225 struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata = { 226 .max_width = 4, 227 .host_caps = (MMC_CAP_4_BIT_DATA | 228 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), 229 }; 230 231 struct platform_device s3c_device_hsmmc1 = { 232 .name = "s3c-sdhci", 233 .id = 1, 234 .num_resources = ARRAY_SIZE(s3c_hsmmc1_resource), 235 .resource = s3c_hsmmc1_resource, 236 .dev = { 237 .dma_mask = &samsung_device_dma_mask, 238 .coherent_dma_mask = DMA_BIT_MASK(32), 239 .platform_data = &s3c_hsmmc1_def_platdata, 240 }, 241 }; 242 243 void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd) 244 { 245 s3c_sdhci_set_platdata(pd, &s3c_hsmmc1_def_platdata); 246 } 247 #endif /* CONFIG_S3C_DEV_HSMMC1 */ 248 249 /* HSMMC2 */ 250 251 #ifdef CONFIG_S3C_DEV_HSMMC2 252 static struct resource s3c_hsmmc2_resource[] = { 253 [0] = DEFINE_RES_MEM(S3C_PA_HSMMC2, SZ_4K), 254 [1] = DEFINE_RES_IRQ(IRQ_HSMMC2), 255 }; 256 257 struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata = { 258 .max_width = 4, 259 .host_caps = (MMC_CAP_4_BIT_DATA | 260 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), 261 }; 262 263 struct platform_device s3c_device_hsmmc2 = { 264 .name = "s3c-sdhci", 265 .id = 2, 266 .num_resources = ARRAY_SIZE(s3c_hsmmc2_resource), 267 .resource = s3c_hsmmc2_resource, 268 .dev = { 269 .dma_mask = &samsung_device_dma_mask, 270 .coherent_dma_mask = DMA_BIT_MASK(32), 271 .platform_data = &s3c_hsmmc2_def_platdata, 272 }, 273 }; 274 275 void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd) 276 { 277 s3c_sdhci_set_platdata(pd, &s3c_hsmmc2_def_platdata); 278 } 279 #endif /* CONFIG_S3C_DEV_HSMMC2 */ 280 281 #ifdef CONFIG_S3C_DEV_HSMMC3 282 static struct resource s3c_hsmmc3_resource[] = { 283 [0] = DEFINE_RES_MEM(S3C_PA_HSMMC3, SZ_4K), 284 [1] = DEFINE_RES_IRQ(IRQ_HSMMC3), 285 }; 286 287 struct s3c_sdhci_platdata s3c_hsmmc3_def_platdata = { 288 .max_width = 4, 289 .host_caps = (MMC_CAP_4_BIT_DATA | 290 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), 291 }; 292 293 struct platform_device s3c_device_hsmmc3 = { 294 .name = "s3c-sdhci", 295 .id = 3, 296 .num_resources = ARRAY_SIZE(s3c_hsmmc3_resource), 297 .resource = s3c_hsmmc3_resource, 298 .dev = { 299 .dma_mask = &samsung_device_dma_mask, 300 .coherent_dma_mask = DMA_BIT_MASK(32), 301 .platform_data = &s3c_hsmmc3_def_platdata, 302 }, 303 }; 304 305 void s3c_sdhci3_set_platdata(struct s3c_sdhci_platdata *pd) 306 { 307 s3c_sdhci_set_platdata(pd, &s3c_hsmmc3_def_platdata); 308 } 309 #endif /* CONFIG_S3C_DEV_HSMMC3 */ 310 311 /* I2C */ 312 313 static struct resource s3c_i2c0_resource[] = { 314 [0] = DEFINE_RES_MEM(S3C_PA_IIC, SZ_4K), 315 [1] = DEFINE_RES_IRQ(IRQ_IIC), 316 }; 317 318 struct platform_device s3c_device_i2c0 = { 319 .name = "s3c2410-i2c", 320 .id = 0, 321 .num_resources = ARRAY_SIZE(s3c_i2c0_resource), 322 .resource = s3c_i2c0_resource, 323 }; 324 325 struct s3c2410_platform_i2c default_i2c_data __initdata = { 326 .flags = 0, 327 .slave_addr = 0x10, 328 .frequency = 100*1000, 329 .sda_delay = 100, 330 }; 331 332 void __init s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *pd) 333 { 334 struct s3c2410_platform_i2c *npd; 335 336 if (!pd) { 337 pd = &default_i2c_data; 338 pd->bus_num = 0; 339 } 340 341 npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_i2c0); 342 343 if (!npd->cfg_gpio) 344 npd->cfg_gpio = s3c_i2c0_cfg_gpio; 345 } 346 347 #ifdef CONFIG_S3C_DEV_I2C1 348 static struct resource s3c_i2c1_resource[] = { 349 [0] = DEFINE_RES_MEM(S3C_PA_IIC1, SZ_4K), 350 [1] = DEFINE_RES_IRQ(IRQ_IIC1), 351 }; 352 353 struct platform_device s3c_device_i2c1 = { 354 .name = "s3c2410-i2c", 355 .id = 1, 356 .num_resources = ARRAY_SIZE(s3c_i2c1_resource), 357 .resource = s3c_i2c1_resource, 358 }; 359 360 void __init s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *pd) 361 { 362 struct s3c2410_platform_i2c *npd; 363 364 if (!pd) { 365 pd = &default_i2c_data; 366 pd->bus_num = 1; 367 } 368 369 npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_i2c1); 370 371 if (!npd->cfg_gpio) 372 npd->cfg_gpio = s3c_i2c1_cfg_gpio; 373 } 374 #endif /* CONFIG_S3C_DEV_I2C1 */ 375 376 #ifdef CONFIG_S3C_DEV_I2C2 377 static struct resource s3c_i2c2_resource[] = { 378 [0] = DEFINE_RES_MEM(S3C_PA_IIC2, SZ_4K), 379 [1] = DEFINE_RES_IRQ(IRQ_IIC2), 380 }; 381 382 struct platform_device s3c_device_i2c2 = { 383 .name = "s3c2410-i2c", 384 .id = 2, 385 .num_resources = ARRAY_SIZE(s3c_i2c2_resource), 386 .resource = s3c_i2c2_resource, 387 }; 388 389 void __init s3c_i2c2_set_platdata(struct s3c2410_platform_i2c *pd) 390 { 391 struct s3c2410_platform_i2c *npd; 392 393 if (!pd) { 394 pd = &default_i2c_data; 395 pd->bus_num = 2; 396 } 397 398 npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_i2c2); 399 400 if (!npd->cfg_gpio) 401 npd->cfg_gpio = s3c_i2c2_cfg_gpio; 402 } 403 #endif /* CONFIG_S3C_DEV_I2C2 */ 404 405 #ifdef CONFIG_S3C_DEV_I2C3 406 static struct resource s3c_i2c3_resource[] = { 407 [0] = DEFINE_RES_MEM(S3C_PA_IIC3, SZ_4K), 408 [1] = DEFINE_RES_IRQ(IRQ_IIC3), 409 }; 410 411 struct platform_device s3c_device_i2c3 = { 412 .name = "s3c2440-i2c", 413 .id = 3, 414 .num_resources = ARRAY_SIZE(s3c_i2c3_resource), 415 .resource = s3c_i2c3_resource, 416 }; 417 418 void __init s3c_i2c3_set_platdata(struct s3c2410_platform_i2c *pd) 419 { 420 struct s3c2410_platform_i2c *npd; 421 422 if (!pd) { 423 pd = &default_i2c_data; 424 pd->bus_num = 3; 425 } 426 427 npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_i2c3); 428 429 if (!npd->cfg_gpio) 430 npd->cfg_gpio = s3c_i2c3_cfg_gpio; 431 } 432 #endif /*CONFIG_S3C_DEV_I2C3 */ 433 434 #ifdef CONFIG_S3C_DEV_I2C4 435 static struct resource s3c_i2c4_resource[] = { 436 [0] = DEFINE_RES_MEM(S3C_PA_IIC4, SZ_4K), 437 [1] = DEFINE_RES_IRQ(IRQ_IIC4), 438 }; 439 440 struct platform_device s3c_device_i2c4 = { 441 .name = "s3c2440-i2c", 442 .id = 4, 443 .num_resources = ARRAY_SIZE(s3c_i2c4_resource), 444 .resource = s3c_i2c4_resource, 445 }; 446 447 void __init s3c_i2c4_set_platdata(struct s3c2410_platform_i2c *pd) 448 { 449 struct s3c2410_platform_i2c *npd; 450 451 if (!pd) { 452 pd = &default_i2c_data; 453 pd->bus_num = 4; 454 } 455 456 npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_i2c4); 457 458 if (!npd->cfg_gpio) 459 npd->cfg_gpio = s3c_i2c4_cfg_gpio; 460 } 461 #endif /*CONFIG_S3C_DEV_I2C4 */ 462 463 #ifdef CONFIG_S3C_DEV_I2C5 464 static struct resource s3c_i2c5_resource[] = { 465 [0] = DEFINE_RES_MEM(S3C_PA_IIC5, SZ_4K), 466 [1] = DEFINE_RES_IRQ(IRQ_IIC5), 467 }; 468 469 struct platform_device s3c_device_i2c5 = { 470 .name = "s3c2440-i2c", 471 .id = 5, 472 .num_resources = ARRAY_SIZE(s3c_i2c5_resource), 473 .resource = s3c_i2c5_resource, 474 }; 475 476 void __init s3c_i2c5_set_platdata(struct s3c2410_platform_i2c *pd) 477 { 478 struct s3c2410_platform_i2c *npd; 479 480 if (!pd) { 481 pd = &default_i2c_data; 482 pd->bus_num = 5; 483 } 484 485 npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_i2c5); 486 487 if (!npd->cfg_gpio) 488 npd->cfg_gpio = s3c_i2c5_cfg_gpio; 489 } 490 #endif /*CONFIG_S3C_DEV_I2C5 */ 491 492 #ifdef CONFIG_S3C_DEV_I2C6 493 static struct resource s3c_i2c6_resource[] = { 494 [0] = DEFINE_RES_MEM(S3C_PA_IIC6, SZ_4K), 495 [1] = DEFINE_RES_IRQ(IRQ_IIC6), 496 }; 497 498 struct platform_device s3c_device_i2c6 = { 499 .name = "s3c2440-i2c", 500 .id = 6, 501 .num_resources = ARRAY_SIZE(s3c_i2c6_resource), 502 .resource = s3c_i2c6_resource, 503 }; 504 505 void __init s3c_i2c6_set_platdata(struct s3c2410_platform_i2c *pd) 506 { 507 struct s3c2410_platform_i2c *npd; 508 509 if (!pd) { 510 pd = &default_i2c_data; 511 pd->bus_num = 6; 512 } 513 514 npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_i2c6); 515 516 if (!npd->cfg_gpio) 517 npd->cfg_gpio = s3c_i2c6_cfg_gpio; 518 } 519 #endif /* CONFIG_S3C_DEV_I2C6 */ 520 521 #ifdef CONFIG_S3C_DEV_I2C7 522 static struct resource s3c_i2c7_resource[] = { 523 [0] = DEFINE_RES_MEM(S3C_PA_IIC7, SZ_4K), 524 [1] = DEFINE_RES_IRQ(IRQ_IIC7), 525 }; 526 527 struct platform_device s3c_device_i2c7 = { 528 .name = "s3c2440-i2c", 529 .id = 7, 530 .num_resources = ARRAY_SIZE(s3c_i2c7_resource), 531 .resource = s3c_i2c7_resource, 532 }; 533 534 void __init s3c_i2c7_set_platdata(struct s3c2410_platform_i2c *pd) 535 { 536 struct s3c2410_platform_i2c *npd; 537 538 if (!pd) { 539 pd = &default_i2c_data; 540 pd->bus_num = 7; 541 } 542 543 npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_i2c7); 544 545 if (!npd->cfg_gpio) 546 npd->cfg_gpio = s3c_i2c7_cfg_gpio; 547 } 548 #endif /* CONFIG_S3C_DEV_I2C7 */ 549 550 /* I2S */ 551 552 #ifdef CONFIG_PLAT_S3C24XX 553 static struct resource s3c_iis_resource[] = { 554 [0] = DEFINE_RES_MEM(S3C24XX_PA_IIS, S3C24XX_SZ_IIS), 555 }; 556 557 struct platform_device s3c_device_iis = { 558 .name = "s3c24xx-iis", 559 .id = -1, 560 .num_resources = ARRAY_SIZE(s3c_iis_resource), 561 .resource = s3c_iis_resource, 562 .dev = { 563 .dma_mask = &samsung_device_dma_mask, 564 .coherent_dma_mask = DMA_BIT_MASK(32), 565 } 566 }; 567 #endif /* CONFIG_PLAT_S3C24XX */ 568 569 /* IDE CFCON */ 570 571 #ifdef CONFIG_SAMSUNG_DEV_IDE 572 static struct resource s3c_cfcon_resource[] = { 573 [0] = DEFINE_RES_MEM(SAMSUNG_PA_CFCON, SZ_16K), 574 [1] = DEFINE_RES_IRQ(IRQ_CFCON), 575 }; 576 577 struct platform_device s3c_device_cfcon = { 578 .id = 0, 579 .num_resources = ARRAY_SIZE(s3c_cfcon_resource), 580 .resource = s3c_cfcon_resource, 581 }; 582 583 void __init s3c_ide_set_platdata(struct s3c_ide_platdata *pdata) 584 { 585 s3c_set_platdata(pdata, sizeof(struct s3c_ide_platdata), 586 &s3c_device_cfcon); 587 } 588 #endif /* CONFIG_SAMSUNG_DEV_IDE */ 589 590 /* KEYPAD */ 591 592 #ifdef CONFIG_SAMSUNG_DEV_KEYPAD 593 static struct resource samsung_keypad_resources[] = { 594 [0] = DEFINE_RES_MEM(SAMSUNG_PA_KEYPAD, SZ_32), 595 [1] = DEFINE_RES_IRQ(IRQ_KEYPAD), 596 }; 597 598 struct platform_device samsung_device_keypad = { 599 .name = "samsung-keypad", 600 .id = -1, 601 .num_resources = ARRAY_SIZE(samsung_keypad_resources), 602 .resource = samsung_keypad_resources, 603 }; 604 605 void __init samsung_keypad_set_platdata(struct samsung_keypad_platdata *pd) 606 { 607 struct samsung_keypad_platdata *npd; 608 609 npd = s3c_set_platdata(pd, sizeof(*npd), &samsung_device_keypad); 610 611 if (!npd->cfg_gpio) 612 npd->cfg_gpio = samsung_keypad_cfg_gpio; 613 } 614 #endif /* CONFIG_SAMSUNG_DEV_KEYPAD */ 615 616 /* LCD Controller */ 617 618 #ifdef CONFIG_PLAT_S3C24XX 619 static struct resource s3c_lcd_resource[] = { 620 [0] = DEFINE_RES_MEM(S3C24XX_PA_LCD, S3C24XX_SZ_LCD), 621 [1] = DEFINE_RES_IRQ(IRQ_LCD), 622 }; 623 624 struct platform_device s3c_device_lcd = { 625 .name = "s3c2410-lcd", 626 .id = -1, 627 .num_resources = ARRAY_SIZE(s3c_lcd_resource), 628 .resource = s3c_lcd_resource, 629 .dev = { 630 .dma_mask = &samsung_device_dma_mask, 631 .coherent_dma_mask = DMA_BIT_MASK(32), 632 } 633 }; 634 635 void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *pd) 636 { 637 struct s3c2410fb_mach_info *npd; 638 639 npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_lcd); 640 if (npd) { 641 npd->displays = kmemdup(pd->displays, 642 sizeof(struct s3c2410fb_display) * npd->num_displays, 643 GFP_KERNEL); 644 if (!npd->displays) 645 printk(KERN_ERR "no memory for LCD display data\n"); 646 } else { 647 printk(KERN_ERR "no memory for LCD platform data\n"); 648 } 649 } 650 #endif /* CONFIG_PLAT_S3C24XX */ 651 652 /* NAND */ 653 654 #ifdef CONFIG_S3C_DEV_NAND 655 static struct resource s3c_nand_resource[] = { 656 [0] = DEFINE_RES_MEM(S3C_PA_NAND, SZ_1M), 657 }; 658 659 struct platform_device s3c_device_nand = { 660 .name = "s3c2410-nand", 661 .id = -1, 662 .num_resources = ARRAY_SIZE(s3c_nand_resource), 663 .resource = s3c_nand_resource, 664 }; 665 666 /* 667 * s3c_nand_copy_set() - copy nand set data 668 * @set: The new structure, directly copied from the old. 669 * 670 * Copy all the fields from the NAND set field from what is probably __initdata 671 * to new kernel memory. The code returns 0 if the copy happened correctly or 672 * an error code for the calling function to display. 673 * 674 * Note, we currently do not try and look to see if we've already copied the 675 * data in a previous set. 676 */ 677 static int __init s3c_nand_copy_set(struct s3c2410_nand_set *set) 678 { 679 void *ptr; 680 int size; 681 682 size = sizeof(struct mtd_partition) * set->nr_partitions; 683 if (size) { 684 ptr = kmemdup(set->partitions, size, GFP_KERNEL); 685 set->partitions = ptr; 686 687 if (!ptr) 688 return -ENOMEM; 689 } 690 691 if (set->nr_map && set->nr_chips) { 692 size = sizeof(int) * set->nr_chips; 693 ptr = kmemdup(set->nr_map, size, GFP_KERNEL); 694 set->nr_map = ptr; 695 696 if (!ptr) 697 return -ENOMEM; 698 } 699 700 return 0; 701 } 702 703 void __init s3c_nand_set_platdata(struct s3c2410_platform_nand *nand) 704 { 705 struct s3c2410_platform_nand *npd; 706 int size; 707 int ret; 708 709 /* note, if we get a failure in allocation, we simply drop out of the 710 * function. If there is so little memory available at initialisation 711 * time then there is little chance the system is going to run. 712 */ 713 714 npd = s3c_set_platdata(nand, sizeof(*npd), &s3c_device_nand); 715 if (!npd) 716 return; 717 718 /* now see if we need to copy any of the nand set data */ 719 720 size = sizeof(struct s3c2410_nand_set) * npd->nr_sets; 721 if (size) { 722 struct s3c2410_nand_set *from = npd->sets; 723 struct s3c2410_nand_set *to; 724 int i; 725 726 to = kmemdup(from, size, GFP_KERNEL); 727 npd->sets = to; /* set, even if we failed */ 728 729 if (!to) { 730 printk(KERN_ERR "%s: no memory for sets\n", __func__); 731 return; 732 } 733 734 for (i = 0; i < npd->nr_sets; i++) { 735 ret = s3c_nand_copy_set(to); 736 if (ret) { 737 printk(KERN_ERR "%s: failed to copy set %d\n", 738 __func__, i); 739 return; 740 } 741 to++; 742 } 743 } 744 } 745 #endif /* CONFIG_S3C_DEV_NAND */ 746 747 /* ONENAND */ 748 749 #ifdef CONFIG_S3C_DEV_ONENAND 750 static struct resource s3c_onenand_resources[] = { 751 [0] = DEFINE_RES_MEM(S3C_PA_ONENAND, SZ_1K), 752 [1] = DEFINE_RES_MEM(S3C_PA_ONENAND_BUF, S3C_SZ_ONENAND_BUF), 753 [2] = DEFINE_RES_IRQ(IRQ_ONENAND), 754 }; 755 756 struct platform_device s3c_device_onenand = { 757 .name = "samsung-onenand", 758 .id = 0, 759 .num_resources = ARRAY_SIZE(s3c_onenand_resources), 760 .resource = s3c_onenand_resources, 761 }; 762 #endif /* CONFIG_S3C_DEV_ONENAND */ 763 764 #ifdef CONFIG_S3C64XX_DEV_ONENAND1 765 static struct resource s3c64xx_onenand1_resources[] = { 766 [0] = DEFINE_RES_MEM(S3C64XX_PA_ONENAND1, SZ_1K), 767 [1] = DEFINE_RES_MEM(S3C64XX_PA_ONENAND1_BUF, S3C64XX_SZ_ONENAND1_BUF), 768 [2] = DEFINE_RES_IRQ(IRQ_ONENAND1), 769 }; 770 771 struct platform_device s3c64xx_device_onenand1 = { 772 .name = "samsung-onenand", 773 .id = 1, 774 .num_resources = ARRAY_SIZE(s3c64xx_onenand1_resources), 775 .resource = s3c64xx_onenand1_resources, 776 }; 777 778 void __init s3c64xx_onenand1_set_platdata(struct onenand_platform_data *pdata) 779 { 780 s3c_set_platdata(pdata, sizeof(struct onenand_platform_data), 781 &s3c64xx_device_onenand1); 782 } 783 #endif /* CONFIG_S3C64XX_DEV_ONENAND1 */ 784 785 /* PWM Timer */ 786 787 #ifdef CONFIG_SAMSUNG_DEV_PWM 788 static struct resource samsung_pwm_resource[] = { 789 DEFINE_RES_MEM(SAMSUNG_PA_TIMER, SZ_4K), 790 }; 791 792 struct platform_device samsung_device_pwm = { 793 .name = "samsung-pwm", 794 .id = -1, 795 .num_resources = ARRAY_SIZE(samsung_pwm_resource), 796 .resource = samsung_pwm_resource, 797 }; 798 799 void __init samsung_pwm_set_platdata(struct samsung_pwm_variant *pd) 800 { 801 samsung_device_pwm.dev.platform_data = pd; 802 } 803 #endif /* CONFIG_SAMSUNG_DEV_PWM */ 804 805 /* RTC */ 806 807 #ifdef CONFIG_PLAT_S3C24XX 808 static struct resource s3c_rtc_resource[] = { 809 [0] = DEFINE_RES_MEM(S3C24XX_PA_RTC, SZ_256), 810 [1] = DEFINE_RES_IRQ(IRQ_RTC), 811 [2] = DEFINE_RES_IRQ(IRQ_TICK), 812 }; 813 814 struct platform_device s3c_device_rtc = { 815 .name = "s3c2410-rtc", 816 .id = -1, 817 .num_resources = ARRAY_SIZE(s3c_rtc_resource), 818 .resource = s3c_rtc_resource, 819 }; 820 #endif /* CONFIG_PLAT_S3C24XX */ 821 822 #ifdef CONFIG_S3C_DEV_RTC 823 static struct resource s3c_rtc_resource[] = { 824 [0] = DEFINE_RES_MEM(S3C_PA_RTC, SZ_256), 825 [1] = DEFINE_RES_IRQ(IRQ_RTC_ALARM), 826 [2] = DEFINE_RES_IRQ(IRQ_RTC_TIC), 827 }; 828 829 struct platform_device s3c_device_rtc = { 830 .name = "s3c64xx-rtc", 831 .id = -1, 832 .num_resources = ARRAY_SIZE(s3c_rtc_resource), 833 .resource = s3c_rtc_resource, 834 }; 835 #endif /* CONFIG_S3C_DEV_RTC */ 836 837 /* SDI */ 838 839 #ifdef CONFIG_PLAT_S3C24XX 840 void s3c24xx_mci_def_set_power(unsigned char power_mode, unsigned short vdd) 841 { 842 switch (power_mode) { 843 case MMC_POWER_ON: 844 case MMC_POWER_UP: 845 /* Configure GPE5...GPE10 pins in SD mode */ 846 s3c_gpio_cfgall_range(S3C2410_GPE(5), 6, S3C_GPIO_SFN(2), 847 S3C_GPIO_PULL_NONE); 848 break; 849 850 case MMC_POWER_OFF: 851 default: 852 gpio_direction_output(S3C2410_GPE(5), 0); 853 break; 854 } 855 } 856 857 static struct resource s3c_sdi_resource[] = { 858 [0] = DEFINE_RES_MEM(S3C24XX_PA_SDI, S3C24XX_SZ_SDI), 859 [1] = DEFINE_RES_IRQ(IRQ_SDI), 860 }; 861 862 static struct s3c24xx_mci_pdata s3cmci_def_pdata = { 863 /* This is currently here to avoid a number of if (host->pdata) 864 * checks. Any zero fields to ensure reasonable defaults are picked. */ 865 .no_wprotect = 1, 866 .no_detect = 1, 867 .set_power = s3c24xx_mci_def_set_power, 868 }; 869 870 struct platform_device s3c_device_sdi = { 871 .name = "s3c2410-sdi", 872 .id = -1, 873 .num_resources = ARRAY_SIZE(s3c_sdi_resource), 874 .resource = s3c_sdi_resource, 875 .dev.platform_data = &s3cmci_def_pdata, 876 }; 877 878 void __init s3c24xx_mci_set_platdata(struct s3c24xx_mci_pdata *pdata) 879 { 880 s3c_set_platdata(pdata, sizeof(struct s3c24xx_mci_pdata), 881 &s3c_device_sdi); 882 } 883 #endif /* CONFIG_PLAT_S3C24XX */ 884 885 /* SPI */ 886 887 #ifdef CONFIG_PLAT_S3C24XX 888 static struct resource s3c_spi0_resource[] = { 889 [0] = DEFINE_RES_MEM(S3C24XX_PA_SPI, SZ_32), 890 [1] = DEFINE_RES_IRQ(IRQ_SPI0), 891 }; 892 893 struct platform_device s3c_device_spi0 = { 894 .name = "s3c2410-spi", 895 .id = 0, 896 .num_resources = ARRAY_SIZE(s3c_spi0_resource), 897 .resource = s3c_spi0_resource, 898 .dev = { 899 .dma_mask = &samsung_device_dma_mask, 900 .coherent_dma_mask = DMA_BIT_MASK(32), 901 } 902 }; 903 904 static struct resource s3c_spi1_resource[] = { 905 [0] = DEFINE_RES_MEM(S3C24XX_PA_SPI1, SZ_32), 906 [1] = DEFINE_RES_IRQ(IRQ_SPI1), 907 }; 908 909 struct platform_device s3c_device_spi1 = { 910 .name = "s3c2410-spi", 911 .id = 1, 912 .num_resources = ARRAY_SIZE(s3c_spi1_resource), 913 .resource = s3c_spi1_resource, 914 .dev = { 915 .dma_mask = &samsung_device_dma_mask, 916 .coherent_dma_mask = DMA_BIT_MASK(32), 917 } 918 }; 919 #endif /* CONFIG_PLAT_S3C24XX */ 920 921 /* Touchscreen */ 922 923 #ifdef CONFIG_PLAT_S3C24XX 924 static struct resource s3c_ts_resource[] = { 925 [0] = DEFINE_RES_MEM(S3C24XX_PA_ADC, S3C24XX_SZ_ADC), 926 [1] = DEFINE_RES_IRQ(IRQ_TC), 927 }; 928 929 struct platform_device s3c_device_ts = { 930 .name = "s3c2410-ts", 931 .id = -1, 932 .dev.parent = &s3c_device_adc.dev, 933 .num_resources = ARRAY_SIZE(s3c_ts_resource), 934 .resource = s3c_ts_resource, 935 }; 936 937 void __init s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *hard_s3c2410ts_info) 938 { 939 s3c_set_platdata(hard_s3c2410ts_info, 940 sizeof(struct s3c2410_ts_mach_info), &s3c_device_ts); 941 } 942 #endif /* CONFIG_PLAT_S3C24XX */ 943 944 #ifdef CONFIG_SAMSUNG_DEV_TS 945 static struct s3c2410_ts_mach_info default_ts_data __initdata = { 946 .delay = 10000, 947 .presc = 49, 948 .oversampling_shift = 2, 949 }; 950 951 void __init s3c64xx_ts_set_platdata(struct s3c2410_ts_mach_info *pd) 952 { 953 if (!pd) 954 pd = &default_ts_data; 955 956 s3c_set_platdata(pd, sizeof(struct s3c2410_ts_mach_info), 957 &s3c_device_adc); 958 } 959 #endif /* CONFIG_SAMSUNG_DEV_TS */ 960 961 /* USB */ 962 963 #ifdef CONFIG_S3C_DEV_USB_HOST 964 static struct resource s3c_usb_resource[] = { 965 [0] = DEFINE_RES_MEM(S3C_PA_USBHOST, SZ_256), 966 [1] = DEFINE_RES_IRQ(IRQ_USBH), 967 }; 968 969 struct platform_device s3c_device_ohci = { 970 .name = "s3c2410-ohci", 971 .id = -1, 972 .num_resources = ARRAY_SIZE(s3c_usb_resource), 973 .resource = s3c_usb_resource, 974 .dev = { 975 .dma_mask = &samsung_device_dma_mask, 976 .coherent_dma_mask = DMA_BIT_MASK(32), 977 } 978 }; 979 980 /* 981 * s3c_ohci_set_platdata - initialise OHCI device platform data 982 * @info: The platform data. 983 * 984 * This call copies the @info passed in and sets the device .platform_data 985 * field to that copy. The @info is copied so that the original can be marked 986 * __initdata. 987 */ 988 989 void __init s3c_ohci_set_platdata(struct s3c2410_hcd_info *info) 990 { 991 s3c_set_platdata(info, sizeof(struct s3c2410_hcd_info), 992 &s3c_device_ohci); 993 } 994 #endif /* CONFIG_S3C_DEV_USB_HOST */ 995 996 /* USB Device (Gadget) */ 997 998 #ifdef CONFIG_PLAT_S3C24XX 999 static struct resource s3c_usbgadget_resource[] = { 1000 [0] = DEFINE_RES_MEM(S3C24XX_PA_USBDEV, S3C24XX_SZ_USBDEV), 1001 [1] = DEFINE_RES_IRQ(IRQ_USBD), 1002 }; 1003 1004 struct platform_device s3c_device_usbgadget = { 1005 .name = "s3c2410-usbgadget", 1006 .id = -1, 1007 .num_resources = ARRAY_SIZE(s3c_usbgadget_resource), 1008 .resource = s3c_usbgadget_resource, 1009 }; 1010 1011 void __init s3c24xx_udc_set_platdata(struct s3c2410_udc_mach_info *pd) 1012 { 1013 s3c_set_platdata(pd, sizeof(*pd), &s3c_device_usbgadget); 1014 } 1015 #endif /* CONFIG_PLAT_S3C24XX */ 1016 1017 /* USB HSOTG */ 1018 1019 #ifdef CONFIG_S3C_DEV_USB_HSOTG 1020 static struct resource s3c_usb_hsotg_resources[] = { 1021 [0] = DEFINE_RES_MEM(S3C_PA_USB_HSOTG, SZ_128K), 1022 [1] = DEFINE_RES_IRQ(IRQ_OTG), 1023 }; 1024 1025 struct platform_device s3c_device_usb_hsotg = { 1026 .name = "s3c-hsotg", 1027 .id = -1, 1028 .num_resources = ARRAY_SIZE(s3c_usb_hsotg_resources), 1029 .resource = s3c_usb_hsotg_resources, 1030 .dev = { 1031 .dma_mask = &samsung_device_dma_mask, 1032 .coherent_dma_mask = DMA_BIT_MASK(32), 1033 }, 1034 }; 1035 1036 void __init dwc2_hsotg_set_platdata(struct dwc2_hsotg_plat *pd) 1037 { 1038 struct dwc2_hsotg_plat *npd; 1039 1040 npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_usb_hsotg); 1041 1042 if (!npd->phy_init) 1043 npd->phy_init = s3c_usb_phy_init; 1044 if (!npd->phy_exit) 1045 npd->phy_exit = s3c_usb_phy_exit; 1046 } 1047 #endif /* CONFIG_S3C_DEV_USB_HSOTG */ 1048 1049 /* USB High Spped 2.0 Device (Gadget) */ 1050 1051 #ifdef CONFIG_PLAT_S3C24XX 1052 static struct resource s3c_hsudc_resource[] = { 1053 [0] = DEFINE_RES_MEM(S3C2416_PA_HSUDC, S3C2416_SZ_HSUDC), 1054 [1] = DEFINE_RES_IRQ(IRQ_USBD), 1055 }; 1056 1057 struct platform_device s3c_device_usb_hsudc = { 1058 .name = "s3c-hsudc", 1059 .id = -1, 1060 .num_resources = ARRAY_SIZE(s3c_hsudc_resource), 1061 .resource = s3c_hsudc_resource, 1062 .dev = { 1063 .dma_mask = &samsung_device_dma_mask, 1064 .coherent_dma_mask = DMA_BIT_MASK(32), 1065 }, 1066 }; 1067 1068 void __init s3c24xx_hsudc_set_platdata(struct s3c24xx_hsudc_platdata *pd) 1069 { 1070 s3c_set_platdata(pd, sizeof(*pd), &s3c_device_usb_hsudc); 1071 pd->phy_init = s3c_hsudc_init_phy; 1072 pd->phy_uninit = s3c_hsudc_uninit_phy; 1073 } 1074 #endif /* CONFIG_PLAT_S3C24XX */ 1075 1076 /* WDT */ 1077 1078 #ifdef CONFIG_S3C_DEV_WDT 1079 static struct resource s3c_wdt_resource[] = { 1080 [0] = DEFINE_RES_MEM(S3C_PA_WDT, SZ_1K), 1081 [1] = DEFINE_RES_IRQ(IRQ_WDT), 1082 }; 1083 1084 struct platform_device s3c_device_wdt = { 1085 .name = "s3c2410-wdt", 1086 .id = -1, 1087 .num_resources = ARRAY_SIZE(s3c_wdt_resource), 1088 .resource = s3c_wdt_resource, 1089 }; 1090 #endif /* CONFIG_S3C_DEV_WDT */ 1091 1092 #ifdef CONFIG_S3C64XX_DEV_SPI0 1093 static struct resource s3c64xx_spi0_resource[] = { 1094 [0] = DEFINE_RES_MEM(S3C_PA_SPI0, SZ_256), 1095 [1] = DEFINE_RES_IRQ(IRQ_SPI0), 1096 }; 1097 1098 struct platform_device s3c64xx_device_spi0 = { 1099 .name = "s3c6410-spi", 1100 .id = 0, 1101 .num_resources = ARRAY_SIZE(s3c64xx_spi0_resource), 1102 .resource = s3c64xx_spi0_resource, 1103 .dev = { 1104 .dma_mask = &samsung_device_dma_mask, 1105 .coherent_dma_mask = DMA_BIT_MASK(32), 1106 }, 1107 }; 1108 1109 void __init s3c64xx_spi0_set_platdata(int src_clk_nr, int num_cs) 1110 { 1111 struct s3c64xx_spi_info pd; 1112 1113 /* Reject invalid configuration */ 1114 if (!num_cs || src_clk_nr < 0) { 1115 pr_err("%s: Invalid SPI configuration\n", __func__); 1116 return; 1117 } 1118 1119 pd.num_cs = num_cs; 1120 pd.src_clk_nr = src_clk_nr; 1121 pd.cfg_gpio = s3c64xx_spi0_cfg_gpio; 1122 1123 s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi0); 1124 } 1125 #endif /* CONFIG_S3C64XX_DEV_SPI0 */ 1126