1/* 2 * linux/arch/arm/mach-omap1/board-ams-delta.c 3 * 4 * Modified from board-generic.c 5 * 6 * Board specific inits for the Amstrad E3 (codename Delta) videophone 7 * 8 * Copyright (C) 2006 Jonathan McDowell <noodles@earth.li> 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#include <linux/basic_mmio_gpio.h> 15#include <linux/gpio.h> 16#include <linux/kernel.h> 17#include <linux/init.h> 18#include <linux/input.h> 19#include <linux/interrupt.h> 20#include <linux/leds.h> 21#include <linux/platform_device.h> 22#include <linux/regulator/consumer.h> 23#include <linux/regulator/fixed.h> 24#include <linux/regulator/machine.h> 25#include <linux/serial_8250.h> 26#include <linux/export.h> 27#include <linux/omapfb.h> 28#include <linux/io.h> 29#include <linux/platform_data/gpio-omap.h> 30 31#include <media/soc_camera.h> 32 33#include <asm/serial.h> 34#include <asm/mach-types.h> 35#include <asm/mach/arch.h> 36#include <asm/mach/map.h> 37 38#include <mach/board-ams-delta.h> 39#include <linux/platform_data/keypad-omap.h> 40#include <mach/mux.h> 41 42#include <mach/hardware.h> 43#include <mach/ams-delta-fiq.h> 44#include <mach/camera.h> 45#include <mach/usb.h> 46 47#include "iomap.h" 48#include "common.h" 49 50static const unsigned int ams_delta_keymap[] = { 51 KEY(0, 0, KEY_F1), /* Advert */ 52 53 KEY(0, 3, KEY_COFFEE), /* Games */ 54 KEY(0, 2, KEY_QUESTION), /* Directory */ 55 KEY(2, 3, KEY_CONNECT), /* Internet */ 56 KEY(1, 2, KEY_SHOP), /* Services */ 57 KEY(1, 1, KEY_PHONE), /* VoiceMail */ 58 59 KEY(0, 1, KEY_DELETE), /* Delete */ 60 KEY(2, 2, KEY_PLAY), /* Play */ 61 KEY(1, 0, KEY_PAGEUP), /* Up */ 62 KEY(1, 3, KEY_PAGEDOWN), /* Down */ 63 KEY(2, 0, KEY_EMAIL), /* ReadEmail */ 64 KEY(2, 1, KEY_STOP), /* Stop */ 65 66 /* Numeric keypad portion */ 67 KEY(0, 7, KEY_KP1), 68 KEY(0, 6, KEY_KP2), 69 KEY(0, 5, KEY_KP3), 70 KEY(1, 7, KEY_KP4), 71 KEY(1, 6, KEY_KP5), 72 KEY(1, 5, KEY_KP6), 73 KEY(2, 7, KEY_KP7), 74 KEY(2, 6, KEY_KP8), 75 KEY(2, 5, KEY_KP9), 76 KEY(3, 6, KEY_KP0), 77 KEY(3, 7, KEY_KPASTERISK), 78 KEY(3, 5, KEY_KPDOT), /* # key */ 79 KEY(7, 2, KEY_NUMLOCK), /* Mute */ 80 KEY(7, 1, KEY_KPMINUS), /* Recall */ 81 KEY(6, 1, KEY_KPPLUS), /* Redial */ 82 KEY(7, 6, KEY_KPSLASH), /* Handsfree */ 83 KEY(6, 0, KEY_ENTER), /* Video */ 84 85 KEY(7, 4, KEY_CAMERA), /* Photo */ 86 87 KEY(0, 4, KEY_F2), /* Home */ 88 KEY(1, 4, KEY_F3), /* Office */ 89 KEY(2, 4, KEY_F4), /* Mobile */ 90 KEY(7, 7, KEY_F5), /* SMS */ 91 KEY(7, 5, KEY_F6), /* Email */ 92 93 /* QWERTY portion of keypad */ 94 KEY(3, 4, KEY_Q), 95 KEY(3, 3, KEY_W), 96 KEY(3, 2, KEY_E), 97 KEY(3, 1, KEY_R), 98 KEY(3, 0, KEY_T), 99 KEY(4, 7, KEY_Y), 100 KEY(4, 6, KEY_U), 101 KEY(4, 5, KEY_I), 102 KEY(4, 4, KEY_O), 103 KEY(4, 3, KEY_P), 104 105 KEY(4, 2, KEY_A), 106 KEY(4, 1, KEY_S), 107 KEY(4, 0, KEY_D), 108 KEY(5, 7, KEY_F), 109 KEY(5, 6, KEY_G), 110 KEY(5, 5, KEY_H), 111 KEY(5, 4, KEY_J), 112 KEY(5, 3, KEY_K), 113 KEY(5, 2, KEY_L), 114 115 KEY(5, 1, KEY_Z), 116 KEY(5, 0, KEY_X), 117 KEY(6, 7, KEY_C), 118 KEY(6, 6, KEY_V), 119 KEY(6, 5, KEY_B), 120 KEY(6, 4, KEY_N), 121 KEY(6, 3, KEY_M), 122 KEY(6, 2, KEY_SPACE), 123 124 KEY(7, 0, KEY_LEFTSHIFT), /* Vol up */ 125 KEY(7, 3, KEY_LEFTCTRL), /* Vol down */ 126}; 127 128#define LATCH1_PHYS 0x01000000 129#define LATCH1_VIRT 0xEA000000 130#define MODEM_PHYS 0x04000000 131#define MODEM_VIRT 0xEB000000 132#define LATCH2_PHYS 0x08000000 133#define LATCH2_VIRT 0xEC000000 134 135static struct map_desc ams_delta_io_desc[] __initdata = { 136 /* AMS_DELTA_LATCH1 */ 137 { 138 .virtual = LATCH1_VIRT, 139 .pfn = __phys_to_pfn(LATCH1_PHYS), 140 .length = 0x01000000, 141 .type = MT_DEVICE 142 }, 143 /* AMS_DELTA_LATCH2 */ 144 { 145 .virtual = LATCH2_VIRT, 146 .pfn = __phys_to_pfn(LATCH2_PHYS), 147 .length = 0x01000000, 148 .type = MT_DEVICE 149 }, 150 /* AMS_DELTA_MODEM */ 151 { 152 .virtual = MODEM_VIRT, 153 .pfn = __phys_to_pfn(MODEM_PHYS), 154 .length = 0x01000000, 155 .type = MT_DEVICE 156 } 157}; 158 159static struct omap_lcd_config ams_delta_lcd_config __initdata = { 160 .ctrl_name = "internal", 161}; 162 163static struct omap_usb_config ams_delta_usb_config __initdata = { 164 .register_host = 1, 165 .hmc_mode = 16, 166 .pins[0] = 2, 167}; 168 169#define LATCH1_GPIO_BASE 232 170#define LATCH1_NGPIO 8 171 172static struct resource latch1_resources[] = { 173 [0] = { 174 .name = "dat", 175 .start = LATCH1_PHYS, 176 .end = LATCH1_PHYS + (LATCH1_NGPIO - 1) / 8, 177 .flags = IORESOURCE_MEM, 178 }, 179}; 180 181static struct bgpio_pdata latch1_pdata = { 182 .base = LATCH1_GPIO_BASE, 183 .ngpio = LATCH1_NGPIO, 184}; 185 186static struct platform_device latch1_gpio_device = { 187 .name = "basic-mmio-gpio", 188 .id = 0, 189 .resource = latch1_resources, 190 .num_resources = ARRAY_SIZE(latch1_resources), 191 .dev = { 192 .platform_data = &latch1_pdata, 193 }, 194}; 195 196static struct resource latch2_resources[] = { 197 [0] = { 198 .name = "dat", 199 .start = LATCH2_PHYS, 200 .end = LATCH2_PHYS + (AMS_DELTA_LATCH2_NGPIO - 1) / 8, 201 .flags = IORESOURCE_MEM, 202 }, 203}; 204 205static struct bgpio_pdata latch2_pdata = { 206 .base = AMS_DELTA_LATCH2_GPIO_BASE, 207 .ngpio = AMS_DELTA_LATCH2_NGPIO, 208}; 209 210static struct platform_device latch2_gpio_device = { 211 .name = "basic-mmio-gpio", 212 .id = 1, 213 .resource = latch2_resources, 214 .num_resources = ARRAY_SIZE(latch2_resources), 215 .dev = { 216 .platform_data = &latch2_pdata, 217 }, 218}; 219 220static const struct gpio latch_gpios[] __initconst = { 221 { 222 .gpio = LATCH1_GPIO_BASE + 6, 223 .flags = GPIOF_OUT_INIT_LOW, 224 .label = "dockit1", 225 }, 226 { 227 .gpio = LATCH1_GPIO_BASE + 7, 228 .flags = GPIOF_OUT_INIT_LOW, 229 .label = "dockit2", 230 }, 231 { 232 .gpio = AMS_DELTA_GPIO_PIN_SCARD_RSTIN, 233 .flags = GPIOF_OUT_INIT_LOW, 234 .label = "scard_rstin", 235 }, 236 { 237 .gpio = AMS_DELTA_GPIO_PIN_SCARD_CMDVCC, 238 .flags = GPIOF_OUT_INIT_LOW, 239 .label = "scard_cmdvcc", 240 }, 241 { 242 .gpio = AMS_DELTA_GPIO_PIN_MODEM_CODEC, 243 .flags = GPIOF_OUT_INIT_LOW, 244 .label = "modem_codec", 245 }, 246 { 247 .gpio = AMS_DELTA_LATCH2_GPIO_BASE + 14, 248 .flags = GPIOF_OUT_INIT_LOW, 249 .label = "hookflash1", 250 }, 251 { 252 .gpio = AMS_DELTA_LATCH2_GPIO_BASE + 15, 253 .flags = GPIOF_OUT_INIT_LOW, 254 .label = "hookflash2", 255 }, 256}; 257 258static struct regulator_consumer_supply modem_nreset_consumers[] = { 259 REGULATOR_SUPPLY("RESET#", "serial8250.1"), 260 REGULATOR_SUPPLY("POR", "cx20442-codec"), 261}; 262 263static struct regulator_init_data modem_nreset_data = { 264 .constraints = { 265 .valid_ops_mask = REGULATOR_CHANGE_STATUS, 266 .boot_on = 1, 267 }, 268 .num_consumer_supplies = ARRAY_SIZE(modem_nreset_consumers), 269 .consumer_supplies = modem_nreset_consumers, 270}; 271 272static struct fixed_voltage_config modem_nreset_config = { 273 .supply_name = "modem_nreset", 274 .microvolts = 3300000, 275 .gpio = AMS_DELTA_GPIO_PIN_MODEM_NRESET, 276 .startup_delay = 25000, 277 .enable_high = 1, 278 .enabled_at_boot = 1, 279 .init_data = &modem_nreset_data, 280}; 281 282static struct platform_device modem_nreset_device = { 283 .name = "reg-fixed-voltage", 284 .id = -1, 285 .dev = { 286 .platform_data = &modem_nreset_config, 287 }, 288}; 289 290struct modem_private_data { 291 struct regulator *regulator; 292}; 293 294static struct modem_private_data modem_priv; 295 296void ams_delta_latch_write(int base, int ngpio, u16 mask, u16 value) 297{ 298 int bit = 0; 299 u16 bitpos = 1 << bit; 300 301 for (; bit < ngpio; bit++, bitpos = bitpos << 1) { 302 if (!(mask & bitpos)) 303 continue; 304 else 305 gpio_set_value(base + bit, (value & bitpos) != 0); 306 } 307} 308EXPORT_SYMBOL(ams_delta_latch_write); 309 310static struct resource ams_delta_nand_resources[] = { 311 [0] = { 312 .start = OMAP1_MPUIO_BASE, 313 .end = OMAP1_MPUIO_BASE + 314 OMAP_MPUIO_IO_CNTL + sizeof(u32) - 1, 315 .flags = IORESOURCE_MEM, 316 }, 317}; 318 319static struct platform_device ams_delta_nand_device = { 320 .name = "ams-delta-nand", 321 .id = -1, 322 .num_resources = ARRAY_SIZE(ams_delta_nand_resources), 323 .resource = ams_delta_nand_resources, 324}; 325 326static struct resource ams_delta_kp_resources[] = { 327 [0] = { 328 .start = INT_KEYBOARD, 329 .end = INT_KEYBOARD, 330 .flags = IORESOURCE_IRQ, 331 }, 332}; 333 334static const struct matrix_keymap_data ams_delta_keymap_data = { 335 .keymap = ams_delta_keymap, 336 .keymap_size = ARRAY_SIZE(ams_delta_keymap), 337}; 338 339static struct omap_kp_platform_data ams_delta_kp_data = { 340 .rows = 8, 341 .cols = 8, 342 .keymap_data = &ams_delta_keymap_data, 343 .delay = 9, 344}; 345 346static struct platform_device ams_delta_kp_device = { 347 .name = "omap-keypad", 348 .id = -1, 349 .dev = { 350 .platform_data = &ams_delta_kp_data, 351 }, 352 .num_resources = ARRAY_SIZE(ams_delta_kp_resources), 353 .resource = ams_delta_kp_resources, 354}; 355 356static struct platform_device ams_delta_lcd_device = { 357 .name = "lcd_ams_delta", 358 .id = -1, 359}; 360 361static const struct gpio_led gpio_leds[] __initconst = { 362 { 363 .name = "camera", 364 .gpio = LATCH1_GPIO_BASE + 0, 365 .default_state = LEDS_GPIO_DEFSTATE_OFF, 366#ifdef CONFIG_LEDS_TRIGGERS 367 .default_trigger = "ams_delta_camera", 368#endif 369 }, 370 { 371 .name = "advert", 372 .gpio = LATCH1_GPIO_BASE + 1, 373 .default_state = LEDS_GPIO_DEFSTATE_OFF, 374 }, 375 { 376 .name = "email", 377 .gpio = LATCH1_GPIO_BASE + 2, 378 .default_state = LEDS_GPIO_DEFSTATE_OFF, 379 }, 380 { 381 .name = "handsfree", 382 .gpio = LATCH1_GPIO_BASE + 3, 383 .default_state = LEDS_GPIO_DEFSTATE_OFF, 384 }, 385 { 386 .name = "voicemail", 387 .gpio = LATCH1_GPIO_BASE + 4, 388 .default_state = LEDS_GPIO_DEFSTATE_OFF, 389 }, 390 { 391 .name = "voice", 392 .gpio = LATCH1_GPIO_BASE + 5, 393 .default_state = LEDS_GPIO_DEFSTATE_OFF, 394 }, 395}; 396 397static const struct gpio_led_platform_data leds_pdata __initconst = { 398 .leds = gpio_leds, 399 .num_leds = ARRAY_SIZE(gpio_leds), 400}; 401 402static struct i2c_board_info ams_delta_camera_board_info[] = { 403 { 404 I2C_BOARD_INFO("ov6650", 0x60), 405 }, 406}; 407 408#ifdef CONFIG_LEDS_TRIGGERS 409DEFINE_LED_TRIGGER(ams_delta_camera_led_trigger); 410 411static int ams_delta_camera_power(struct device *dev, int power) 412{ 413 /* 414 * turn on camera LED 415 */ 416 if (power) 417 led_trigger_event(ams_delta_camera_led_trigger, LED_FULL); 418 else 419 led_trigger_event(ams_delta_camera_led_trigger, LED_OFF); 420 return 0; 421} 422#else 423#define ams_delta_camera_power NULL 424#endif 425 426static struct soc_camera_link ams_delta_iclink = { 427 .bus_id = 0, /* OMAP1 SoC camera bus */ 428 .i2c_adapter_id = 1, 429 .board_info = &ams_delta_camera_board_info[0], 430 .module_name = "ov6650", 431 .power = ams_delta_camera_power, 432}; 433 434static struct platform_device ams_delta_camera_device = { 435 .name = "soc-camera-pdrv", 436 .id = 0, 437 .dev = { 438 .platform_data = &ams_delta_iclink, 439 }, 440}; 441 442static struct omap1_cam_platform_data ams_delta_camera_platform_data = { 443 .camexclk_khz = 12000, /* default 12MHz clock, no extra DPLL */ 444 .lclk_khz_max = 1334, /* results in 5fps CIF, 10fps QCIF */ 445}; 446 447static struct platform_device ams_delta_audio_device = { 448 .name = "ams-delta-audio", 449 .id = -1, 450}; 451 452static struct platform_device cx20442_codec_device = { 453 .name = "cx20442-codec", 454 .id = -1, 455}; 456 457static struct platform_device *ams_delta_devices[] __initdata = { 458 &latch1_gpio_device, 459 &latch2_gpio_device, 460 &ams_delta_kp_device, 461 &ams_delta_camera_device, 462 &ams_delta_audio_device, 463}; 464 465static struct platform_device *late_devices[] __initdata = { 466 &ams_delta_nand_device, 467 &ams_delta_lcd_device, 468 &cx20442_codec_device, 469}; 470 471static void __init ams_delta_init(void) 472{ 473 /* mux pins for uarts */ 474 omap_cfg_reg(UART1_TX); 475 omap_cfg_reg(UART1_RTS); 476 477 /* parallel camera interface */ 478 omap_cfg_reg(H19_1610_CAM_EXCLK); 479 omap_cfg_reg(J15_1610_CAM_LCLK); 480 omap_cfg_reg(L18_1610_CAM_VS); 481 omap_cfg_reg(L15_1610_CAM_HS); 482 omap_cfg_reg(L19_1610_CAM_D0); 483 omap_cfg_reg(K14_1610_CAM_D1); 484 omap_cfg_reg(K15_1610_CAM_D2); 485 omap_cfg_reg(K19_1610_CAM_D3); 486 omap_cfg_reg(K18_1610_CAM_D4); 487 omap_cfg_reg(J14_1610_CAM_D5); 488 omap_cfg_reg(J19_1610_CAM_D6); 489 omap_cfg_reg(J18_1610_CAM_D7); 490 491 omap_serial_init(); 492 omap_register_i2c_bus(1, 100, NULL, 0); 493 494 omap1_usb_init(&ams_delta_usb_config); 495 omap1_set_camera_info(&ams_delta_camera_platform_data); 496#ifdef CONFIG_LEDS_TRIGGERS 497 led_trigger_register_simple("ams_delta_camera", 498 &ams_delta_camera_led_trigger); 499#endif 500 gpio_led_register_device(-1, &leds_pdata); 501 platform_add_devices(ams_delta_devices, ARRAY_SIZE(ams_delta_devices)); 502 503 ams_delta_init_fiq(); 504 505 omap_writew(omap_readw(ARM_RSTCT1) | 0x0004, ARM_RSTCT1); 506 507 omapfb_set_lcd_config(&ams_delta_lcd_config); 508} 509 510static void modem_pm(struct uart_port *port, unsigned int state, unsigned old) 511{ 512 struct modem_private_data *priv = port->private_data; 513 514 if (IS_ERR(priv->regulator)) 515 return; 516 517 if (state == old) 518 return; 519 520 if (state == 0) 521 regulator_enable(priv->regulator); 522 else if (old == 0) 523 regulator_disable(priv->regulator); 524} 525 526static struct plat_serial8250_port ams_delta_modem_ports[] = { 527 { 528 .membase = IOMEM(MODEM_VIRT), 529 .mapbase = MODEM_PHYS, 530 .irq = -EINVAL, /* changed later */ 531 .flags = UPF_BOOT_AUTOCONF, 532 .irqflags = IRQF_TRIGGER_RISING, 533 .iotype = UPIO_MEM, 534 .regshift = 1, 535 .uartclk = BASE_BAUD * 16, 536 .pm = modem_pm, 537 .private_data = &modem_priv, 538 }, 539 { }, 540}; 541 542static struct platform_device ams_delta_modem_device = { 543 .name = "serial8250", 544 .id = PLAT8250_DEV_PLATFORM1, 545 .dev = { 546 .platform_data = ams_delta_modem_ports, 547 }, 548}; 549 550static int __init late_init(void) 551{ 552 int err; 553 554 if (!machine_is_ams_delta()) 555 return -ENODEV; 556 557 err = gpio_request_array(latch_gpios, ARRAY_SIZE(latch_gpios)); 558 if (err) { 559 pr_err("Couldn't take over latch1/latch2 GPIO pins\n"); 560 return err; 561 } 562 563 platform_add_devices(late_devices, ARRAY_SIZE(late_devices)); 564 565 err = platform_device_register(&modem_nreset_device); 566 if (err) { 567 pr_err("Couldn't register the modem regulator device\n"); 568 return err; 569 } 570 571 omap_cfg_reg(M14_1510_GPIO2); 572 ams_delta_modem_ports[0].irq = 573 gpio_to_irq(AMS_DELTA_GPIO_PIN_MODEM_IRQ); 574 575 err = gpio_request(AMS_DELTA_GPIO_PIN_MODEM_IRQ, "modem"); 576 if (err) { 577 pr_err("Couldn't request gpio pin for modem\n"); 578 return err; 579 } 580 gpio_direction_input(AMS_DELTA_GPIO_PIN_MODEM_IRQ); 581 582 /* Initialize the modem_nreset regulator consumer before use */ 583 modem_priv.regulator = ERR_PTR(-ENODEV); 584 585 ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_CODEC, 586 AMS_DELTA_LATCH2_MODEM_CODEC); 587 588 err = platform_device_register(&ams_delta_modem_device); 589 if (err) 590 goto gpio_free; 591 592 /* 593 * Once the modem device is registered, the modem_nreset 594 * regulator can be requested on behalf of that device. 595 */ 596 modem_priv.regulator = regulator_get(&ams_delta_modem_device.dev, 597 "RESET#"); 598 if (IS_ERR(modem_priv.regulator)) { 599 err = PTR_ERR(modem_priv.regulator); 600 goto unregister; 601 } 602 return 0; 603 604unregister: 605 platform_device_unregister(&ams_delta_modem_device); 606gpio_free: 607 gpio_free(AMS_DELTA_GPIO_PIN_MODEM_IRQ); 608 return err; 609} 610 611static void __init ams_delta_init_late(void) 612{ 613 omap1_init_late(); 614 late_init(); 615} 616 617static void __init ams_delta_map_io(void) 618{ 619 omap15xx_map_io(); 620 iotable_init(ams_delta_io_desc, ARRAY_SIZE(ams_delta_io_desc)); 621} 622 623MACHINE_START(AMS_DELTA, "Amstrad E3 (Delta)") 624 /* Maintainer: Jonathan McDowell <noodles@earth.li> */ 625 .atag_offset = 0x100, 626 .map_io = ams_delta_map_io, 627 .init_early = omap1_init_early, 628 .init_irq = omap1_init_irq, 629 .handle_irq = omap1_handle_irq, 630 .init_machine = ams_delta_init, 631 .init_late = ams_delta_init_late, 632 .init_time = omap1_timer_init, 633 .restart = omap1_restart, 634MACHINE_END 635