linux/arch/arm/mach-s3c24xx/mach-h1940.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2//
   3// Copyright (c) 2003-2005 Simtec Electronics
   4//   Ben Dooks <ben@simtec.co.uk>
   5//
   6// http://www.handhelds.org/projects/h1940.html
   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/timer.h>
  14#include <linux/init.h>
  15#include <linux/device.h>
  16#include <linux/serial_core.h>
  17#include <linux/serial_s3c.h>
  18#include <linux/platform_device.h>
  19#include <linux/io.h>
  20#include <linux/gpio.h>
  21#include <linux/gpio/machine.h>
  22#include <linux/input.h>
  23#include <linux/gpio_keys.h>
  24#include <linux/pwm.h>
  25#include <linux/pwm_backlight.h>
  26#include <linux/i2c.h>
  27#include <linux/leds.h>
  28#include <linux/pda_power.h>
  29#include <linux/s3c_adc_battery.h>
  30#include <linux/delay.h>
  31
  32#include <video/platform_lcd.h>
  33
  34#include <linux/mmc/host.h>
  35#include <linux/export.h>
  36
  37#include <asm/irq.h>
  38#include <asm/mach-types.h>
  39#include <asm/mach/arch.h>
  40#include <asm/mach/map.h>
  41#include <asm/mach/irq.h>
  42
  43#include <linux/platform_data/i2c-s3c2410.h>
  44#include <linux/platform_data/mmc-s3cmci.h>
  45#include <linux/platform_data/touchscreen-s3c2410.h>
  46#include <linux/platform_data/usb-s3c2410_udc.h>
  47
  48#include <sound/uda1380.h>
  49
  50#include <mach/fb.h>
  51#include <mach/hardware.h>
  52#include <mach/regs-clock.h>
  53#include <mach/regs-gpio.h>
  54#include <mach/regs-lcd.h>
  55#include <mach/gpio-samsung.h>
  56
  57#include <plat/cpu.h>
  58#include <plat/devs.h>
  59#include <plat/gpio-cfg.h>
  60#include <plat/pm.h>
  61#include <plat/samsung-time.h>
  62
  63#include "common.h"
  64#include "h1940.h"
  65
  66#define H1940_LATCH             ((void __force __iomem *)0xF8000000)
  67
  68#define H1940_PA_LATCH          S3C2410_CS2
  69
  70#define H1940_LATCH_BIT(x)      (1 << ((x) + 16 - S3C_GPIO_END))
  71
  72#define S3C24XX_PLL_MDIV_SHIFT         (12)
  73#define S3C24XX_PLL_PDIV_SHIFT         (4)
  74#define S3C24XX_PLL_SDIV_SHIFT         (0)
  75
  76static struct map_desc h1940_iodesc[] __initdata = {
  77        [0] = {
  78                .virtual        = (unsigned long)H1940_LATCH,
  79                .pfn            = __phys_to_pfn(H1940_PA_LATCH),
  80                .length         = SZ_16K,
  81                .type           = MT_DEVICE
  82        },
  83};
  84
  85#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
  86#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
  87#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
  88
  89static struct s3c2410_uartcfg h1940_uartcfgs[] __initdata = {
  90        [0] = {
  91                .hwport      = 0,
  92                .flags       = 0,
  93                .ucon        = 0x3c5,
  94                .ulcon       = 0x03,
  95                .ufcon       = 0x51,
  96        },
  97        [1] = {
  98                .hwport      = 1,
  99                .flags       = 0,
 100                .ucon        = 0x245,
 101                .ulcon       = 0x03,
 102                .ufcon       = 0x00,
 103        },
 104        /* IR port */
 105        [2] = {
 106                .hwport      = 2,
 107                .flags       = 0,
 108                .uart_flags  = UPF_CONS_FLOW,
 109                .ucon        = 0x3c5,
 110                .ulcon       = 0x43,
 111                .ufcon       = 0x51,
 112        }
 113};
 114
 115/* Board control latch control */
 116
 117static unsigned int latch_state;
 118
 119static void h1940_latch_control(unsigned int clear, unsigned int set)
 120{
 121        unsigned long flags;
 122
 123        local_irq_save(flags);
 124
 125        latch_state &= ~clear;
 126        latch_state |= set;
 127
 128        __raw_writel(latch_state, H1940_LATCH);
 129
 130        local_irq_restore(flags);
 131}
 132
 133static inline int h1940_gpiolib_to_latch(int offset)
 134{
 135        return 1 << (offset + 16);
 136}
 137
 138static void h1940_gpiolib_latch_set(struct gpio_chip *chip,
 139                                        unsigned offset, int value)
 140{
 141        int latch_bit = h1940_gpiolib_to_latch(offset);
 142
 143        h1940_latch_control(value ? 0 : latch_bit,
 144                value ? latch_bit : 0);
 145}
 146
 147static int h1940_gpiolib_latch_output(struct gpio_chip *chip,
 148                                        unsigned offset, int value)
 149{
 150        h1940_gpiolib_latch_set(chip, offset, value);
 151        return 0;
 152}
 153
 154static int h1940_gpiolib_latch_get(struct gpio_chip *chip,
 155                                        unsigned offset)
 156{
 157        return (latch_state >> (offset + 16)) & 1;
 158}
 159
 160static struct gpio_chip h1940_latch_gpiochip = {
 161        .base                   = H1940_LATCH_GPIO(0),
 162        .owner                  = THIS_MODULE,
 163        .label                  = "H1940_LATCH",
 164        .ngpio                  = 16,
 165        .direction_output       = h1940_gpiolib_latch_output,
 166        .set                    = h1940_gpiolib_latch_set,
 167        .get                    = h1940_gpiolib_latch_get,
 168};
 169
 170static struct s3c2410_udc_mach_info h1940_udc_cfg __initdata = {
 171        .vbus_pin               = S3C2410_GPG(5),
 172        .vbus_pin_inverted      = 1,
 173        .pullup_pin             = H1940_LATCH_USB_DP,
 174};
 175
 176static struct s3c2410_ts_mach_info h1940_ts_cfg __initdata = {
 177                .delay = 10000,
 178                .presc = 49,
 179                .oversampling_shift = 2,
 180                .cfg_gpio = s3c24xx_ts_cfg_gpio,
 181};
 182
 183/**
 184 * Set lcd on or off
 185 **/
 186static struct s3c2410fb_display h1940_lcd __initdata = {
 187        .lcdcon5=       S3C2410_LCDCON5_FRM565 | \
 188                        S3C2410_LCDCON5_INVVLINE | \
 189                        S3C2410_LCDCON5_HWSWP,
 190
 191        .type =         S3C2410_LCDCON1_TFT,
 192        .width =        240,
 193        .height =       320,
 194        .pixclock =     260000,
 195        .xres =         240,
 196        .yres =         320,
 197        .bpp =          16,
 198        .left_margin =  8,
 199        .right_margin = 20,
 200        .hsync_len =    4,
 201        .upper_margin = 8,
 202        .lower_margin = 7,
 203        .vsync_len =    1,
 204};
 205
 206static struct s3c2410fb_mach_info h1940_fb_info __initdata = {
 207        .displays = &h1940_lcd,
 208        .num_displays = 1,
 209        .default_display = 0,
 210
 211        .lpcsel =       0x02,
 212        .gpccon =       0xaa940659,
 213        .gpccon_mask =  0xffffc0f0,
 214        .gpcup =        0x0000ffff,
 215        .gpcup_mask =   0xffffffff,
 216        .gpdcon =       0xaa84aaa0,
 217        .gpdcon_mask =  0xffffffff,
 218        .gpdup =        0x0000faff,
 219        .gpdup_mask =   0xffffffff,
 220};
 221
 222static int power_supply_init(struct device *dev)
 223{
 224        return gpio_request(S3C2410_GPF(2), "cable plugged");
 225}
 226
 227static int h1940_is_ac_online(void)
 228{
 229        return !gpio_get_value(S3C2410_GPF(2));
 230}
 231
 232static void power_supply_exit(struct device *dev)
 233{
 234        gpio_free(S3C2410_GPF(2));
 235}
 236
 237static char *h1940_supplicants[] = {
 238        "main-battery",
 239        "backup-battery",
 240};
 241
 242static struct pda_power_pdata power_supply_info = {
 243        .init                   = power_supply_init,
 244        .is_ac_online           = h1940_is_ac_online,
 245        .exit                   = power_supply_exit,
 246        .supplied_to            = h1940_supplicants,
 247        .num_supplicants        = ARRAY_SIZE(h1940_supplicants),
 248};
 249
 250static struct resource power_supply_resources[] = {
 251        [0] = DEFINE_RES_NAMED(IRQ_EINT2, 1, "ac", IORESOURCE_IRQ \
 252                        | IORESOURCE_IRQ_LOWEDGE | IORESOURCE_IRQ_HIGHEDGE),
 253};
 254
 255static struct platform_device power_supply = {
 256        .name           = "pda-power",
 257        .id             = -1,
 258        .dev            = {
 259                                .platform_data =
 260                                        &power_supply_info,
 261        },
 262        .resource       = power_supply_resources,
 263        .num_resources  = ARRAY_SIZE(power_supply_resources),
 264};
 265
 266static const struct s3c_adc_bat_thresh bat_lut_noac[] = {
 267        { .volt = 4070, .cur = 162, .level = 100},
 268        { .volt = 4040, .cur = 165, .level = 95},
 269        { .volt = 4016, .cur = 164, .level = 90},
 270        { .volt = 3996, .cur = 166, .level = 85},
 271        { .volt = 3971, .cur = 168, .level = 80},
 272        { .volt = 3951, .cur = 168, .level = 75},
 273        { .volt = 3931, .cur = 170, .level = 70},
 274        { .volt = 3903, .cur = 172, .level = 65},
 275        { .volt = 3886, .cur = 172, .level = 60},
 276        { .volt = 3858, .cur = 176, .level = 55},
 277        { .volt = 3842, .cur = 176, .level = 50},
 278        { .volt = 3818, .cur = 176, .level = 45},
 279        { .volt = 3789, .cur = 180, .level = 40},
 280        { .volt = 3769, .cur = 180, .level = 35},
 281        { .volt = 3749, .cur = 184, .level = 30},
 282        { .volt = 3732, .cur = 184, .level = 25},
 283        { .volt = 3716, .cur = 184, .level = 20},
 284        { .volt = 3708, .cur = 184, .level = 15},
 285        { .volt = 3716, .cur = 96, .level = 10},
 286        { .volt = 3700, .cur = 96, .level = 5},
 287        { .volt = 3684, .cur = 96, .level = 0},
 288};
 289
 290static const struct s3c_adc_bat_thresh bat_lut_acin[] = {
 291        { .volt = 4130, .cur = 0, .level = 100},
 292        { .volt = 3982, .cur = 0, .level = 50},
 293        { .volt = 3854, .cur = 0, .level = 10},
 294        { .volt = 3841, .cur = 0, .level = 0},
 295};
 296
 297static int h1940_bat_init(void)
 298{
 299        int ret;
 300
 301        ret = gpio_request(H1940_LATCH_SM803_ENABLE, "h1940-charger-enable");
 302        if (ret)
 303                return ret;
 304        gpio_direction_output(H1940_LATCH_SM803_ENABLE, 0);
 305
 306        return 0;
 307
 308}
 309
 310static void h1940_bat_exit(void)
 311{
 312        gpio_free(H1940_LATCH_SM803_ENABLE);
 313}
 314
 315static void h1940_enable_charger(void)
 316{
 317        gpio_set_value(H1940_LATCH_SM803_ENABLE, 1);
 318}
 319
 320static void h1940_disable_charger(void)
 321{
 322        gpio_set_value(H1940_LATCH_SM803_ENABLE, 0);
 323}
 324
 325static struct s3c_adc_bat_pdata h1940_bat_cfg = {
 326        .init = h1940_bat_init,
 327        .exit = h1940_bat_exit,
 328        .enable_charger = h1940_enable_charger,
 329        .disable_charger = h1940_disable_charger,
 330        .gpio_charge_finished = S3C2410_GPF(3),
 331        .gpio_inverted = 1,
 332        .lut_noac = bat_lut_noac,
 333        .lut_noac_cnt = ARRAY_SIZE(bat_lut_noac),
 334        .lut_acin = bat_lut_acin,
 335        .lut_acin_cnt = ARRAY_SIZE(bat_lut_acin),
 336        .volt_channel = 0,
 337        .current_channel = 1,
 338        .volt_mult = 4056,
 339        .current_mult = 1893,
 340        .internal_impedance = 200,
 341        .backup_volt_channel = 3,
 342        /* TODO Check backup volt multiplier */
 343        .backup_volt_mult = 4056,
 344        .backup_volt_min = 0,
 345        .backup_volt_max = 4149288
 346};
 347
 348static struct platform_device h1940_battery = {
 349        .name             = "s3c-adc-battery",
 350        .id               = -1,
 351        .dev = {
 352                .parent = &s3c_device_adc.dev,
 353                .platform_data = &h1940_bat_cfg,
 354        },
 355};
 356
 357static DEFINE_SPINLOCK(h1940_blink_spin);
 358
 359int h1940_led_blink_set(struct gpio_desc *desc, int state,
 360        unsigned long *delay_on, unsigned long *delay_off)
 361{
 362        int blink_gpio, check_gpio1, check_gpio2;
 363        int gpio = desc ? desc_to_gpio(desc) : -EINVAL;
 364
 365        switch (gpio) {
 366        case H1940_LATCH_LED_GREEN:
 367                blink_gpio = S3C2410_GPA(7);
 368                check_gpio1 = S3C2410_GPA(1);
 369                check_gpio2 = S3C2410_GPA(3);
 370                break;
 371        case H1940_LATCH_LED_RED:
 372                blink_gpio = S3C2410_GPA(1);
 373                check_gpio1 = S3C2410_GPA(7);
 374                check_gpio2 = S3C2410_GPA(3);
 375                break;
 376        default:
 377                blink_gpio = S3C2410_GPA(3);
 378                check_gpio1 = S3C2410_GPA(1);
 379                check_gpio2 = S3C2410_GPA(7);
 380                break;
 381        }
 382
 383        if (delay_on && delay_off && !*delay_on && !*delay_off)
 384                *delay_on = *delay_off = 500;
 385
 386        spin_lock(&h1940_blink_spin);
 387
 388        switch (state) {
 389        case GPIO_LED_NO_BLINK_LOW:
 390        case GPIO_LED_NO_BLINK_HIGH:
 391                if (!gpio_get_value(check_gpio1) &&
 392                    !gpio_get_value(check_gpio2))
 393                        gpio_set_value(H1940_LATCH_LED_FLASH, 0);
 394                gpio_set_value(blink_gpio, 0);
 395                if (gpio_is_valid(gpio))
 396                        gpio_set_value(gpio, state);
 397                break;
 398        case GPIO_LED_BLINK:
 399                if (gpio_is_valid(gpio))
 400                        gpio_set_value(gpio, 0);
 401                gpio_set_value(H1940_LATCH_LED_FLASH, 1);
 402                gpio_set_value(blink_gpio, 1);
 403                break;
 404        }
 405
 406        spin_unlock(&h1940_blink_spin);
 407
 408        return 0;
 409}
 410EXPORT_SYMBOL(h1940_led_blink_set);
 411
 412static struct gpio_led h1940_leds_desc[] = {
 413        {
 414                .name                   = "Green",
 415                .default_trigger        = "main-battery-full",
 416                .gpio                   = H1940_LATCH_LED_GREEN,
 417                .retain_state_suspended = 1,
 418        },
 419        {
 420                .name                   = "Red",
 421                .default_trigger
 422                        = "main-battery-charging-blink-full-solid",
 423                .gpio                   = H1940_LATCH_LED_RED,
 424                .retain_state_suspended = 1,
 425        },
 426};
 427
 428static struct gpio_led_platform_data h1940_leds_pdata = {
 429        .num_leds       = ARRAY_SIZE(h1940_leds_desc),
 430        .leds           = h1940_leds_desc,
 431        .gpio_blink_set = h1940_led_blink_set,
 432};
 433
 434static struct platform_device h1940_device_leds = {
 435        .name   = "leds-gpio",
 436        .id     = -1,
 437        .dev    = {
 438                        .platform_data = &h1940_leds_pdata,
 439        },
 440};
 441
 442static struct platform_device h1940_device_bluetooth = {
 443        .name             = "h1940-bt",
 444        .id               = -1,
 445};
 446
 447static void h1940_set_mmc_power(unsigned char power_mode, unsigned short vdd)
 448{
 449        switch (power_mode) {
 450        case MMC_POWER_OFF:
 451                gpio_set_value(H1940_LATCH_SD_POWER, 0);
 452                break;
 453        case MMC_POWER_UP:
 454        case MMC_POWER_ON:
 455                gpio_set_value(H1940_LATCH_SD_POWER, 1);
 456                break;
 457        default:
 458                break;
 459        }
 460}
 461
 462static struct s3c24xx_mci_pdata h1940_mmc_cfg __initdata = {
 463        .set_power     = h1940_set_mmc_power,
 464        .ocr_avail     = MMC_VDD_32_33,
 465};
 466
 467static struct gpiod_lookup_table h1940_mmc_gpio_table = {
 468        .dev_id = "s3c2410-sdi",
 469        .table = {
 470                /* Card detect S3C2410_GPF(5) */
 471                GPIO_LOOKUP("GPF", 5, "cd", GPIO_ACTIVE_LOW),
 472                /* Write protect S3C2410_GPH(8) */
 473                GPIO_LOOKUP("GPH", 8, "wp", GPIO_ACTIVE_LOW),
 474                { },
 475        },
 476};
 477
 478static struct pwm_lookup h1940_pwm_lookup[] = {
 479        PWM_LOOKUP("samsung-pwm", 0, "pwm-backlight", NULL, 36296,
 480                   PWM_POLARITY_NORMAL),
 481};
 482
 483static int h1940_backlight_init(struct device *dev)
 484{
 485        gpio_request(S3C2410_GPB(0), "Backlight");
 486
 487        gpio_direction_output(S3C2410_GPB(0), 0);
 488        s3c_gpio_setpull(S3C2410_GPB(0), S3C_GPIO_PULL_NONE);
 489        s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0);
 490        gpio_set_value(H1940_LATCH_MAX1698_nSHUTDOWN, 1);
 491
 492        return 0;
 493}
 494
 495static int h1940_backlight_notify(struct device *dev, int brightness)
 496{
 497        if (!brightness) {
 498                gpio_direction_output(S3C2410_GPB(0), 1);
 499                gpio_set_value(H1940_LATCH_MAX1698_nSHUTDOWN, 0);
 500        } else {
 501                gpio_direction_output(S3C2410_GPB(0), 0);
 502                s3c_gpio_setpull(S3C2410_GPB(0), S3C_GPIO_PULL_NONE);
 503                s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0);
 504                gpio_set_value(H1940_LATCH_MAX1698_nSHUTDOWN, 1);
 505        }
 506        return brightness;
 507}
 508
 509static void h1940_backlight_exit(struct device *dev)
 510{
 511        gpio_direction_output(S3C2410_GPB(0), 1);
 512        gpio_set_value(H1940_LATCH_MAX1698_nSHUTDOWN, 0);
 513}
 514
 515
 516static struct platform_pwm_backlight_data backlight_data = {
 517        .max_brightness = 100,
 518        .dft_brightness = 50,
 519        .enable_gpio    = -1,
 520        .init           = h1940_backlight_init,
 521        .notify         = h1940_backlight_notify,
 522        .exit           = h1940_backlight_exit,
 523};
 524
 525static struct platform_device h1940_backlight = {
 526        .name = "pwm-backlight",
 527        .dev  = {
 528                .parent = &samsung_device_pwm.dev,
 529                .platform_data = &backlight_data,
 530        },
 531        .id   = -1,
 532};
 533
 534static void h1940_lcd_power_set(struct plat_lcd_data *pd,
 535                                        unsigned int power)
 536{
 537        int value, retries = 100;
 538
 539        if (!power) {
 540                gpio_set_value(S3C2410_GPC(0), 0);
 541                /* wait for 3ac */
 542                do {
 543                        value = gpio_get_value(S3C2410_GPC(6));
 544                } while (value && retries--);
 545
 546                gpio_set_value(H1940_LATCH_LCD_P2, 0);
 547                gpio_set_value(H1940_LATCH_LCD_P3, 0);
 548                gpio_set_value(H1940_LATCH_LCD_P4, 0);
 549
 550                gpio_direction_output(S3C2410_GPC(1), 0);
 551                gpio_direction_output(S3C2410_GPC(4), 0);
 552
 553                gpio_set_value(H1940_LATCH_LCD_P1, 0);
 554                gpio_set_value(H1940_LATCH_LCD_P0, 0);
 555
 556                gpio_set_value(S3C2410_GPC(5), 0);
 557
 558        } else {
 559                gpio_set_value(H1940_LATCH_LCD_P0, 1);
 560                gpio_set_value(H1940_LATCH_LCD_P1, 1);
 561
 562                gpio_direction_input(S3C2410_GPC(1));
 563                gpio_direction_input(S3C2410_GPC(4));
 564                mdelay(10);
 565                s3c_gpio_cfgpin(S3C2410_GPC(1), S3C_GPIO_SFN(2));
 566                s3c_gpio_cfgpin(S3C2410_GPC(4), S3C_GPIO_SFN(2));
 567
 568                gpio_set_value(S3C2410_GPC(5), 1);
 569                gpio_set_value(S3C2410_GPC(0), 1);
 570
 571                gpio_set_value(H1940_LATCH_LCD_P3, 1);
 572                gpio_set_value(H1940_LATCH_LCD_P2, 1);
 573                gpio_set_value(H1940_LATCH_LCD_P4, 1);
 574        }
 575}
 576
 577static struct plat_lcd_data h1940_lcd_power_data = {
 578        .set_power      = h1940_lcd_power_set,
 579};
 580
 581static struct platform_device h1940_lcd_powerdev = {
 582        .name                   = "platform-lcd",
 583        .dev.parent             = &s3c_device_lcd.dev,
 584        .dev.platform_data      = &h1940_lcd_power_data,
 585};
 586
 587static struct uda1380_platform_data uda1380_info = {
 588        .gpio_power     = H1940_LATCH_UDA_POWER,
 589        .gpio_reset     = S3C2410_GPA(12),
 590        .dac_clk        = UDA1380_DAC_CLK_SYSCLK,
 591};
 592
 593static struct i2c_board_info h1940_i2c_devices[] = {
 594        {
 595                I2C_BOARD_INFO("uda1380", 0x1a),
 596                .platform_data = &uda1380_info,
 597        },
 598};
 599
 600#define DECLARE_BUTTON(p, k, n, w)      \
 601        {                               \
 602                .gpio           = p,    \
 603                .code           = k,    \
 604                .desc           = n,    \
 605                .wakeup         = w,    \
 606                .active_low     = 1,    \
 607        }
 608
 609static struct gpio_keys_button h1940_buttons[] = {
 610        DECLARE_BUTTON(S3C2410_GPF(0),       KEY_POWER,          "Power", 1),
 611        DECLARE_BUTTON(S3C2410_GPF(6),       KEY_ENTER,         "Select", 1),
 612        DECLARE_BUTTON(S3C2410_GPF(7),      KEY_RECORD,         "Record", 0),
 613        DECLARE_BUTTON(S3C2410_GPG(0),         KEY_F11,       "Calendar", 0),
 614        DECLARE_BUTTON(S3C2410_GPG(2),         KEY_F12,       "Contacts", 0),
 615        DECLARE_BUTTON(S3C2410_GPG(3),        KEY_MAIL,           "Mail", 0),
 616        DECLARE_BUTTON(S3C2410_GPG(6),        KEY_LEFT,     "Left_arrow", 0),
 617        DECLARE_BUTTON(S3C2410_GPG(7),    KEY_HOMEPAGE,           "Home", 0),
 618        DECLARE_BUTTON(S3C2410_GPG(8),       KEY_RIGHT,    "Right_arrow", 0),
 619        DECLARE_BUTTON(S3C2410_GPG(9),          KEY_UP,       "Up_arrow", 0),
 620        DECLARE_BUTTON(S3C2410_GPG(10),       KEY_DOWN,     "Down_arrow", 0),
 621};
 622
 623static struct gpio_keys_platform_data h1940_buttons_data = {
 624        .buttons        = h1940_buttons,
 625        .nbuttons       = ARRAY_SIZE(h1940_buttons),
 626};
 627
 628static struct platform_device h1940_dev_buttons = {
 629        .name           = "gpio-keys",
 630        .id             = -1,
 631        .dev            = {
 632                .platform_data  = &h1940_buttons_data,
 633        }
 634};
 635
 636static struct platform_device *h1940_devices[] __initdata = {
 637        &h1940_dev_buttons,
 638        &s3c_device_ohci,
 639        &s3c_device_lcd,
 640        &s3c_device_wdt,
 641        &s3c_device_i2c0,
 642        &s3c_device_iis,
 643        &s3c_device_usbgadget,
 644        &h1940_device_leds,
 645        &h1940_device_bluetooth,
 646        &s3c_device_sdi,
 647        &s3c_device_rtc,
 648        &samsung_device_pwm,
 649        &h1940_backlight,
 650        &h1940_lcd_powerdev,
 651        &s3c_device_adc,
 652        &s3c_device_ts,
 653        &power_supply,
 654        &h1940_battery,
 655};
 656
 657static void __init h1940_map_io(void)
 658{
 659        s3c24xx_init_io(h1940_iodesc, ARRAY_SIZE(h1940_iodesc));
 660        s3c24xx_init_uarts(h1940_uartcfgs, ARRAY_SIZE(h1940_uartcfgs));
 661        samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 662
 663        /* setup PM */
 664
 665#ifdef CONFIG_PM_H1940
 666        memcpy(phys_to_virt(H1940_SUSPEND_RESUMEAT), h1940_pm_return, 1024);
 667#endif
 668        s3c_pm_init();
 669
 670        /* Add latch gpio chip, set latch initial value */
 671        h1940_latch_control(0, 0);
 672        WARN_ON(gpiochip_add_data(&h1940_latch_gpiochip, NULL));
 673}
 674
 675static void __init h1940_init_time(void)
 676{
 677        s3c2410_init_clocks(12000000);
 678        samsung_timer_init();
 679}
 680
 681/* H1940 and RX3715 need to reserve this for suspend */
 682static void __init h1940_reserve(void)
 683{
 684        memblock_reserve(0x30003000, 0x1000);
 685        memblock_reserve(0x30081000, 0x1000);
 686}
 687
 688static void __init h1940_init(void)
 689{
 690        u32 tmp;
 691
 692        s3c24xx_fb_set_platdata(&h1940_fb_info);
 693        gpiod_add_lookup_table(&h1940_mmc_gpio_table);
 694        s3c24xx_mci_set_platdata(&h1940_mmc_cfg);
 695        s3c24xx_udc_set_platdata(&h1940_udc_cfg);
 696        s3c24xx_ts_set_platdata(&h1940_ts_cfg);
 697        s3c_i2c0_set_platdata(NULL);
 698
 699        /* Turn off suspend on both USB ports, and switch the
 700         * selectable USB port to USB device mode. */
 701
 702        s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
 703                              S3C2410_MISCCR_USBSUSPND0 |
 704                              S3C2410_MISCCR_USBSUSPND1, 0x0);
 705
 706        tmp =   (0x78 << S3C24XX_PLL_MDIV_SHIFT)
 707              | (0x02 << S3C24XX_PLL_PDIV_SHIFT)
 708              | (0x03 << S3C24XX_PLL_SDIV_SHIFT);
 709        writel(tmp, S3C2410_UPLLCON);
 710
 711        gpio_request(S3C2410_GPC(0), "LCD power");
 712        gpio_request(S3C2410_GPC(1), "LCD power");
 713        gpio_request(S3C2410_GPC(4), "LCD power");
 714        gpio_request(S3C2410_GPC(5), "LCD power");
 715        gpio_request(S3C2410_GPC(6), "LCD power");
 716        gpio_request(H1940_LATCH_LCD_P0, "LCD power");
 717        gpio_request(H1940_LATCH_LCD_P1, "LCD power");
 718        gpio_request(H1940_LATCH_LCD_P2, "LCD power");
 719        gpio_request(H1940_LATCH_LCD_P3, "LCD power");
 720        gpio_request(H1940_LATCH_LCD_P4, "LCD power");
 721        gpio_request(H1940_LATCH_MAX1698_nSHUTDOWN, "LCD power");
 722        gpio_direction_output(S3C2410_GPC(0), 0);
 723        gpio_direction_output(S3C2410_GPC(1), 0);
 724        gpio_direction_output(S3C2410_GPC(4), 0);
 725        gpio_direction_output(S3C2410_GPC(5), 0);
 726        gpio_direction_input(S3C2410_GPC(6));
 727        gpio_direction_output(H1940_LATCH_LCD_P0, 0);
 728        gpio_direction_output(H1940_LATCH_LCD_P1, 0);
 729        gpio_direction_output(H1940_LATCH_LCD_P2, 0);
 730        gpio_direction_output(H1940_LATCH_LCD_P3, 0);
 731        gpio_direction_output(H1940_LATCH_LCD_P4, 0);
 732        gpio_direction_output(H1940_LATCH_MAX1698_nSHUTDOWN, 0);
 733
 734        gpio_request(H1940_LATCH_SD_POWER, "SD power");
 735        gpio_direction_output(H1940_LATCH_SD_POWER, 0);
 736
 737        pwm_add_table(h1940_pwm_lookup, ARRAY_SIZE(h1940_pwm_lookup));
 738        platform_add_devices(h1940_devices, ARRAY_SIZE(h1940_devices));
 739
 740        gpio_request(S3C2410_GPA(1), "Red LED blink");
 741        gpio_request(S3C2410_GPA(3), "Blue LED blink");
 742        gpio_request(S3C2410_GPA(7), "Green LED blink");
 743        gpio_request(H1940_LATCH_LED_FLASH, "LED blink");
 744        gpio_direction_output(S3C2410_GPA(1), 0);
 745        gpio_direction_output(S3C2410_GPA(3), 0);
 746        gpio_direction_output(S3C2410_GPA(7), 0);
 747        gpio_direction_output(H1940_LATCH_LED_FLASH, 0);
 748
 749        i2c_register_board_info(0, h1940_i2c_devices,
 750                ARRAY_SIZE(h1940_i2c_devices));
 751}
 752
 753MACHINE_START(H1940, "IPAQ-H1940")
 754        /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
 755        .atag_offset    = 0x100,
 756        .map_io         = h1940_map_io,
 757        .reserve        = h1940_reserve,
 758        .init_irq       = s3c2410_init_irq,
 759        .init_machine   = h1940_init,
 760        .init_time      = h1940_init_time,
 761MACHINE_END
 762