1/* 2 * linux/arch/arm/mach-omap2/board-omap3touchbook.c 3 * 4 * Copyright (C) 2009 Always Innovating 5 * 6 * Modified from mach-omap2/board-omap3beagleboard.c 7 * 8 * Initial code: Grégoire Gentil, Tim Yamin 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 as 12 * published by the Free Software Foundation. 13 */ 14 15#include <linux/kernel.h> 16#include <linux/init.h> 17#include <linux/platform_device.h> 18#include <linux/delay.h> 19#include <linux/err.h> 20#include <linux/clk.h> 21#include <linux/io.h> 22#include <linux/leds.h> 23#include <linux/gpio.h> 24#include <linux/input.h> 25#include <linux/gpio_keys.h> 26 27#include <linux/mtd/mtd.h> 28#include <linux/mtd/partitions.h> 29#include <linux/mtd/nand.h> 30#include <linux/mmc/host.h> 31 32#include <plat/mcspi.h> 33#include <linux/spi/spi.h> 34 35#include <linux/spi/ads7846.h> 36 37#include <linux/regulator/machine.h> 38#include <linux/i2c/twl.h> 39 40#include <mach/hardware.h> 41#include <asm/mach-types.h> 42#include <asm/mach/arch.h> 43#include <asm/mach/map.h> 44#include <asm/mach/flash.h> 45#include <asm/system_info.h> 46 47#include <plat/board.h> 48#include "common.h" 49#include <plat/gpmc.h> 50#include <plat/nand.h> 51#include <plat/usb.h> 52 53#include "mux.h" 54#include "hsmmc.h" 55#include "common-board-devices.h" 56 57#include <asm/setup.h> 58 59#define OMAP3_AC_GPIO 136 60#define OMAP3_TS_GPIO 162 61#define TB_BL_PWM_TIMER 9 62#define TB_KILL_POWER_GPIO 168 63 64static unsigned long touchbook_revision; 65 66static struct mtd_partition omap3touchbook_nand_partitions[] = { 67 /* All the partition sizes are listed in terms of NAND block size */ 68 { 69 .name = "X-Loader", 70 .offset = 0, 71 .size = 4 * NAND_BLOCK_SIZE, 72 .mask_flags = MTD_WRITEABLE, /* force read-only */ 73 }, 74 { 75 .name = "U-Boot", 76 .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */ 77 .size = 15 * NAND_BLOCK_SIZE, 78 .mask_flags = MTD_WRITEABLE, /* force read-only */ 79 }, 80 { 81 .name = "U-Boot Env", 82 .offset = MTDPART_OFS_APPEND, /* Offset = 0x260000 */ 83 .size = 1 * NAND_BLOCK_SIZE, 84 }, 85 { 86 .name = "Kernel", 87 .offset = MTDPART_OFS_APPEND, /* Offset = 0x280000 */ 88 .size = 32 * NAND_BLOCK_SIZE, 89 }, 90 { 91 .name = "File System", 92 .offset = MTDPART_OFS_APPEND, /* Offset = 0x680000 */ 93 .size = MTDPART_SIZ_FULL, 94 }, 95}; 96 97#include "sdram-micron-mt46h32m32lf-6.h" 98 99static struct omap2_hsmmc_info mmc[] = { 100 { 101 .mmc = 1, 102 .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, 103 .gpio_wp = 29, 104 .deferred = true, 105 }, 106 {} /* Terminator */ 107}; 108 109static struct regulator_consumer_supply touchbook_vmmc1_supply[] = { 110 REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"), 111}; 112 113static struct regulator_consumer_supply touchbook_vsim_supply[] = { 114 REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.0"), 115}; 116 117static struct gpio_led gpio_leds[]; 118 119static int touchbook_twl_gpio_setup(struct device *dev, 120 unsigned gpio, unsigned ngpio) 121{ 122 /* gpio + 0 is "mmc0_cd" (input/IRQ) */ 123 mmc[0].gpio_cd = gpio + 0; 124 omap_hsmmc_late_init(mmc); 125 126 /* REVISIT: need ehci-omap hooks for external VBUS 127 * power switch and overcurrent detect 128 */ 129 gpio_request_one(gpio + 1, GPIOF_IN, "EHCI_nOC"); 130 131 /* TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, active low) */ 132 gpio_request_one(gpio + TWL4030_GPIO_MAX, GPIOF_OUT_INIT_LOW, 133 "nEN_USB_PWR"); 134 135 /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */ 136 gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1; 137 138 return 0; 139} 140 141static struct twl4030_gpio_platform_data touchbook_gpio_data = { 142 .gpio_base = OMAP_MAX_GPIO_LINES, 143 .irq_base = TWL4030_GPIO_IRQ_BASE, 144 .irq_end = TWL4030_GPIO_IRQ_END, 145 .use_leds = true, 146 .pullups = BIT(1), 147 .pulldowns = BIT(2) | BIT(6) | BIT(7) | BIT(8) | BIT(13) 148 | BIT(15) | BIT(16) | BIT(17), 149 .setup = touchbook_twl_gpio_setup, 150}; 151 152static struct regulator_consumer_supply touchbook_vdac_supply[] = { 153{ 154 .supply = "vdac", 155}, 156}; 157 158static struct regulator_consumer_supply touchbook_vdvi_supply[] = { 159{ 160 .supply = "vdvi", 161}, 162}; 163 164/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */ 165static struct regulator_init_data touchbook_vmmc1 = { 166 .constraints = { 167 .min_uV = 1850000, 168 .max_uV = 3150000, 169 .valid_modes_mask = REGULATOR_MODE_NORMAL 170 | REGULATOR_MODE_STANDBY, 171 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE 172 | REGULATOR_CHANGE_MODE 173 | REGULATOR_CHANGE_STATUS, 174 }, 175 .num_consumer_supplies = ARRAY_SIZE(touchbook_vmmc1_supply), 176 .consumer_supplies = touchbook_vmmc1_supply, 177}; 178 179/* VSIM for MMC1 pins DAT4..DAT7 (2 mA, plus card == max 50 mA) */ 180static struct regulator_init_data touchbook_vsim = { 181 .constraints = { 182 .min_uV = 1800000, 183 .max_uV = 3000000, 184 .valid_modes_mask = REGULATOR_MODE_NORMAL 185 | REGULATOR_MODE_STANDBY, 186 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE 187 | REGULATOR_CHANGE_MODE 188 | REGULATOR_CHANGE_STATUS, 189 }, 190 .num_consumer_supplies = ARRAY_SIZE(touchbook_vsim_supply), 191 .consumer_supplies = touchbook_vsim_supply, 192}; 193 194static struct twl4030_platform_data touchbook_twldata = { 195 /* platform_data for children goes here */ 196 .gpio = &touchbook_gpio_data, 197 .vmmc1 = &touchbook_vmmc1, 198 .vsim = &touchbook_vsim, 199}; 200 201static struct i2c_board_info __initdata touchBook_i2c_boardinfo[] = { 202 { 203 I2C_BOARD_INFO("bq27200", 0x55), 204 }, 205}; 206 207static int __init omap3_touchbook_i2c_init(void) 208{ 209 /* Standard TouchBook bus */ 210 omap3_pmic_get_config(&touchbook_twldata, 211 TWL_COMMON_PDATA_USB | TWL_COMMON_PDATA_AUDIO, 212 TWL_COMMON_REGULATOR_VDAC | TWL_COMMON_REGULATOR_VPLL2); 213 214 touchbook_twldata.vdac->num_consumer_supplies = 215 ARRAY_SIZE(touchbook_vdac_supply); 216 touchbook_twldata.vdac->consumer_supplies = touchbook_vdac_supply; 217 218 touchbook_twldata.vpll2->constraints.name = "VDVI"; 219 touchbook_twldata.vpll2->num_consumer_supplies = 220 ARRAY_SIZE(touchbook_vdvi_supply); 221 touchbook_twldata.vpll2->consumer_supplies = touchbook_vdvi_supply; 222 223 omap3_pmic_init("twl4030", &touchbook_twldata); 224 /* Additional TouchBook bus */ 225 omap_register_i2c_bus(3, 100, touchBook_i2c_boardinfo, 226 ARRAY_SIZE(touchBook_i2c_boardinfo)); 227 228 return 0; 229} 230 231static struct ads7846_platform_data ads7846_pdata = { 232 .x_min = 100, 233 .y_min = 265, 234 .x_max = 3950, 235 .y_max = 3750, 236 .x_plate_ohms = 40, 237 .pressure_max = 255, 238 .debounce_max = 10, 239 .debounce_tol = 5, 240 .debounce_rep = 1, 241 .gpio_pendown = OMAP3_TS_GPIO, 242 .keep_vref_on = 1, 243}; 244 245static struct gpio_led gpio_leds[] = { 246 { 247 .name = "touchbook::usr0", 248 .default_trigger = "heartbeat", 249 .gpio = 150, 250 }, 251 { 252 .name = "touchbook::usr1", 253 .default_trigger = "mmc0", 254 .gpio = 149, 255 }, 256 { 257 .name = "touchbook::pmu_stat", 258 .gpio = -EINVAL, /* gets replaced */ 259 .active_low = true, 260 }, 261}; 262 263static struct gpio_led_platform_data gpio_led_info = { 264 .leds = gpio_leds, 265 .num_leds = ARRAY_SIZE(gpio_leds), 266}; 267 268static struct platform_device leds_gpio = { 269 .name = "leds-gpio", 270 .id = -1, 271 .dev = { 272 .platform_data = &gpio_led_info, 273 }, 274}; 275 276static struct gpio_keys_button gpio_buttons[] = { 277 { 278 .code = BTN_EXTRA, 279 .gpio = 7, 280 .desc = "user", 281 .wakeup = 1, 282 }, 283 { 284 .code = KEY_POWER, 285 .gpio = 183, 286 .desc = "power", 287 .wakeup = 1, 288 }, 289}; 290 291static struct gpio_keys_platform_data gpio_key_info = { 292 .buttons = gpio_buttons, 293 .nbuttons = ARRAY_SIZE(gpio_buttons), 294}; 295 296static struct platform_device keys_gpio = { 297 .name = "gpio-keys", 298 .id = -1, 299 .dev = { 300 .platform_data = &gpio_key_info, 301 }, 302}; 303 304#ifdef CONFIG_OMAP_MUX 305static struct omap_board_mux board_mux[] __initdata = { 306 { .reg_offset = OMAP_MUX_TERMINATOR }, 307}; 308#endif 309 310static struct platform_device *omap3_touchbook_devices[] __initdata = { 311 &leds_gpio, 312 &keys_gpio, 313}; 314 315static const struct usbhs_omap_board_data usbhs_bdata __initconst = { 316 317 .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, 318 .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, 319 .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, 320 321 .phy_reset = true, 322 .reset_gpio_port[0] = -EINVAL, 323 .reset_gpio_port[1] = 147, 324 .reset_gpio_port[2] = -EINVAL 325}; 326 327static void omap3_touchbook_poweroff(void) 328{ 329 int pwr_off = TB_KILL_POWER_GPIO; 330 331 if (gpio_request_one(pwr_off, GPIOF_OUT_INIT_LOW, "DVI reset") < 0) 332 printk(KERN_ERR "Unable to get kill power GPIO\n"); 333} 334 335static int __init early_touchbook_revision(char *p) 336{ 337 if (!p) 338 return 0; 339 340 return strict_strtoul(p, 10, &touchbook_revision); 341} 342early_param("tbr", early_touchbook_revision); 343 344static void __init omap3_touchbook_init(void) 345{ 346 omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); 347 348 pm_power_off = omap3_touchbook_poweroff; 349 350 if (system_rev >= 0x20 && system_rev <= 0x34301000) { 351 omap_mux_init_gpio(23, OMAP_PIN_INPUT); 352 mmc[0].gpio_wp = 23; 353 } else { 354 omap_mux_init_gpio(29, OMAP_PIN_INPUT); 355 } 356 omap_hsmmc_init(mmc); 357 358 omap3_touchbook_i2c_init(); 359 platform_add_devices(omap3_touchbook_devices, 360 ARRAY_SIZE(omap3_touchbook_devices)); 361 omap_serial_init(); 362 omap_sdrc_init(mt46h32m32lf6_sdrc_params, 363 mt46h32m32lf6_sdrc_params); 364 365 omap_mux_init_gpio(170, OMAP_PIN_INPUT); 366 /* REVISIT leave DVI powered down until it's needed ... */ 367 gpio_request_one(176, GPIOF_OUT_INIT_HIGH, "DVI_nPD"); 368 369 /* Touchscreen and accelerometer */ 370 omap_ads7846_init(4, OMAP3_TS_GPIO, 310, &ads7846_pdata); 371 usb_musb_init(NULL); 372 usbhs_init(&usbhs_bdata); 373 omap_nand_flash_init(NAND_BUSWIDTH_16, omap3touchbook_nand_partitions, 374 ARRAY_SIZE(omap3touchbook_nand_partitions)); 375 376 /* Ensure SDRC pins are mux'd for self-refresh */ 377 omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT); 378 omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT); 379} 380 381MACHINE_START(TOUCHBOOK, "OMAP3 touchbook Board") 382 /* Maintainer: Gregoire Gentil - http://www.alwaysinnovating.com */ 383 .atag_offset = 0x100, 384 .reserve = omap_reserve, 385 .map_io = omap3_map_io, 386 .init_early = omap3430_init_early, 387 .init_irq = omap3_init_irq, 388 .handle_irq = omap3_intc_handle_irq, 389 .init_machine = omap3_touchbook_init, 390 .timer = &omap3_secure_timer, 391 .restart = omap_prcm_restart, 392MACHINE_END 393