mach-rx1950.c revision 364374121b78ec599b10dd84648ccceb4d037285
1/* 2 * Copyright (c) 2006-2009 Victor Chukhantsev, Denis Grigoriev, 3 * Copyright (c) 2007-2010 Vasily Khoruzhick 4 * 5 * based on smdk2440 written by Ben Dooks 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 * 11*/ 12 13#include <linux/kernel.h> 14#include <linux/types.h> 15#include <linux/interrupt.h> 16#include <linux/list.h> 17#include <linux/memblock.h> 18#include <linux/delay.h> 19#include <linux/timer.h> 20#include <linux/init.h> 21#include <linux/gpio.h> 22#include <linux/platform_device.h> 23#include <linux/serial_core.h> 24#include <linux/input.h> 25#include <linux/gpio_keys.h> 26#include <linux/device.h> 27#include <linux/pda_power.h> 28#include <linux/pwm_backlight.h> 29#include <linux/pwm.h> 30#include <linux/s3c_adc_battery.h> 31#include <linux/leds.h> 32#include <linux/i2c.h> 33 34#include <linux/mtd/mtd.h> 35#include <linux/mtd/partitions.h> 36 37#include <linux/mmc/host.h> 38 39#include <asm/mach-types.h> 40#include <asm/mach/arch.h> 41#include <asm/mach/map.h> 42 43#include <linux/platform_data/i2c-s3c2410.h> 44#include <linux/platform_data/mmc-s3cmci.h> 45#include <linux/platform_data/mtd-nand-s3c2410.h> 46#include <linux/platform_data/touchscreen-s3c2410.h> 47#include <linux/platform_data/usb-s3c2410_udc.h> 48 49#include <sound/uda1380.h> 50 51#include <mach/fb.h> 52#include <mach/regs-gpio.h> 53#include <mach/regs-lcd.h> 54#include <mach/gpio-samsung.h> 55 56#include <plat/clock.h> 57#include <plat/cpu.h> 58#include <plat/devs.h> 59#include <plat/pm.h> 60#include <plat/regs-serial.h> 61#include <plat/samsung-time.h> 62#include <plat/gpio-cfg.h> 63 64#include "common.h" 65#include "h1940.h" 66 67#define LCD_PWM_PERIOD 192960 68#define LCD_PWM_DUTY 127353 69 70static struct map_desc rx1950_iodesc[] __initdata = { 71}; 72 73static struct s3c2410_uartcfg rx1950_uartcfgs[] __initdata = { 74 [0] = { 75 .hwport = 0, 76 .flags = 0, 77 .ucon = 0x3c5, 78 .ulcon = 0x03, 79 .ufcon = 0x51, 80 .clk_sel = S3C2410_UCON_CLKSEL3, 81 }, 82 [1] = { 83 .hwport = 1, 84 .flags = 0, 85 .ucon = 0x3c5, 86 .ulcon = 0x03, 87 .ufcon = 0x51, 88 .clk_sel = S3C2410_UCON_CLKSEL3, 89 }, 90 /* IR port */ 91 [2] = { 92 .hwport = 2, 93 .flags = 0, 94 .ucon = 0x3c5, 95 .ulcon = 0x43, 96 .ufcon = 0xf1, 97 .clk_sel = S3C2410_UCON_CLKSEL3, 98 }, 99}; 100 101static struct s3c2410fb_display rx1950_display = { 102 .type = S3C2410_LCDCON1_TFT, 103 .width = 240, 104 .height = 320, 105 .xres = 240, 106 .yres = 320, 107 .bpp = 16, 108 109 .pixclock = 260000, 110 .left_margin = 10, 111 .right_margin = 20, 112 .hsync_len = 10, 113 .upper_margin = 2, 114 .lower_margin = 2, 115 .vsync_len = 2, 116 117 .lcdcon5 = S3C2410_LCDCON5_FRM565 | 118 S3C2410_LCDCON5_INVVCLK | 119 S3C2410_LCDCON5_INVVLINE | 120 S3C2410_LCDCON5_INVVFRAME | 121 S3C2410_LCDCON5_HWSWP | 122 (0x02 << 13) | 123 (0x02 << 15), 124 125}; 126 127static int power_supply_init(struct device *dev) 128{ 129 return gpio_request(S3C2410_GPF(2), "cable plugged"); 130} 131 132static int rx1950_is_ac_online(void) 133{ 134 return !gpio_get_value(S3C2410_GPF(2)); 135} 136 137static void power_supply_exit(struct device *dev) 138{ 139 gpio_free(S3C2410_GPF(2)); 140} 141 142static char *rx1950_supplicants[] = { 143 "main-battery" 144}; 145 146static struct pda_power_pdata power_supply_info = { 147 .init = power_supply_init, 148 .is_ac_online = rx1950_is_ac_online, 149 .exit = power_supply_exit, 150 .supplied_to = rx1950_supplicants, 151 .num_supplicants = ARRAY_SIZE(rx1950_supplicants), 152}; 153 154static struct resource power_supply_resources[] = { 155 [0] = DEFINE_RES_NAMED(IRQ_EINT2, 1, "ac", IORESOURCE_IRQ \ 156 | IORESOURCE_IRQ_LOWEDGE | IORESOURCE_IRQ_HIGHEDGE), 157}; 158 159static struct platform_device power_supply = { 160 .name = "pda-power", 161 .id = -1, 162 .dev = { 163 .platform_data = 164 &power_supply_info, 165 }, 166 .resource = power_supply_resources, 167 .num_resources = ARRAY_SIZE(power_supply_resources), 168}; 169 170static const struct s3c_adc_bat_thresh bat_lut_noac[] = { 171 { .volt = 4100, .cur = 156, .level = 100}, 172 { .volt = 4050, .cur = 156, .level = 95}, 173 { .volt = 4025, .cur = 141, .level = 90}, 174 { .volt = 3995, .cur = 144, .level = 85}, 175 { .volt = 3957, .cur = 162, .level = 80}, 176 { .volt = 3931, .cur = 147, .level = 75}, 177 { .volt = 3902, .cur = 147, .level = 70}, 178 { .volt = 3863, .cur = 153, .level = 65}, 179 { .volt = 3838, .cur = 150, .level = 60}, 180 { .volt = 3800, .cur = 153, .level = 55}, 181 { .volt = 3765, .cur = 153, .level = 50}, 182 { .volt = 3748, .cur = 172, .level = 45}, 183 { .volt = 3740, .cur = 153, .level = 40}, 184 { .volt = 3714, .cur = 175, .level = 35}, 185 { .volt = 3710, .cur = 156, .level = 30}, 186 { .volt = 3963, .cur = 156, .level = 25}, 187 { .volt = 3672, .cur = 178, .level = 20}, 188 { .volt = 3651, .cur = 178, .level = 15}, 189 { .volt = 3629, .cur = 178, .level = 10}, 190 { .volt = 3612, .cur = 162, .level = 5}, 191 { .volt = 3605, .cur = 162, .level = 0}, 192}; 193 194static const struct s3c_adc_bat_thresh bat_lut_acin[] = { 195 { .volt = 4200, .cur = 0, .level = 100}, 196 { .volt = 4190, .cur = 0, .level = 99}, 197 { .volt = 4178, .cur = 0, .level = 95}, 198 { .volt = 4110, .cur = 0, .level = 70}, 199 { .volt = 4076, .cur = 0, .level = 65}, 200 { .volt = 4046, .cur = 0, .level = 60}, 201 { .volt = 4021, .cur = 0, .level = 55}, 202 { .volt = 3999, .cur = 0, .level = 50}, 203 { .volt = 3982, .cur = 0, .level = 45}, 204 { .volt = 3965, .cur = 0, .level = 40}, 205 { .volt = 3957, .cur = 0, .level = 35}, 206 { .volt = 3948, .cur = 0, .level = 30}, 207 { .volt = 3936, .cur = 0, .level = 25}, 208 { .volt = 3927, .cur = 0, .level = 20}, 209 { .volt = 3906, .cur = 0, .level = 15}, 210 { .volt = 3880, .cur = 0, .level = 10}, 211 { .volt = 3829, .cur = 0, .level = 5}, 212 { .volt = 3820, .cur = 0, .level = 0}, 213}; 214 215static int rx1950_bat_init(void) 216{ 217 int ret; 218 219 ret = gpio_request(S3C2410_GPJ(2), "rx1950-charger-enable-1"); 220 if (ret) 221 goto err_gpio1; 222 ret = gpio_request(S3C2410_GPJ(3), "rx1950-charger-enable-2"); 223 if (ret) 224 goto err_gpio2; 225 226 return 0; 227 228err_gpio2: 229 gpio_free(S3C2410_GPJ(2)); 230err_gpio1: 231 return ret; 232} 233 234static void rx1950_bat_exit(void) 235{ 236 gpio_free(S3C2410_GPJ(2)); 237 gpio_free(S3C2410_GPJ(3)); 238} 239 240static void rx1950_enable_charger(void) 241{ 242 gpio_direction_output(S3C2410_GPJ(2), 1); 243 gpio_direction_output(S3C2410_GPJ(3), 1); 244} 245 246static void rx1950_disable_charger(void) 247{ 248 gpio_direction_output(S3C2410_GPJ(2), 0); 249 gpio_direction_output(S3C2410_GPJ(3), 0); 250} 251 252static DEFINE_SPINLOCK(rx1950_blink_spin); 253 254static int rx1950_led_blink_set(unsigned gpio, int state, 255 unsigned long *delay_on, unsigned long *delay_off) 256{ 257 int blink_gpio, check_gpio; 258 259 switch (gpio) { 260 case S3C2410_GPA(6): 261 blink_gpio = S3C2410_GPA(4); 262 check_gpio = S3C2410_GPA(3); 263 break; 264 case S3C2410_GPA(7): 265 blink_gpio = S3C2410_GPA(3); 266 check_gpio = S3C2410_GPA(4); 267 break; 268 default: 269 return -EINVAL; 270 break; 271 } 272 273 if (delay_on && delay_off && !*delay_on && !*delay_off) 274 *delay_on = *delay_off = 500; 275 276 spin_lock(&rx1950_blink_spin); 277 278 switch (state) { 279 case GPIO_LED_NO_BLINK_LOW: 280 case GPIO_LED_NO_BLINK_HIGH: 281 if (!gpio_get_value(check_gpio)) 282 gpio_set_value(S3C2410_GPJ(6), 0); 283 gpio_set_value(blink_gpio, 0); 284 gpio_set_value(gpio, state); 285 break; 286 case GPIO_LED_BLINK: 287 gpio_set_value(gpio, 0); 288 gpio_set_value(S3C2410_GPJ(6), 1); 289 gpio_set_value(blink_gpio, 1); 290 break; 291 } 292 293 spin_unlock(&rx1950_blink_spin); 294 295 return 0; 296} 297 298static struct gpio_led rx1950_leds_desc[] = { 299 { 300 .name = "Green", 301 .default_trigger = "main-battery-full", 302 .gpio = S3C2410_GPA(6), 303 .retain_state_suspended = 1, 304 }, 305 { 306 .name = "Red", 307 .default_trigger 308 = "main-battery-charging-blink-full-solid", 309 .gpio = S3C2410_GPA(7), 310 .retain_state_suspended = 1, 311 }, 312 { 313 .name = "Blue", 314 .default_trigger = "rx1950-acx-mem", 315 .gpio = S3C2410_GPA(11), 316 .retain_state_suspended = 1, 317 }, 318}; 319 320static struct gpio_led_platform_data rx1950_leds_pdata = { 321 .num_leds = ARRAY_SIZE(rx1950_leds_desc), 322 .leds = rx1950_leds_desc, 323 .gpio_blink_set = rx1950_led_blink_set, 324}; 325 326static struct platform_device rx1950_leds = { 327 .name = "leds-gpio", 328 .id = -1, 329 .dev = { 330 .platform_data = &rx1950_leds_pdata, 331 }, 332}; 333 334static struct s3c_adc_bat_pdata rx1950_bat_cfg = { 335 .init = rx1950_bat_init, 336 .exit = rx1950_bat_exit, 337 .enable_charger = rx1950_enable_charger, 338 .disable_charger = rx1950_disable_charger, 339 .gpio_charge_finished = S3C2410_GPF(3), 340 .lut_noac = bat_lut_noac, 341 .lut_noac_cnt = ARRAY_SIZE(bat_lut_noac), 342 .lut_acin = bat_lut_acin, 343 .lut_acin_cnt = ARRAY_SIZE(bat_lut_acin), 344 .volt_channel = 0, 345 .current_channel = 1, 346 .volt_mult = 4235, 347 .current_mult = 2900, 348 .internal_impedance = 200, 349}; 350 351static struct platform_device rx1950_battery = { 352 .name = "s3c-adc-battery", 353 .id = -1, 354 .dev = { 355 .parent = &s3c_device_adc.dev, 356 .platform_data = &rx1950_bat_cfg, 357 }, 358}; 359 360static struct s3c2410fb_mach_info rx1950_lcd_cfg = { 361 .displays = &rx1950_display, 362 .num_displays = 1, 363 .default_display = 0, 364 365 .lpcsel = 0x02, 366 .gpccon = 0xaa9556a9, 367 .gpccon_mask = 0xffc003fc, 368 .gpcup = 0x0000ffff, 369 .gpcup_mask = 0xffffffff, 370 371 .gpdcon = 0xaa90aaa1, 372 .gpdcon_mask = 0xffc0fff0, 373 .gpdup = 0x0000fcfd, 374 .gpdup_mask = 0xffffffff, 375 376}; 377 378static struct pwm_device *lcd_pwm; 379 380static void rx1950_lcd_power(int enable) 381{ 382 int i; 383 static int enabled; 384 if (enabled == enable) 385 return; 386 if (!enable) { 387 388 /* GPC11-GPC15->OUTPUT */ 389 for (i = 11; i < 16; i++) 390 gpio_direction_output(S3C2410_GPC(i), 1); 391 392 /* Wait a bit here... */ 393 mdelay(100); 394 395 /* GPD2-GPD7->OUTPUT */ 396 /* GPD11-GPD15->OUTPUT */ 397 /* GPD2-GPD7->1, GPD11-GPD15->1 */ 398 for (i = 2; i < 8; i++) 399 gpio_direction_output(S3C2410_GPD(i), 1); 400 for (i = 11; i < 16; i++) 401 gpio_direction_output(S3C2410_GPD(i), 1); 402 403 /* Wait a bit here...*/ 404 mdelay(100); 405 406 /* GPB0->OUTPUT, GPB0->0 */ 407 gpio_direction_output(S3C2410_GPB(0), 0); 408 409 /* GPC1-GPC4->OUTPUT, GPC1-4->0 */ 410 for (i = 1; i < 5; i++) 411 gpio_direction_output(S3C2410_GPC(i), 0); 412 413 /* GPC15-GPC11->0 */ 414 for (i = 11; i < 16; i++) 415 gpio_direction_output(S3C2410_GPC(i), 0); 416 417 /* GPD15-GPD11->0, GPD2->GPD7->0 */ 418 for (i = 11; i < 16; i++) 419 gpio_direction_output(S3C2410_GPD(i), 0); 420 421 for (i = 2; i < 8; i++) 422 gpio_direction_output(S3C2410_GPD(i), 0); 423 424 /* GPC6->0, GPC7->0, GPC5->0 */ 425 gpio_direction_output(S3C2410_GPC(6), 0); 426 gpio_direction_output(S3C2410_GPC(7), 0); 427 gpio_direction_output(S3C2410_GPC(5), 0); 428 429 /* GPB1->OUTPUT, GPB1->0 */ 430 gpio_direction_output(S3C2410_GPB(1), 0); 431 pwm_config(lcd_pwm, 0, LCD_PWM_PERIOD); 432 pwm_disable(lcd_pwm); 433 434 /* GPC0->0, GPC10->0 */ 435 gpio_direction_output(S3C2410_GPC(0), 0); 436 gpio_direction_output(S3C2410_GPC(10), 0); 437 } else { 438 pwm_config(lcd_pwm, LCD_PWM_DUTY, LCD_PWM_PERIOD); 439 pwm_enable(lcd_pwm); 440 441 gpio_direction_output(S3C2410_GPC(0), 1); 442 gpio_direction_output(S3C2410_GPC(5), 1); 443 444 s3c_gpio_cfgpin(S3C2410_GPB(1), S3C2410_GPB1_TOUT1); 445 gpio_direction_output(S3C2410_GPC(7), 1); 446 447 for (i = 1; i < 5; i++) 448 s3c_gpio_cfgpin(S3C2410_GPC(i), S3C_GPIO_SFN(2)); 449 450 for (i = 11; i < 16; i++) 451 s3c_gpio_cfgpin(S3C2410_GPC(i), S3C_GPIO_SFN(2)); 452 453 for (i = 2; i < 8; i++) 454 s3c_gpio_cfgpin(S3C2410_GPD(i), S3C_GPIO_SFN(2)); 455 456 for (i = 11; i < 16; i++) 457 s3c_gpio_cfgpin(S3C2410_GPD(i), S3C_GPIO_SFN(2)); 458 459 gpio_direction_output(S3C2410_GPC(10), 1); 460 gpio_direction_output(S3C2410_GPC(6), 1); 461 } 462 enabled = enable; 463} 464 465static void rx1950_bl_power(int enable) 466{ 467 static int enabled; 468 if (enabled == enable) 469 return; 470 if (!enable) { 471 gpio_direction_output(S3C2410_GPB(0), 0); 472 } else { 473 /* LED driver need a "push" to power on */ 474 gpio_direction_output(S3C2410_GPB(0), 1); 475 /* Warm up backlight for one period of PWM. 476 * Without this trick its almost impossible to 477 * enable backlight with low brightness value 478 */ 479 ndelay(48000); 480 s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0); 481 } 482 enabled = enable; 483} 484 485static int rx1950_backlight_init(struct device *dev) 486{ 487 WARN_ON(gpio_request(S3C2410_GPB(0), "Backlight")); 488 lcd_pwm = pwm_request(1, "RX1950 LCD"); 489 if (IS_ERR(lcd_pwm)) { 490 dev_err(dev, "Unable to request PWM for LCD power!\n"); 491 return PTR_ERR(lcd_pwm); 492 } 493 494 rx1950_lcd_power(1); 495 rx1950_bl_power(1); 496 497 return 0; 498} 499 500static void rx1950_backlight_exit(struct device *dev) 501{ 502 rx1950_bl_power(0); 503 rx1950_lcd_power(0); 504 505 pwm_free(lcd_pwm); 506 gpio_free(S3C2410_GPB(0)); 507} 508 509 510static int rx1950_backlight_notify(struct device *dev, int brightness) 511{ 512 if (!brightness) { 513 rx1950_bl_power(0); 514 rx1950_lcd_power(0); 515 } else { 516 rx1950_lcd_power(1); 517 rx1950_bl_power(1); 518 } 519 return brightness; 520} 521 522static struct platform_pwm_backlight_data rx1950_backlight_data = { 523 .pwm_id = 0, 524 .max_brightness = 24, 525 .dft_brightness = 4, 526 .pwm_period_ns = 48000, 527 .enable_gpio = -1, 528 .init = rx1950_backlight_init, 529 .notify = rx1950_backlight_notify, 530 .exit = rx1950_backlight_exit, 531}; 532 533static struct platform_device rx1950_backlight = { 534 .name = "pwm-backlight", 535 .dev = { 536 .parent = &samsung_device_pwm.dev, 537 .platform_data = &rx1950_backlight_data, 538 }, 539}; 540 541static void rx1950_set_mmc_power(unsigned char power_mode, unsigned short vdd) 542{ 543 switch (power_mode) { 544 case MMC_POWER_OFF: 545 gpio_direction_output(S3C2410_GPJ(1), 0); 546 break; 547 case MMC_POWER_UP: 548 case MMC_POWER_ON: 549 gpio_direction_output(S3C2410_GPJ(1), 1); 550 break; 551 default: 552 break; 553 } 554} 555 556static struct s3c24xx_mci_pdata rx1950_mmc_cfg __initdata = { 557 .gpio_detect = S3C2410_GPF(5), 558 .gpio_wprotect = S3C2410_GPH(8), 559 .set_power = rx1950_set_mmc_power, 560 .ocr_avail = MMC_VDD_32_33, 561}; 562 563static struct mtd_partition rx1950_nand_part[] = { 564 [0] = { 565 .name = "Boot0", 566 .offset = 0, 567 .size = 0x4000, 568 .mask_flags = MTD_WRITEABLE, 569 }, 570 [1] = { 571 .name = "Boot1", 572 .offset = MTDPART_OFS_APPEND, 573 .size = 0x40000, 574 .mask_flags = MTD_WRITEABLE, 575 }, 576 [2] = { 577 .name = "Kernel", 578 .offset = MTDPART_OFS_APPEND, 579 .size = 0x300000, 580 .mask_flags = 0, 581 }, 582 [3] = { 583 .name = "Filesystem", 584 .offset = MTDPART_OFS_APPEND, 585 .size = MTDPART_SIZ_FULL, 586 .mask_flags = 0, 587 }, 588}; 589 590static struct s3c2410_nand_set rx1950_nand_sets[] = { 591 [0] = { 592 .name = "Internal", 593 .nr_chips = 1, 594 .nr_partitions = ARRAY_SIZE(rx1950_nand_part), 595 .partitions = rx1950_nand_part, 596 }, 597}; 598 599static struct s3c2410_platform_nand rx1950_nand_info = { 600 .tacls = 25, 601 .twrph0 = 50, 602 .twrph1 = 15, 603 .nr_sets = ARRAY_SIZE(rx1950_nand_sets), 604 .sets = rx1950_nand_sets, 605}; 606 607static struct s3c2410_udc_mach_info rx1950_udc_cfg __initdata = { 608 .vbus_pin = S3C2410_GPG(5), 609 .vbus_pin_inverted = 1, 610 .pullup_pin = S3C2410_GPJ(5), 611}; 612 613static struct s3c2410_ts_mach_info rx1950_ts_cfg __initdata = { 614 .delay = 10000, 615 .presc = 49, 616 .oversampling_shift = 3, 617}; 618 619static struct gpio_keys_button rx1950_gpio_keys_table[] = { 620 { 621 .code = KEY_POWER, 622 .gpio = S3C2410_GPF(0), 623 .active_low = 1, 624 .desc = "Power button", 625 .wakeup = 1, 626 }, 627 { 628 .code = KEY_F5, 629 .gpio = S3C2410_GPF(7), 630 .active_low = 1, 631 .desc = "Record button", 632 }, 633 { 634 .code = KEY_F1, 635 .gpio = S3C2410_GPG(0), 636 .active_low = 1, 637 .desc = "Calendar button", 638 }, 639 { 640 .code = KEY_F2, 641 .gpio = S3C2410_GPG(2), 642 .active_low = 1, 643 .desc = "Contacts button", 644 }, 645 { 646 .code = KEY_F3, 647 .gpio = S3C2410_GPG(3), 648 .active_low = 1, 649 .desc = "Mail button", 650 }, 651 { 652 .code = KEY_F4, 653 .gpio = S3C2410_GPG(7), 654 .active_low = 1, 655 .desc = "WLAN button", 656 }, 657 { 658 .code = KEY_LEFT, 659 .gpio = S3C2410_GPG(10), 660 .active_low = 1, 661 .desc = "Left button", 662 }, 663 { 664 .code = KEY_RIGHT, 665 .gpio = S3C2410_GPG(11), 666 .active_low = 1, 667 .desc = "Right button", 668 }, 669 { 670 .code = KEY_UP, 671 .gpio = S3C2410_GPG(4), 672 .active_low = 1, 673 .desc = "Up button", 674 }, 675 { 676 .code = KEY_DOWN, 677 .gpio = S3C2410_GPG(6), 678 .active_low = 1, 679 .desc = "Down button", 680 }, 681 { 682 .code = KEY_ENTER, 683 .gpio = S3C2410_GPG(9), 684 .active_low = 1, 685 .desc = "Ok button" 686 }, 687}; 688 689static struct gpio_keys_platform_data rx1950_gpio_keys_data = { 690 .buttons = rx1950_gpio_keys_table, 691 .nbuttons = ARRAY_SIZE(rx1950_gpio_keys_table), 692}; 693 694static struct platform_device rx1950_device_gpiokeys = { 695 .name = "gpio-keys", 696 .dev.platform_data = &rx1950_gpio_keys_data, 697}; 698 699static struct uda1380_platform_data uda1380_info = { 700 .gpio_power = S3C2410_GPJ(0), 701 .gpio_reset = S3C2410_GPD(0), 702 .dac_clk = UDA1380_DAC_CLK_SYSCLK, 703}; 704 705static struct i2c_board_info rx1950_i2c_devices[] = { 706 { 707 I2C_BOARD_INFO("uda1380", 0x1a), 708 .platform_data = &uda1380_info, 709 }, 710}; 711 712static struct platform_device *rx1950_devices[] __initdata = { 713 &s3c_device_lcd, 714 &s3c_device_wdt, 715 &s3c_device_i2c0, 716 &s3c_device_iis, 717 &s3c_device_usbgadget, 718 &s3c_device_rtc, 719 &s3c_device_nand, 720 &s3c_device_sdi, 721 &s3c_device_adc, 722 &s3c_device_ts, 723 &samsung_device_pwm, 724 &rx1950_backlight, 725 &rx1950_device_gpiokeys, 726 &power_supply, 727 &rx1950_battery, 728 &rx1950_leds, 729}; 730 731static struct clk *rx1950_clocks[] __initdata = { 732 &s3c24xx_clkout0, 733 &s3c24xx_clkout1, 734}; 735 736static void __init rx1950_map_io(void) 737{ 738 s3c24xx_clkout0.parent = &clk_h; 739 s3c24xx_clkout1.parent = &clk_f; 740 741 s3c24xx_register_clocks(rx1950_clocks, ARRAY_SIZE(rx1950_clocks)); 742 743 s3c24xx_init_io(rx1950_iodesc, ARRAY_SIZE(rx1950_iodesc)); 744 s3c24xx_init_clocks(16934000); 745 s3c24xx_init_uarts(rx1950_uartcfgs, ARRAY_SIZE(rx1950_uartcfgs)); 746 samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); 747 748 /* setup PM */ 749 750#ifdef CONFIG_PM_H1940 751 memcpy(phys_to_virt(H1940_SUSPEND_RESUMEAT), h1940_pm_return, 8); 752#endif 753 754 s3c_pm_init(); 755} 756 757static void __init rx1950_init_machine(void) 758{ 759 int i; 760 761 s3c24xx_fb_set_platdata(&rx1950_lcd_cfg); 762 s3c24xx_udc_set_platdata(&rx1950_udc_cfg); 763 s3c24xx_ts_set_platdata(&rx1950_ts_cfg); 764 s3c24xx_mci_set_platdata(&rx1950_mmc_cfg); 765 s3c_i2c0_set_platdata(NULL); 766 s3c_nand_set_platdata(&rx1950_nand_info); 767 768 /* Turn off suspend on both USB ports, and switch the 769 * selectable USB port to USB device mode. */ 770 s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST | 771 S3C2410_MISCCR_USBSUSPND0 | 772 S3C2410_MISCCR_USBSUSPND1, 0x0); 773 774 /* mmc power is disabled by default */ 775 WARN_ON(gpio_request(S3C2410_GPJ(1), "MMC power")); 776 gpio_direction_output(S3C2410_GPJ(1), 0); 777 778 for (i = 0; i < 8; i++) 779 WARN_ON(gpio_request(S3C2410_GPC(i), "LCD power")); 780 781 for (i = 10; i < 16; i++) 782 WARN_ON(gpio_request(S3C2410_GPC(i), "LCD power")); 783 784 for (i = 2; i < 8; i++) 785 WARN_ON(gpio_request(S3C2410_GPD(i), "LCD power")); 786 787 for (i = 11; i < 16; i++) 788 WARN_ON(gpio_request(S3C2410_GPD(i), "LCD power")); 789 790 WARN_ON(gpio_request(S3C2410_GPB(1), "LCD power")); 791 792 WARN_ON(gpio_request(S3C2410_GPA(3), "Red blink")); 793 WARN_ON(gpio_request(S3C2410_GPA(4), "Green blink")); 794 WARN_ON(gpio_request(S3C2410_GPJ(6), "LED blink")); 795 gpio_direction_output(S3C2410_GPA(3), 0); 796 gpio_direction_output(S3C2410_GPA(4), 0); 797 gpio_direction_output(S3C2410_GPJ(6), 0); 798 799 platform_add_devices(rx1950_devices, ARRAY_SIZE(rx1950_devices)); 800 801 i2c_register_board_info(0, rx1950_i2c_devices, 802 ARRAY_SIZE(rx1950_i2c_devices)); 803} 804 805/* H1940 and RX3715 need to reserve this for suspend */ 806static void __init rx1950_reserve(void) 807{ 808 memblock_reserve(0x30003000, 0x1000); 809 memblock_reserve(0x30081000, 0x1000); 810} 811 812MACHINE_START(RX1950, "HP iPAQ RX1950") 813 /* Maintainers: Vasily Khoruzhick */ 814 .atag_offset = 0x100, 815 .map_io = rx1950_map_io, 816 .reserve = rx1950_reserve, 817 .init_irq = s3c2442_init_irq, 818 .init_machine = rx1950_init_machine, 819 .init_time = samsung_timer_init, 820 .restart = s3c244x_restart, 821MACHINE_END 822