linux/arch/arm/mach-w90x900/dev.c
<<
>>
Prefs
   1/*
   2 * linux/arch/arm/mach-w90x900/dev.c
   3 *
   4 * Copyright (C) 2009 Nuvoton corporation.
   5 *
   6 * Wan ZongShun <mcuos.com@gmail.com>
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License as
  10 * published by the Free Software Foundation;version 2 of the License.
  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/platform_device.h>
  21#include <linux/slab.h>
  22#include <linux/cpu.h>
  23
  24#include <linux/mtd/physmap.h>
  25#include <linux/mtd/mtd.h>
  26#include <linux/mtd/partitions.h>
  27
  28#include <linux/spi/spi.h>
  29#include <linux/spi/flash.h>
  30
  31#include <asm/system_misc.h>
  32#include <asm/mach/arch.h>
  33#include <asm/mach/map.h>
  34#include <asm/mach/irq.h>
  35#include <asm/mach-types.h>
  36
  37#include <mach/regs-serial.h>
  38#include <linux/platform_data/spi-nuc900.h>
  39#include <mach/map.h>
  40#include <linux/platform_data/video-nuc900fb.h>
  41#include <mach/regs-ldm.h>
  42#include <linux/platform_data/keypad-w90p910.h>
  43
  44#include "cpu.h"
  45
  46/*NUC900 evb norflash driver data */
  47
  48#define NUC900_FLASH_BASE       0xA0000000
  49#define NUC900_FLASH_SIZE       0x400000
  50#define SPIOFFSET               0x200
  51#define SPIOREG_SIZE            0x100
  52
  53static struct mtd_partition nuc900_flash_partitions[] = {
  54        {
  55                .name   =       "NOR Partition 1 for kernel (960K)",
  56                .size   =       0xF0000,
  57                .offset =       0x10000,
  58        },
  59        {
  60                .name   =       "NOR Partition 2 for image (1M)",
  61                .size   =       0x100000,
  62                .offset =       0x100000,
  63        },
  64        {
  65                .name   =       "NOR Partition 3 for user (2M)",
  66                .size   =       0x200000,
  67                .offset =       0x00200000,
  68        }
  69};
  70
  71static struct physmap_flash_data nuc900_flash_data = {
  72        .width          =       2,
  73        .parts          =       nuc900_flash_partitions,
  74        .nr_parts       =       ARRAY_SIZE(nuc900_flash_partitions),
  75};
  76
  77static struct resource nuc900_flash_resources[] = {
  78        {
  79                .start  =       NUC900_FLASH_BASE,
  80                .end    =       NUC900_FLASH_BASE + NUC900_FLASH_SIZE - 1,
  81                .flags  =       IORESOURCE_MEM,
  82        }
  83};
  84
  85static struct platform_device nuc900_flash_device = {
  86        .name           =       "physmap-flash",
  87        .id             =       0,
  88        .dev            = {
  89                                .platform_data = &nuc900_flash_data,
  90                        },
  91        .resource       =       nuc900_flash_resources,
  92        .num_resources  =       ARRAY_SIZE(nuc900_flash_resources),
  93};
  94
  95/* USB EHCI Host Controller */
  96
  97static struct resource nuc900_usb_ehci_resource[] = {
  98        [0] = {
  99                .start = W90X900_PA_USBEHCIHOST,
 100                .end   = W90X900_PA_USBEHCIHOST + W90X900_SZ_USBEHCIHOST - 1,
 101                .flags = IORESOURCE_MEM,
 102        },
 103        [1] = {
 104                .start = IRQ_USBH,
 105                .end   = IRQ_USBH,
 106                .flags = IORESOURCE_IRQ,
 107        }
 108};
 109
 110static u64 nuc900_device_usb_ehci_dmamask = 0xffffffffUL;
 111
 112static struct platform_device nuc900_device_usb_ehci = {
 113        .name             = "nuc900-ehci",
 114        .id               = -1,
 115        .num_resources    = ARRAY_SIZE(nuc900_usb_ehci_resource),
 116        .resource         = nuc900_usb_ehci_resource,
 117        .dev              = {
 118                .dma_mask = &nuc900_device_usb_ehci_dmamask,
 119                .coherent_dma_mask = 0xffffffffUL
 120        }
 121};
 122
 123/* USB OHCI Host Controller */
 124
 125static struct resource nuc900_usb_ohci_resource[] = {
 126        [0] = {
 127                .start = W90X900_PA_USBOHCIHOST,
 128                .end   = W90X900_PA_USBOHCIHOST + W90X900_SZ_USBOHCIHOST - 1,
 129                .flags = IORESOURCE_MEM,
 130        },
 131        [1] = {
 132                .start = IRQ_USBH,
 133                .end   = IRQ_USBH,
 134                .flags = IORESOURCE_IRQ,
 135        }
 136};
 137
 138static u64 nuc900_device_usb_ohci_dmamask = 0xffffffffUL;
 139static struct platform_device nuc900_device_usb_ohci = {
 140        .name             = "nuc900-ohci",
 141        .id               = -1,
 142        .num_resources    = ARRAY_SIZE(nuc900_usb_ohci_resource),
 143        .resource         = nuc900_usb_ohci_resource,
 144        .dev              = {
 145                .dma_mask = &nuc900_device_usb_ohci_dmamask,
 146                .coherent_dma_mask = 0xffffffffUL
 147        }
 148};
 149
 150/* USB Device (Gadget)*/
 151
 152static struct resource nuc900_usbgadget_resource[] = {
 153        [0] = {
 154                .start = W90X900_PA_USBDEV,
 155                .end   = W90X900_PA_USBDEV + W90X900_SZ_USBDEV - 1,
 156                .flags = IORESOURCE_MEM,
 157        },
 158        [1] = {
 159                .start = IRQ_USBD,
 160                .end   = IRQ_USBD,
 161                .flags = IORESOURCE_IRQ,
 162        }
 163};
 164
 165static struct platform_device nuc900_device_usbgadget = {
 166        .name           = "nuc900-usbgadget",
 167        .id             = -1,
 168        .num_resources  = ARRAY_SIZE(nuc900_usbgadget_resource),
 169        .resource       = nuc900_usbgadget_resource,
 170};
 171
 172/* MAC device */
 173
 174static struct resource nuc900_emc_resource[] = {
 175        [0] = {
 176                .start = W90X900_PA_EMC,
 177                .end   = W90X900_PA_EMC + W90X900_SZ_EMC - 1,
 178                .flags = IORESOURCE_MEM,
 179        },
 180        [1] = {
 181                .start = IRQ_EMCTX,
 182                .end   = IRQ_EMCTX,
 183                .flags = IORESOURCE_IRQ,
 184        },
 185        [2] = {
 186                .start = IRQ_EMCRX,
 187                .end   = IRQ_EMCRX,
 188                .flags = IORESOURCE_IRQ,
 189        }
 190};
 191
 192static u64 nuc900_device_emc_dmamask = 0xffffffffUL;
 193static struct platform_device nuc900_device_emc = {
 194        .name           = "nuc900-emc",
 195        .id             = -1,
 196        .num_resources  = ARRAY_SIZE(nuc900_emc_resource),
 197        .resource       = nuc900_emc_resource,
 198        .dev              = {
 199                .dma_mask = &nuc900_device_emc_dmamask,
 200                .coherent_dma_mask = 0xffffffffUL
 201        }
 202};
 203
 204/* SPI device */
 205
 206static struct nuc900_spi_info nuc900_spiflash_data = {
 207        .num_cs         = 1,
 208        .lsb            = 0,
 209        .txneg          = 1,
 210        .rxneg          = 0,
 211        .divider        = 24,
 212        .sleep          = 0,
 213        .txnum          = 0,
 214        .txbitlen       = 8,
 215        .bus_num        = 0,
 216};
 217
 218static struct resource nuc900_spi_resource[] = {
 219        [0] = {
 220                .start = W90X900_PA_I2C + SPIOFFSET,
 221                .end   = W90X900_PA_I2C + SPIOFFSET + SPIOREG_SIZE - 1,
 222                .flags = IORESOURCE_MEM,
 223        },
 224        [1] = {
 225                .start = IRQ_SSP,
 226                .end   = IRQ_SSP,
 227                .flags = IORESOURCE_IRQ,
 228        }
 229};
 230
 231static struct platform_device nuc900_device_spi = {
 232        .name           = "nuc900-spi",
 233        .id             = -1,
 234        .num_resources  = ARRAY_SIZE(nuc900_spi_resource),
 235        .resource       = nuc900_spi_resource,
 236        .dev            = {
 237                                .platform_data = &nuc900_spiflash_data,
 238                        }
 239};
 240
 241/* spi device, spi flash info */
 242
 243static struct mtd_partition nuc900_spi_flash_partitions[] = {
 244        {
 245                .name = "bootloader(spi)",
 246                .size = 0x0100000,
 247                .offset = 0,
 248        },
 249};
 250
 251static struct flash_platform_data nuc900_spi_flash_data = {
 252        .name = "m25p80",
 253        .parts =  nuc900_spi_flash_partitions,
 254        .nr_parts = ARRAY_SIZE(nuc900_spi_flash_partitions),
 255        .type = "w25x16",
 256};
 257
 258static struct spi_board_info nuc900_spi_board_info[] __initdata = {
 259        {
 260                .modalias = "m25p80",
 261                .max_speed_hz = 20000000,
 262                .bus_num = 0,
 263                .chip_select = 0,
 264                .platform_data = &nuc900_spi_flash_data,
 265                .mode = SPI_MODE_0,
 266        },
 267};
 268
 269/* WDT Device */
 270
 271static struct resource nuc900_wdt_resource[] = {
 272        [0] = {
 273                .start = W90X900_PA_TIMER,
 274                .end   = W90X900_PA_TIMER + W90X900_SZ_TIMER - 1,
 275                .flags = IORESOURCE_MEM,
 276        },
 277        [1] = {
 278                .start = IRQ_WDT,
 279                .end   = IRQ_WDT,
 280                .flags = IORESOURCE_IRQ,
 281        }
 282};
 283
 284static struct platform_device nuc900_device_wdt = {
 285        .name           = "nuc900-wdt",
 286        .id             = -1,
 287        .num_resources  = ARRAY_SIZE(nuc900_wdt_resource),
 288        .resource       = nuc900_wdt_resource,
 289};
 290
 291/*
 292 * public device definition between 910 and 920, or 910
 293 * and 950 or 950 and 960...,their dev platform register
 294 * should be in specific file such as nuc950, nuc960 c
 295 * files rather than the public dev.c file here. so the
 296 * corresponding platform_device definition should not be
 297 * static.
 298*/
 299
 300/* RTC controller*/
 301
 302static struct resource nuc900_rtc_resource[] = {
 303        [0] = {
 304                .start = W90X900_PA_RTC,
 305                .end   = W90X900_PA_RTC + 0xff,
 306                .flags = IORESOURCE_MEM,
 307        },
 308        [1] = {
 309                .start = IRQ_RTC,
 310                .end   = IRQ_RTC,
 311                .flags = IORESOURCE_IRQ,
 312        },
 313};
 314
 315struct platform_device nuc900_device_rtc = {
 316        .name           = "nuc900-rtc",
 317        .id             = -1,
 318        .num_resources  = ARRAY_SIZE(nuc900_rtc_resource),
 319        .resource       = nuc900_rtc_resource,
 320};
 321
 322/*TouchScreen controller*/
 323
 324static struct resource nuc900_ts_resource[] = {
 325        [0] = {
 326                .start = W90X900_PA_ADC,
 327                .end   = W90X900_PA_ADC + W90X900_SZ_ADC-1,
 328                .flags = IORESOURCE_MEM,
 329        },
 330        [1] = {
 331                .start = IRQ_ADC,
 332                .end   = IRQ_ADC,
 333                .flags = IORESOURCE_IRQ,
 334        },
 335};
 336
 337struct platform_device nuc900_device_ts = {
 338        .name           = "nuc900-ts",
 339        .id             = -1,
 340        .resource       = nuc900_ts_resource,
 341        .num_resources  = ARRAY_SIZE(nuc900_ts_resource),
 342};
 343
 344/* FMI Device */
 345
 346static struct resource nuc900_fmi_resource[] = {
 347        [0] = {
 348                .start = W90X900_PA_FMI,
 349                .end   = W90X900_PA_FMI + W90X900_SZ_FMI - 1,
 350                .flags = IORESOURCE_MEM,
 351        },
 352        [1] = {
 353                .start = IRQ_FMI,
 354                .end   = IRQ_FMI,
 355                .flags = IORESOURCE_IRQ,
 356        }
 357};
 358
 359struct platform_device nuc900_device_fmi = {
 360        .name           = "nuc900-fmi",
 361        .id             = -1,
 362        .num_resources  = ARRAY_SIZE(nuc900_fmi_resource),
 363        .resource       = nuc900_fmi_resource,
 364};
 365
 366/* KPI controller*/
 367
 368static int nuc900_keymap[] = {
 369        KEY(0, 0, KEY_A),
 370        KEY(0, 1, KEY_B),
 371        KEY(0, 2, KEY_C),
 372        KEY(0, 3, KEY_D),
 373
 374        KEY(1, 0, KEY_E),
 375        KEY(1, 1, KEY_F),
 376        KEY(1, 2, KEY_G),
 377        KEY(1, 3, KEY_H),
 378
 379        KEY(2, 0, KEY_I),
 380        KEY(2, 1, KEY_J),
 381        KEY(2, 2, KEY_K),
 382        KEY(2, 3, KEY_L),
 383
 384        KEY(3, 0, KEY_M),
 385        KEY(3, 1, KEY_N),
 386        KEY(3, 2, KEY_O),
 387        KEY(3, 3, KEY_P),
 388};
 389
 390static struct matrix_keymap_data nuc900_map_data = {
 391        .keymap                 = nuc900_keymap,
 392        .keymap_size            = ARRAY_SIZE(nuc900_keymap),
 393};
 394
 395struct w90p910_keypad_platform_data nuc900_keypad_info = {
 396        .keymap_data    = &nuc900_map_data,
 397        .prescale       = 0xfa,
 398        .debounce       = 0x50,
 399};
 400
 401static struct resource nuc900_kpi_resource[] = {
 402        [0] = {
 403                .start = W90X900_PA_KPI,
 404                .end   = W90X900_PA_KPI + W90X900_SZ_KPI - 1,
 405                .flags = IORESOURCE_MEM,
 406        },
 407        [1] = {
 408                .start = IRQ_KPI,
 409                .end   = IRQ_KPI,
 410                .flags = IORESOURCE_IRQ,
 411        }
 412
 413};
 414
 415struct platform_device nuc900_device_kpi = {
 416        .name           = "nuc900-kpi",
 417        .id             = -1,
 418        .num_resources  = ARRAY_SIZE(nuc900_kpi_resource),
 419        .resource       = nuc900_kpi_resource,
 420        .dev            = {
 421                                .platform_data = &nuc900_keypad_info,
 422                        }
 423};
 424
 425/* LCD controller*/
 426
 427static struct nuc900fb_display nuc900_lcd_info[] = {
 428        /* Giantplus Technology GPM1040A0 320x240 Color TFT LCD */
 429        [0] = {
 430                .type           = LCM_DCCS_VA_SRC_RGB565,
 431                .width          = 320,
 432                .height         = 240,
 433                .xres           = 320,
 434                .yres           = 240,
 435                .bpp            = 16,
 436                .pixclock       = 200000,
 437                .left_margin    = 34,
 438                .right_margin   = 54,
 439                .hsync_len      = 10,
 440                .upper_margin   = 18,
 441                .lower_margin   = 4,
 442                .vsync_len      = 1,
 443                .dccs           = 0x8e00041a,
 444                .devctl         = 0x060800c0,
 445                .fbctrl         = 0x00a000a0,
 446                .scale          = 0x04000400,
 447        },
 448};
 449
 450static struct nuc900fb_mach_info nuc900_fb_info = {
 451#if defined(CONFIG_GPM1040A0_320X240)
 452        .displays               = &nuc900_lcd_info[0],
 453#else
 454        .displays               = nuc900_lcd_info,
 455#endif
 456        .num_displays           = ARRAY_SIZE(nuc900_lcd_info),
 457        .default_display        = 0,
 458        .gpio_dir               = 0x00000004,
 459        .gpio_dir_mask          = 0xFFFFFFFD,
 460        .gpio_data              = 0x00000004,
 461        .gpio_data_mask         = 0xFFFFFFFD,
 462};
 463
 464static struct resource nuc900_lcd_resource[] = {
 465        [0] = {
 466                .start = W90X900_PA_LCD,
 467                .end   = W90X900_PA_LCD + W90X900_SZ_LCD - 1,
 468                .flags = IORESOURCE_MEM,
 469        },
 470        [1] = {
 471                .start = IRQ_LCD,
 472                .end   = IRQ_LCD,
 473                .flags = IORESOURCE_IRQ,
 474        }
 475};
 476
 477static u64 nuc900_device_lcd_dmamask = -1;
 478struct platform_device nuc900_device_lcd = {
 479        .name             = "nuc900-lcd",
 480        .id               = -1,
 481        .num_resources    = ARRAY_SIZE(nuc900_lcd_resource),
 482        .resource         = nuc900_lcd_resource,
 483        .dev              = {
 484                .dma_mask               = &nuc900_device_lcd_dmamask,
 485                .coherent_dma_mask      = -1,
 486                .platform_data = &nuc900_fb_info,
 487        }
 488};
 489
 490/* AUDIO controller*/
 491static u64 nuc900_device_audio_dmamask = -1;
 492static struct resource nuc900_ac97_resource[] = {
 493        [0] = {
 494                .start = W90X900_PA_ACTL,
 495                .end   = W90X900_PA_ACTL + W90X900_SZ_ACTL - 1,
 496                .flags = IORESOURCE_MEM,
 497        },
 498        [1] = {
 499                .start = IRQ_ACTL,
 500                .end   = IRQ_ACTL,
 501                .flags = IORESOURCE_IRQ,
 502        }
 503
 504};
 505
 506struct platform_device nuc900_device_ac97 = {
 507        .name           = "nuc900-ac97",
 508        .id             = -1,
 509        .num_resources  = ARRAY_SIZE(nuc900_ac97_resource),
 510        .resource       = nuc900_ac97_resource,
 511        .dev              = {
 512                .dma_mask               = &nuc900_device_audio_dmamask,
 513                .coherent_dma_mask      = -1,
 514        }
 515};
 516
 517/*Here should be your evb resourse,such as LCD*/
 518
 519static struct platform_device *nuc900_public_dev[] __initdata = {
 520        &nuc900_serial_device,
 521        &nuc900_flash_device,
 522        &nuc900_device_usb_ehci,
 523        &nuc900_device_usb_ohci,
 524        &nuc900_device_usbgadget,
 525        &nuc900_device_emc,
 526        &nuc900_device_spi,
 527        &nuc900_device_wdt,
 528        &nuc900_device_ac97,
 529};
 530
 531/* Provide adding specific CPU platform devices API */
 532
 533void __init nuc900_board_init(struct platform_device **device, int size)
 534{
 535        cpu_idle_poll_ctrl(true);
 536        platform_add_devices(device, size);
 537        platform_add_devices(nuc900_public_dev, ARRAY_SIZE(nuc900_public_dev));
 538        spi_register_board_info(nuc900_spi_board_info,
 539                                        ARRAY_SIZE(nuc900_spi_board_info));
 540}
 541
 542