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