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 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/input.h> 26 27#include <asm/hardware.h> 28#include <asm/mach-types.h> 29#include <asm/mach/arch.h> 30#include <asm/mach/flash.h> 31#include <asm/mach/map.h> 32 33#include <asm/arch/mux.h> 34#include <asm/arch/fpga.h> 35#include <asm/arch/gpio.h> 36#include <asm/arch/tc.h> 37#include <asm/arch/usb.h> 38#include <asm/arch/keypad.h> 39#include <asm/arch/common.h> 40#include <asm/arch/mcbsp.h> 41#include <asm/arch/omap-alsa.h> 42 43static int innovator_keymap[] = { 44 KEY(0, 0, KEY_F1), 45 KEY(0, 3, KEY_DOWN), 46 KEY(1, 1, KEY_F2), 47 KEY(1, 2, KEY_RIGHT), 48 KEY(2, 0, KEY_F3), 49 KEY(2, 1, KEY_F4), 50 KEY(2, 2, KEY_UP), 51 KEY(3, 2, KEY_ENTER), 52 KEY(3, 3, KEY_LEFT), 53 0 54}; 55 56static struct mtd_partition innovator_partitions[] = { 57 /* bootloader (U-Boot, etc) in first sector */ 58 { 59 .name = "bootloader", 60 .offset = 0, 61 .size = SZ_128K, 62 .mask_flags = MTD_WRITEABLE, /* force read-only */ 63 }, 64 /* bootloader params in the next sector */ 65 { 66 .name = "params", 67 .offset = MTDPART_OFS_APPEND, 68 .size = SZ_128K, 69 .mask_flags = 0, 70 }, 71 /* kernel */ 72 { 73 .name = "kernel", 74 .offset = MTDPART_OFS_APPEND, 75 .size = SZ_2M, 76 .mask_flags = 0 77 }, 78 /* rest of flash1 is a file system */ 79 { 80 .name = "rootfs", 81 .offset = MTDPART_OFS_APPEND, 82 .size = SZ_16M - SZ_2M - 2 * SZ_128K, 83 .mask_flags = 0 84 }, 85 /* file system */ 86 { 87 .name = "filesystem", 88 .offset = MTDPART_OFS_APPEND, 89 .size = MTDPART_SIZ_FULL, 90 .mask_flags = 0 91 } 92}; 93 94static struct flash_platform_data innovator_flash_data = { 95 .map_name = "cfi_probe", 96 .width = 2, 97 .parts = innovator_partitions, 98 .nr_parts = ARRAY_SIZE(innovator_partitions), 99}; 100 101static struct resource innovator_flash_resource = { 102 .start = OMAP_CS0_PHYS, 103 .end = OMAP_CS0_PHYS + SZ_32M - 1, 104 .flags = IORESOURCE_MEM, 105}; 106 107static struct platform_device innovator_flash_device = { 108 .name = "omapflash", 109 .id = 0, 110 .dev = { 111 .platform_data = &innovator_flash_data, 112 }, 113 .num_resources = 1, 114 .resource = &innovator_flash_resource, 115}; 116 117#define DEFAULT_BITPERSAMPLE 16 118 119static struct omap_mcbsp_reg_cfg mcbsp_regs = { 120 .spcr2 = FREE | FRST | GRST | XRST | XINTM(3), 121 .spcr1 = RINTM(3) | RRST, 122 .rcr2 = RPHASE | RFRLEN2(OMAP_MCBSP_WORD_8) | 123 RWDLEN2(OMAP_MCBSP_WORD_16) | RDATDLY(0), 124 .rcr1 = RFRLEN1(OMAP_MCBSP_WORD_8) | RWDLEN1(OMAP_MCBSP_WORD_16), 125 .xcr2 = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) | 126 XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(0) | XFIG, 127 .xcr1 = XFRLEN1(OMAP_MCBSP_WORD_8) | XWDLEN1(OMAP_MCBSP_WORD_16), 128 .srgr1 = FWID(DEFAULT_BITPERSAMPLE - 1), 129 .srgr2 = GSYNC | CLKSP | FSGM | FPER(DEFAULT_BITPERSAMPLE * 2 - 1), 130 /*.pcr0 = FSXM | FSRM | CLKXM | CLKRM | CLKXP | CLKRP,*/ /* mcbsp: master */ 131 .pcr0 = CLKXP | CLKRP, /* mcbsp: slave */ 132}; 133 134static struct omap_alsa_codec_config alsa_config = { 135 .name = "OMAP Innovator AIC23", 136 .mcbsp_regs_alsa = &mcbsp_regs, 137 .codec_configure_dev = NULL, // aic23_configure, 138 .codec_set_samplerate = NULL, // aic23_set_samplerate, 139 .codec_clock_setup = NULL, // aic23_clock_setup, 140 .codec_clock_on = NULL, // aic23_clock_on, 141 .codec_clock_off = NULL, // aic23_clock_off, 142 .get_default_samplerate = NULL, // aic23_get_default_samplerate, 143}; 144 145static struct platform_device innovator_mcbsp1_device = { 146 .name = "omap_alsa_mcbsp", 147 .id = 1, 148 .dev = { 149 .platform_data = &alsa_config, 150 }, 151}; 152 153static struct resource innovator_kp_resources[] = { 154 [0] = { 155 .start = INT_KEYBOARD, 156 .end = INT_KEYBOARD, 157 .flags = IORESOURCE_IRQ, 158 }, 159}; 160 161static struct omap_kp_platform_data innovator_kp_data = { 162 .rows = 8, 163 .cols = 8, 164 .keymap = innovator_keymap, 165 .keymapsize = ARRAY_SIZE(innovator_keymap), 166 .delay = 4, 167}; 168 169static struct platform_device innovator_kp_device = { 170 .name = "omap-keypad", 171 .id = -1, 172 .dev = { 173 .platform_data = &innovator_kp_data, 174 }, 175 .num_resources = ARRAY_SIZE(innovator_kp_resources), 176 .resource = innovator_kp_resources, 177}; 178 179 180#ifdef CONFIG_ARCH_OMAP15XX 181 182#include <linux/spi/spi.h> 183#include <linux/spi/ads7846.h> 184 185 186/* Only FPGA needs to be mapped here. All others are done with ioremap */ 187static struct map_desc innovator1510_io_desc[] __initdata = { 188 { 189 .virtual = OMAP1510_FPGA_BASE, 190 .pfn = __phys_to_pfn(OMAP1510_FPGA_START), 191 .length = OMAP1510_FPGA_SIZE, 192 .type = MT_DEVICE 193 } 194}; 195 196static struct resource innovator1510_smc91x_resources[] = { 197 [0] = { 198 .start = OMAP1510_FPGA_ETHR_START, /* Physical */ 199 .end = OMAP1510_FPGA_ETHR_START + 0xf, 200 .flags = IORESOURCE_MEM, 201 }, 202 [1] = { 203 .start = OMAP1510_INT_ETHER, 204 .end = OMAP1510_INT_ETHER, 205 .flags = IORESOURCE_IRQ, 206 }, 207}; 208 209static struct platform_device innovator1510_smc91x_device = { 210 .name = "smc91x", 211 .id = 0, 212 .num_resources = ARRAY_SIZE(innovator1510_smc91x_resources), 213 .resource = innovator1510_smc91x_resources, 214}; 215 216static struct platform_device innovator1510_lcd_device = { 217 .name = "lcd_inn1510", 218 .id = -1, 219}; 220 221static struct platform_device innovator1510_spi_device = { 222 .name = "spi_inn1510", 223 .id = -1, 224}; 225 226static struct platform_device *innovator1510_devices[] __initdata = { 227 &innovator_flash_device, 228 &innovator1510_smc91x_device, 229 &innovator_mcbsp1_device, 230 &innovator_kp_device, 231 &innovator1510_lcd_device, 232 &innovator1510_spi_device, 233}; 234 235static int innovator_get_pendown_state(void) 236{ 237 return !(fpga_read(OMAP1510_FPGA_TOUCHSCREEN) & (1 << 5)); 238} 239 240static const struct ads7846_platform_data innovator1510_ts_info = { 241 .model = 7846, 242 .vref_delay_usecs = 100, /* internal, no capacitor */ 243 .x_plate_ohms = 419, 244 .y_plate_ohms = 486, 245 .get_pendown_state = innovator_get_pendown_state, 246}; 247 248static struct spi_board_info __initdata innovator1510_boardinfo[] = { { 249 /* FPGA (bus "10") CS0 has an ads7846e */ 250 .modalias = "ads7846", 251 .platform_data = &innovator1510_ts_info, 252 .irq = OMAP1510_INT_FPGA_TS, 253 .max_speed_hz = 120000 /* max sample rate at 3V */ 254 * 26 /* command + data + overhead */, 255 .bus_num = 10, 256 .chip_select = 0, 257} }; 258 259#endif /* CONFIG_ARCH_OMAP15XX */ 260 261#ifdef CONFIG_ARCH_OMAP16XX 262 263static struct resource innovator1610_smc91x_resources[] = { 264 [0] = { 265 .start = INNOVATOR1610_ETHR_START, /* Physical */ 266 .end = INNOVATOR1610_ETHR_START + 0xf, 267 .flags = IORESOURCE_MEM, 268 }, 269 [1] = { 270 .start = OMAP_GPIO_IRQ(0), 271 .end = OMAP_GPIO_IRQ(0), 272 .flags = IORESOURCE_IRQ, 273 }, 274}; 275 276static struct platform_device innovator1610_smc91x_device = { 277 .name = "smc91x", 278 .id = 0, 279 .num_resources = ARRAY_SIZE(innovator1610_smc91x_resources), 280 .resource = innovator1610_smc91x_resources, 281}; 282 283static struct platform_device innovator1610_lcd_device = { 284 .name = "inn1610_lcd", 285 .id = -1, 286}; 287 288static struct platform_device *innovator1610_devices[] __initdata = { 289 &innovator_flash_device, 290 &innovator1610_smc91x_device, 291 &innovator_kp_device, 292 &innovator1610_lcd_device, 293}; 294 295#endif /* CONFIG_ARCH_OMAP16XX */ 296 297static void __init innovator_init_smc91x(void) 298{ 299 if (cpu_is_omap1510()) { 300 fpga_write(fpga_read(OMAP1510_FPGA_RST) & ~1, 301 OMAP1510_FPGA_RST); 302 udelay(750); 303 } else { 304 if ((omap_request_gpio(0)) < 0) { 305 printk("Error requesting gpio 0 for smc91x irq\n"); 306 return; 307 } 308 } 309} 310 311static void __init innovator_init_irq(void) 312{ 313 omap1_init_common_hw(); 314 omap_init_irq(); 315 omap_gpio_init(); 316#ifdef CONFIG_ARCH_OMAP15XX 317 if (cpu_is_omap1510()) { 318 omap1510_fpga_init_irq(); 319 } 320#endif 321 innovator_init_smc91x(); 322} 323 324#ifdef CONFIG_ARCH_OMAP15XX 325static struct omap_usb_config innovator1510_usb_config __initdata = { 326 /* for bundled non-standard host and peripheral cables */ 327 .hmc_mode = 4, 328 329 .register_host = 1, 330 .pins[1] = 6, 331 .pins[2] = 6, /* Conflicts with UART2 */ 332 333 .register_dev = 1, 334 .pins[0] = 2, 335}; 336 337static struct omap_lcd_config innovator1510_lcd_config __initdata = { 338 .ctrl_name = "internal", 339}; 340#endif 341 342#ifdef CONFIG_ARCH_OMAP16XX 343static struct omap_usb_config h2_usb_config __initdata = { 344 /* usb1 has a Mini-AB port and external isp1301 transceiver */ 345 .otg = 2, 346 347#ifdef CONFIG_USB_GADGET_OMAP 348 .hmc_mode = 19, // 0:host(off) 1:dev|otg 2:disabled 349 // .hmc_mode = 21, // 0:host(off) 1:dev(loopback) 2:host(loopback) 350#elif defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) 351 /* NONSTANDARD CABLE NEEDED (B-to-Mini-B) */ 352 .hmc_mode = 20, // 1:dev|otg(off) 1:host 2:disabled 353#endif 354 355 .pins[1] = 3, 356}; 357 358static struct omap_lcd_config innovator1610_lcd_config __initdata = { 359 .ctrl_name = "internal", 360}; 361#endif 362 363static struct omap_mmc_config innovator_mmc_config __initdata = { 364 .mmc [0] = { 365 .enabled = 1, 366 .wire4 = 1, 367 .wp_pin = OMAP_MPUIO(3), 368 .power_pin = -1, /* FPGA F3 UIO42 */ 369 .switch_pin = -1, /* FPGA F4 UIO43 */ 370 }, 371}; 372 373static struct omap_uart_config innovator_uart_config __initdata = { 374 .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), 375}; 376 377static struct omap_board_config_kernel innovator_config[] = { 378 { OMAP_TAG_USB, NULL }, 379 { OMAP_TAG_LCD, NULL }, 380 { OMAP_TAG_MMC, &innovator_mmc_config }, 381 { OMAP_TAG_UART, &innovator_uart_config }, 382}; 383 384static void __init innovator_init(void) 385{ 386#ifdef CONFIG_ARCH_OMAP15XX 387 if (cpu_is_omap1510()) { 388 platform_add_devices(innovator1510_devices, ARRAY_SIZE(innovator1510_devices)); 389 spi_register_board_info(innovator1510_boardinfo, 390 ARRAY_SIZE(innovator1510_boardinfo)); 391 } 392#endif 393#ifdef CONFIG_ARCH_OMAP16XX 394 if (!cpu_is_omap1510()) { 395 platform_add_devices(innovator1610_devices, ARRAY_SIZE(innovator1610_devices)); 396 } 397#endif 398 399#ifdef CONFIG_ARCH_OMAP15XX 400 if (cpu_is_omap1510()) { 401 innovator_config[0].data = &innovator1510_usb_config; 402 innovator_config[1].data = &innovator1510_lcd_config; 403 } 404#endif 405#ifdef CONFIG_ARCH_OMAP16XX 406 if (cpu_is_omap1610()) { 407 innovator_config[0].data = &h2_usb_config; 408 innovator_config[1].data = &innovator1610_lcd_config; 409 } 410#endif 411 omap_board_config = innovator_config; 412 omap_board_config_size = ARRAY_SIZE(innovator_config); 413 omap_serial_init(); 414} 415 416static void __init innovator_map_io(void) 417{ 418 omap1_map_common_io(); 419 420#ifdef CONFIG_ARCH_OMAP15XX 421 if (cpu_is_omap1510()) { 422 iotable_init(innovator1510_io_desc, ARRAY_SIZE(innovator1510_io_desc)); 423 udelay(10); /* Delay needed for FPGA */ 424 425 /* Dump the Innovator FPGA rev early - useful info for support. */ 426 printk("Innovator FPGA Rev %d.%d Board Rev %d\n", 427 fpga_read(OMAP1510_FPGA_REV_HIGH), 428 fpga_read(OMAP1510_FPGA_REV_LOW), 429 fpga_read(OMAP1510_FPGA_BOARD_REV)); 430 } 431#endif 432} 433 434MACHINE_START(OMAP_INNOVATOR, "TI-Innovator") 435 /* Maintainer: MontaVista Software, Inc. */ 436 .phys_io = 0xfff00000, 437 .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, 438 .boot_params = 0x10000100, 439 .map_io = innovator_map_io, 440 .init_irq = innovator_init_irq, 441 .init_machine = innovator_init, 442 .timer = &omap_timer, 443MACHINE_END 444