linux/arch/arm/mach-omap1/board-innovator.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * linux/arch/arm/mach-omap1/board-innovator.c
   4 *
   5 * Board specific inits for OMAP-1510 and OMAP-1610 Innovator
   6 *
   7 * Copyright (C) 2001 RidgeRun, Inc.
   8 * Author: Greg Lonnon <glonnon@ridgerun.com>
   9 *
  10 * Copyright (C) 2002 MontaVista Software, Inc.
  11 *
  12 * Separated FPGA interrupts from innovator1510.c and cleaned up for 2.6
  13 * Copyright (C) 2004 Nokia Corporation by Tony Lindrgen <tony@atomide.com>
  14 */
  15#include <linux/gpio.h>
  16#include <linux/kernel.h>
  17#include <linux/init.h>
  18#include <linux/platform_device.h>
  19#include <linux/delay.h>
  20#include <linux/mtd/mtd.h>
  21#include <linux/mtd/partitions.h>
  22#include <linux/mtd/physmap.h>
  23#include <linux/input.h>
  24#include <linux/smc91x.h>
  25#include <linux/omapfb.h>
  26
  27#include <asm/mach-types.h>
  28#include <asm/mach/arch.h>
  29#include <asm/mach/map.h>
  30
  31#include <mach/mux.h>
  32#include "flash.h"
  33#include <mach/tc.h>
  34#include <linux/platform_data/keypad-omap.h>
  35
  36#include <mach/hardware.h>
  37#include <mach/usb.h>
  38
  39#include "iomap.h"
  40#include "common.h"
  41#include "mmc.h"
  42
  43/* At OMAP1610 Innovator the Ethernet is directly connected to CS1 */
  44#define INNOVATOR1610_ETHR_START        0x04000300
  45
  46static const unsigned int innovator_keymap[] = {
  47        KEY(0, 0, KEY_F1),
  48        KEY(3, 0, KEY_DOWN),
  49        KEY(1, 1, KEY_F2),
  50        KEY(2, 1, KEY_RIGHT),
  51        KEY(0, 2, KEY_F3),
  52        KEY(1, 2, KEY_F4),
  53        KEY(2, 2, KEY_UP),
  54        KEY(2, 3, KEY_ENTER),
  55        KEY(3, 3, KEY_LEFT),
  56};
  57
  58static struct mtd_partition innovator_partitions[] = {
  59        /* bootloader (U-Boot, etc) in first sector */
  60        {
  61              .name             = "bootloader",
  62              .offset           = 0,
  63              .size             = SZ_128K,
  64              .mask_flags       = MTD_WRITEABLE, /* force read-only */
  65        },
  66        /* bootloader params in the next sector */
  67        {
  68              .name             = "params",
  69              .offset           = MTDPART_OFS_APPEND,
  70              .size             = SZ_128K,
  71              .mask_flags       = 0,
  72        },
  73        /* kernel */
  74        {
  75              .name             = "kernel",
  76              .offset           = MTDPART_OFS_APPEND,
  77              .size             = SZ_2M,
  78              .mask_flags       = 0
  79        },
  80        /* rest of flash1 is a file system */
  81        {
  82              .name             = "rootfs",
  83              .offset           = MTDPART_OFS_APPEND,
  84              .size             = SZ_16M - SZ_2M - 2 * SZ_128K,
  85              .mask_flags       = 0
  86        },
  87        /* file system */
  88        {
  89              .name             = "filesystem",
  90              .offset           = MTDPART_OFS_APPEND,
  91              .size             = MTDPART_SIZ_FULL,
  92              .mask_flags       = 0
  93        }
  94};
  95
  96static struct physmap_flash_data innovator_flash_data = {
  97        .width          = 2,
  98        .set_vpp        = omap1_set_vpp,
  99        .parts          = innovator_partitions,
 100        .nr_parts       = ARRAY_SIZE(innovator_partitions),
 101};
 102
 103static struct resource innovator_flash_resource = {
 104        .start          = OMAP_CS0_PHYS,
 105        .end            = OMAP_CS0_PHYS + SZ_32M - 1,
 106        .flags          = IORESOURCE_MEM,
 107};
 108
 109static struct platform_device innovator_flash_device = {
 110        .name           = "physmap-flash",
 111        .id             = 0,
 112        .dev            = {
 113                .platform_data  = &innovator_flash_data,
 114        },
 115        .num_resources  = 1,
 116        .resource       = &innovator_flash_resource,
 117};
 118
 119static struct resource innovator_kp_resources[] = {
 120        [0] = {
 121                .start  = INT_KEYBOARD,
 122                .end    = INT_KEYBOARD,
 123                .flags  = IORESOURCE_IRQ,
 124        },
 125};
 126
 127static const struct matrix_keymap_data innovator_keymap_data = {
 128        .keymap         = innovator_keymap,
 129        .keymap_size    = ARRAY_SIZE(innovator_keymap),
 130};
 131
 132static struct omap_kp_platform_data innovator_kp_data = {
 133        .rows           = 8,
 134        .cols           = 8,
 135        .keymap_data    = &innovator_keymap_data,
 136        .delay          = 4,
 137};
 138
 139static struct platform_device innovator_kp_device = {
 140        .name           = "omap-keypad",
 141        .id             = -1,
 142        .dev            = {
 143                .platform_data = &innovator_kp_data,
 144        },
 145        .num_resources  = ARRAY_SIZE(innovator_kp_resources),
 146        .resource       = innovator_kp_resources,
 147};
 148
 149static struct smc91x_platdata innovator_smc91x_info = {
 150        .flags  = SMC91X_USE_16BIT | SMC91X_NOWAIT,
 151        .leda   = RPC_LED_100_10,
 152        .ledb   = RPC_LED_TX_RX,
 153};
 154
 155#ifdef CONFIG_ARCH_OMAP15XX
 156
 157#include <linux/spi/spi.h>
 158#include <linux/spi/ads7846.h>
 159
 160
 161/* Only FPGA needs to be mapped here. All others are done with ioremap */
 162static struct map_desc innovator1510_io_desc[] __initdata = {
 163        {
 164                .virtual        = OMAP1510_FPGA_BASE,
 165                .pfn            = __phys_to_pfn(OMAP1510_FPGA_START),
 166                .length         = OMAP1510_FPGA_SIZE,
 167                .type           = MT_DEVICE
 168        }
 169};
 170
 171static struct resource innovator1510_smc91x_resources[] = {
 172        [0] = {
 173                .start  = OMAP1510_FPGA_ETHR_START,     /* Physical */
 174                .end    = OMAP1510_FPGA_ETHR_START + 0xf,
 175                .flags  = IORESOURCE_MEM,
 176        },
 177        [1] = {
 178                .start  = OMAP1510_INT_ETHER,
 179                .end    = OMAP1510_INT_ETHER,
 180                .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
 181        },
 182};
 183
 184static struct platform_device innovator1510_smc91x_device = {
 185        .name           = "smc91x",
 186        .id             = 0,
 187        .dev    = {
 188                .platform_data  = &innovator_smc91x_info,
 189        },
 190        .num_resources  = ARRAY_SIZE(innovator1510_smc91x_resources),
 191        .resource       = innovator1510_smc91x_resources,
 192};
 193
 194static struct platform_device innovator1510_lcd_device = {
 195        .name           = "lcd_inn1510",
 196        .id             = -1,
 197};
 198
 199static struct platform_device innovator1510_spi_device = {
 200        .name           = "spi_inn1510",
 201        .id             = -1,
 202};
 203
 204static struct platform_device *innovator1510_devices[] __initdata = {
 205        &innovator_flash_device,
 206        &innovator1510_smc91x_device,
 207        &innovator_kp_device,
 208        &innovator1510_lcd_device,
 209        &innovator1510_spi_device,
 210};
 211
 212static int innovator_get_pendown_state(void)
 213{
 214        return !(__raw_readb(OMAP1510_FPGA_TOUCHSCREEN) & (1 << 5));
 215}
 216
 217static const struct ads7846_platform_data innovator1510_ts_info = {
 218        .model                  = 7846,
 219        .vref_delay_usecs       = 100,  /* internal, no capacitor */
 220        .x_plate_ohms           = 419,
 221        .y_plate_ohms           = 486,
 222        .get_pendown_state      = innovator_get_pendown_state,
 223};
 224
 225static struct spi_board_info __initdata innovator1510_boardinfo[] = { {
 226        /* FPGA (bus "10") CS0 has an ads7846e */
 227        .modalias               = "ads7846",
 228        .platform_data          = &innovator1510_ts_info,
 229        .irq                    = OMAP1510_INT_FPGA_TS,
 230        .max_speed_hz           = 120000 /* max sample rate at 3V */
 231                                        * 26 /* command + data + overhead */,
 232        .bus_num                = 10,
 233        .chip_select            = 0,
 234} };
 235
 236#endif /* CONFIG_ARCH_OMAP15XX */
 237
 238#ifdef CONFIG_ARCH_OMAP16XX
 239
 240static struct resource innovator1610_smc91x_resources[] = {
 241        [0] = {
 242                .start  = INNOVATOR1610_ETHR_START,             /* Physical */
 243                .end    = INNOVATOR1610_ETHR_START + 0xf,
 244                .flags  = IORESOURCE_MEM,
 245        },
 246        [1] = {
 247                .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
 248        },
 249};
 250
 251static struct platform_device innovator1610_smc91x_device = {
 252        .name           = "smc91x",
 253        .id             = 0,
 254        .dev    = {
 255                .platform_data  = &innovator_smc91x_info,
 256        },
 257        .num_resources  = ARRAY_SIZE(innovator1610_smc91x_resources),
 258        .resource       = innovator1610_smc91x_resources,
 259};
 260
 261static struct platform_device innovator1610_lcd_device = {
 262        .name           = "inn1610_lcd",
 263        .id             = -1,
 264};
 265
 266static struct platform_device *innovator1610_devices[] __initdata = {
 267        &innovator_flash_device,
 268        &innovator1610_smc91x_device,
 269        &innovator_kp_device,
 270        &innovator1610_lcd_device,
 271};
 272
 273#endif /* CONFIG_ARCH_OMAP16XX */
 274
 275static void __init innovator_init_smc91x(void)
 276{
 277        if (cpu_is_omap1510()) {
 278                __raw_writeb(__raw_readb(OMAP1510_FPGA_RST) & ~1,
 279                           OMAP1510_FPGA_RST);
 280                udelay(750);
 281        } else {
 282                if (gpio_request(0, "SMC91x irq") < 0) {
 283                        printk("Error requesting gpio 0 for smc91x irq\n");
 284                        return;
 285                }
 286        }
 287}
 288
 289#ifdef CONFIG_ARCH_OMAP15XX
 290static struct omap_usb_config innovator1510_usb_config __initdata = {
 291        /* for bundled non-standard host and peripheral cables */
 292        .hmc_mode       = 4,
 293
 294        .register_host  = 1,
 295        .pins[1]        = 6,
 296        .pins[2]        = 6,            /* Conflicts with UART2 */
 297
 298        .register_dev   = 1,
 299        .pins[0]        = 2,
 300};
 301
 302static const struct omap_lcd_config innovator1510_lcd_config __initconst = {
 303        .ctrl_name      = "internal",
 304};
 305#endif
 306
 307#ifdef CONFIG_ARCH_OMAP16XX
 308static struct omap_usb_config h2_usb_config __initdata = {
 309        /* usb1 has a Mini-AB port and external isp1301 transceiver */
 310        .otg            = 2,
 311
 312#if IS_ENABLED(CONFIG_USB_OMAP)
 313        .hmc_mode       = 19,   /* 0:host(off) 1:dev|otg 2:disabled */
 314        /* .hmc_mode    = 21,*/ /* 0:host(off) 1:dev(loopback) 2:host(loopback) */
 315#elif   IS_ENABLED(CONFIG_USB_OHCI_HCD)
 316        /* NONSTANDARD CABLE NEEDED (B-to-Mini-B) */
 317        .hmc_mode       = 20,   /* 1:dev|otg(off) 1:host 2:disabled */
 318#endif
 319
 320        .pins[1]        = 3,
 321};
 322
 323static const struct omap_lcd_config innovator1610_lcd_config __initconst = {
 324        .ctrl_name      = "internal",
 325};
 326#endif
 327
 328#if IS_ENABLED(CONFIG_MMC_OMAP)
 329
 330static int mmc_set_power(struct device *dev, int slot, int power_on,
 331                                int vdd)
 332{
 333        if (power_on)
 334                __raw_writeb(__raw_readb(OMAP1510_FPGA_POWER) | (1 << 3),
 335                                OMAP1510_FPGA_POWER);
 336        else
 337                __raw_writeb(__raw_readb(OMAP1510_FPGA_POWER) & ~(1 << 3),
 338                                OMAP1510_FPGA_POWER);
 339
 340        return 0;
 341}
 342
 343/*
 344 * Innovator could use the following functions tested:
 345 * - mmc_get_wp that uses OMAP_MPUIO(3)
 346 * - mmc_get_cover_state that uses FPGA F4 UIO43
 347 */
 348static struct omap_mmc_platform_data mmc1_data = {
 349        .nr_slots                       = 1,
 350        .slots[0]       = {
 351                .set_power              = mmc_set_power,
 352                .wires                  = 4,
 353                .name                   = "mmcblk",
 354        },
 355};
 356
 357static struct omap_mmc_platform_data *mmc_data[OMAP16XX_NR_MMC];
 358
 359static void __init innovator_mmc_init(void)
 360{
 361        mmc_data[0] = &mmc1_data;
 362        omap1_init_mmc(mmc_data, OMAP15XX_NR_MMC);
 363}
 364
 365#else
 366static inline void innovator_mmc_init(void)
 367{
 368}
 369#endif
 370
 371static void __init innovator_init(void)
 372{
 373        if (cpu_is_omap1510())
 374                omap1510_fpga_init_irq();
 375        innovator_init_smc91x();
 376
 377#ifdef CONFIG_ARCH_OMAP15XX
 378        if (cpu_is_omap1510()) {
 379                unsigned char reg;
 380
 381                /* mux pins for uarts */
 382                omap_cfg_reg(UART1_TX);
 383                omap_cfg_reg(UART1_RTS);
 384                omap_cfg_reg(UART2_TX);
 385                omap_cfg_reg(UART2_RTS);
 386                omap_cfg_reg(UART3_TX);
 387                omap_cfg_reg(UART3_RX);
 388
 389                reg = __raw_readb(OMAP1510_FPGA_POWER);
 390                reg |= OMAP1510_FPGA_PCR_COM1_EN;
 391                __raw_writeb(reg, OMAP1510_FPGA_POWER);
 392                udelay(10);
 393
 394                reg = __raw_readb(OMAP1510_FPGA_POWER);
 395                reg |= OMAP1510_FPGA_PCR_COM2_EN;
 396                __raw_writeb(reg, OMAP1510_FPGA_POWER);
 397                udelay(10);
 398
 399                platform_add_devices(innovator1510_devices, ARRAY_SIZE(innovator1510_devices));
 400                spi_register_board_info(innovator1510_boardinfo,
 401                                ARRAY_SIZE(innovator1510_boardinfo));
 402        }
 403#endif
 404#ifdef CONFIG_ARCH_OMAP16XX
 405        if (!cpu_is_omap1510()) {
 406                innovator1610_smc91x_resources[1].start = gpio_to_irq(0);
 407                innovator1610_smc91x_resources[1].end = gpio_to_irq(0);
 408                platform_add_devices(innovator1610_devices, ARRAY_SIZE(innovator1610_devices));
 409        }
 410#endif
 411
 412#ifdef CONFIG_ARCH_OMAP15XX
 413        if (cpu_is_omap1510()) {
 414                omap1_usb_init(&innovator1510_usb_config);
 415                omapfb_set_lcd_config(&innovator1510_lcd_config);
 416        }
 417#endif
 418#ifdef CONFIG_ARCH_OMAP16XX
 419        if (cpu_is_omap1610()) {
 420                omap1_usb_init(&h2_usb_config);
 421                omapfb_set_lcd_config(&innovator1610_lcd_config);
 422        }
 423#endif
 424        omap_serial_init();
 425        omap_register_i2c_bus(1, 100, NULL, 0);
 426        innovator_mmc_init();
 427}
 428
 429/*
 430 * REVISIT: Assume 15xx for now, we don't want to do revision check
 431 * until later on. The right way to fix this is to set up a different
 432 * machine_id for 16xx Innovator, or use device tree.
 433 */
 434static void __init innovator_map_io(void)
 435{
 436#ifdef CONFIG_ARCH_OMAP15XX
 437        omap15xx_map_io();
 438
 439        iotable_init(innovator1510_io_desc, ARRAY_SIZE(innovator1510_io_desc));
 440        udelay(10);     /* Delay needed for FPGA */
 441
 442        /* Dump the Innovator FPGA rev early - useful info for support. */
 443        pr_debug("Innovator FPGA Rev %d.%d Board Rev %d\n",
 444                        __raw_readb(OMAP1510_FPGA_REV_HIGH),
 445                        __raw_readb(OMAP1510_FPGA_REV_LOW),
 446                        __raw_readb(OMAP1510_FPGA_BOARD_REV));
 447#endif
 448}
 449
 450MACHINE_START(OMAP_INNOVATOR, "TI-Innovator")
 451        /* Maintainer: MontaVista Software, Inc. */
 452        .atag_offset    = 0x100,
 453        .map_io         = innovator_map_io,
 454        .init_early     = omap1_init_early,
 455        .init_irq       = omap1_init_irq,
 456        .handle_irq     = omap1_handle_irq,
 457        .init_machine   = innovator_init,
 458        .init_late      = omap1_init_late,
 459        .init_time      = omap1_timer_init,
 460        .restart        = omap1_restart,
 461MACHINE_END
 462