linux/arch/arm/mach-omap1/board-perseus2.c
<<
>>
Prefs
   1/*
   2 * linux/arch/arm/mach-omap1/board-perseus2.c
   3 *
   4 * Modified from board-generic.c
   5 *
   6 * Original OMAP730 support by Jean Pihet <j-pihet@ti.com>
   7 * Updated for 2.6 by Kevin Hilman <kjh@hilman.org>
   8 *
   9 * This program is free software; you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License version 2 as
  11 * published by the Free Software Foundation.
  12 */
  13#include <linux/gpio.h>
  14#include <linux/kernel.h>
  15#include <linux/init.h>
  16#include <linux/platform_device.h>
  17#include <linux/delay.h>
  18#include <linux/mtd/mtd.h>
  19#include <linux/mtd/nand.h>
  20#include <linux/mtd/partitions.h>
  21#include <linux/mtd/physmap.h>
  22#include <linux/input.h>
  23#include <linux/smc91x.h>
  24
  25#include <mach/hardware.h>
  26#include <asm/mach-types.h>
  27#include <asm/mach/arch.h>
  28#include <asm/mach/map.h>
  29
  30#include <plat/tc.h>
  31#include <plat/mux.h>
  32#include <plat/fpga.h>
  33#include <plat/flash.h>
  34#include <plat/keypad.h>
  35#include "common.h"
  36#include <plat/board.h>
  37
  38static const unsigned int p2_keymap[] = {
  39        KEY(0, 0, KEY_UP),
  40        KEY(1, 0, KEY_RIGHT),
  41        KEY(2, 0, KEY_LEFT),
  42        KEY(3, 0, KEY_DOWN),
  43        KEY(4, 0, KEY_ENTER),
  44        KEY(0, 1, KEY_F10),
  45        KEY(1, 1, KEY_SEND),
  46        KEY(2, 1, KEY_END),
  47        KEY(3, 1, KEY_VOLUMEDOWN),
  48        KEY(4, 1, KEY_VOLUMEUP),
  49        KEY(5, 1, KEY_RECORD),
  50        KEY(0, 2, KEY_F9),
  51        KEY(1, 2, KEY_3),
  52        KEY(2, 2, KEY_6),
  53        KEY(3, 2, KEY_9),
  54        KEY(4, 2, KEY_KPDOT),
  55        KEY(0, 3, KEY_BACK),
  56        KEY(1, 3, KEY_2),
  57        KEY(2, 3, KEY_5),
  58        KEY(3, 3, KEY_8),
  59        KEY(4, 3, KEY_0),
  60        KEY(5, 3, KEY_KPSLASH),
  61        KEY(0, 4, KEY_HOME),
  62        KEY(1, 4, KEY_1),
  63        KEY(2, 4, KEY_4),
  64        KEY(3, 4, KEY_7),
  65        KEY(4, 4, KEY_KPASTERISK),
  66        KEY(5, 4, KEY_POWER),
  67};
  68
  69static struct smc91x_platdata smc91x_info = {
  70        .flags  = SMC91X_USE_16BIT | SMC91X_NOWAIT,
  71        .leda   = RPC_LED_100_10,
  72        .ledb   = RPC_LED_TX_RX,
  73};
  74
  75static struct resource smc91x_resources[] = {
  76        [0] = {
  77                .start  = H2P2_DBG_FPGA_ETHR_START,     /* Physical */
  78                .end    = H2P2_DBG_FPGA_ETHR_START + 0xf,
  79                .flags  = IORESOURCE_MEM,
  80        },
  81        [1] = {
  82                .start  = INT_7XX_MPU_EXT_NIRQ,
  83                .end    = 0,
  84                .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
  85        },
  86};
  87
  88static struct mtd_partition nor_partitions[] = {
  89        /* bootloader (U-Boot, etc) in first sector */
  90        {
  91              .name             = "bootloader",
  92              .offset           = 0,
  93              .size             = SZ_128K,
  94              .mask_flags       = MTD_WRITEABLE, /* force read-only */
  95        },
  96        /* bootloader params in the next sector */
  97        {
  98              .name             = "params",
  99              .offset           = MTDPART_OFS_APPEND,
 100              .size             = SZ_128K,
 101              .mask_flags       = 0,
 102        },
 103        /* kernel */
 104        {
 105              .name             = "kernel",
 106              .offset           = MTDPART_OFS_APPEND,
 107              .size             = SZ_2M,
 108              .mask_flags       = 0
 109        },
 110        /* rest of flash is a file system */
 111        {
 112              .name             = "rootfs",
 113              .offset           = MTDPART_OFS_APPEND,
 114              .size             = MTDPART_SIZ_FULL,
 115              .mask_flags       = 0
 116        },
 117};
 118
 119static struct physmap_flash_data nor_data = {
 120        .width          = 2,
 121        .set_vpp        = omap1_set_vpp,
 122        .parts          = nor_partitions,
 123        .nr_parts       = ARRAY_SIZE(nor_partitions),
 124};
 125
 126static struct resource nor_resource = {
 127        .start          = OMAP_CS0_PHYS,
 128        .end            = OMAP_CS0_PHYS + SZ_32M - 1,
 129        .flags          = IORESOURCE_MEM,
 130};
 131
 132static struct platform_device nor_device = {
 133        .name           = "physmap-flash",
 134        .id             = 0,
 135        .dev            = {
 136                .platform_data  = &nor_data,
 137        },
 138        .num_resources  = 1,
 139        .resource       = &nor_resource,
 140};
 141
 142static void nand_cmd_ctl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
 143{
 144        struct nand_chip *this = mtd->priv;
 145        unsigned long mask;
 146
 147        if (cmd == NAND_CMD_NONE)
 148                return;
 149
 150        mask = (ctrl & NAND_CLE) ? 0x02 : 0;
 151        if (ctrl & NAND_ALE)
 152                mask |= 0x04;
 153        writeb(cmd, (unsigned long)this->IO_ADDR_W | mask);
 154}
 155
 156#define P2_NAND_RB_GPIO_PIN     62
 157
 158static int nand_dev_ready(struct mtd_info *mtd)
 159{
 160        return gpio_get_value(P2_NAND_RB_GPIO_PIN);
 161}
 162
 163static const char *part_probes[] = { "cmdlinepart", NULL };
 164
 165static struct platform_nand_data nand_data = {
 166        .chip   = {
 167                .nr_chips               = 1,
 168                .chip_offset            = 0,
 169                .options                = NAND_SAMSUNG_LP_OPTIONS,
 170                .part_probe_types       = part_probes,
 171        },
 172        .ctrl   = {
 173                .cmd_ctrl       = nand_cmd_ctl,
 174                .dev_ready      = nand_dev_ready,
 175        },
 176};
 177
 178static struct resource nand_resource = {
 179        .start          = OMAP_CS3_PHYS,
 180        .end            = OMAP_CS3_PHYS + SZ_4K - 1,
 181        .flags          = IORESOURCE_MEM,
 182};
 183
 184static struct platform_device nand_device = {
 185        .name           = "gen_nand",
 186        .id             = 0,
 187        .dev            = {
 188                .platform_data  = &nand_data,
 189        },
 190        .num_resources  = 1,
 191        .resource       = &nand_resource,
 192};
 193
 194static struct platform_device smc91x_device = {
 195        .name           = "smc91x",
 196        .id             = 0,
 197        .dev    = {
 198                .platform_data  = &smc91x_info,
 199        },
 200        .num_resources  = ARRAY_SIZE(smc91x_resources),
 201        .resource       = smc91x_resources,
 202};
 203
 204static struct resource kp_resources[] = {
 205        [0] = {
 206                .start  = INT_7XX_MPUIO_KEYPAD,
 207                .end    = INT_7XX_MPUIO_KEYPAD,
 208                .flags  = IORESOURCE_IRQ,
 209        },
 210};
 211
 212static const struct matrix_keymap_data p2_keymap_data = {
 213        .keymap         = p2_keymap,
 214        .keymap_size    = ARRAY_SIZE(p2_keymap),
 215};
 216
 217static struct omap_kp_platform_data kp_data = {
 218        .rows           = 8,
 219        .cols           = 8,
 220        .keymap_data    = &p2_keymap_data,
 221        .delay          = 4,
 222        .dbounce        = true,
 223};
 224
 225static struct platform_device kp_device = {
 226        .name           = "omap-keypad",
 227        .id             = -1,
 228        .dev            = {
 229                .platform_data = &kp_data,
 230        },
 231        .num_resources  = ARRAY_SIZE(kp_resources),
 232        .resource       = kp_resources,
 233};
 234
 235static struct platform_device lcd_device = {
 236        .name           = "lcd_p2",
 237        .id             = -1,
 238};
 239
 240static struct platform_device *devices[] __initdata = {
 241        &nor_device,
 242        &nand_device,
 243        &smc91x_device,
 244        &kp_device,
 245        &lcd_device,
 246};
 247
 248static struct omap_lcd_config perseus2_lcd_config __initdata = {
 249        .ctrl_name      = "internal",
 250};
 251
 252static struct omap_board_config_kernel perseus2_config[] __initdata = {
 253        { OMAP_TAG_LCD,         &perseus2_lcd_config },
 254};
 255
 256static void __init perseus2_init_smc91x(void)
 257{
 258        fpga_write(1, H2P2_DBG_FPGA_LAN_RESET);
 259        mdelay(50);
 260        fpga_write(fpga_read(H2P2_DBG_FPGA_LAN_RESET) & ~1,
 261                   H2P2_DBG_FPGA_LAN_RESET);
 262        mdelay(50);
 263}
 264
 265static void __init omap_perseus2_init(void)
 266{
 267        /* Early, board-dependent init */
 268
 269        /*
 270         * Hold GSM Reset until needed
 271         */
 272        omap_writew(omap_readw(OMAP7XX_DSP_M_CTL) & ~1, OMAP7XX_DSP_M_CTL);
 273
 274        /*
 275         * UARTs -> done automagically by 8250 driver
 276         */
 277
 278        /*
 279         * CSx timings, GPIO Mux ... setup
 280         */
 281
 282        /* Flash: CS0 timings setup */
 283        omap_writel(0x0000fff3, OMAP7XX_FLASH_CFG_0);
 284        omap_writel(0x00000088, OMAP7XX_FLASH_ACFG_0);
 285
 286        /*
 287         * Ethernet support through the debug board
 288         * CS1 timings setup
 289         */
 290        omap_writel(0x0000fff3, OMAP7XX_FLASH_CFG_1);
 291        omap_writel(0x00000000, OMAP7XX_FLASH_ACFG_1);
 292
 293        /*
 294         * Configure MPU_EXT_NIRQ IO in IO_CONF9 register,
 295         * It is used as the Ethernet controller interrupt
 296         */
 297        omap_writel(omap_readl(OMAP7XX_IO_CONF_9) & 0x1FFFFFFF,
 298                                OMAP7XX_IO_CONF_9);
 299
 300        perseus2_init_smc91x();
 301
 302        if (gpio_request(P2_NAND_RB_GPIO_PIN, "NAND ready") < 0)
 303                BUG();
 304        gpio_direction_input(P2_NAND_RB_GPIO_PIN);
 305
 306        omap_cfg_reg(L3_1610_FLASH_CS2B_OE);
 307        omap_cfg_reg(M8_1610_FLASH_CS2B_WE);
 308
 309        /* Mux pins for keypad */
 310        omap_cfg_reg(E2_7XX_KBR0);
 311        omap_cfg_reg(J7_7XX_KBR1);
 312        omap_cfg_reg(E1_7XX_KBR2);
 313        omap_cfg_reg(F3_7XX_KBR3);
 314        omap_cfg_reg(D2_7XX_KBR4);
 315        omap_cfg_reg(C2_7XX_KBC0);
 316        omap_cfg_reg(D3_7XX_KBC1);
 317        omap_cfg_reg(E4_7XX_KBC2);
 318        omap_cfg_reg(F4_7XX_KBC3);
 319        omap_cfg_reg(E3_7XX_KBC4);
 320
 321        platform_add_devices(devices, ARRAY_SIZE(devices));
 322
 323        omap_board_config = perseus2_config;
 324        omap_board_config_size = ARRAY_SIZE(perseus2_config);
 325        omap_serial_init();
 326        omap_register_i2c_bus(1, 100, NULL, 0);
 327}
 328
 329/* Only FPGA needs to be mapped here. All others are done with ioremap */
 330static struct map_desc omap_perseus2_io_desc[] __initdata = {
 331        {
 332                .virtual        = H2P2_DBG_FPGA_BASE,
 333                .pfn            = __phys_to_pfn(H2P2_DBG_FPGA_START),
 334                .length         = H2P2_DBG_FPGA_SIZE,
 335                .type           = MT_DEVICE
 336        }
 337};
 338
 339static void __init omap_perseus2_map_io(void)
 340{
 341        omap7xx_map_io();
 342        iotable_init(omap_perseus2_io_desc,
 343                     ARRAY_SIZE(omap_perseus2_io_desc));
 344}
 345
 346MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2")
 347        /* Maintainer: Kevin Hilman <kjh@hilman.org> */
 348        .atag_offset    = 0x100,
 349        .map_io         = omap_perseus2_map_io,
 350        .init_early     = omap1_init_early,
 351        .reserve        = omap_reserve,
 352        .init_irq       = omap1_init_irq,
 353        .init_machine   = omap_perseus2_init,
 354        .timer          = &omap1_timer,
 355        .restart        = omap1_restart,
 356MACHINE_END
 357