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