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        .enable_gpio    = -1,
 382        .init           = magician_backlight_init,
 383        .notify         = magician_backlight_notify,
 384        .exit           = magician_backlight_exit,
 385};
 386
 387static struct platform_device backlight = {
 388        .name = "pwm-backlight",
 389        .id   = -1,
 390        .dev  = {
 391                .parent        = &pxa27x_device_pwm0.dev,
 392                .platform_data = &backlight_data,
 393        },
 394};
 395
 396/*
 397 * LEDs
 398 */
 399
 400static struct gpio_led gpio_leds[] = {
 401        {
 402                .name = "magician::vibra",
 403                .default_trigger = "none",
 404                .gpio = GPIO22_MAGICIAN_VIBRA_EN,
 405        },
 406        {
 407                .name = "magician::phone_bl",
 408                .default_trigger = "backlight",
 409                .gpio = GPIO103_MAGICIAN_LED_KP,
 410        },
 411};
 412
 413static struct gpio_led_platform_data gpio_led_info = {
 414        .leds = gpio_leds,
 415        .num_leds = ARRAY_SIZE(gpio_leds),
 416};
 417
 418static struct platform_device leds_gpio = {
 419        .name = "leds-gpio",
 420        .id   = -1,
 421        .dev  = {
 422                .platform_data = &gpio_led_info,
 423        },
 424};
 425
 426static struct pasic3_led pasic3_leds[] = {
 427        {
 428                .led = {
 429                        .name            = "magician:red",
 430                        .default_trigger = "ds2760-battery.0-charging",
 431                },
 432                .hw_num = 0,
 433                .bit2   = PASIC3_BIT2_LED0,
 434                .mask   = PASIC3_MASK_LED0,
 435        },
 436        {
 437                .led = {
 438                        .name            = "magician:green",
 439                        .default_trigger = "ds2760-battery.0-charging-or-full",
 440                },
 441                .hw_num = 1,
 442                .bit2   = PASIC3_BIT2_LED1,
 443                .mask   = PASIC3_MASK_LED1,
 444        },
 445        {
 446                .led = {
 447                        .name            = "magician:blue",
 448                        .default_trigger = "bluetooth",
 449                },
 450                .hw_num = 2,
 451                .bit2   = PASIC3_BIT2_LED2,
 452                .mask   = PASIC3_MASK_LED2,
 453        },
 454};
 455
 456static struct pasic3_leds_machinfo pasic3_leds_info = {
 457        .num_leds   = ARRAY_SIZE(pasic3_leds),
 458        .power_gpio = EGPIO_MAGICIAN_LED_POWER,
 459        .leds       = pasic3_leds,
 460};
 461
 462/*
 463 * PASIC3 with DS1WM
 464 */
 465
 466static struct resource pasic3_resources[] = {
 467        [0] = {
 468                .start  = PXA_CS2_PHYS,
 469                .end    = PXA_CS2_PHYS + 0x1b,
 470                .flags  = IORESOURCE_MEM,
 471        },
 472        /* No IRQ handler in the PASIC3, DS1WM needs an external IRQ */
 473        [1] = {
 474                .start  = PXA_GPIO_TO_IRQ(GPIO107_MAGICIAN_DS1WM_IRQ),
 475                .end    = PXA_GPIO_TO_IRQ(GPIO107_MAGICIAN_DS1WM_IRQ),
 476                .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
 477        }
 478};
 479
 480static struct pasic3_platform_data pasic3_platform_data = {
 481        .led_pdata  = &pasic3_leds_info,
 482        .clock_rate = 4000000,
 483};
 484
 485static struct platform_device pasic3 = {
 486        .name           = "pasic3",
 487        .id             = -1,
 488        .num_resources  = ARRAY_SIZE(pasic3_resources),
 489        .resource       = pasic3_resources,
 490        .dev = {
 491                .platform_data = &pasic3_platform_data,
 492        },
 493};
 494
 495/*
 496 * USB "Transceiver"
 497 */
 498
 499static struct resource gpio_vbus_resource = {
 500        .flags = IORESOURCE_IRQ,
 501        .start = IRQ_MAGICIAN_VBUS,
 502        .end   = IRQ_MAGICIAN_VBUS,
 503};
 504
 505static struct gpio_vbus_mach_info gpio_vbus_info = {
 506        .gpio_pullup = GPIO27_MAGICIAN_USBC_PUEN,
 507        .gpio_vbus   = EGPIO_MAGICIAN_CABLE_STATE_USB,
 508};
 509
 510static struct platform_device gpio_vbus = {
 511        .name          = "gpio-vbus",
 512        .id            = -1,
 513        .num_resources = 1,
 514        .resource      = &gpio_vbus_resource,
 515        .dev = {
 516                .platform_data = &gpio_vbus_info,
 517        },
 518};
 519
 520/*
 521 * External power
 522 */
 523
 524static int power_supply_init(struct device *dev)
 525{
 526        return gpio_request(EGPIO_MAGICIAN_CABLE_STATE_AC, "CABLE_STATE_AC");
 527}
 528
 529static int magician_is_ac_online(void)
 530{
 531        return gpio_get_value(EGPIO_MAGICIAN_CABLE_STATE_AC);
 532}
 533
 534static void power_supply_exit(struct device *dev)
 535{
 536        gpio_free(EGPIO_MAGICIAN_CABLE_STATE_AC);
 537}
 538
 539static char *magician_supplicants[] = {
 540        "ds2760-battery.0", "backup-battery"
 541};
 542
 543static struct pda_power_pdata power_supply_info = {
 544        .init            = power_supply_init,
 545        .is_ac_online    = magician_is_ac_online,
 546        .exit            = power_supply_exit,
 547        .supplied_to     = magician_supplicants,
 548        .num_supplicants = ARRAY_SIZE(magician_supplicants),
 549};
 550
 551static struct resource power_supply_resources[] = {
 552        [0] = {
 553                .name  = "ac",
 554                .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
 555                         IORESOURCE_IRQ_LOWEDGE,
 556                .start = IRQ_MAGICIAN_VBUS,
 557                .end   = IRQ_MAGICIAN_VBUS,
 558        },
 559        [1] = {
 560                .name  = "usb",
 561                .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
 562                         IORESOURCE_IRQ_LOWEDGE,
 563                .start = IRQ_MAGICIAN_VBUS,
 564                .end   = IRQ_MAGICIAN_VBUS,
 565        },
 566};
 567
 568static struct platform_device power_supply = {
 569        .name = "pda-power",
 570        .id   = -1,
 571        .dev  = {
 572                .platform_data = &power_supply_info,
 573        },
 574        .resource      = power_supply_resources,
 575        .num_resources = ARRAY_SIZE(power_supply_resources),
 576};
 577
 578/*
 579 * Battery charger
 580 */
 581
 582static struct regulator_consumer_supply bq24022_consumers[] = {
 583        REGULATOR_SUPPLY("vbus_draw", NULL),
 584        REGULATOR_SUPPLY("ac_draw", NULL),
 585};
 586
 587static struct regulator_init_data bq24022_init_data = {
 588        .constraints = {
 589                .max_uA         = 500000,
 590                .valid_ops_mask = REGULATOR_CHANGE_CURRENT | REGULATOR_CHANGE_STATUS,
 591        },
 592        .num_consumer_supplies  = ARRAY_SIZE(bq24022_consumers),
 593        .consumer_supplies      = bq24022_consumers,
 594};
 595
 596static struct gpio bq24022_gpios[] = {
 597        { EGPIO_MAGICIAN_BQ24022_ISET2, GPIOF_OUT_INIT_LOW, "bq24022_iset2" },
 598};
 599
 600static struct gpio_regulator_state bq24022_states[] = {
 601        { .value = 100000, .gpios = (0 << 0) },
 602        { .value = 500000, .gpios = (1 << 0) },
 603};
 604
 605static struct gpio_regulator_config bq24022_info = {
 606        .supply_name = "bq24022",
 607
 608        .enable_gpio = GPIO30_MAGICIAN_BQ24022_nCHARGE_EN,
 609        .enable_high = 0,
 610        .enabled_at_boot = 0,
 611
 612        .gpios = bq24022_gpios,
 613        .nr_gpios = ARRAY_SIZE(bq24022_gpios),
 614
 615        .states = bq24022_states,
 616        .nr_states = ARRAY_SIZE(bq24022_states),
 617
 618        .type = REGULATOR_CURRENT,
 619        .init_data = &bq24022_init_data,
 620};
 621
 622static struct platform_device bq24022 = {
 623        .name = "gpio-regulator",
 624        .id   = -1,
 625        .dev  = {
 626                .platform_data = &bq24022_info,
 627        },
 628};
 629
 630/*
 631 * MMC/SD
 632 */
 633
 634static int magician_mci_init(struct device *dev,
 635                                irq_handler_t detect_irq, void *data)
 636{
 637        return request_irq(IRQ_MAGICIAN_SD, detect_irq, IRQF_DISABLED,
 638                           "mmc card detect", data);
 639}
 640
 641static void magician_mci_exit(struct device *dev, void *data)
 642{
 643        free_irq(IRQ_MAGICIAN_SD, data);
 644}
 645
 646static struct pxamci_platform_data magician_mci_info = {
 647        .ocr_mask               = MMC_VDD_32_33|MMC_VDD_33_34,
 648        .init                   = magician_mci_init,
 649        .exit                   = magician_mci_exit,
 650        .gpio_card_detect       = -1,
 651        .gpio_card_ro           = EGPIO_MAGICIAN_nSD_READONLY,
 652        .gpio_card_ro_invert    = 1,
 653        .gpio_power             = EGPIO_MAGICIAN_SD_POWER,
 654};
 655
 656
 657/*
 658 * USB OHCI
 659 */
 660
 661static struct pxaohci_platform_data magician_ohci_info = {
 662        .port_mode      = PMM_PERPORT_MODE,
 663        .flags          = ENABLE_PORT1 | ENABLE_PORT3 | POWER_CONTROL_LOW,
 664        .power_budget   = 0,
 665};
 666
 667
 668/*
 669 * StrataFlash
 670 */
 671
 672static void magician_set_vpp(struct platform_device *pdev, int vpp)
 673{
 674        gpio_set_value(EGPIO_MAGICIAN_FLASH_VPP, vpp);
 675}
 676
 677static struct resource strataflash_resource = {
 678        .start = PXA_CS0_PHYS,
 679        .end   = PXA_CS0_PHYS + SZ_64M - 1,
 680        .flags = IORESOURCE_MEM,
 681};
 682
 683static struct physmap_flash_data strataflash_data = {
 684        .width = 4,
 685        .set_vpp = magician_set_vpp,
 686};
 687
 688static struct platform_device strataflash = {
 689        .name          = "physmap-flash",
 690        .id            = -1,
 691        .resource      = &strataflash_resource,
 692        .num_resources = 1,
 693        .dev = {
 694                .platform_data = &strataflash_data,
 695        },
 696};
 697
 698/*
 699 * I2C
 700 */
 701
 702static struct i2c_pxa_platform_data i2c_info = {
 703        .fast_mode = 1,
 704};
 705
 706/*
 707 * Platform devices
 708 */
 709
 710static struct platform_device *devices[] __initdata = {
 711        &gpio_keys,
 712        &egpio,
 713        &backlight,
 714        &pasic3,
 715        &bq24022,
 716        &gpio_vbus,
 717        &power_supply,
 718        &strataflash,
 719        &leds_gpio,
 720};
 721
 722static struct gpio magician_global_gpios[] = {
 723        { GPIO13_MAGICIAN_CPLD_IRQ,   GPIOF_IN, "CPLD_IRQ" },
 724        { GPIO107_MAGICIAN_DS1WM_IRQ, GPIOF_IN, "DS1WM_IRQ" },
 725        { GPIO104_MAGICIAN_LCD_POWER_1, GPIOF_OUT_INIT_LOW, "LCD power 1" },
 726        { GPIO105_MAGICIAN_LCD_POWER_2, GPIOF_OUT_INIT_LOW, "LCD power 2" },
 727        { GPIO106_MAGICIAN_LCD_POWER_3, GPIOF_OUT_INIT_LOW, "LCD power 3" },
 728        { GPIO83_MAGICIAN_nIR_EN, GPIOF_OUT_INIT_HIGH, "nIR_EN" },
 729};
 730
 731static void __init magician_init(void)
 732{
 733        void __iomem *cpld;
 734        int lcd_select;
 735        int err;
 736
 737        pxa2xx_mfp_config(ARRAY_AND_SIZE(magician_pin_config));
 738        err = gpio_request_array(ARRAY_AND_SIZE(magician_global_gpios));
 739        if (err)
 740                pr_err("magician: Failed to request GPIOs: %d\n", err);
 741
 742        pxa_set_ffuart_info(NULL);
 743        pxa_set_btuart_info(NULL);
 744        pxa_set_stuart_info(NULL);
 745
 746        platform_add_devices(ARRAY_AND_SIZE(devices));
 747
 748        pxa_set_ficp_info(&magician_ficp_info);
 749        pxa27x_set_i2c_power_info(NULL);
 750        pxa_set_i2c_info(&i2c_info);
 751        pxa_set_mci_info(&magician_mci_info);
 752        pxa_set_ohci_info(&magician_ohci_info);
 753
 754        /* Check LCD type we have */
 755        cpld = ioremap_nocache(PXA_CS3_PHYS, 0x1000);
 756        if (cpld) {
 757                u8 board_id = __raw_readb(cpld+0x14);
 758                iounmap(cpld);
 759                system_rev = board_id & 0x7;
 760                lcd_select = board_id & 0x8;
 761                pr_info("LCD type: %s\n", lcd_select ? "Samsung" : "Toppoly");
 762                if (lcd_select && (system_rev < 3))
 763                        gpio_request_one(GPIO75_MAGICIAN_SAMSUNG_POWER,
 764                                         GPIOF_OUT_INIT_LOW, "SAMSUNG_POWER");
 765                pxa_set_fb_info(NULL, lcd_select ? &samsung_info : &toppoly_info);
 766        } else
 767                pr_err("LCD detection: CPLD mapping failed\n");
 768}
 769
 770
 771MACHINE_START(MAGICIAN, "HTC Magician")
 772        .atag_offset = 0x100,
 773        .map_io = pxa27x_map_io,
 774        .nr_irqs = MAGICIAN_NR_IRQS,
 775        .init_irq = pxa27x_init_irq,
 776        .handle_irq = pxa27x_handle_irq,
 777        .init_machine = magician_init,
 778        .init_time      = pxa_timer_init,
 779        .restart        = pxa_restart,
 780MACHINE_END
 781