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