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