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