linux/arch/arm/mach-s3c24xx/mach-gta02.c
<<
>>
Prefs
   1/*
   2 * S3C2442 Machine Support for Openmoko GTA02 / FreeRunner.
   3 *
   4 * Copyright (C) 2006-2009 by Openmoko, Inc.
   5 * Authors: Harald Welte <laforge@openmoko.org>
   6 *          Andy Green <andy@openmoko.org>
   7 *          Werner Almesberger <werner@openmoko.org>
   8 * All rights reserved.
   9 *
  10 * This program is free software; you can redistribute it and/or
  11 * modify it under the terms of the GNU General Public License as
  12 * published by the Free Software Foundation; either version 2 of
  13 * the License, or (at your option) any later version.
  14 *
  15 * This program is distributed in the hope that it will be useful,
  16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18 * GNU General Public License for more details.
  19 *
  20 * You should have received a copy of the GNU General Public License
  21 * along with this program; if not, write to the Free Software
  22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  23 * MA 02111-1307 USA
  24 */
  25
  26#include <linux/kernel.h>
  27#include <linux/types.h>
  28#include <linux/interrupt.h>
  29#include <linux/list.h>
  30#include <linux/delay.h>
  31#include <linux/timer.h>
  32#include <linux/init.h>
  33#include <linux/gpio.h>
  34#include <linux/gpio_keys.h>
  35#include <linux/workqueue.h>
  36#include <linux/platform_device.h>
  37#include <linux/serial_core.h>
  38#include <linux/input.h>
  39#include <linux/io.h>
  40#include <linux/i2c.h>
  41
  42#include <linux/mmc/host.h>
  43
  44#include <linux/mfd/pcf50633/adc.h>
  45#include <linux/mfd/pcf50633/backlight.h>
  46#include <linux/mfd/pcf50633/core.h>
  47#include <linux/mfd/pcf50633/gpio.h>
  48#include <linux/mfd/pcf50633/mbc.h>
  49#include <linux/mfd/pcf50633/pmic.h>
  50
  51#include <linux/mtd/mtd.h>
  52#include <linux/mtd/nand.h>
  53#include <linux/mtd/nand_ecc.h>
  54#include <linux/mtd/partitions.h>
  55#include <linux/mtd/physmap.h>
  56
  57#include <linux/regulator/machine.h>
  58
  59#include <linux/spi/spi.h>
  60#include <linux/spi/s3c24xx.h>
  61
  62#include <asm/irq.h>
  63#include <asm/mach-types.h>
  64#include <asm/mach/arch.h>
  65#include <asm/mach/map.h>
  66#include <asm/mach/irq.h>
  67
  68#include <linux/platform_data/i2c-s3c2410.h>
  69#include <linux/platform_data/mtd-nand-s3c2410.h>
  70#include <linux/platform_data/touchscreen-s3c2410.h>
  71#include <linux/platform_data/usb-ohci-s3c2410.h>
  72#include <linux/platform_data/usb-s3c2410_udc.h>
  73
  74#include <mach/fb.h>
  75#include <mach/hardware.h>
  76#include <mach/regs-gpio.h>
  77#include <mach/regs-irq.h>
  78#include <mach/gpio-samsung.h>
  79
  80#include <plat/cpu.h>
  81#include <plat/devs.h>
  82#include <plat/gpio-cfg.h>
  83#include <plat/pm.h>
  84#include <plat/regs-serial.h>
  85#include <plat/samsung-time.h>
  86
  87#include "common.h"
  88#include "gta02.h"
  89
  90static struct pcf50633 *gta02_pcf;
  91
  92/*
  93 * This gets called frequently when we paniced.
  94 */
  95
  96static long gta02_panic_blink(int state)
  97{
  98        long delay = 0;
  99        char led;
 100
 101        led = (state) ? 1 : 0;
 102        gpio_direction_output(GTA02_GPIO_AUX_LED, led);
 103
 104        return delay;
 105}
 106
 107
 108static struct map_desc gta02_iodesc[] __initdata = {
 109        {
 110                .virtual        = 0xe0000000,
 111                .pfn            = __phys_to_pfn(S3C2410_CS3 + 0x01000000),
 112                .length         = SZ_1M,
 113                .type           = MT_DEVICE
 114        },
 115};
 116
 117#define UCON (S3C2410_UCON_DEFAULT | S3C2443_UCON_RXERR_IRQEN)
 118#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB)
 119#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
 120
 121static struct s3c2410_uartcfg gta02_uartcfgs[] = {
 122        [0] = {
 123                .hwport         = 0,
 124                .flags          = 0,
 125                .ucon           = UCON,
 126                .ulcon          = ULCON,
 127                .ufcon          = UFCON,
 128        },
 129        [1] = {
 130                .hwport         = 1,
 131                .flags          = 0,
 132                .ucon           = UCON,
 133                .ulcon          = ULCON,
 134                .ufcon          = UFCON,
 135        },
 136        [2] = {
 137                .hwport         = 2,
 138                .flags          = 0,
 139                .ucon           = UCON,
 140                .ulcon          = ULCON,
 141                .ufcon          = UFCON,
 142        },
 143};
 144
 145#ifdef CONFIG_CHARGER_PCF50633
 146/*
 147 * On GTA02 the 1A charger features a 48K resistor to 0V on the ID pin.
 148 * We use this to recognize that we can pull 1A from the USB socket.
 149 *
 150 * These constants are the measured pcf50633 ADC levels with the 1A
 151 * charger / 48K resistor, and with no pulldown resistor.
 152 */
 153
 154#define ADC_NOM_CHG_DETECT_1A 6
 155#define ADC_NOM_CHG_DETECT_USB 43
 156
 157static void
 158gta02_configure_pmu_for_charger(struct pcf50633 *pcf, void *unused, int res)
 159{
 160        int  ma;
 161
 162        /* Interpret charger type */
 163        if (res < ((ADC_NOM_CHG_DETECT_USB + ADC_NOM_CHG_DETECT_1A) / 2)) {
 164
 165                /*
 166                 * Sanity - stop GPO driving out now that we have a 1A charger
 167                 * GPO controls USB Host power generation on GTA02
 168                 */
 169                pcf50633_gpio_set(pcf, PCF50633_GPO, 0);
 170
 171                ma = 1000;
 172        } else
 173                ma = 100;
 174
 175        pcf50633_mbc_usb_curlim_set(pcf, ma);
 176}
 177
 178static struct delayed_work gta02_charger_work;
 179static int gta02_usb_vbus_draw;
 180
 181static void gta02_charger_worker(struct work_struct *work)
 182{
 183        if (gta02_usb_vbus_draw) {
 184                pcf50633_mbc_usb_curlim_set(gta02_pcf, gta02_usb_vbus_draw);
 185                return;
 186        }
 187
 188#ifdef CONFIG_PCF50633_ADC
 189        pcf50633_adc_async_read(gta02_pcf,
 190                                PCF50633_ADCC1_MUX_ADCIN1,
 191                                PCF50633_ADCC1_AVERAGE_16,
 192                                gta02_configure_pmu_for_charger,
 193                                NULL);
 194#else
 195        /*
 196         * If the PCF50633 ADC is disabled we fallback to a
 197         * 100mA limit for safety.
 198         */
 199        pcf50633_mbc_usb_curlim_set(pcf, 100);
 200#endif
 201}
 202
 203#define GTA02_CHARGER_CONFIGURE_TIMEOUT ((3000 * HZ) / 1000)
 204
 205static void gta02_pmu_event_callback(struct pcf50633 *pcf, int irq)
 206{
 207        if (irq == PCF50633_IRQ_USBINS) {
 208                schedule_delayed_work(&gta02_charger_work,
 209                                      GTA02_CHARGER_CONFIGURE_TIMEOUT);
 210
 211                return;
 212        }
 213
 214        if (irq == PCF50633_IRQ_USBREM) {
 215                cancel_delayed_work_sync(&gta02_charger_work);
 216                gta02_usb_vbus_draw = 0;
 217        }
 218}
 219
 220static void gta02_udc_vbus_draw(unsigned int ma)
 221{
 222        if (!gta02_pcf)
 223                return;
 224
 225        gta02_usb_vbus_draw = ma;
 226
 227        schedule_delayed_work(&gta02_charger_work,
 228                              GTA02_CHARGER_CONFIGURE_TIMEOUT);
 229}
 230#else /* !CONFIG_CHARGER_PCF50633 */
 231#define gta02_pmu_event_callback        NULL
 232#define gta02_udc_vbus_draw             NULL
 233#endif
 234
 235/*
 236 * This is called when pc50633 is probed, unfortunately quite late in the
 237 * day since it is an I2C bus device. Here we can belatedly define some
 238 * platform devices with the advantage that we can mark the pcf50633 as the
 239 * parent. This makes them get suspended and resumed with their parent
 240 * the pcf50633 still around.
 241 */
 242
 243static void gta02_pmu_attach_child_devices(struct pcf50633 *pcf);
 244
 245
 246static char *gta02_batteries[] = {
 247        "battery",
 248};
 249
 250static struct pcf50633_bl_platform_data gta02_backlight_data = {
 251        .default_brightness = 0x3f,
 252        .default_brightness_limit = 0,
 253        .ramp_time = 5,
 254};
 255
 256static struct pcf50633_platform_data gta02_pcf_pdata = {
 257        .resumers = {
 258                [0] =   PCF50633_INT1_USBINS |
 259                        PCF50633_INT1_USBREM |
 260                        PCF50633_INT1_ALARM,
 261                [1] =   PCF50633_INT2_ONKEYF,
 262                [2] =   PCF50633_INT3_ONKEY1S,
 263                [3] =   PCF50633_INT4_LOWSYS |
 264                        PCF50633_INT4_LOWBAT |
 265                        PCF50633_INT4_HIGHTMP,
 266        },
 267
 268        .batteries = gta02_batteries,
 269        .num_batteries = ARRAY_SIZE(gta02_batteries),
 270
 271        .charger_reference_current_ma = 1000,
 272
 273        .backlight_data = &gta02_backlight_data,
 274
 275        .reg_init_data = {
 276                [PCF50633_REGULATOR_AUTO] = {
 277                        .constraints = {
 278                                .min_uV = 3300000,
 279                                .max_uV = 3300000,
 280                                .valid_modes_mask = REGULATOR_MODE_NORMAL,
 281                                .always_on = 1,
 282                                .apply_uV = 1,
 283                        },
 284                },
 285                [PCF50633_REGULATOR_DOWN1] = {
 286                        .constraints = {
 287                                .min_uV = 1300000,
 288                                .max_uV = 1600000,
 289                                .valid_modes_mask = REGULATOR_MODE_NORMAL,
 290                                .always_on = 1,
 291                                .apply_uV = 1,
 292                        },
 293                },
 294                [PCF50633_REGULATOR_DOWN2] = {
 295                        .constraints = {
 296                                .min_uV = 1800000,
 297                                .max_uV = 1800000,
 298                                .valid_modes_mask = REGULATOR_MODE_NORMAL,
 299                                .apply_uV = 1,
 300                                .always_on = 1,
 301                        },
 302                },
 303                [PCF50633_REGULATOR_HCLDO] = {
 304                        .constraints = {
 305                                .min_uV = 2000000,
 306                                .max_uV = 3300000,
 307                                .valid_modes_mask = REGULATOR_MODE_NORMAL,
 308                                .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
 309                                                REGULATOR_CHANGE_STATUS,
 310                        },
 311                },
 312                [PCF50633_REGULATOR_LDO1] = {
 313                        .constraints = {
 314                                .min_uV = 3300000,
 315                                .max_uV = 3300000,
 316                                .valid_modes_mask = REGULATOR_MODE_NORMAL,
 317                                .valid_ops_mask = REGULATOR_CHANGE_STATUS,
 318                                .apply_uV = 1,
 319                        },
 320                },
 321                [PCF50633_REGULATOR_LDO2] = {
 322                        .constraints = {
 323                                .min_uV = 3300000,
 324                                .max_uV = 3300000,
 325                                .valid_modes_mask = REGULATOR_MODE_NORMAL,
 326                                .apply_uV = 1,
 327                        },
 328                },
 329                [PCF50633_REGULATOR_LDO3] = {
 330                        .constraints = {
 331                                .min_uV = 3000000,
 332                                .max_uV = 3000000,
 333                                .valid_modes_mask = REGULATOR_MODE_NORMAL,
 334                                .apply_uV = 1,
 335                        },
 336                },
 337                [PCF50633_REGULATOR_LDO4] = {
 338                        .constraints = {
 339                                .min_uV = 3200000,
 340                                .max_uV = 3200000,
 341                                .valid_modes_mask = REGULATOR_MODE_NORMAL,
 342                                .valid_ops_mask = REGULATOR_CHANGE_STATUS,
 343                                .apply_uV = 1,
 344                        },
 345                },
 346                [PCF50633_REGULATOR_LDO5] = {
 347                        .constraints = {
 348                                .min_uV = 3000000,
 349                                .max_uV = 3000000,
 350                                .valid_modes_mask = REGULATOR_MODE_NORMAL,
 351                                .valid_ops_mask = REGULATOR_CHANGE_STATUS,
 352                                .apply_uV = 1,
 353                        },
 354                },
 355                [PCF50633_REGULATOR_LDO6] = {
 356                        .constraints = {
 357                                .min_uV = 3000000,
 358                                .max_uV = 3000000,
 359                                .valid_modes_mask = REGULATOR_MODE_NORMAL,
 360                        },
 361                },
 362                [PCF50633_REGULATOR_MEMLDO] = {
 363                        .constraints = {
 364                                .min_uV = 1800000,
 365                                .max_uV = 1800000,
 366                                .valid_modes_mask = REGULATOR_MODE_NORMAL,
 367                        },
 368                },
 369
 370        },
 371        .probe_done = gta02_pmu_attach_child_devices,
 372        .mbc_event_callback = gta02_pmu_event_callback,
 373};
 374
 375
 376/* NOR Flash. */
 377
 378#define GTA02_FLASH_BASE        0x18000000 /* GCS3 */
 379#define GTA02_FLASH_SIZE        0x200000 /* 2MBytes */
 380
 381static struct physmap_flash_data gta02_nor_flash_data = {
 382        .width          = 2,
 383};
 384
 385static struct resource gta02_nor_flash_resource =
 386        DEFINE_RES_MEM(GTA02_FLASH_BASE, GTA02_FLASH_SIZE);
 387
 388static struct platform_device gta02_nor_flash = {
 389        .name           = "physmap-flash",
 390        .id             = 0,
 391        .dev            = {
 392                .platform_data  = &gta02_nor_flash_data,
 393        },
 394        .resource       = &gta02_nor_flash_resource,
 395        .num_resources  = 1,
 396};
 397
 398
 399static struct platform_device s3c24xx_pwm_device = {
 400        .name           = "s3c24xx_pwm",
 401        .num_resources  = 0,
 402};
 403
 404static struct platform_device gta02_dfbmcs320_device = {
 405        .name = "dfbmcs320",
 406};
 407
 408static struct i2c_board_info gta02_i2c_devs[] __initdata = {
 409        {
 410                I2C_BOARD_INFO("pcf50633", 0x73),
 411                .irq = GTA02_IRQ_PCF50633,
 412                .platform_data = &gta02_pcf_pdata,
 413        },
 414        {
 415                I2C_BOARD_INFO("wm8753", 0x1a),
 416        },
 417};
 418
 419static struct s3c2410_nand_set __initdata gta02_nand_sets[] = {
 420        [0] = {
 421                /*
 422                 * This name is also hard-coded in the boot loaders, so
 423                 * changing it would would require all users to upgrade
 424                 * their boot loaders, some of which are stored in a NOR
 425                 * that is considered to be immutable.
 426                 */
 427                .name           = "neo1973-nand",
 428                .nr_chips       = 1,
 429                .flash_bbt      = 1,
 430        },
 431};
 432
 433/*
 434 * Choose a set of timings derived from S3C@2442B MCP54
 435 * data sheet (K5D2G13ACM-D075 MCP Memory).
 436 */
 437
 438static struct s3c2410_platform_nand __initdata gta02_nand_info = {
 439        .tacls          = 0,
 440        .twrph0         = 25,
 441        .twrph1         = 15,
 442        .nr_sets        = ARRAY_SIZE(gta02_nand_sets),
 443        .sets           = gta02_nand_sets,
 444};
 445
 446
 447/* Get PMU to set USB current limit accordingly. */
 448static struct s3c2410_udc_mach_info gta02_udc_cfg __initdata = {
 449        .vbus_draw      = gta02_udc_vbus_draw,
 450        .pullup_pin = GTA02_GPIO_USB_PULLUP,
 451};
 452
 453/* USB */
 454static struct s3c2410_hcd_info gta02_usb_info __initdata = {
 455        .port[0]        = {
 456                .flags  = S3C_HCDFLG_USED,
 457        },
 458        .port[1]        = {
 459                .flags  = 0,
 460        },
 461};
 462
 463/* Touchscreen */
 464static struct s3c2410_ts_mach_info gta02_ts_info = {
 465        .delay                  = 10000,
 466        .presc                  = 0xff, /* slow as we can go */
 467        .oversampling_shift     = 2,
 468};
 469
 470/* Buttons */
 471static struct gpio_keys_button gta02_buttons[] = {
 472        {
 473                .gpio = GTA02_GPIO_AUX_KEY,
 474                .code = KEY_PHONE,
 475                .desc = "Aux",
 476                .type = EV_KEY,
 477                .debounce_interval = 100,
 478        },
 479        {
 480                .gpio = GTA02_GPIO_HOLD_KEY,
 481                .code = KEY_PAUSE,
 482                .desc = "Hold",
 483                .type = EV_KEY,
 484                .debounce_interval = 100,
 485        },
 486};
 487
 488static struct gpio_keys_platform_data gta02_buttons_pdata = {
 489        .buttons = gta02_buttons,
 490        .nbuttons = ARRAY_SIZE(gta02_buttons),
 491};
 492
 493static struct platform_device gta02_buttons_device = {
 494        .name = "gpio-keys",
 495        .id = -1,
 496        .dev = {
 497                .platform_data = &gta02_buttons_pdata,
 498        },
 499};
 500
 501static void __init gta02_map_io(void)
 502{
 503        s3c24xx_init_io(gta02_iodesc, ARRAY_SIZE(gta02_iodesc));
 504        s3c24xx_init_clocks(12000000);
 505        s3c24xx_init_uarts(gta02_uartcfgs, ARRAY_SIZE(gta02_uartcfgs));
 506        samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 507}
 508
 509
 510/* These are the guys that don't need to be children of PMU. */
 511
 512static struct platform_device *gta02_devices[] __initdata = {
 513        &s3c_device_ohci,
 514        &s3c_device_wdt,
 515        &s3c_device_sdi,
 516        &s3c_device_usbgadget,
 517        &s3c_device_nand,
 518        &gta02_nor_flash,
 519        &s3c24xx_pwm_device,
 520        &s3c_device_iis,
 521        &s3c_device_i2c0,
 522        &gta02_dfbmcs320_device,
 523        &gta02_buttons_device,
 524        &s3c_device_adc,
 525        &s3c_device_ts,
 526};
 527
 528/* These guys DO need to be children of PMU. */
 529
 530static struct platform_device *gta02_devices_pmu_children[] = {
 531};
 532
 533
 534/*
 535 * This is called when pc50633 is probed, quite late in the day since it is an
 536 * I2C bus device.  Here we can define platform devices with the advantage that
 537 * we can mark the pcf50633 as the parent.  This makes them get suspended and
 538 * resumed with their parent the pcf50633 still around.  All devices whose
 539 * operation depends on something from pcf50633 must have this relationship
 540 * made explicit like this, or suspend and resume will become an unreliable
 541 * hellworld.
 542 */
 543
 544static void gta02_pmu_attach_child_devices(struct pcf50633 *pcf)
 545{
 546        int n;
 547
 548        /* Grab a copy of the now probed PMU pointer. */
 549        gta02_pcf = pcf;
 550
 551        for (n = 0; n < ARRAY_SIZE(gta02_devices_pmu_children); n++)
 552                gta02_devices_pmu_children[n]->dev.parent = pcf->dev;
 553
 554        platform_add_devices(gta02_devices_pmu_children,
 555                             ARRAY_SIZE(gta02_devices_pmu_children));
 556}
 557
 558static void gta02_poweroff(void)
 559{
 560        pcf50633_reg_set_bit_mask(gta02_pcf, PCF50633_REG_OOCSHDWN, 1, 1);
 561}
 562
 563static void __init gta02_machine_init(void)
 564{
 565        /* Set the panic callback to turn AUX LED on or off. */
 566        panic_blink = gta02_panic_blink;
 567
 568        s3c_pm_init();
 569
 570#ifdef CONFIG_CHARGER_PCF50633
 571        INIT_DELAYED_WORK(&gta02_charger_work, gta02_charger_worker);
 572#endif
 573
 574        s3c24xx_udc_set_platdata(&gta02_udc_cfg);
 575        s3c24xx_ts_set_platdata(&gta02_ts_info);
 576        s3c_ohci_set_platdata(&gta02_usb_info);
 577        s3c_nand_set_platdata(&gta02_nand_info);
 578        s3c_i2c0_set_platdata(NULL);
 579
 580        i2c_register_board_info(0, gta02_i2c_devs, ARRAY_SIZE(gta02_i2c_devs));
 581
 582        platform_add_devices(gta02_devices, ARRAY_SIZE(gta02_devices));
 583        pm_power_off = gta02_poweroff;
 584
 585        regulator_has_full_constraints();
 586}
 587
 588
 589MACHINE_START(NEO1973_GTA02, "GTA02")
 590        /* Maintainer: Nelson Castillo <arhuaco@freaks-unidos.net> */
 591        .atag_offset    = 0x100,
 592        .map_io         = gta02_map_io,
 593        .init_irq       = s3c2442_init_irq,
 594        .init_machine   = gta02_machine_init,
 595        .init_time      = samsung_timer_init,
 596        .restart        = s3c244x_restart,
 597MACHINE_END
 598