linux/arch/arm/mach-pxa/balloon3.c
<<
>>
Prefs
   1/*
   2 *  linux/arch/arm/mach-pxa/balloon3.c
   3 *
   4 *  Support for Balloonboard.org Balloon3 board.
   5 *
   6 *  Author:     Nick Bane, Wookey, Jonathan McDowell
   7 *  Created:    June, 2006
   8 *  Copyright:  Toby Churchill Ltd
   9 *  Derived from mainstone.c, by Nico Pitre
  10 *
  11 *  This program is free software; you can redistribute it and/or modify
  12 *  it under the terms of the GNU General Public License version 2 as
  13 *  published by the Free Software Foundation.
  14 */
  15
  16#include <linux/init.h>
  17#include <linux/platform_device.h>
  18#include <linux/interrupt.h>
  19#include <linux/sched.h>
  20#include <linux/bitops.h>
  21#include <linux/fb.h>
  22#include <linux/gpio.h>
  23#include <linux/ioport.h>
  24#include <linux/ucb1400.h>
  25#include <linux/mtd/mtd.h>
  26#include <linux/mtd/partitions.h>
  27#include <linux/types.h>
  28#include <linux/i2c/pcf857x.h>
  29#include <linux/i2c/pxa-i2c.h>
  30#include <linux/mtd/nand.h>
  31#include <linux/mtd/physmap.h>
  32#include <linux/regulator/max1586.h>
  33
  34#include <asm/setup.h>
  35#include <asm/mach-types.h>
  36#include <asm/irq.h>
  37#include <asm/sizes.h>
  38
  39#include <asm/mach/arch.h>
  40#include <asm/mach/map.h>
  41#include <asm/mach/irq.h>
  42#include <asm/mach/flash.h>
  43
  44#include <mach/pxa27x.h>
  45#include <mach/balloon3.h>
  46#include <mach/audio.h>
  47#include <mach/pxafb.h>
  48#include <mach/mmc.h>
  49#include <mach/udc.h>
  50#include <mach/pxa27x-udc.h>
  51#include <mach/irda.h>
  52#include <mach/ohci.h>
  53
  54#include "generic.h"
  55#include "devices.h"
  56
  57/******************************************************************************
  58 * Pin configuration
  59 ******************************************************************************/
  60static unsigned long balloon3_pin_config[] __initdata = {
  61        /* Select BTUART 'COM1/ttyS0' as IO option for pins 42/43/44/45 */
  62        GPIO42_BTUART_RXD,
  63        GPIO43_BTUART_TXD,
  64        GPIO44_BTUART_CTS,
  65        GPIO45_BTUART_RTS,
  66
  67        /* Reset, configured as GPIO wakeup source */
  68        GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH,
  69};
  70
  71/******************************************************************************
  72 * Compatibility: Parameter parsing
  73 ******************************************************************************/
  74static unsigned long balloon3_irq_enabled;
  75
  76static unsigned long balloon3_features_present =
  77                (1 << BALLOON3_FEATURE_OHCI) | (1 << BALLOON3_FEATURE_CF) |
  78                (1 << BALLOON3_FEATURE_AUDIO) |
  79                (1 << BALLOON3_FEATURE_TOPPOLY);
  80
  81int balloon3_has(enum balloon3_features feature)
  82{
  83        return (balloon3_features_present & (1 << feature)) ? 1 : 0;
  84}
  85EXPORT_SYMBOL_GPL(balloon3_has);
  86
  87int __init parse_balloon3_features(char *arg)
  88{
  89        if (!arg)
  90                return 0;
  91
  92        return strict_strtoul(arg, 0, &balloon3_features_present);
  93}
  94early_param("balloon3_features", parse_balloon3_features);
  95
  96/******************************************************************************
  97 * Compact Flash slot
  98 ******************************************************************************/
  99#if     defined(CONFIG_PCMCIA_PXA2XX) || defined(CONFIG_PCMCIA_PXA2XX_MODULE)
 100static unsigned long balloon3_cf_pin_config[] __initdata = {
 101        GPIO48_nPOE,
 102        GPIO49_nPWE,
 103        GPIO50_nPIOR,
 104        GPIO51_nPIOW,
 105        GPIO85_nPCE_1,
 106        GPIO54_nPCE_2,
 107        GPIO79_PSKTSEL,
 108        GPIO55_nPREG,
 109        GPIO56_nPWAIT,
 110        GPIO57_nIOIS16,
 111};
 112
 113static void __init balloon3_cf_init(void)
 114{
 115        if (!balloon3_has(BALLOON3_FEATURE_CF))
 116                return;
 117
 118        pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_cf_pin_config));
 119}
 120#else
 121static inline void balloon3_cf_init(void) {}
 122#endif
 123
 124/******************************************************************************
 125 * NOR Flash
 126 ******************************************************************************/
 127#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
 128static struct mtd_partition balloon3_nor_partitions[] = {
 129        {
 130                .name           = "Flash",
 131                .offset         = 0x00000000,
 132                .size           = MTDPART_SIZ_FULL,
 133        }
 134};
 135
 136static struct physmap_flash_data balloon3_flash_data[] = {
 137        {
 138                .width          = 2,    /* bankwidth in bytes */
 139                .parts          = balloon3_nor_partitions,
 140                .nr_parts       = ARRAY_SIZE(balloon3_nor_partitions)
 141        }
 142};
 143
 144static struct resource balloon3_flash_resource = {
 145        .start  = PXA_CS0_PHYS,
 146        .end    = PXA_CS0_PHYS + SZ_64M - 1,
 147        .flags  = IORESOURCE_MEM,
 148};
 149
 150static struct platform_device balloon3_flash = {
 151        .name           = "physmap-flash",
 152        .id             = 0,
 153        .resource       = &balloon3_flash_resource,
 154        .num_resources  = 1,
 155        .dev            = {
 156                .platform_data = balloon3_flash_data,
 157        },
 158};
 159static void __init balloon3_nor_init(void)
 160{
 161        platform_device_register(&balloon3_flash);
 162}
 163#else
 164static inline void balloon3_nor_init(void) {}
 165#endif
 166
 167/******************************************************************************
 168 * Audio and Touchscreen
 169 ******************************************************************************/
 170#if     defined(CONFIG_TOUCHSCREEN_UCB1400) || \
 171        defined(CONFIG_TOUCHSCREEN_UCB1400_MODULE)
 172static unsigned long balloon3_ac97_pin_config[] __initdata = {
 173        GPIO28_AC97_BITCLK,
 174        GPIO29_AC97_SDATA_IN_0,
 175        GPIO30_AC97_SDATA_OUT,
 176        GPIO31_AC97_SYNC,
 177        GPIO113_AC97_nRESET,
 178        GPIO95_GPIO,
 179};
 180
 181static struct ucb1400_pdata vpac270_ucb1400_pdata = {
 182        .irq            = IRQ_GPIO(BALLOON3_GPIO_CODEC_IRQ),
 183};
 184
 185
 186static struct platform_device balloon3_ucb1400_device = {
 187        .name           = "ucb1400_core",
 188        .id             = -1,
 189        .dev            = {
 190                .platform_data = &vpac270_ucb1400_pdata,
 191        },
 192};
 193
 194static void __init balloon3_ts_init(void)
 195{
 196        if (!balloon3_has(BALLOON3_FEATURE_AUDIO))
 197                return;
 198
 199        pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_ac97_pin_config));
 200        pxa_set_ac97_info(NULL);
 201        platform_device_register(&balloon3_ucb1400_device);
 202}
 203#else
 204static inline void balloon3_ts_init(void) {}
 205#endif
 206
 207/******************************************************************************
 208 * Framebuffer
 209 ******************************************************************************/
 210#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
 211static unsigned long balloon3_lcd_pin_config[] __initdata = {
 212        GPIOxx_LCD_TFT_16BPP,
 213        GPIO99_GPIO,
 214};
 215
 216static struct pxafb_mode_info balloon3_lcd_modes[] = {
 217        {
 218                .pixclock               = 38000,
 219                .xres                   = 480,
 220                .yres                   = 640,
 221                .bpp                    = 16,
 222                .hsync_len              = 8,
 223                .left_margin            = 8,
 224                .right_margin           = 8,
 225                .vsync_len              = 2,
 226                .upper_margin           = 4,
 227                .lower_margin           = 5,
 228                .sync                   = 0,
 229        },
 230};
 231
 232static struct pxafb_mach_info balloon3_lcd_screen = {
 233        .modes                  = balloon3_lcd_modes,
 234        .num_modes              = ARRAY_SIZE(balloon3_lcd_modes),
 235        .lcd_conn               = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
 236};
 237
 238static void balloon3_backlight_power(int on)
 239{
 240        gpio_set_value(BALLOON3_GPIO_RUN_BACKLIGHT, on);
 241}
 242
 243static void __init balloon3_lcd_init(void)
 244{
 245        int ret;
 246
 247        if (!balloon3_has(BALLOON3_FEATURE_TOPPOLY))
 248                return;
 249
 250        pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_lcd_pin_config));
 251
 252        ret = gpio_request(BALLOON3_GPIO_RUN_BACKLIGHT, "BKL-ON");
 253        if (ret) {
 254                pr_err("Requesting BKL-ON GPIO failed!\n");
 255                goto err;
 256        }
 257
 258        ret = gpio_direction_output(BALLOON3_GPIO_RUN_BACKLIGHT, 1);
 259        if (ret) {
 260                pr_err("Setting BKL-ON GPIO direction failed!\n");
 261                goto err2;
 262        }
 263
 264        balloon3_lcd_screen.pxafb_backlight_power = balloon3_backlight_power;
 265        pxa_set_fb_info(NULL, &balloon3_lcd_screen);
 266        return;
 267
 268err2:
 269        gpio_free(BALLOON3_GPIO_RUN_BACKLIGHT);
 270err:
 271        return;
 272}
 273#else
 274static inline void balloon3_lcd_init(void) {}
 275#endif
 276
 277/******************************************************************************
 278 * SD/MMC card controller
 279 ******************************************************************************/
 280#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
 281static unsigned long balloon3_mmc_pin_config[] __initdata = {
 282        GPIO32_MMC_CLK,
 283        GPIO92_MMC_DAT_0,
 284        GPIO109_MMC_DAT_1,
 285        GPIO110_MMC_DAT_2,
 286        GPIO111_MMC_DAT_3,
 287        GPIO112_MMC_CMD,
 288};
 289
 290static struct pxamci_platform_data balloon3_mci_platform_data = {
 291        .ocr_mask               = MMC_VDD_32_33 | MMC_VDD_33_34,
 292        .gpio_card_detect       = -1,
 293        .gpio_card_ro           = -1,
 294        .gpio_power             = -1,
 295        .detect_delay_ms        = 200,
 296};
 297
 298static void __init balloon3_mmc_init(void)
 299{
 300        pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_mmc_pin_config));
 301        pxa_set_mci_info(&balloon3_mci_platform_data);
 302}
 303#else
 304static inline void balloon3_mmc_init(void) {}
 305#endif
 306
 307/******************************************************************************
 308 * USB Gadget
 309 ******************************************************************************/
 310#if defined(CONFIG_USB_GADGET_PXA27X)||defined(CONFIG_USB_GADGET_PXA27X_MODULE)
 311static void balloon3_udc_command(int cmd)
 312{
 313        if (cmd == PXA2XX_UDC_CMD_CONNECT)
 314                UP2OCR |= UP2OCR_DPPUE | UP2OCR_DPPUBE;
 315        else if (cmd == PXA2XX_UDC_CMD_DISCONNECT)
 316                UP2OCR &= ~UP2OCR_DPPUE;
 317}
 318
 319static int balloon3_udc_is_connected(void)
 320{
 321        return 1;
 322}
 323
 324static struct pxa2xx_udc_mach_info balloon3_udc_info __initdata = {
 325        .udc_command            = balloon3_udc_command,
 326        .udc_is_connected       = balloon3_udc_is_connected,
 327        .gpio_pullup            = -1,
 328};
 329
 330static void __init balloon3_udc_init(void)
 331{
 332        pxa_set_udc_info(&balloon3_udc_info);
 333        platform_device_register(&balloon3_gpio_vbus);
 334}
 335#else
 336static inline void balloon3_udc_init(void) {}
 337#endif
 338
 339/******************************************************************************
 340 * IrDA
 341 ******************************************************************************/
 342#if defined(CONFIG_IRDA) || defined(CONFIG_IRDA_MODULE)
 343static struct pxaficp_platform_data balloon3_ficp_platform_data = {
 344        .transceiver_cap        = IR_FIRMODE | IR_SIRMODE | IR_OFF,
 345};
 346
 347static void __init balloon3_irda_init(void)
 348{
 349        pxa_set_ficp_info(&balloon3_ficp_platform_data);
 350}
 351#else
 352static inline void balloon3_irda_init(void) {}
 353#endif
 354
 355/******************************************************************************
 356 * USB Host
 357 ******************************************************************************/
 358#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
 359static unsigned long balloon3_uhc_pin_config[] __initdata = {
 360        GPIO88_USBH1_PWR,
 361        GPIO89_USBH1_PEN,
 362};
 363
 364static struct pxaohci_platform_data balloon3_ohci_info = {
 365        .port_mode      = PMM_PERPORT_MODE,
 366        .flags          = ENABLE_PORT_ALL | POWER_CONTROL_LOW | POWER_SENSE_LOW,
 367};
 368
 369static void __init balloon3_uhc_init(void)
 370{
 371        if (!balloon3_has(BALLOON3_FEATURE_OHCI))
 372                return;
 373        pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_uhc_pin_config));
 374        pxa_set_ohci_info(&balloon3_ohci_info);
 375}
 376#else
 377static inline void balloon3_uhc_init(void) {}
 378#endif
 379
 380/******************************************************************************
 381 * LEDs
 382 ******************************************************************************/
 383#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
 384static unsigned long balloon3_led_pin_config[] __initdata = {
 385        GPIO9_GPIO,     /* NAND activity LED */
 386        GPIO10_GPIO,    /* Heartbeat LED */
 387};
 388
 389struct gpio_led balloon3_gpio_leds[] = {
 390        {
 391                .name                   = "balloon3:green:idle",
 392                .default_trigger        = "heartbeat",
 393                .gpio                   = BALLOON3_GPIO_LED_IDLE,
 394                .active_low             = 1,
 395        }, {
 396                .name                   = "balloon3:green:nand",
 397                .default_trigger        = "nand-disk",
 398                .gpio                   = BALLOON3_GPIO_LED_NAND,
 399                .active_low             = 1,
 400        },
 401};
 402
 403static struct gpio_led_platform_data balloon3_gpio_led_info = {
 404        .leds           = balloon3_gpio_leds,
 405        .num_leds       = ARRAY_SIZE(balloon3_gpio_leds),
 406};
 407
 408static struct platform_device balloon3_leds = {
 409        .name   = "leds-gpio",
 410        .id     = 0,
 411        .dev    = {
 412                .platform_data  = &balloon3_gpio_led_info,
 413        }
 414};
 415
 416struct gpio_led balloon3_pcf_gpio_leds[] = {
 417        {
 418                .name                   = "balloon3:green:led0",
 419                .gpio                   = BALLOON3_PCF_GPIO_LED0,
 420                .active_low             = 1,
 421        }, {
 422                .name                   = "balloon3:green:led1",
 423                .gpio                   = BALLOON3_PCF_GPIO_LED1,
 424                .active_low             = 1,
 425        }, {
 426                .name                   = "balloon3:orange:led2",
 427                .gpio                   = BALLOON3_PCF_GPIO_LED2,
 428                .active_low             = 1,
 429        }, {
 430                .name                   = "balloon3:orange:led3",
 431                .gpio                   = BALLOON3_PCF_GPIO_LED3,
 432                .active_low             = 1,
 433        }, {
 434                .name                   = "balloon3:orange:led4",
 435                .gpio                   = BALLOON3_PCF_GPIO_LED4,
 436                .active_low             = 1,
 437        }, {
 438                .name                   = "balloon3:orange:led5",
 439                .gpio                   = BALLOON3_PCF_GPIO_LED5,
 440                .active_low             = 1,
 441        }, {
 442                .name                   = "balloon3:red:led6",
 443                .gpio                   = BALLOON3_PCF_GPIO_LED6,
 444                .active_low             = 1,
 445        }, {
 446                .name                   = "balloon3:red:led7",
 447                .gpio                   = BALLOON3_PCF_GPIO_LED7,
 448                .active_low             = 1,
 449        },
 450};
 451
 452static struct gpio_led_platform_data balloon3_pcf_gpio_led_info = {
 453        .leds           = balloon3_pcf_gpio_leds,
 454        .num_leds       = ARRAY_SIZE(balloon3_pcf_gpio_leds),
 455};
 456
 457static struct platform_device balloon3_pcf_leds = {
 458        .name   = "leds-gpio",
 459        .id     = 1,
 460        .dev    = {
 461                .platform_data  = &balloon3_pcf_gpio_led_info,
 462        }
 463};
 464
 465static void __init balloon3_leds_init(void)
 466{
 467        pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_led_pin_config));
 468        platform_device_register(&balloon3_leds);
 469        platform_device_register(&balloon3_pcf_leds);
 470}
 471#else
 472static inline void balloon3_leds_init(void) {}
 473#endif
 474
 475/******************************************************************************
 476 * FPGA IRQ
 477 ******************************************************************************/
 478static void balloon3_mask_irq(struct irq_data *d)
 479{
 480        int balloon3_irq = (d->irq - BALLOON3_IRQ(0));
 481        balloon3_irq_enabled &= ~(1 << balloon3_irq);
 482        __raw_writel(~balloon3_irq_enabled, BALLOON3_INT_CONTROL_REG);
 483}
 484
 485static void balloon3_unmask_irq(struct irq_data *d)
 486{
 487        int balloon3_irq = (d->irq - BALLOON3_IRQ(0));
 488        balloon3_irq_enabled |= (1 << balloon3_irq);
 489        __raw_writel(~balloon3_irq_enabled, BALLOON3_INT_CONTROL_REG);
 490}
 491
 492static struct irq_chip balloon3_irq_chip = {
 493        .name           = "FPGA",
 494        .irq_ack        = balloon3_mask_irq,
 495        .irq_mask       = balloon3_mask_irq,
 496        .irq_unmask     = balloon3_unmask_irq,
 497};
 498
 499static void balloon3_irq_handler(unsigned int irq, struct irq_desc *desc)
 500{
 501        unsigned long pending = __raw_readl(BALLOON3_INT_CONTROL_REG) &
 502                                        balloon3_irq_enabled;
 503        do {
 504                /* clear useless edge notification */
 505                if (desc->irq_data.chip->irq_ack) {
 506                        struct irq_data *d;
 507
 508                        d = irq_get_irq_data(BALLOON3_AUX_NIRQ);
 509                        desc->irq_data.chip->irq_ack(d);
 510                }
 511
 512                while (pending) {
 513                        irq = BALLOON3_IRQ(0) + __ffs(pending);
 514                        generic_handle_irq(irq);
 515                        pending &= pending - 1;
 516                }
 517                pending = __raw_readl(BALLOON3_INT_CONTROL_REG) &
 518                                balloon3_irq_enabled;
 519        } while (pending);
 520}
 521
 522static void __init balloon3_init_irq(void)
 523{
 524        int irq;
 525
 526        pxa27x_init_irq();
 527        /* setup extra Balloon3 irqs */
 528        for (irq = BALLOON3_IRQ(0); irq <= BALLOON3_IRQ(7); irq++) {
 529                irq_set_chip_and_handler(irq, &balloon3_irq_chip,
 530                                         handle_level_irq);
 531                set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
 532        }
 533
 534        irq_set_chained_handler(BALLOON3_AUX_NIRQ, balloon3_irq_handler);
 535        irq_set_irq_type(BALLOON3_AUX_NIRQ, IRQ_TYPE_EDGE_FALLING);
 536
 537        pr_debug("%s: chained handler installed - irq %d automatically "
 538                "enabled\n", __func__, BALLOON3_AUX_NIRQ);
 539}
 540
 541/******************************************************************************
 542 * GPIO expander
 543 ******************************************************************************/
 544#if defined(CONFIG_GPIO_PCF857X) || defined(CONFIG_GPIO_PCF857X_MODULE)
 545static struct pcf857x_platform_data balloon3_pcf857x_pdata = {
 546        .gpio_base      = BALLOON3_PCF_GPIO_BASE,
 547        .n_latch        = 0,
 548        .setup          = NULL,
 549        .teardown       = NULL,
 550        .context        = NULL,
 551};
 552
 553static struct i2c_board_info __initdata balloon3_i2c_devs[] = {
 554        {
 555                I2C_BOARD_INFO("pcf8574a", 0x38),
 556                .platform_data  = &balloon3_pcf857x_pdata,
 557        },
 558};
 559
 560static void __init balloon3_i2c_init(void)
 561{
 562        pxa_set_i2c_info(NULL);
 563        i2c_register_board_info(0, ARRAY_AND_SIZE(balloon3_i2c_devs));
 564}
 565#else
 566static inline void balloon3_i2c_init(void) {}
 567#endif
 568
 569/******************************************************************************
 570 * NAND
 571 ******************************************************************************/
 572#if defined(CONFIG_MTD_NAND_PLATFORM)||defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
 573static void balloon3_nand_cmd_ctl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
 574{
 575        struct nand_chip *this = mtd->priv;
 576        uint8_t balloon3_ctl_set = 0, balloon3_ctl_clr = 0;
 577
 578        if (ctrl & NAND_CTRL_CHANGE) {
 579                if (ctrl & NAND_CLE)
 580                        balloon3_ctl_set |= BALLOON3_NAND_CONTROL_FLCLE;
 581                else
 582                        balloon3_ctl_clr |= BALLOON3_NAND_CONTROL_FLCLE;
 583
 584                if (ctrl & NAND_ALE)
 585                        balloon3_ctl_set |= BALLOON3_NAND_CONTROL_FLALE;
 586                else
 587                        balloon3_ctl_clr |= BALLOON3_NAND_CONTROL_FLALE;
 588
 589                if (balloon3_ctl_clr)
 590                        __raw_writel(balloon3_ctl_clr,
 591                                BALLOON3_NAND_CONTROL_REG);
 592                if (balloon3_ctl_set)
 593                        __raw_writel(balloon3_ctl_set,
 594                                BALLOON3_NAND_CONTROL_REG |
 595                                BALLOON3_FPGA_SETnCLR);
 596        }
 597
 598        if (cmd != NAND_CMD_NONE)
 599                writeb(cmd, this->IO_ADDR_W);
 600}
 601
 602static void balloon3_nand_select_chip(struct mtd_info *mtd, int chip)
 603{
 604        if (chip < 0 || chip > 3)
 605                return;
 606
 607        /* Assert all nCE lines */
 608        __raw_writew(
 609                BALLOON3_NAND_CONTROL_FLCE0 | BALLOON3_NAND_CONTROL_FLCE1 |
 610                BALLOON3_NAND_CONTROL_FLCE2 | BALLOON3_NAND_CONTROL_FLCE3,
 611                BALLOON3_NAND_CONTROL_REG | BALLOON3_FPGA_SETnCLR);
 612
 613        /* Deassert correct nCE line */
 614        __raw_writew(BALLOON3_NAND_CONTROL_FLCE0 << chip,
 615                BALLOON3_NAND_CONTROL_REG);
 616}
 617
 618static int balloon3_nand_dev_ready(struct mtd_info *mtd)
 619{
 620        return __raw_readl(BALLOON3_NAND_STAT_REG) & BALLOON3_NAND_STAT_RNB;
 621}
 622
 623static int balloon3_nand_probe(struct platform_device *pdev)
 624{
 625        uint16_t ver;
 626        int ret;
 627
 628        __raw_writew(BALLOON3_NAND_CONTROL2_16BIT,
 629                BALLOON3_NAND_CONTROL2_REG | BALLOON3_FPGA_SETnCLR);
 630
 631        ver = __raw_readw(BALLOON3_FPGA_VER);
 632        if (ver < 0x4f08)
 633                pr_warn("The FPGA code, version 0x%04x, is too old. "
 634                        "NAND support might be broken in this version!", ver);
 635
 636        /* Power up the NAND chips */
 637        ret = gpio_request(BALLOON3_GPIO_RUN_NAND, "NAND");
 638        if (ret)
 639                goto err1;
 640
 641        ret = gpio_direction_output(BALLOON3_GPIO_RUN_NAND, 1);
 642        if (ret)
 643                goto err2;
 644
 645        gpio_set_value(BALLOON3_GPIO_RUN_NAND, 1);
 646
 647        /* Deassert all nCE lines and write protect line */
 648        __raw_writel(
 649                BALLOON3_NAND_CONTROL_FLCE0 | BALLOON3_NAND_CONTROL_FLCE1 |
 650                BALLOON3_NAND_CONTROL_FLCE2 | BALLOON3_NAND_CONTROL_FLCE3 |
 651                BALLOON3_NAND_CONTROL_FLWP,
 652                BALLOON3_NAND_CONTROL_REG | BALLOON3_FPGA_SETnCLR);
 653        return 0;
 654
 655err2:
 656        gpio_free(BALLOON3_GPIO_RUN_NAND);
 657err1:
 658        return ret;
 659}
 660
 661static void balloon3_nand_remove(struct platform_device *pdev)
 662{
 663        /* Power down the NAND chips */
 664        gpio_set_value(BALLOON3_GPIO_RUN_NAND, 0);
 665        gpio_free(BALLOON3_GPIO_RUN_NAND);
 666}
 667
 668static struct mtd_partition balloon3_partition_info[] = {
 669        [0] = {
 670                .name   = "Boot",
 671                .offset = 0,
 672                .size   = SZ_4M,
 673        },
 674        [1] = {
 675                .name   = "RootFS",
 676                .offset = MTDPART_OFS_APPEND,
 677                .size   = MTDPART_SIZ_FULL
 678        },
 679};
 680
 681static const char *balloon3_part_probes[] = { "cmdlinepart", NULL };
 682
 683struct platform_nand_data balloon3_nand_pdata = {
 684        .chip = {
 685                .nr_chips       = 4,
 686                .chip_offset    = 0,
 687                .nr_partitions  = ARRAY_SIZE(balloon3_partition_info),
 688                .partitions     = balloon3_partition_info,
 689                .chip_delay     = 50,
 690                .part_probe_types = balloon3_part_probes,
 691        },
 692        .ctrl = {
 693                .hwcontrol      = 0,
 694                .dev_ready      = balloon3_nand_dev_ready,
 695                .select_chip    = balloon3_nand_select_chip,
 696                .cmd_ctrl       = balloon3_nand_cmd_ctl,
 697                .probe          = balloon3_nand_probe,
 698                .remove         = balloon3_nand_remove,
 699        },
 700};
 701
 702static struct resource balloon3_nand_resource[] = {
 703        [0] = {
 704                .start = BALLOON3_NAND_BASE,
 705                .end   = BALLOON3_NAND_BASE + 0x4,
 706                .flags = IORESOURCE_MEM,
 707        },
 708};
 709
 710static struct platform_device balloon3_nand = {
 711        .name           = "gen_nand",
 712        .num_resources  = ARRAY_SIZE(balloon3_nand_resource),
 713        .resource       = balloon3_nand_resource,
 714        .id             = -1,
 715        .dev            = {
 716                .platform_data = &balloon3_nand_pdata,
 717        }
 718};
 719
 720static void __init balloon3_nand_init(void)
 721{
 722        platform_device_register(&balloon3_nand);
 723}
 724#else
 725static inline void balloon3_nand_init(void) {}
 726#endif
 727
 728/******************************************************************************
 729 * Core power regulator
 730 ******************************************************************************/
 731#if defined(CONFIG_REGULATOR_MAX1586) || \
 732    defined(CONFIG_REGULATOR_MAX1586_MODULE)
 733static struct regulator_consumer_supply balloon3_max1587a_consumers[] = {
 734        {
 735                .supply = "vcc_core",
 736        }
 737};
 738
 739static struct regulator_init_data balloon3_max1587a_v3_info = {
 740        .constraints = {
 741                .name           = "vcc_core range",
 742                .min_uV         = 900000,
 743                .max_uV         = 1705000,
 744                .always_on      = 1,
 745                .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
 746        },
 747        .consumer_supplies      = balloon3_max1587a_consumers,
 748        .num_consumer_supplies  = ARRAY_SIZE(balloon3_max1587a_consumers),
 749};
 750
 751static struct max1586_subdev_data balloon3_max1587a_subdevs[] = {
 752        {
 753                .name           = "vcc_core",
 754                .id             = MAX1586_V3,
 755                .platform_data  = &balloon3_max1587a_v3_info,
 756        }
 757};
 758
 759static struct max1586_platform_data balloon3_max1587a_info = {
 760        .subdevs     = balloon3_max1587a_subdevs,
 761        .num_subdevs = ARRAY_SIZE(balloon3_max1587a_subdevs),
 762        .v3_gain     = MAX1586_GAIN_R24_3k32, /* 730..1550 mV */
 763};
 764
 765static struct i2c_board_info __initdata balloon3_pi2c_board_info[] = {
 766        {
 767                I2C_BOARD_INFO("max1586", 0x14),
 768                .platform_data  = &balloon3_max1587a_info,
 769        },
 770};
 771
 772static void __init balloon3_pmic_init(void)
 773{
 774        pxa27x_set_i2c_power_info(NULL);
 775        i2c_register_board_info(1, ARRAY_AND_SIZE(balloon3_pi2c_board_info));
 776}
 777#else
 778static inline void balloon3_pmic_init(void) {}
 779#endif
 780
 781/******************************************************************************
 782 * Machine init
 783 ******************************************************************************/
 784static void __init balloon3_init(void)
 785{
 786        ARB_CNTRL = ARB_CORE_PARK | 0x234;
 787
 788        pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_pin_config));
 789
 790        pxa_set_ffuart_info(NULL);
 791        pxa_set_btuart_info(NULL);
 792        pxa_set_stuart_info(NULL);
 793
 794        balloon3_i2c_init();
 795        balloon3_irda_init();
 796        balloon3_lcd_init();
 797        balloon3_leds_init();
 798        balloon3_mmc_init();
 799        balloon3_nand_init();
 800        balloon3_nor_init();
 801        balloon3_pmic_init();
 802        balloon3_ts_init();
 803        balloon3_udc_init();
 804        balloon3_uhc_init();
 805        balloon3_cf_init();
 806}
 807
 808static struct map_desc balloon3_io_desc[] __initdata = {
 809        {       /* CPLD/FPGA */
 810                .virtual        =  BALLOON3_FPGA_VIRT,
 811                .pfn            = __phys_to_pfn(BALLOON3_FPGA_PHYS),
 812                .length         = BALLOON3_FPGA_LENGTH,
 813                .type           = MT_DEVICE,
 814        },
 815};
 816
 817static void __init balloon3_map_io(void)
 818{
 819        pxa27x_map_io();
 820        iotable_init(balloon3_io_desc, ARRAY_SIZE(balloon3_io_desc));
 821}
 822
 823MACHINE_START(BALLOON3, "Balloon3")
 824        /* Maintainer: Nick Bane. */
 825        .map_io         = balloon3_map_io,
 826        .nr_irqs        = BALLOON3_NR_IRQS,
 827        .init_irq       = balloon3_init_irq,
 828        .handle_irq     = pxa27x_handle_irq,
 829        .timer          = &pxa_timer,
 830        .init_machine   = balloon3_init,
 831        .boot_params    = PLAT_PHYS_OFFSET + 0x100,
 832MACHINE_END
 833