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 <linux/platform_data/video-pxafb.h>
  42#include <linux/platform_data/mmc-pxamci.h>
  43#include <linux/platform_data/irda-pxaficp.h>
  44#include <linux/platform_data/usb-ohci-pxa27x.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        REGULATOR_SUPPLY("vbus_draw", NULL),
 583        REGULATOR_SUPPLY("ac_draw", NULL),
 584};
 585
 586static struct regulator_init_data bq24022_init_data = {
 587        .constraints = {
 588                .max_uA         = 500000,
 589                .valid_ops_mask = REGULATOR_CHANGE_CURRENT | REGULATOR_CHANGE_STATUS,
 590        },
 591        .num_consumer_supplies  = ARRAY_SIZE(bq24022_consumers),
 592        .consumer_supplies      = bq24022_consumers,
 593};
 594
 595static struct gpio bq24022_gpios[] = {
 596        { EGPIO_MAGICIAN_BQ24022_ISET2, GPIOF_OUT_INIT_LOW, "bq24022_iset2" },
 597};
 598
 599static struct gpio_regulator_state bq24022_states[] = {
 600        { .value = 100000, .gpios = (0 << 0) },
 601        { .value = 500000, .gpios = (1 << 0) },
 602};
 603
 604static struct gpio_regulator_config bq24022_info = {
 605        .supply_name = "bq24022",
 606
 607        .enable_gpio = GPIO30_MAGICIAN_BQ24022_nCHARGE_EN,
 608        .enable_high = 0,
 609        .enabled_at_boot = 0,
 610
 611        .gpios = bq24022_gpios,
 612        .nr_gpios = ARRAY_SIZE(bq24022_gpios),
 613
 614        .states = bq24022_states,
 615        .nr_states = ARRAY_SIZE(bq24022_states),
 616
 617        .type = REGULATOR_CURRENT,
 618        .init_data = &bq24022_init_data,
 619};
 620
 621static struct platform_device bq24022 = {
 622        .name = "gpio-regulator",
 623        .id   = -1,
 624        .dev  = {
 625                .platform_data = &bq24022_info,
 626        },
 627};
 628
 629/*
 630 * MMC/SD
 631 */
 632
 633static int magician_mci_init(struct device *dev,
 634                                irq_handler_t detect_irq, void *data)
 635{
 636        return request_irq(IRQ_MAGICIAN_SD, detect_irq, IRQF_DISABLED,
 637                           "mmc card detect", data);
 638}
 639
 640static void magician_mci_exit(struct device *dev, void *data)
 641{
 642        free_irq(IRQ_MAGICIAN_SD, data);
 643}
 644
 645static struct pxamci_platform_data magician_mci_info = {
 646        .ocr_mask               = MMC_VDD_32_33|MMC_VDD_33_34,
 647        .init                   = magician_mci_init,
 648        .exit                   = magician_mci_exit,
 649        .gpio_card_detect       = -1,
 650        .gpio_card_ro           = EGPIO_MAGICIAN_nSD_READONLY,
 651        .gpio_card_ro_invert    = 1,
 652        .gpio_power             = EGPIO_MAGICIAN_SD_POWER,
 653};
 654
 655
 656/*
 657 * USB OHCI
 658 */
 659
 660static struct pxaohci_platform_data magician_ohci_info = {
 661        .port_mode      = PMM_PERPORT_MODE,
 662        .flags          = ENABLE_PORT1 | ENABLE_PORT3 | POWER_CONTROL_LOW,
 663        .power_budget   = 0,
 664};
 665
 666
 667/*
 668 * StrataFlash
 669 */
 670
 671static void magician_set_vpp(struct platform_device *pdev, int vpp)
 672{
 673        gpio_set_value(EGPIO_MAGICIAN_FLASH_VPP, vpp);
 674}
 675
 676static struct resource strataflash_resource = {
 677        .start = PXA_CS0_PHYS,
 678        .end   = PXA_CS0_PHYS + SZ_64M - 1,
 679        .flags = IORESOURCE_MEM,
 680};
 681
 682static struct physmap_flash_data strataflash_data = {
 683        .width = 4,
 684        .set_vpp = magician_set_vpp,
 685};
 686
 687static struct platform_device strataflash = {
 688        .name          = "physmap-flash",
 689        .id            = -1,
 690        .resource      = &strataflash_resource,
 691        .num_resources = 1,
 692        .dev = {
 693                .platform_data = &strataflash_data,
 694        },
 695};
 696
 697/*
 698 * I2C
 699 */
 700
 701static struct i2c_pxa_platform_data i2c_info = {
 702        .fast_mode = 1,
 703};
 704
 705/*
 706 * Platform devices
 707 */
 708
 709static struct platform_device *devices[] __initdata = {
 710        &gpio_keys,
 711        &egpio,
 712        &backlight,
 713        &pasic3,
 714        &bq24022,
 715        &gpio_vbus,
 716        &power_supply,
 717        &strataflash,
 718        &leds_gpio,
 719};
 720
 721static struct gpio magician_global_gpios[] = {
 722        { GPIO13_MAGICIAN_CPLD_IRQ,   GPIOF_IN, "CPLD_IRQ" },
 723        { GPIO107_MAGICIAN_DS1WM_IRQ, GPIOF_IN, "DS1WM_IRQ" },
 724        { GPIO104_MAGICIAN_LCD_POWER_1, GPIOF_OUT_INIT_LOW, "LCD power 1" },
 725        { GPIO105_MAGICIAN_LCD_POWER_2, GPIOF_OUT_INIT_LOW, "LCD power 2" },
 726        { GPIO106_MAGICIAN_LCD_POWER_3, GPIOF_OUT_INIT_LOW, "LCD power 3" },
 727        { GPIO83_MAGICIAN_nIR_EN, GPIOF_OUT_INIT_HIGH, "nIR_EN" },
 728};
 729
 730static void __init magician_init(void)
 731{
 732        void __iomem *cpld;
 733        int lcd_select;
 734        int err;
 735
 736        pxa2xx_mfp_config(ARRAY_AND_SIZE(magician_pin_config));
 737        err = gpio_request_array(ARRAY_AND_SIZE(magician_global_gpios));
 738        if (err)
 739                pr_err("magician: Failed to request GPIOs: %d\n", err);
 740
 741        pxa_set_ffuart_info(NULL);
 742        pxa_set_btuart_info(NULL);
 743        pxa_set_stuart_info(NULL);
 744
 745        platform_add_devices(ARRAY_AND_SIZE(devices));
 746
 747        pxa_set_ficp_info(&magician_ficp_info);
 748        pxa27x_set_i2c_power_info(NULL);
 749        pxa_set_i2c_info(&i2c_info);
 750        pxa_set_mci_info(&magician_mci_info);
 751        pxa_set_ohci_info(&magician_ohci_info);
 752
 753        /* Check LCD type we have */
 754        cpld = ioremap_nocache(PXA_CS3_PHYS, 0x1000);
 755        if (cpld) {
 756                u8 board_id = __raw_readb(cpld+0x14);
 757                iounmap(cpld);
 758                system_rev = board_id & 0x7;
 759                lcd_select = board_id & 0x8;
 760                pr_info("LCD type: %s\n", lcd_select ? "Samsung" : "Toppoly");
 761                if (lcd_select && (system_rev < 3))
 762                        gpio_request_one(GPIO75_MAGICIAN_SAMSUNG_POWER,
 763                                         GPIOF_OUT_INIT_LOW, "SAMSUNG_POWER");
 764                pxa_set_fb_info(NULL, lcd_select ? &samsung_info : &toppoly_info);
 765        } else
 766                pr_err("LCD detection: CPLD mapping failed\n");
 767}
 768
 769
 770MACHINE_START(MAGICIAN, "HTC Magician")
 771        .atag_offset = 0x100,
 772        .map_io = pxa27x_map_io,
 773        .nr_irqs = MAGICIAN_NR_IRQS,
 774        .init_irq = pxa27x_init_irq,
 775        .handle_irq = pxa27x_handle_irq,
 776        .init_machine = magician_init,
 777        .init_time      = pxa_timer_init,
 778        .restart        = pxa_restart,
 779MACHINE_END
 780