linux/arch/arm/mach-pxa/magician.c
<<
>>
Prefs
   1/*
   2 * Support for HTC Magician PDA phones:
   3 * i-mate JAM, O2 Xda mini, Orange SPV M500, Qtek s100, Qtek s110
   4 * and T-Mobile MDA Compact.
   5 *
   6 * Copyright (c) 2006-2007 Philipp Zabel
   7 *
   8 * Based on hx4700.c, spitz.c and others.
   9 *
  10 * This program is free software; you can redistribute it and/or modify
  11 * it under the terms of the GNU General Public License version 2 as
  12 * published by the Free Software Foundation.
  13 *
  14 */
  15
  16#include <linux/kernel.h>
  17#include <linux/init.h>
  18#include <linux/platform_device.h>
  19#include <linux/delay.h>
  20#include <linux/gpio.h>
  21#include <linux/gpio_keys.h>
  22#include <linux/input.h>
  23#include <linux/mfd/htc-egpio.h>
  24#include <linux/mfd/htc-pasic3.h>
  25#include <linux/mtd/physmap.h>
  26#include <linux/pda_power.h>
  27#include <linux/pwm_backlight.h>
  28#include <linux/regulator/driver.h>
  29#include <linux/regulator/gpio-regulator.h>
  30#include <linux/regulator/machine.h>
  31#include <linux/usb/gpio_vbus.h>
  32#include <linux/i2c/pxa-i2c.h>
  33
  34#include <mach/hardware.h>
  35#include <asm/mach-types.h>
  36#include <asm/mach/arch.h>
  37#include <asm/system_info.h>
  38
  39#include <mach/pxa27x.h>
  40#include <mach/magician.h>
  41#include <mach/pxafb.h>
  42#include <mach/mmc.h>
  43#include <mach/irda.h>
  44#include <mach/ohci.h>
  45
  46#include "devices.h"
  47#include "generic.h"
  48
  49static unsigned long magician_pin_config[] __initdata = {
  50
  51        /* SDRAM and Static Memory I/O Signals */
  52        GPIO20_nSDCS_2,
  53        GPIO21_nSDCS_3,
  54        GPIO15_nCS_1,
  55        GPIO78_nCS_2,   /* PASIC3 */
  56        GPIO79_nCS_3,   /* EGPIO CPLD */
  57        GPIO80_nCS_4,
  58        GPIO33_nCS_5,
  59
  60        /* I2C */
  61        GPIO117_I2C_SCL,
  62        GPIO118_I2C_SDA,
  63
  64        /* PWM 0 */
  65        GPIO16_PWM0_OUT,
  66
  67        /* I2S */
  68        GPIO28_I2S_BITCLK_OUT,
  69        GPIO29_I2S_SDATA_IN,
  70        GPIO31_I2S_SYNC,
  71        GPIO113_I2S_SYSCLK,
  72
  73        /* SSP 1 */
  74        GPIO23_SSP1_SCLK,
  75        GPIO24_SSP1_SFRM,
  76        GPIO25_SSP1_TXD,
  77
  78        /* SSP 2 */
  79        GPIO19_SSP2_SCLK,
  80        GPIO14_SSP2_SFRM,
  81        GPIO89_SSP2_TXD,
  82        GPIO88_SSP2_RXD,
  83
  84        /* MMC */
  85        GPIO32_MMC_CLK,
  86        GPIO92_MMC_DAT_0,
  87        GPIO109_MMC_DAT_1,
  88        GPIO110_MMC_DAT_2,
  89        GPIO111_MMC_DAT_3,
  90        GPIO112_MMC_CMD,
  91
  92        /* LCD */
  93        GPIOxx_LCD_TFT_16BPP,
  94
  95        /* QCI */
  96        GPIO12_CIF_DD_7,
  97        GPIO17_CIF_DD_6,
  98        GPIO50_CIF_DD_3,
  99        GPIO51_CIF_DD_2,
 100        GPIO52_CIF_DD_4,
 101        GPIO53_CIF_MCLK,
 102        GPIO54_CIF_PCLK,
 103        GPIO55_CIF_DD_1,
 104        GPIO81_CIF_DD_0,
 105        GPIO82_CIF_DD_5,
 106        GPIO84_CIF_FV,
 107        GPIO85_CIF_LV,
 108
 109        /* Magician specific input GPIOs */
 110        GPIO9_GPIO,     /* unknown */
 111        GPIO10_GPIO,    /* GSM_IRQ */
 112        GPIO13_GPIO,    /* CPLD_IRQ */
 113        GPIO107_GPIO,   /* DS1WM_IRQ */
 114        GPIO108_GPIO,   /* GSM_READY */
 115        GPIO115_GPIO,   /* nPEN_IRQ */
 116
 117        /* I2C */
 118        GPIO117_I2C_SCL,
 119        GPIO118_I2C_SDA,
 120};
 121
 122/*
 123 * IRDA
 124 */
 125
 126static struct pxaficp_platform_data magician_ficp_info = {
 127        .gpio_pwdown            = GPIO83_MAGICIAN_nIR_EN,
 128        .transceiver_cap        = IR_SIRMODE | IR_OFF,
 129};
 130
 131/*
 132 * GPIO Keys
 133 */
 134
 135#define INIT_KEY(_code, _gpio, _desc)   \
 136        {                               \
 137                .code   = KEY_##_code,  \
 138                .gpio   = _gpio,        \
 139                .desc   = _desc,        \
 140                .type   = EV_KEY,       \
 141                .wakeup = 1,            \
 142        }
 143
 144static struct gpio_keys_button magician_button_table[] = {
 145        INIT_KEY(POWER,      GPIO0_MAGICIAN_KEY_POWER,      "Power button"),
 146        INIT_KEY(ESC,        GPIO37_MAGICIAN_KEY_HANGUP,    "Hangup button"),
 147        INIT_KEY(F10,        GPIO38_MAGICIAN_KEY_CONTACTS,  "Contacts button"),
 148        INIT_KEY(CALENDAR,   GPIO90_MAGICIAN_KEY_CALENDAR,  "Calendar button"),
 149        INIT_KEY(CAMERA,     GPIO91_MAGICIAN_KEY_CAMERA,    "Camera button"),
 150        INIT_KEY(UP,         GPIO93_MAGICIAN_KEY_UP,        "Up button"),
 151        INIT_KEY(DOWN,       GPIO94_MAGICIAN_KEY_DOWN,      "Down button"),
 152        INIT_KEY(LEFT,       GPIO95_MAGICIAN_KEY_LEFT,      "Left button"),
 153        INIT_KEY(RIGHT,      GPIO96_MAGICIAN_KEY_RIGHT,     "Right button"),
 154        INIT_KEY(KPENTER,    GPIO97_MAGICIAN_KEY_ENTER,     "Action button"),
 155        INIT_KEY(RECORD,     GPIO98_MAGICIAN_KEY_RECORD,    "Record button"),
 156        INIT_KEY(VOLUMEUP,   GPIO100_MAGICIAN_KEY_VOL_UP,   "Volume up"),
 157        INIT_KEY(VOLUMEDOWN, GPIO101_MAGICIAN_KEY_VOL_DOWN, "Volume down"),
 158        INIT_KEY(PHONE,      GPIO102_MAGICIAN_KEY_PHONE,    "Phone button"),
 159        INIT_KEY(PLAY,       GPIO99_MAGICIAN_HEADPHONE_IN,  "Headset button"),
 160};
 161
 162static struct gpio_keys_platform_data gpio_keys_data = {
 163        .buttons  = magician_button_table,
 164        .nbuttons = ARRAY_SIZE(magician_button_table),
 165};
 166
 167static struct platform_device gpio_keys = {
 168        .name = "gpio-keys",
 169        .dev  = {
 170                .platform_data = &gpio_keys_data,
 171        },
 172        .id   = -1,
 173};
 174
 175
 176/*
 177 * EGPIO (Xilinx CPLD)
 178 *
 179 * 7 32-bit aligned 8-bit registers: 3x output, 1x irq, 3x input
 180 */
 181
 182static struct resource egpio_resources[] = {
 183        [0] = {
 184                .start = PXA_CS3_PHYS,
 185                .end   = PXA_CS3_PHYS + 0x20 - 1,
 186                .flags = IORESOURCE_MEM,
 187        },
 188        [1] = {
 189                .start = PXA_GPIO_TO_IRQ(GPIO13_MAGICIAN_CPLD_IRQ),
 190                .end   = PXA_GPIO_TO_IRQ(GPIO13_MAGICIAN_CPLD_IRQ),
 191                .flags = IORESOURCE_IRQ,
 192        },
 193};
 194
 195static struct htc_egpio_chip egpio_chips[] = {
 196        [0] = {
 197                .reg_start = 0,
 198                .gpio_base = MAGICIAN_EGPIO(0, 0),
 199                .num_gpios = 24,
 200                .direction = HTC_EGPIO_OUTPUT,
 201                .initial_values = 0x40, /* EGPIO_MAGICIAN_GSM_RESET */
 202        },
 203        [1] = {
 204                .reg_start = 4,
 205                .gpio_base = MAGICIAN_EGPIO(4, 0),
 206                .num_gpios = 24,
 207                .direction = HTC_EGPIO_INPUT,
 208        },
 209};
 210
 211static struct htc_egpio_platform_data egpio_info = {
 212        .reg_width    = 8,
 213        .bus_width    = 32,
 214        .irq_base     = IRQ_BOARD_START,
 215        .num_irqs     = 4,
 216        .ack_register = 3,
 217        .chip         = egpio_chips,
 218        .num_chips    = ARRAY_SIZE(egpio_chips),
 219};
 220
 221static struct platform_device egpio = {
 222        .name          = "htc-egpio",
 223        .id            = -1,
 224        .resource      = egpio_resources,
 225        .num_resources = ARRAY_SIZE(egpio_resources),
 226        .dev = {
 227                .platform_data = &egpio_info,
 228        },
 229};
 230
 231/*
 232 * LCD - Toppoly TD028STEB1 or Samsung LTP280QV
 233 */
 234
 235static struct pxafb_mode_info toppoly_modes[] = {
 236        {
 237                .pixclock     = 96153,
 238                .bpp          = 16,
 239                .xres         = 240,
 240                .yres         = 320,
 241                .hsync_len    = 11,
 242                .vsync_len    = 3,
 243                .left_margin  = 19,
 244                .upper_margin = 2,
 245                .right_margin = 10,
 246                .lower_margin = 2,
 247                .sync         = 0,
 248        },
 249};
 250
 251static struct pxafb_mode_info samsung_modes[] = {
 252        {
 253                .pixclock     = 96153,
 254                .bpp          = 16,
 255                .xres         = 240,
 256                .yres         = 320,
 257                .hsync_len    = 8,
 258                .vsync_len    = 4,
 259                .left_margin  = 9,
 260                .upper_margin = 4,
 261                .right_margin = 9,
 262                .lower_margin = 4,
 263                .sync         = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
 264        },
 265};
 266
 267static void toppoly_lcd_power(int on, struct fb_var_screeninfo *si)
 268{
 269        pr_debug("Toppoly LCD power\n");
 270
 271        if (on) {
 272                pr_debug("on\n");
 273                gpio_set_value(EGPIO_MAGICIAN_TOPPOLY_POWER, 1);
 274                gpio_set_value(GPIO106_MAGICIAN_LCD_POWER_3, 1);
 275                udelay(2000);
 276                gpio_set_value(EGPIO_MAGICIAN_LCD_POWER, 1);
 277                udelay(2000);
 278                /* FIXME: enable LCDC here */
 279                udelay(2000);
 280                gpio_set_value(GPIO104_MAGICIAN_LCD_POWER_1, 1);
 281                udelay(2000);
 282                gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 1);
 283        } else {
 284                pr_debug("off\n");
 285                msleep(15);
 286                gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 0);
 287                udelay(500);
 288                gpio_set_value(GPIO104_MAGICIAN_LCD_POWER_1, 0);
 289                udelay(1000);
 290                gpio_set_value(GPIO106_MAGICIAN_LCD_POWER_3, 0);
 291                gpio_set_value(EGPIO_MAGICIAN_LCD_POWER, 0);
 292        }
 293}
 294
 295static void samsung_lcd_power(int on, struct fb_var_screeninfo *si)
 296{
 297        pr_debug("Samsung LCD power\n");
 298
 299        if (on) {
 300                pr_debug("on\n");
 301                if (system_rev < 3)
 302                        gpio_set_value(GPIO75_MAGICIAN_SAMSUNG_POWER, 1);
 303                else
 304                        gpio_set_value(EGPIO_MAGICIAN_LCD_POWER, 1);
 305                mdelay(10);
 306                gpio_set_value(GPIO106_MAGICIAN_LCD_POWER_3, 1);
 307                mdelay(10);
 308                gpio_set_value(GPIO104_MAGICIAN_LCD_POWER_1, 1);
 309                mdelay(30);
 310                gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 1);
 311                mdelay(10);
 312        } else {
 313                pr_debug("off\n");
 314                mdelay(10);
 315                gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 0);
 316                mdelay(30);
 317                gpio_set_value(GPIO104_MAGICIAN_LCD_POWER_1, 0);
 318                mdelay(10);
 319                gpio_set_value(GPIO106_MAGICIAN_LCD_POWER_3, 0);
 320                mdelay(10);
 321                if (system_rev < 3)
 322                        gpio_set_value(GPIO75_MAGICIAN_SAMSUNG_POWER, 0);
 323                else
 324                        gpio_set_value(EGPIO_MAGICIAN_LCD_POWER, 0);
 325        }
 326}
 327
 328static struct pxafb_mach_info toppoly_info = {
 329        .modes           = toppoly_modes,
 330        .num_modes       = 1,
 331        .fixed_modes     = 1,
 332        .lcd_conn       = LCD_COLOR_TFT_16BPP,
 333        .pxafb_lcd_power = toppoly_lcd_power,
 334};
 335
 336static struct pxafb_mach_info samsung_info = {
 337        .modes           = samsung_modes,
 338        .num_modes       = 1,
 339        .fixed_modes     = 1,
 340        .lcd_conn        = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL |\
 341                           LCD_ALTERNATE_MAPPING,
 342        .pxafb_lcd_power = samsung_lcd_power,
 343};
 344
 345/*
 346 * Backlight
 347 */
 348
 349static struct gpio magician_bl_gpios[] = {
 350        { EGPIO_MAGICIAN_BL_POWER,  GPIOF_DIR_OUT, "Backlight power" },
 351        { EGPIO_MAGICIAN_BL_POWER2, GPIOF_DIR_OUT, "Backlight power 2" },
 352};
 353
 354static int magician_backlight_init(struct device *dev)
 355{
 356        return gpio_request_array(ARRAY_AND_SIZE(magician_bl_gpios));
 357}
 358
 359static int magician_backlight_notify(struct device *dev, int brightness)
 360{
 361        gpio_set_value(EGPIO_MAGICIAN_BL_POWER, brightness);
 362        if (brightness >= 200) {
 363                gpio_set_value(EGPIO_MAGICIAN_BL_POWER2, 1);
 364                return brightness - 72;
 365        } else {
 366                gpio_set_value(EGPIO_MAGICIAN_BL_POWER2, 0);
 367                return brightness;
 368        }
 369}
 370
 371static void magician_backlight_exit(struct device *dev)
 372{
 373        gpio_free_array(ARRAY_AND_SIZE(magician_bl_gpios));
 374}
 375
 376static struct platform_pwm_backlight_data backlight_data = {
 377        .pwm_id         = 0,
 378        .max_brightness = 272,
 379        .dft_brightness = 100,
 380        .pwm_period_ns  = 30923,
 381        .init           = magician_backlight_init,
 382        .notify         = magician_backlight_notify,
 383        .exit           = magician_backlight_exit,
 384};
 385
 386static struct platform_device backlight = {
 387        .name = "pwm-backlight",
 388        .id   = -1,
 389        .dev  = {
 390                .parent        = &pxa27x_device_pwm0.dev,
 391                .platform_data = &backlight_data,
 392        },
 393};
 394
 395/*
 396 * LEDs
 397 */
 398
 399static struct gpio_led gpio_leds[] = {
 400        {
 401                .name = "magician::vibra",
 402                .default_trigger = "none",
 403                .gpio = GPIO22_MAGICIAN_VIBRA_EN,
 404        },
 405        {
 406                .name = "magician::phone_bl",
 407                .default_trigger = "backlight",
 408                .gpio = GPIO103_MAGICIAN_LED_KP,
 409        },
 410};
 411
 412static struct gpio_led_platform_data gpio_led_info = {
 413        .leds = gpio_leds,
 414        .num_leds = ARRAY_SIZE(gpio_leds),
 415};
 416
 417static struct platform_device leds_gpio = {
 418        .name = "leds-gpio",
 419        .id   = -1,
 420        .dev  = {
 421                .platform_data = &gpio_led_info,
 422        },
 423};
 424
 425static struct pasic3_led pasic3_leds[] = {
 426        {
 427                .led = {
 428                        .name            = "magician:red",
 429                        .default_trigger = "ds2760-battery.0-charging",
 430                },
 431                .hw_num = 0,
 432                .bit2   = PASIC3_BIT2_LED0,
 433                .mask   = PASIC3_MASK_LED0,
 434        },
 435        {
 436                .led = {
 437                        .name            = "magician:green",
 438                        .default_trigger = "ds2760-battery.0-charging-or-full",
 439                },
 440                .hw_num = 1,
 441                .bit2   = PASIC3_BIT2_LED1,
 442                .mask   = PASIC3_MASK_LED1,
 443        },
 444        {
 445                .led = {
 446                        .name            = "magician:blue",
 447                        .default_trigger = "bluetooth",
 448                },
 449                .hw_num = 2,
 450                .bit2   = PASIC3_BIT2_LED2,
 451                .mask   = PASIC3_MASK_LED2,
 452        },
 453};
 454
 455static struct pasic3_leds_machinfo pasic3_leds_info = {
 456        .num_leds   = ARRAY_SIZE(pasic3_leds),
 457        .power_gpio = EGPIO_MAGICIAN_LED_POWER,
 458        .leds       = pasic3_leds,
 459};
 460
 461/*
 462 * PASIC3 with DS1WM
 463 */
 464
 465static struct resource pasic3_resources[] = {
 466        [0] = {
 467                .start  = PXA_CS2_PHYS,
 468                .end    = PXA_CS2_PHYS + 0x1b,
 469                .flags  = IORESOURCE_MEM,
 470        },
 471        /* No IRQ handler in the PASIC3, DS1WM needs an external IRQ */
 472        [1] = {
 473                .start  = PXA_GPIO_TO_IRQ(GPIO107_MAGICIAN_DS1WM_IRQ),
 474                .end    = PXA_GPIO_TO_IRQ(GPIO107_MAGICIAN_DS1WM_IRQ),
 475                .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
 476        }
 477};
 478
 479static struct pasic3_platform_data pasic3_platform_data = {
 480        .led_pdata  = &pasic3_leds_info,
 481        .clock_rate = 4000000,
 482};
 483
 484static struct platform_device pasic3 = {
 485        .name           = "pasic3",
 486        .id             = -1,
 487        .num_resources  = ARRAY_SIZE(pasic3_resources),
 488        .resource       = pasic3_resources,
 489        .dev = {
 490                .platform_data = &pasic3_platform_data,
 491        },
 492};
 493
 494/*
 495 * USB "Transceiver"
 496 */
 497
 498static struct resource gpio_vbus_resource = {
 499        .flags = IORESOURCE_IRQ,
 500        .start = IRQ_MAGICIAN_VBUS,
 501        .end   = IRQ_MAGICIAN_VBUS,
 502};
 503
 504static struct gpio_vbus_mach_info gpio_vbus_info = {
 505        .gpio_pullup = GPIO27_MAGICIAN_USBC_PUEN,
 506        .gpio_vbus   = EGPIO_MAGICIAN_CABLE_STATE_USB,
 507};
 508
 509static struct platform_device gpio_vbus = {
 510        .name          = "gpio-vbus",
 511        .id            = -1,
 512        .num_resources = 1,
 513        .resource      = &gpio_vbus_resource,
 514        .dev = {
 515                .platform_data = &gpio_vbus_info,
 516        },
 517};
 518
 519/*
 520 * External power
 521 */
 522
 523static int power_supply_init(struct device *dev)
 524{
 525        return gpio_request(EGPIO_MAGICIAN_CABLE_STATE_AC, "CABLE_STATE_AC");
 526}
 527
 528static int magician_is_ac_online(void)
 529{
 530        return gpio_get_value(EGPIO_MAGICIAN_CABLE_STATE_AC);
 531}
 532
 533static void power_supply_exit(struct device *dev)
 534{
 535        gpio_free(EGPIO_MAGICIAN_CABLE_STATE_AC);
 536}
 537
 538static char *magician_supplicants[] = {
 539        "ds2760-battery.0", "backup-battery"
 540};
 541
 542static struct pda_power_pdata power_supply_info = {
 543        .init            = power_supply_init,
 544        .is_ac_online    = magician_is_ac_online,
 545        .exit            = power_supply_exit,
 546        .supplied_to     = magician_supplicants,
 547        .num_supplicants = ARRAY_SIZE(magician_supplicants),
 548};
 549
 550static struct resource power_supply_resources[] = {
 551        [0] = {
 552                .name  = "ac",
 553                .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
 554                         IORESOURCE_IRQ_LOWEDGE,
 555                .start = IRQ_MAGICIAN_VBUS,
 556                .end   = IRQ_MAGICIAN_VBUS,
 557        },
 558        [1] = {
 559                .name  = "usb",
 560                .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
 561                         IORESOURCE_IRQ_LOWEDGE,
 562                .start = IRQ_MAGICIAN_VBUS,
 563                .end   = IRQ_MAGICIAN_VBUS,
 564        },
 565};
 566
 567static struct platform_device power_supply = {
 568        .name = "pda-power",
 569        .id   = -1,
 570        .dev  = {
 571                .platform_data = &power_supply_info,
 572        },
 573        .resource      = power_supply_resources,
 574        .num_resources = ARRAY_SIZE(power_supply_resources),
 575};
 576
 577/*
 578 * Battery charger
 579 */
 580
 581static struct regulator_consumer_supply bq24022_consumers[] = {
 582        {
 583                .supply = "vbus_draw",
 584        },
 585        {
 586                .supply = "ac_draw",
 587        },
 588};
 589
 590static struct regulator_init_data bq24022_init_data = {
 591        .constraints = {
 592                .max_uA         = 500000,
 593                .valid_ops_mask = REGULATOR_CHANGE_CURRENT | REGULATOR_CHANGE_STATUS,
 594        },
 595        .num_consumer_supplies  = ARRAY_SIZE(bq24022_consumers),
 596        .consumer_supplies      = bq24022_consumers,
 597};
 598
 599static struct gpio bq24022_gpios[] = {
 600        { EGPIO_MAGICIAN_BQ24022_ISET2, GPIOF_OUT_INIT_LOW, "bq24022_iset2" },
 601};
 602
 603static struct gpio_regulator_state bq24022_states[] = {
 604        { .value = 100000, .gpios = (0 << 0) },
 605        { .value = 500000, .gpios = (1 << 0) },
 606};
 607
 608static struct gpio_regulator_config bq24022_info = {
 609        .supply_name = "bq24022",
 610
 611        .enable_gpio = GPIO30_MAGICIAN_BQ24022_nCHARGE_EN,
 612        .enable_high = 0,
 613        .enabled_at_boot = 0,
 614
 615        .gpios = bq24022_gpios,
 616        .nr_gpios = ARRAY_SIZE(bq24022_gpios),
 617
 618        .states = bq24022_states,
 619        .nr_states = ARRAY_SIZE(bq24022_states),
 620
 621        .type = REGULATOR_CURRENT,
 622        .init_data = &bq24022_init_data,
 623};
 624
 625static struct platform_device bq24022 = {
 626        .name = "gpio-regulator",
 627        .id   = -1,
 628        .dev  = {
 629                .platform_data = &bq24022_info,
 630        },
 631};
 632
 633/*
 634 * MMC/SD
 635 */
 636
 637static int magician_mci_init(struct device *dev,
 638                                irq_handler_t detect_irq, void *data)
 639{
 640        return request_irq(IRQ_MAGICIAN_SD, detect_irq,
 641                                IRQF_DISABLED | IRQF_SAMPLE_RANDOM,
 642                                "mmc card detect", data);
 643}
 644
 645static void magician_mci_exit(struct device *dev, void *data)
 646{
 647        free_irq(IRQ_MAGICIAN_SD, data);
 648}
 649
 650static struct pxamci_platform_data magician_mci_info = {
 651        .ocr_mask               = MMC_VDD_32_33|MMC_VDD_33_34,
 652        .init                   = magician_mci_init,
 653        .exit                   = magician_mci_exit,
 654        .gpio_card_detect       = -1,
 655        .gpio_card_ro           = EGPIO_MAGICIAN_nSD_READONLY,
 656        .gpio_card_ro_invert    = 1,
 657        .gpio_power             = EGPIO_MAGICIAN_SD_POWER,
 658};
 659
 660
 661/*
 662 * USB OHCI
 663 */
 664
 665static struct pxaohci_platform_data magician_ohci_info = {
 666        .port_mode      = PMM_PERPORT_MODE,
 667        .flags          = ENABLE_PORT1 | ENABLE_PORT3 | POWER_CONTROL_LOW,
 668        .power_budget   = 0,
 669};
 670
 671
 672/*
 673 * StrataFlash
 674 */
 675
 676static void magician_set_vpp(struct platform_device *pdev, int vpp)
 677{
 678        gpio_set_value(EGPIO_MAGICIAN_FLASH_VPP, vpp);
 679}
 680
 681static struct resource strataflash_resource = {
 682        .start = PXA_CS0_PHYS,
 683        .end   = PXA_CS0_PHYS + SZ_64M - 1,
 684        .flags = IORESOURCE_MEM,
 685};
 686
 687static struct physmap_flash_data strataflash_data = {
 688        .width = 4,
 689        .set_vpp = magician_set_vpp,
 690};
 691
 692static struct platform_device strataflash = {
 693        .name          = "physmap-flash",
 694        .id            = -1,
 695        .resource      = &strataflash_resource,
 696        .num_resources = 1,
 697        .dev = {
 698                .platform_data = &strataflash_data,
 699        },
 700};
 701
 702/*
 703 * I2C
 704 */
 705
 706static struct i2c_pxa_platform_data i2c_info = {
 707        .fast_mode = 1,
 708};
 709
 710/*
 711 * Platform devices
 712 */
 713
 714static struct platform_device *devices[] __initdata = {
 715        &gpio_keys,
 716        &egpio,
 717        &backlight,
 718        &pasic3,
 719        &bq24022,
 720        &gpio_vbus,
 721        &power_supply,
 722        &strataflash,
 723        &leds_gpio,
 724};
 725
 726static struct gpio magician_global_gpios[] = {
 727        { GPIO13_MAGICIAN_CPLD_IRQ,   GPIOF_IN, "CPLD_IRQ" },
 728        { GPIO107_MAGICIAN_DS1WM_IRQ, GPIOF_IN, "DS1WM_IRQ" },
 729        { GPIO104_MAGICIAN_LCD_POWER_1, GPIOF_OUT_INIT_LOW, "LCD power 1" },
 730        { GPIO105_MAGICIAN_LCD_POWER_2, GPIOF_OUT_INIT_LOW, "LCD power 2" },
 731        { GPIO106_MAGICIAN_LCD_POWER_3, GPIOF_OUT_INIT_LOW, "LCD power 3" },
 732        { GPIO83_MAGICIAN_nIR_EN, GPIOF_OUT_INIT_HIGH, "nIR_EN" },
 733};
 734
 735static void __init magician_init(void)
 736{
 737        void __iomem *cpld;
 738        int lcd_select;
 739        int err;
 740
 741        pxa2xx_mfp_config(ARRAY_AND_SIZE(magician_pin_config));
 742        err = gpio_request_array(ARRAY_AND_SIZE(magician_global_gpios));
 743        if (err)
 744                pr_err("magician: Failed to request GPIOs: %d\n", err);
 745
 746        pxa_set_ffuart_info(NULL);
 747        pxa_set_btuart_info(NULL);
 748        pxa_set_stuart_info(NULL);
 749
 750        platform_add_devices(ARRAY_AND_SIZE(devices));
 751
 752        pxa_set_ficp_info(&magician_ficp_info);
 753        pxa27x_set_i2c_power_info(NULL);
 754        pxa_set_i2c_info(&i2c_info);
 755        pxa_set_mci_info(&magician_mci_info);
 756        pxa_set_ohci_info(&magician_ohci_info);
 757
 758        /* Check LCD type we have */
 759        cpld = ioremap_nocache(PXA_CS3_PHYS, 0x1000);
 760        if (cpld) {
 761                u8 board_id = __raw_readb(cpld+0x14);
 762                iounmap(cpld);
 763                system_rev = board_id & 0x7;
 764                lcd_select = board_id & 0x8;
 765                pr_info("LCD type: %s\n", lcd_select ? "Samsung" : "Toppoly");
 766                if (lcd_select && (system_rev < 3))
 767                        gpio_request_one(GPIO75_MAGICIAN_SAMSUNG_POWER,
 768                                         GPIOF_OUT_INIT_LOW, "SAMSUNG_POWER");
 769                pxa_set_fb_info(NULL, lcd_select ? &samsung_info : &toppoly_info);
 770        } else
 771                pr_err("LCD detection: CPLD mapping failed\n");
 772}
 773
 774
 775MACHINE_START(MAGICIAN, "HTC Magician")
 776        .atag_offset = 0x100,
 777        .map_io = pxa27x_map_io,
 778        .nr_irqs = MAGICIAN_NR_IRQS,
 779        .init_irq = pxa27x_init_irq,
 780        .handle_irq = pxa27x_handle_irq,
 781        .init_machine = magician_init,
 782        .timer = &pxa_timer,
 783        .restart        = pxa_restart,
 784MACHINE_END
 785