1/* linux/arch/arm/plat-s3c24xx/devs.c 2 * 3 * Copyright (c) 2004 Simtec Electronics 4 * Ben Dooks <ben@simtec.co.uk> 5 * 6 * Base S3C24XX platform device definitions 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 * 12*/ 13 14#include <linux/kernel.h> 15#include <linux/types.h> 16#include <linux/interrupt.h> 17#include <linux/list.h> 18#include <linux/timer.h> 19#include <linux/init.h> 20#include <linux/serial_core.h> 21#include <linux/platform_device.h> 22#include <linux/io.h> 23#include <linux/slab.h> 24#include <linux/string.h> 25 26#include <asm/mach/arch.h> 27#include <asm/mach/map.h> 28#include <asm/mach/irq.h> 29#include <mach/fb.h> 30#include <mach/hardware.h> 31#include <mach/dma.h> 32#include <mach/irqs.h> 33#include <asm/irq.h> 34 35#include <plat/regs-serial.h> 36#include <plat/udc.h> 37#include <plat/mci.h> 38 39#include <plat/devs.h> 40#include <plat/cpu.h> 41#include <plat/regs-spi.h> 42#include <plat/ts.h> 43 44/* Serial port registrations */ 45 46static struct resource s3c2410_uart0_resource[] = { 47 [0] = { 48 .start = S3C2410_PA_UART0, 49 .end = S3C2410_PA_UART0 + 0x3fff, 50 .flags = IORESOURCE_MEM, 51 }, 52 [1] = { 53 .start = IRQ_S3CUART_RX0, 54 .end = IRQ_S3CUART_ERR0, 55 .flags = IORESOURCE_IRQ, 56 } 57}; 58 59static struct resource s3c2410_uart1_resource[] = { 60 [0] = { 61 .start = S3C2410_PA_UART1, 62 .end = S3C2410_PA_UART1 + 0x3fff, 63 .flags = IORESOURCE_MEM, 64 }, 65 [1] = { 66 .start = IRQ_S3CUART_RX1, 67 .end = IRQ_S3CUART_ERR1, 68 .flags = IORESOURCE_IRQ, 69 } 70}; 71 72static struct resource s3c2410_uart2_resource[] = { 73 [0] = { 74 .start = S3C2410_PA_UART2, 75 .end = S3C2410_PA_UART2 + 0x3fff, 76 .flags = IORESOURCE_MEM, 77 }, 78 [1] = { 79 .start = IRQ_S3CUART_RX2, 80 .end = IRQ_S3CUART_ERR2, 81 .flags = IORESOURCE_IRQ, 82 } 83}; 84 85static struct resource s3c2410_uart3_resource[] = { 86 [0] = { 87 .start = S3C2443_PA_UART3, 88 .end = S3C2443_PA_UART3 + 0x3fff, 89 .flags = IORESOURCE_MEM, 90 }, 91 [1] = { 92 .start = IRQ_S3CUART_RX3, 93 .end = IRQ_S3CUART_ERR3, 94 .flags = IORESOURCE_IRQ, 95 }, 96}; 97 98struct s3c24xx_uart_resources s3c2410_uart_resources[] __initdata = { 99 [0] = { 100 .resources = s3c2410_uart0_resource, 101 .nr_resources = ARRAY_SIZE(s3c2410_uart0_resource), 102 }, 103 [1] = { 104 .resources = s3c2410_uart1_resource, 105 .nr_resources = ARRAY_SIZE(s3c2410_uart1_resource), 106 }, 107 [2] = { 108 .resources = s3c2410_uart2_resource, 109 .nr_resources = ARRAY_SIZE(s3c2410_uart2_resource), 110 }, 111 [3] = { 112 .resources = s3c2410_uart3_resource, 113 .nr_resources = ARRAY_SIZE(s3c2410_uart3_resource), 114 }, 115}; 116 117/* LCD Controller */ 118 119static struct resource s3c_lcd_resource[] = { 120 [0] = { 121 .start = S3C24XX_PA_LCD, 122 .end = S3C24XX_PA_LCD + S3C24XX_SZ_LCD - 1, 123 .flags = IORESOURCE_MEM, 124 }, 125 [1] = { 126 .start = IRQ_LCD, 127 .end = IRQ_LCD, 128 .flags = IORESOURCE_IRQ, 129 } 130 131}; 132 133static u64 s3c_device_lcd_dmamask = 0xffffffffUL; 134 135struct platform_device s3c_device_lcd = { 136 .name = "s3c2410-lcd", 137 .id = -1, 138 .num_resources = ARRAY_SIZE(s3c_lcd_resource), 139 .resource = s3c_lcd_resource, 140 .dev = { 141 .dma_mask = &s3c_device_lcd_dmamask, 142 .coherent_dma_mask = 0xffffffffUL 143 } 144}; 145 146EXPORT_SYMBOL(s3c_device_lcd); 147 148void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *pd) 149{ 150 struct s3c2410fb_mach_info *npd; 151 152 npd = kmemdup(pd, sizeof(*npd), GFP_KERNEL); 153 if (npd) { 154 s3c_device_lcd.dev.platform_data = npd; 155 npd->displays = kmemdup(pd->displays, 156 sizeof(struct s3c2410fb_display) * npd->num_displays, 157 GFP_KERNEL); 158 if (!npd->displays) 159 printk(KERN_ERR "no memory for LCD display data\n"); 160 } else { 161 printk(KERN_ERR "no memory for LCD platform data\n"); 162 } 163} 164 165/* Touchscreen */ 166 167static struct resource s3c_ts_resource[] = { 168 [0] = { 169 .start = S3C24XX_PA_ADC, 170 .end = S3C24XX_PA_ADC + S3C24XX_SZ_ADC - 1, 171 .flags = IORESOURCE_MEM, 172 }, 173 [1] = { 174 .start = IRQ_TC, 175 .end = IRQ_TC, 176 .flags = IORESOURCE_IRQ, 177 }, 178 179}; 180 181struct platform_device s3c_device_ts = { 182 .name = "s3c2410-ts", 183 .id = -1, 184 .dev.parent = &s3c_device_adc.dev, 185 .num_resources = ARRAY_SIZE(s3c_ts_resource), 186 .resource = s3c_ts_resource, 187}; 188EXPORT_SYMBOL(s3c_device_ts); 189 190static struct s3c2410_ts_mach_info s3c2410ts_info; 191 192void __init s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *hard_s3c2410ts_info) 193{ 194 memcpy(&s3c2410ts_info, hard_s3c2410ts_info, sizeof(struct s3c2410_ts_mach_info)); 195 s3c_device_ts.dev.platform_data = &s3c2410ts_info; 196} 197EXPORT_SYMBOL(s3c24xx_ts_set_platdata); 198 199/* USB Device (Gadget)*/ 200 201static struct resource s3c_usbgadget_resource[] = { 202 [0] = { 203 .start = S3C24XX_PA_USBDEV, 204 .end = S3C24XX_PA_USBDEV + S3C24XX_SZ_USBDEV - 1, 205 .flags = IORESOURCE_MEM, 206 }, 207 [1] = { 208 .start = IRQ_USBD, 209 .end = IRQ_USBD, 210 .flags = IORESOURCE_IRQ, 211 } 212 213}; 214 215struct platform_device s3c_device_usbgadget = { 216 .name = "s3c2410-usbgadget", 217 .id = -1, 218 .num_resources = ARRAY_SIZE(s3c_usbgadget_resource), 219 .resource = s3c_usbgadget_resource, 220}; 221 222EXPORT_SYMBOL(s3c_device_usbgadget); 223 224void __init s3c24xx_udc_set_platdata(struct s3c2410_udc_mach_info *pd) 225{ 226 struct s3c2410_udc_mach_info *npd; 227 228 npd = kmalloc(sizeof(*npd), GFP_KERNEL); 229 if (npd) { 230 memcpy(npd, pd, sizeof(*npd)); 231 s3c_device_usbgadget.dev.platform_data = npd; 232 } else { 233 printk(KERN_ERR "no memory for udc platform data\n"); 234 } 235} 236 237/* IIS */ 238 239static struct resource s3c_iis_resource[] = { 240 [0] = { 241 .start = S3C24XX_PA_IIS, 242 .end = S3C24XX_PA_IIS + S3C24XX_SZ_IIS -1, 243 .flags = IORESOURCE_MEM, 244 } 245}; 246 247static u64 s3c_device_iis_dmamask = 0xffffffffUL; 248 249struct platform_device s3c_device_iis = { 250 .name = "s3c2410-iis", 251 .id = -1, 252 .num_resources = ARRAY_SIZE(s3c_iis_resource), 253 .resource = s3c_iis_resource, 254 .dev = { 255 .dma_mask = &s3c_device_iis_dmamask, 256 .coherent_dma_mask = 0xffffffffUL 257 } 258}; 259 260EXPORT_SYMBOL(s3c_device_iis); 261 262/* RTC */ 263 264static struct resource s3c_rtc_resource[] = { 265 [0] = { 266 .start = S3C24XX_PA_RTC, 267 .end = S3C24XX_PA_RTC + 0xff, 268 .flags = IORESOURCE_MEM, 269 }, 270 [1] = { 271 .start = IRQ_RTC, 272 .end = IRQ_RTC, 273 .flags = IORESOURCE_IRQ, 274 }, 275 [2] = { 276 .start = IRQ_TICK, 277 .end = IRQ_TICK, 278 .flags = IORESOURCE_IRQ 279 } 280}; 281 282struct platform_device s3c_device_rtc = { 283 .name = "s3c2410-rtc", 284 .id = -1, 285 .num_resources = ARRAY_SIZE(s3c_rtc_resource), 286 .resource = s3c_rtc_resource, 287}; 288 289EXPORT_SYMBOL(s3c_device_rtc); 290 291/* ADC */ 292 293static struct resource s3c_adc_resource[] = { 294 [0] = { 295 .start = S3C24XX_PA_ADC, 296 .end = S3C24XX_PA_ADC + S3C24XX_SZ_ADC - 1, 297 .flags = IORESOURCE_MEM, 298 }, 299 [1] = { 300 .start = IRQ_TC, 301 .end = IRQ_TC, 302 .flags = IORESOURCE_IRQ, 303 }, 304 [2] = { 305 .start = IRQ_ADC, 306 .end = IRQ_ADC, 307 .flags = IORESOURCE_IRQ, 308 } 309 310}; 311 312struct platform_device s3c_device_adc = { 313 .name = "s3c24xx-adc", 314 .id = -1, 315 .num_resources = ARRAY_SIZE(s3c_adc_resource), 316 .resource = s3c_adc_resource, 317}; 318 319/* SDI */ 320 321static struct resource s3c_sdi_resource[] = { 322 [0] = { 323 .start = S3C24XX_PA_SDI, 324 .end = S3C24XX_PA_SDI + S3C24XX_SZ_SDI - 1, 325 .flags = IORESOURCE_MEM, 326 }, 327 [1] = { 328 .start = IRQ_SDI, 329 .end = IRQ_SDI, 330 .flags = IORESOURCE_IRQ, 331 } 332 333}; 334 335struct platform_device s3c_device_sdi = { 336 .name = "s3c2410-sdi", 337 .id = -1, 338 .num_resources = ARRAY_SIZE(s3c_sdi_resource), 339 .resource = s3c_sdi_resource, 340}; 341 342EXPORT_SYMBOL(s3c_device_sdi); 343 344void __init s3c24xx_mci_set_platdata(struct s3c24xx_mci_pdata *pdata) 345{ 346 struct s3c24xx_mci_pdata *npd; 347 348 npd = kmemdup(pdata, sizeof(struct s3c24xx_mci_pdata), GFP_KERNEL); 349 if (!npd) 350 printk(KERN_ERR "%s: no memory to copy pdata", __func__); 351 352 s3c_device_sdi.dev.platform_data = npd; 353} 354 355 356/* SPI (0) */ 357 358static struct resource s3c_spi0_resource[] = { 359 [0] = { 360 .start = S3C24XX_PA_SPI, 361 .end = S3C24XX_PA_SPI + 0x1f, 362 .flags = IORESOURCE_MEM, 363 }, 364 [1] = { 365 .start = IRQ_SPI0, 366 .end = IRQ_SPI0, 367 .flags = IORESOURCE_IRQ, 368 } 369 370}; 371 372static u64 s3c_device_spi0_dmamask = 0xffffffffUL; 373 374struct platform_device s3c_device_spi0 = { 375 .name = "s3c2410-spi", 376 .id = 0, 377 .num_resources = ARRAY_SIZE(s3c_spi0_resource), 378 .resource = s3c_spi0_resource, 379 .dev = { 380 .dma_mask = &s3c_device_spi0_dmamask, 381 .coherent_dma_mask = 0xffffffffUL 382 } 383}; 384 385EXPORT_SYMBOL(s3c_device_spi0); 386 387/* SPI (1) */ 388 389static struct resource s3c_spi1_resource[] = { 390 [0] = { 391 .start = S3C24XX_PA_SPI + S3C2410_SPI1, 392 .end = S3C24XX_PA_SPI + S3C2410_SPI1 + 0x1f, 393 .flags = IORESOURCE_MEM, 394 }, 395 [1] = { 396 .start = IRQ_SPI1, 397 .end = IRQ_SPI1, 398 .flags = IORESOURCE_IRQ, 399 } 400 401}; 402 403static u64 s3c_device_spi1_dmamask = 0xffffffffUL; 404 405struct platform_device s3c_device_spi1 = { 406 .name = "s3c2410-spi", 407 .id = 1, 408 .num_resources = ARRAY_SIZE(s3c_spi1_resource), 409 .resource = s3c_spi1_resource, 410 .dev = { 411 .dma_mask = &s3c_device_spi1_dmamask, 412 .coherent_dma_mask = 0xffffffffUL 413 } 414}; 415 416EXPORT_SYMBOL(s3c_device_spi1); 417 418#ifdef CONFIG_CPU_S3C2440 419 420/* Camif Controller */ 421 422static struct resource s3c_camif_resource[] = { 423 [0] = { 424 .start = S3C2440_PA_CAMIF, 425 .end = S3C2440_PA_CAMIF + S3C2440_SZ_CAMIF - 1, 426 .flags = IORESOURCE_MEM, 427 }, 428 [1] = { 429 .start = IRQ_CAM, 430 .end = IRQ_CAM, 431 .flags = IORESOURCE_IRQ, 432 } 433 434}; 435 436static u64 s3c_device_camif_dmamask = 0xffffffffUL; 437 438struct platform_device s3c_device_camif = { 439 .name = "s3c2440-camif", 440 .id = -1, 441 .num_resources = ARRAY_SIZE(s3c_camif_resource), 442 .resource = s3c_camif_resource, 443 .dev = { 444 .dma_mask = &s3c_device_camif_dmamask, 445 .coherent_dma_mask = 0xffffffffUL 446 } 447}; 448 449EXPORT_SYMBOL(s3c_device_camif); 450 451/* AC97 */ 452 453static struct resource s3c_ac97_resource[] = { 454 [0] = { 455 .start = S3C2440_PA_AC97, 456 .end = S3C2440_PA_AC97 + S3C2440_SZ_AC97 -1, 457 .flags = IORESOURCE_MEM, 458 }, 459 [1] = { 460 .start = IRQ_S3C244x_AC97, 461 .end = IRQ_S3C244x_AC97, 462 .flags = IORESOURCE_IRQ, 463 }, 464 [2] = { 465 .name = "PCM out", 466 .start = DMACH_PCM_OUT, 467 .end = DMACH_PCM_OUT, 468 .flags = IORESOURCE_DMA, 469 }, 470 [3] = { 471 .name = "PCM in", 472 .start = DMACH_PCM_IN, 473 .end = DMACH_PCM_IN, 474 .flags = IORESOURCE_DMA, 475 }, 476 [4] = { 477 .name = "Mic in", 478 .start = DMACH_MIC_IN, 479 .end = DMACH_MIC_IN, 480 .flags = IORESOURCE_DMA, 481 }, 482}; 483 484static u64 s3c_device_ac97_dmamask = 0xffffffffUL; 485 486struct platform_device s3c_device_ac97 = { 487 .name = "s3c-ac97", 488 .id = -1, 489 .num_resources = ARRAY_SIZE(s3c_ac97_resource), 490 .resource = s3c_ac97_resource, 491 .dev = { 492 .dma_mask = &s3c_device_ac97_dmamask, 493 .coherent_dma_mask = 0xffffffffUL 494 } 495}; 496 497EXPORT_SYMBOL(s3c_device_ac97); 498 499#endif // CONFIG_CPU_S32440 500