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