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/sysdev.h>
  19#include <linux/interrupt.h>
  20#include <linux/sched.h>
  21#include <linux/bitops.h>
  22#include <linux/fb.h>
  23#include <linux/gpio.h>
  24#include <linux/ioport.h>
  25#include <linux/mtd/mtd.h>
  26#include <linux/mtd/partitions.h>
  27#include <linux/types.h>
  28
  29#include <asm/setup.h>
  30#include <asm/mach-types.h>
  31#include <asm/irq.h>
  32#include <asm/sizes.h>
  33
  34#include <asm/mach/arch.h>
  35#include <asm/mach/map.h>
  36#include <asm/mach/irq.h>
  37#include <asm/mach/flash.h>
  38
  39#include <mach/pxa27x.h>
  40#include <mach/balloon3.h>
  41#include <mach/audio.h>
  42#include <mach/pxafb.h>
  43#include <mach/mmc.h>
  44#include <mach/udc.h>
  45#include <mach/pxa27x-udc.h>
  46#include <mach/irda.h>
  47#include <mach/ohci.h>
  48
  49#include <plat/i2c.h>
  50
  51#include "generic.h"
  52#include "devices.h"
  53
  54static unsigned long balloon3_irq_enabled;
  55
  56static unsigned long balloon3_features_present =
  57                (1 << BALLOON3_FEATURE_OHCI) | (1 << BALLOON3_FEATURE_CF) |
  58                (1 << BALLOON3_FEATURE_AUDIO) |
  59                (1 << BALLOON3_FEATURE_TOPPOLY);
  60
  61int balloon3_has(enum balloon3_features feature)
  62{
  63        return (balloon3_features_present & (1 << feature)) ? 1 : 0;
  64}
  65EXPORT_SYMBOL_GPL(balloon3_has);
  66
  67int __init parse_balloon3_features(char *arg)
  68{
  69        if (!arg)
  70                return 0;
  71
  72        return strict_strtoul(arg, 0, &balloon3_features_present);
  73}
  74early_param("balloon3_features", parse_balloon3_features);
  75
  76static void balloon3_mask_irq(unsigned int irq)
  77{
  78        int balloon3_irq = (irq - BALLOON3_IRQ(0));
  79        balloon3_irq_enabled &= ~(1 << balloon3_irq);
  80        __raw_writel(~balloon3_irq_enabled, BALLOON3_INT_CONTROL_REG);
  81}
  82
  83static void balloon3_unmask_irq(unsigned int irq)
  84{
  85        int balloon3_irq = (irq - BALLOON3_IRQ(0));
  86        balloon3_irq_enabled |= (1 << balloon3_irq);
  87        __raw_writel(~balloon3_irq_enabled, BALLOON3_INT_CONTROL_REG);
  88}
  89
  90static struct irq_chip balloon3_irq_chip = {
  91        .name           = "FPGA",
  92        .ack            = balloon3_mask_irq,
  93        .mask           = balloon3_mask_irq,
  94        .unmask         = balloon3_unmask_irq,
  95};
  96
  97static void balloon3_irq_handler(unsigned int irq, struct irq_desc *desc)
  98{
  99        unsigned long pending = __raw_readl(BALLOON3_INT_CONTROL_REG) &
 100                                        balloon3_irq_enabled;
 101
 102        do {
 103                /* clear useless edge notification */
 104                if (desc->chip->ack)
 105                        desc->chip->ack(BALLOON3_AUX_NIRQ);
 106                while (pending) {
 107                        irq = BALLOON3_IRQ(0) + __ffs(pending);
 108                        generic_handle_irq(irq);
 109                        pending &= pending - 1;
 110                }
 111                pending = __raw_readl(BALLOON3_INT_CONTROL_REG) &
 112                                balloon3_irq_enabled;
 113        } while (pending);
 114}
 115
 116static void __init balloon3_init_irq(void)
 117{
 118        int irq;
 119
 120        pxa27x_init_irq();
 121        /* setup extra Balloon3 irqs */
 122        for (irq = BALLOON3_IRQ(0); irq <= BALLOON3_IRQ(7); irq++) {
 123                set_irq_chip(irq, &balloon3_irq_chip);
 124                set_irq_handler(irq, handle_level_irq);
 125                set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
 126        }
 127
 128        set_irq_chained_handler(BALLOON3_AUX_NIRQ, balloon3_irq_handler);
 129        set_irq_type(BALLOON3_AUX_NIRQ, IRQ_TYPE_EDGE_FALLING);
 130
 131        pr_debug("%s: chained handler installed - irq %d automatically "
 132                "enabled\n", __func__, BALLOON3_AUX_NIRQ);
 133}
 134
 135static void balloon3_backlight_power(int on)
 136{
 137        pr_debug("%s: power is %s\n", __func__, on ? "on" : "off");
 138        gpio_set_value(BALLOON3_GPIO_RUN_BACKLIGHT, on);
 139}
 140
 141static unsigned long balloon3_lcd_pin_config[] = {
 142        /* LCD - 16bpp Active TFT */
 143        GPIO58_LCD_LDD_0,
 144        GPIO59_LCD_LDD_1,
 145        GPIO60_LCD_LDD_2,
 146        GPIO61_LCD_LDD_3,
 147        GPIO62_LCD_LDD_4,
 148        GPIO63_LCD_LDD_5,
 149        GPIO64_LCD_LDD_6,
 150        GPIO65_LCD_LDD_7,
 151        GPIO66_LCD_LDD_8,
 152        GPIO67_LCD_LDD_9,
 153        GPIO68_LCD_LDD_10,
 154        GPIO69_LCD_LDD_11,
 155        GPIO70_LCD_LDD_12,
 156        GPIO71_LCD_LDD_13,
 157        GPIO72_LCD_LDD_14,
 158        GPIO73_LCD_LDD_15,
 159        GPIO74_LCD_FCLK,
 160        GPIO75_LCD_LCLK,
 161        GPIO76_LCD_PCLK,
 162        GPIO77_LCD_BIAS,
 163
 164        GPIO99_GPIO,            /* Backlight */
 165};
 166
 167static struct pxafb_mode_info balloon3_lcd_modes[] = {
 168        {
 169                .pixclock               = 38000,
 170                .xres                   = 480,
 171                .yres                   = 640,
 172                .bpp                    = 16,
 173                .hsync_len              = 8,
 174                .left_margin            = 8,
 175                .right_margin           = 8,
 176                .vsync_len              = 2,
 177                .upper_margin           = 4,
 178                .lower_margin           = 5,
 179                .sync                   = 0,
 180        },
 181};
 182
 183static struct pxafb_mach_info balloon3_pxafb_info = {
 184        .modes                  = balloon3_lcd_modes,
 185        .num_modes              = ARRAY_SIZE(balloon3_lcd_modes),
 186        .lcd_conn               = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
 187        .pxafb_backlight_power  = balloon3_backlight_power,
 188};
 189
 190static unsigned long balloon3_mmc_pin_config[] = {
 191        GPIO32_MMC_CLK,
 192        GPIO92_MMC_DAT_0,
 193        GPIO109_MMC_DAT_1,
 194        GPIO110_MMC_DAT_2,
 195        GPIO111_MMC_DAT_3,
 196        GPIO112_MMC_CMD,
 197};
 198
 199static void balloon3_mci_setpower(struct device *dev, unsigned int vdd)
 200{
 201        struct pxamci_platform_data *p_d = dev->platform_data;
 202
 203        if ((1 << vdd) & p_d->ocr_mask) {
 204                pr_debug("%s: on\n", __func__);
 205                /* FIXME something to prod here? */
 206        } else {
 207                pr_debug("%s: off\n", __func__);
 208                /* FIXME something to prod here? */
 209        }
 210}
 211
 212static struct pxamci_platform_data balloon3_mci_platform_data = {
 213        .ocr_mask       = MMC_VDD_32_33|MMC_VDD_33_34,
 214        .setpower       = balloon3_mci_setpower,
 215};
 216
 217static int balloon3_udc_is_connected(void)
 218{
 219        pr_debug("%s: udc connected\n", __func__);
 220        return 1;
 221}
 222
 223static void balloon3_udc_command(int cmd)
 224{
 225        switch (cmd) {
 226        case PXA2XX_UDC_CMD_CONNECT:
 227                UP2OCR |= (UP2OCR_DPPUE + UP2OCR_DPPUBE);
 228                pr_debug("%s: connect\n", __func__);
 229                break;
 230        case PXA2XX_UDC_CMD_DISCONNECT:
 231                UP2OCR &= ~UP2OCR_DPPUE;
 232                pr_debug("%s: disconnect\n", __func__);
 233                break;
 234        }
 235}
 236
 237static struct pxa2xx_udc_mach_info balloon3_udc_info = {
 238        .udc_is_connected = balloon3_udc_is_connected,
 239        .udc_command      = balloon3_udc_command,
 240};
 241
 242static struct pxaficp_platform_data balloon3_ficp_platform_data = {
 243        .transceiver_cap  = IR_SIRMODE | IR_FIRMODE | IR_OFF,
 244};
 245
 246static unsigned long balloon3_ohci_pin_config[] = {
 247        GPIO88_USBH1_PWR,
 248        GPIO89_USBH1_PEN,
 249};
 250
 251static struct pxaohci_platform_data balloon3_ohci_platform_data = {
 252        .port_mode      = PMM_PERPORT_MODE,
 253        .flags          = ENABLE_PORT_ALL | POWER_CONTROL_LOW | POWER_SENSE_LOW,
 254};
 255
 256static unsigned long balloon3_pin_config[] __initdata = {
 257        /* Select BTUART 'COM1/ttyS0' as IO option for pins 42/43/44/45 */
 258        GPIO42_BTUART_RXD,
 259        GPIO43_BTUART_TXD,
 260        GPIO44_BTUART_CTS,
 261        GPIO45_BTUART_RTS,
 262
 263        /* Wakeup GPIO */
 264        GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH,
 265
 266        /* NAND & IDLE LED GPIOs */
 267        GPIO9_GPIO,
 268        GPIO10_GPIO,
 269};
 270
 271static struct gpio_led balloon3_gpio_leds[] = {
 272        {
 273                .name                   = "balloon3:green:idle",
 274                .default_trigger        = "heartbeat",
 275                .gpio                   = BALLOON3_GPIO_LED_IDLE,
 276                .active_low             = 1,
 277        },
 278        {
 279                .name                   = "balloon3:green:nand",
 280                .default_trigger        = "nand-disk",
 281                .gpio                   = BALLOON3_GPIO_LED_NAND,
 282                .active_low             = 1,
 283        },
 284};
 285
 286static struct gpio_led_platform_data balloon3_gpio_leds_platform_data = {
 287        .leds           = balloon3_gpio_leds,
 288        .num_leds       = ARRAY_SIZE(balloon3_gpio_leds),
 289};
 290
 291static struct platform_device balloon3led_device = {
 292        .name   = "leds-gpio",
 293        .id     = -1,
 294        .dev    = {
 295                .platform_data  = &balloon3_gpio_leds_platform_data,
 296        },
 297};
 298
 299static void __init balloon3_init(void)
 300{
 301        pr_info("Initialising Balloon3\n");
 302
 303        /* system bus arbiter setting
 304         * - Core_Park
 305         * - LCD_wt:DMA_wt:CORE_Wt = 2:3:4
 306         */
 307        ARB_CNTRL = ARB_CORE_PARK | 0x234;
 308
 309        pxa_set_i2c_info(NULL);
 310        if (balloon3_has(BALLOON3_FEATURE_AUDIO))
 311                pxa_set_ac97_info(NULL);
 312
 313        if (balloon3_has(BALLOON3_FEATURE_TOPPOLY)) {
 314                pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_lcd_pin_config));
 315                gpio_request(BALLOON3_GPIO_RUN_BACKLIGHT,
 316                        "LCD Backlight Power");
 317                gpio_direction_output(BALLOON3_GPIO_RUN_BACKLIGHT, 1);
 318                set_pxa_fb_info(&balloon3_pxafb_info);
 319        }
 320
 321        if (balloon3_has(BALLOON3_FEATURE_MMC)) {
 322                pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_mmc_pin_config));
 323                pxa_set_mci_info(&balloon3_mci_platform_data);
 324        }
 325        pxa_set_ficp_info(&balloon3_ficp_platform_data);
 326        if (balloon3_has(BALLOON3_FEATURE_OHCI)) {
 327                pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_ohci_pin_config));
 328                pxa_set_ohci_info(&balloon3_ohci_platform_data);
 329        }
 330        pxa_set_udc_info(&balloon3_udc_info);
 331
 332        pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_pin_config));
 333
 334        platform_device_register(&balloon3led_device);
 335}
 336
 337static struct map_desc balloon3_io_desc[] __initdata = {
 338        {       /* CPLD/FPGA */
 339                .virtual        =  BALLOON3_FPGA_VIRT,
 340                .pfn            = __phys_to_pfn(BALLOON3_FPGA_PHYS),
 341                .length         = BALLOON3_FPGA_LENGTH,
 342                .type           = MT_DEVICE,
 343        },
 344};
 345
 346static void __init balloon3_map_io(void)
 347{
 348        pxa_map_io();
 349        iotable_init(balloon3_io_desc, ARRAY_SIZE(balloon3_io_desc));
 350}
 351
 352MACHINE_START(BALLOON3, "Balloon3")
 353        /* Maintainer: Nick Bane. */
 354        .phys_io        = 0x40000000,
 355        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
 356        .map_io         = balloon3_map_io,
 357        .init_irq       = balloon3_init_irq,
 358        .timer          = &pxa_timer,
 359        .init_machine   = balloon3_init,
 360        .boot_params    = PHYS_OFFSET + 0x100,
 361MACHINE_END
 362