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