linux/arch/arm/mach-pxa/palmtx.c
<<
>>
Prefs
   1/*
   2 * Hardware definitions for PalmTX
   3 *
   4 * Author:     Marek Vasut <marek.vasut@gmail.com>
   5 *
   6 * Based on work of:
   7 *              Alex Osborne <ato@meshy.org>
   8 *              Cristiano P. <cristianop@users.sourceforge.net>
   9 *              Jan Herman <2hp@seznam.cz>
  10 *              Michal Hrusecky
  11 *
  12 * This program is free software; you can redistribute it and/or modify
  13 * it under the terms of the GNU General Public License version 2 as
  14 * published by the Free Software Foundation.
  15 *
  16 * (find more info at www.hackndev.com)
  17 *
  18 */
  19
  20#include <linux/platform_device.h>
  21#include <linux/delay.h>
  22#include <linux/irq.h>
  23#include <linux/gpio_keys.h>
  24#include <linux/input.h>
  25#include <linux/pda_power.h>
  26#include <linux/pwm_backlight.h>
  27#include <linux/gpio.h>
  28#include <linux/wm97xx_batt.h>
  29#include <linux/power_supply.h>
  30#include <linux/usb/gpio_vbus.h>
  31#include <linux/mtd/nand.h>
  32#include <linux/mtd/partitions.h>
  33#include <linux/mtd/mtd.h>
  34#include <linux/mtd/physmap.h>
  35
  36#include <asm/mach-types.h>
  37#include <asm/mach/arch.h>
  38#include <asm/mach/map.h>
  39
  40#include <mach/pxa27x.h>
  41#include <mach/audio.h>
  42#include <mach/palmtx.h>
  43#include <mach/mmc.h>
  44#include <mach/pxafb.h>
  45#include <mach/irda.h>
  46#include <mach/pxa27x_keypad.h>
  47#include <mach/udc.h>
  48#include <mach/palmasoc.h>
  49
  50#include "generic.h"
  51#include "devices.h"
  52
  53/******************************************************************************
  54 * Pin configuration
  55 ******************************************************************************/
  56static unsigned long palmtx_pin_config[] __initdata = {
  57        /* MMC */
  58        GPIO32_MMC_CLK,
  59        GPIO92_MMC_DAT_0,
  60        GPIO109_MMC_DAT_1,
  61        GPIO110_MMC_DAT_2,
  62        GPIO111_MMC_DAT_3,
  63        GPIO112_MMC_CMD,
  64        GPIO14_GPIO,    /* SD detect */
  65        GPIO114_GPIO,   /* SD power */
  66        GPIO115_GPIO,   /* SD r/o switch */
  67
  68        /* AC97 */
  69        GPIO28_AC97_BITCLK,
  70        GPIO29_AC97_SDATA_IN_0,
  71        GPIO30_AC97_SDATA_OUT,
  72        GPIO31_AC97_SYNC,
  73        GPIO89_AC97_SYSCLK,
  74        GPIO95_AC97_nRESET,
  75
  76        /* IrDA */
  77        GPIO40_GPIO,    /* ir disable */
  78        GPIO46_FICP_RXD,
  79        GPIO47_FICP_TXD,
  80
  81        /* PWM */
  82        GPIO16_PWM0_OUT,
  83
  84        /* USB */
  85        GPIO13_GPIO,    /* usb detect */
  86        GPIO93_GPIO,    /* usb power */
  87
  88        /* PCMCIA */
  89        GPIO48_nPOE,
  90        GPIO49_nPWE,
  91        GPIO50_nPIOR,
  92        GPIO51_nPIOW,
  93        GPIO85_nPCE_1,
  94        GPIO54_nPCE_2,
  95        GPIO79_PSKTSEL,
  96        GPIO55_nPREG,
  97        GPIO56_nPWAIT,
  98        GPIO57_nIOIS16,
  99        GPIO94_GPIO,    /* wifi power 1 */
 100        GPIO108_GPIO,   /* wifi power 2 */
 101        GPIO116_GPIO,   /* wifi ready */
 102
 103        /* MATRIX KEYPAD */
 104        GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
 105        GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH,
 106        GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH,
 107        GPIO97_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH,
 108        GPIO103_KP_MKOUT_0,
 109        GPIO104_KP_MKOUT_1,
 110        GPIO105_KP_MKOUT_2,
 111
 112        /* LCD */
 113        GPIO58_LCD_LDD_0,
 114        GPIO59_LCD_LDD_1,
 115        GPIO60_LCD_LDD_2,
 116        GPIO61_LCD_LDD_3,
 117        GPIO62_LCD_LDD_4,
 118        GPIO63_LCD_LDD_5,
 119        GPIO64_LCD_LDD_6,
 120        GPIO65_LCD_LDD_7,
 121        GPIO66_LCD_LDD_8,
 122        GPIO67_LCD_LDD_9,
 123        GPIO68_LCD_LDD_10,
 124        GPIO69_LCD_LDD_11,
 125        GPIO70_LCD_LDD_12,
 126        GPIO71_LCD_LDD_13,
 127        GPIO72_LCD_LDD_14,
 128        GPIO73_LCD_LDD_15,
 129        GPIO74_LCD_FCLK,
 130        GPIO75_LCD_LCLK,
 131        GPIO76_LCD_PCLK,
 132        GPIO77_LCD_BIAS,
 133
 134        /* FFUART */
 135        GPIO34_FFUART_RXD,
 136        GPIO39_FFUART_TXD,
 137
 138        /* NAND */
 139        GPIO15_nCS_1,
 140        GPIO18_RDY,
 141
 142        /* MISC. */
 143        GPIO10_GPIO,    /* hotsync button */
 144        GPIO12_GPIO,    /* power detect */
 145        GPIO107_GPIO,   /* earphone detect */
 146};
 147
 148/******************************************************************************
 149 * NOR Flash
 150 ******************************************************************************/
 151static struct mtd_partition palmtx_partitions[] = {
 152        {
 153                .name           = "Flash",
 154                .offset         = 0x00000000,
 155                .size           = MTDPART_SIZ_FULL,
 156                .mask_flags     = 0
 157        }
 158};
 159
 160static struct physmap_flash_data palmtx_flash_data[] = {
 161        {
 162                .width          = 2,                    /* bankwidth in bytes */
 163                .parts          = palmtx_partitions,
 164                .nr_parts       = ARRAY_SIZE(palmtx_partitions)
 165        }
 166};
 167
 168static struct resource palmtx_flash_resource = {
 169        .start  = PXA_CS0_PHYS,
 170        .end    = PXA_CS0_PHYS + SZ_8M - 1,
 171        .flags  = IORESOURCE_MEM,
 172};
 173
 174static struct platform_device palmtx_flash = {
 175        .name           = "physmap-flash",
 176        .id             = 0,
 177        .resource       = &palmtx_flash_resource,
 178        .num_resources  = 1,
 179        .dev            = {
 180                .platform_data = palmtx_flash_data,
 181        },
 182};
 183
 184/******************************************************************************
 185 * SD/MMC card controller
 186 ******************************************************************************/
 187static struct pxamci_platform_data palmtx_mci_platform_data = {
 188        .ocr_mask               = MMC_VDD_32_33 | MMC_VDD_33_34,
 189        .gpio_card_detect       = GPIO_NR_PALMTX_SD_DETECT_N,
 190        .gpio_card_ro           = GPIO_NR_PALMTX_SD_READONLY,
 191        .gpio_power             = GPIO_NR_PALMTX_SD_POWER,
 192        .detect_delay           = 20,
 193};
 194
 195/******************************************************************************
 196 * GPIO keyboard
 197 ******************************************************************************/
 198static unsigned int palmtx_matrix_keys[] = {
 199        KEY(0, 0, KEY_POWER),
 200        KEY(0, 1, KEY_F1),
 201        KEY(0, 2, KEY_ENTER),
 202
 203        KEY(1, 0, KEY_F2),
 204        KEY(1, 1, KEY_F3),
 205        KEY(1, 2, KEY_F4),
 206
 207        KEY(2, 0, KEY_UP),
 208        KEY(2, 2, KEY_DOWN),
 209
 210        KEY(3, 0, KEY_RIGHT),
 211        KEY(3, 2, KEY_LEFT),
 212};
 213
 214static struct pxa27x_keypad_platform_data palmtx_keypad_platform_data = {
 215        .matrix_key_rows        = 4,
 216        .matrix_key_cols        = 3,
 217        .matrix_key_map         = palmtx_matrix_keys,
 218        .matrix_key_map_size    = ARRAY_SIZE(palmtx_matrix_keys),
 219
 220        .debounce_interval      = 30,
 221};
 222
 223/******************************************************************************
 224 * GPIO keys
 225 ******************************************************************************/
 226static struct gpio_keys_button palmtx_pxa_buttons[] = {
 227        {KEY_F8, GPIO_NR_PALMTX_HOTSYNC_BUTTON_N, 1, "HotSync Button" },
 228};
 229
 230static struct gpio_keys_platform_data palmtx_pxa_keys_data = {
 231        .buttons        = palmtx_pxa_buttons,
 232        .nbuttons       = ARRAY_SIZE(palmtx_pxa_buttons),
 233};
 234
 235static struct platform_device palmtx_pxa_keys = {
 236        .name   = "gpio-keys",
 237        .id     = -1,
 238        .dev    = {
 239                .platform_data = &palmtx_pxa_keys_data,
 240        },
 241};
 242
 243/******************************************************************************
 244 * Backlight
 245 ******************************************************************************/
 246static int palmtx_backlight_init(struct device *dev)
 247{
 248        int ret;
 249
 250        ret = gpio_request(GPIO_NR_PALMTX_BL_POWER, "BL POWER");
 251        if (ret)
 252                goto err;
 253        ret = gpio_direction_output(GPIO_NR_PALMTX_BL_POWER, 0);
 254        if (ret)
 255                goto err2;
 256        ret = gpio_request(GPIO_NR_PALMTX_LCD_POWER, "LCD POWER");
 257        if (ret)
 258                goto err2;
 259        ret = gpio_direction_output(GPIO_NR_PALMTX_LCD_POWER, 0);
 260        if (ret)
 261                goto err3;
 262
 263        return 0;
 264err3:
 265        gpio_free(GPIO_NR_PALMTX_LCD_POWER);
 266err2:
 267        gpio_free(GPIO_NR_PALMTX_BL_POWER);
 268err:
 269        return ret;
 270}
 271
 272static int palmtx_backlight_notify(int brightness)
 273{
 274        gpio_set_value(GPIO_NR_PALMTX_BL_POWER, brightness);
 275        gpio_set_value(GPIO_NR_PALMTX_LCD_POWER, brightness);
 276        return brightness;
 277}
 278
 279static void palmtx_backlight_exit(struct device *dev)
 280{
 281        gpio_free(GPIO_NR_PALMTX_BL_POWER);
 282        gpio_free(GPIO_NR_PALMTX_LCD_POWER);
 283}
 284
 285static struct platform_pwm_backlight_data palmtx_backlight_data = {
 286        .pwm_id         = 0,
 287        .max_brightness = PALMTX_MAX_INTENSITY,
 288        .dft_brightness = PALMTX_MAX_INTENSITY,
 289        .pwm_period_ns  = PALMTX_PERIOD_NS,
 290        .init           = palmtx_backlight_init,
 291        .notify         = palmtx_backlight_notify,
 292        .exit           = palmtx_backlight_exit,
 293};
 294
 295static struct platform_device palmtx_backlight = {
 296        .name   = "pwm-backlight",
 297        .dev    = {
 298                .parent         = &pxa27x_device_pwm0.dev,
 299                .platform_data  = &palmtx_backlight_data,
 300        },
 301};
 302
 303/******************************************************************************
 304 * IrDA
 305 ******************************************************************************/
 306static struct pxaficp_platform_data palmtx_ficp_platform_data = {
 307        .gpio_pwdown            = GPIO_NR_PALMTX_IR_DISABLE,
 308        .transceiver_cap        = IR_SIRMODE | IR_OFF,
 309};
 310
 311/******************************************************************************
 312 * UDC
 313 ******************************************************************************/
 314static struct gpio_vbus_mach_info palmtx_udc_info = {
 315        .gpio_vbus              = GPIO_NR_PALMTX_USB_DETECT_N,
 316        .gpio_vbus_inverted     = 1,
 317        .gpio_pullup            = GPIO_NR_PALMTX_USB_PULLUP,
 318};
 319
 320static struct platform_device palmtx_gpio_vbus = {
 321        .name   = "gpio-vbus",
 322        .id     = -1,
 323        .dev    = {
 324                .platform_data  = &palmtx_udc_info,
 325        },
 326};
 327
 328/******************************************************************************
 329 * Power supply
 330 ******************************************************************************/
 331static int power_supply_init(struct device *dev)
 332{
 333        int ret;
 334
 335        ret = gpio_request(GPIO_NR_PALMTX_POWER_DETECT, "CABLE_STATE_AC");
 336        if (ret)
 337                goto err1;
 338        ret = gpio_direction_input(GPIO_NR_PALMTX_POWER_DETECT);
 339        if (ret)
 340                goto err2;
 341
 342        return 0;
 343
 344err2:
 345        gpio_free(GPIO_NR_PALMTX_POWER_DETECT);
 346err1:
 347        return ret;
 348}
 349
 350static int palmtx_is_ac_online(void)
 351{
 352        return gpio_get_value(GPIO_NR_PALMTX_POWER_DETECT);
 353}
 354
 355static void power_supply_exit(struct device *dev)
 356{
 357        gpio_free(GPIO_NR_PALMTX_POWER_DETECT);
 358}
 359
 360static char *palmtx_supplicants[] = {
 361        "main-battery",
 362};
 363
 364static struct pda_power_pdata power_supply_info = {
 365        .init            = power_supply_init,
 366        .is_ac_online    = palmtx_is_ac_online,
 367        .exit            = power_supply_exit,
 368        .supplied_to     = palmtx_supplicants,
 369        .num_supplicants = ARRAY_SIZE(palmtx_supplicants),
 370};
 371
 372static struct platform_device power_supply = {
 373        .name = "pda-power",
 374        .id   = -1,
 375        .dev  = {
 376                .platform_data = &power_supply_info,
 377        },
 378};
 379
 380/******************************************************************************
 381 * WM97xx battery
 382 ******************************************************************************/
 383static struct wm97xx_batt_info wm97xx_batt_pdata = {
 384        .batt_aux       = WM97XX_AUX_ID3,
 385        .temp_aux       = WM97XX_AUX_ID2,
 386        .charge_gpio    = -1,
 387        .max_voltage    = PALMTX_BAT_MAX_VOLTAGE,
 388        .min_voltage    = PALMTX_BAT_MIN_VOLTAGE,
 389        .batt_mult      = 1000,
 390        .batt_div       = 414,
 391        .temp_mult      = 1,
 392        .temp_div       = 1,
 393        .batt_tech      = POWER_SUPPLY_TECHNOLOGY_LIPO,
 394        .batt_name      = "main-batt",
 395};
 396
 397/******************************************************************************
 398 * aSoC audio
 399 ******************************************************************************/
 400static struct palm27x_asoc_info palmtx_asoc_pdata = {
 401        .jack_gpio      = GPIO_NR_PALMTX_EARPHONE_DETECT,
 402};
 403
 404static pxa2xx_audio_ops_t palmtx_ac97_pdata = {
 405        .reset_gpio     = 95,
 406};
 407
 408static struct platform_device palmtx_asoc = {
 409        .name = "palm27x-asoc",
 410        .id   = -1,
 411        .dev  = {
 412                .platform_data = &palmtx_asoc_pdata,
 413        },
 414};
 415
 416/******************************************************************************
 417 * Framebuffer
 418 ******************************************************************************/
 419static struct pxafb_mode_info palmtx_lcd_modes[] = {
 420{
 421        .pixclock       = 57692,
 422        .xres           = 320,
 423        .yres           = 480,
 424        .bpp            = 16,
 425
 426        .left_margin    = 32,
 427        .right_margin   = 1,
 428        .upper_margin   = 7,
 429        .lower_margin   = 1,
 430
 431        .hsync_len      = 4,
 432        .vsync_len      = 1,
 433},
 434};
 435
 436static struct pxafb_mach_info palmtx_lcd_screen = {
 437        .modes          = palmtx_lcd_modes,
 438        .num_modes      = ARRAY_SIZE(palmtx_lcd_modes),
 439        .lcd_conn       = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
 440};
 441
 442/******************************************************************************
 443 * NAND Flash
 444 ******************************************************************************/
 445static void palmtx_nand_cmd_ctl(struct mtd_info *mtd, int cmd,
 446                                 unsigned int ctrl)
 447{
 448        struct nand_chip *this = mtd->priv;
 449        unsigned long nandaddr = (unsigned long)this->IO_ADDR_W;
 450
 451        if (cmd == NAND_CMD_NONE)
 452                return;
 453
 454        if (ctrl & NAND_CLE)
 455                writeb(cmd, PALMTX_NAND_CLE_VIRT);
 456        else if (ctrl & NAND_ALE)
 457                writeb(cmd, PALMTX_NAND_ALE_VIRT);
 458        else
 459                writeb(cmd, nandaddr);
 460}
 461
 462static struct mtd_partition palmtx_partition_info[] = {
 463        [0] = {
 464                .name   = "palmtx-0",
 465                .offset = 0,
 466                .size   = MTDPART_SIZ_FULL
 467        },
 468};
 469
 470static const char *palmtx_part_probes[] = { "cmdlinepart", NULL };
 471
 472struct platform_nand_data palmtx_nand_platdata = {
 473        .chip   = {
 474                .nr_chips               = 1,
 475                .chip_offset            = 0,
 476                .nr_partitions          = ARRAY_SIZE(palmtx_partition_info),
 477                .partitions             = palmtx_partition_info,
 478                .chip_delay             = 20,
 479                .part_probe_types       = palmtx_part_probes,
 480        },
 481        .ctrl   = {
 482                .cmd_ctrl       = palmtx_nand_cmd_ctl,
 483        },
 484};
 485
 486static struct resource palmtx_nand_resource[] = {
 487        [0]     = {
 488                .start  = PXA_CS1_PHYS,
 489                .end    = PXA_CS1_PHYS + SZ_1M - 1,
 490                .flags  = IORESOURCE_MEM,
 491        },
 492};
 493
 494static struct platform_device palmtx_nand = {
 495        .name           = "gen_nand",
 496        .num_resources  = ARRAY_SIZE(palmtx_nand_resource),
 497        .resource       = palmtx_nand_resource,
 498        .id             = -1,
 499        .dev            = {
 500                .platform_data  = &palmtx_nand_platdata,
 501        }
 502};
 503
 504/******************************************************************************
 505 * Power management - standby
 506 ******************************************************************************/
 507static void __init palmtx_pm_init(void)
 508{
 509        static u32 resume[] = {
 510                0xe3a00101,     /* mov  r0,     #0x40000000 */
 511                0xe380060f,     /* orr  r0, r0, #0x00f00000 */
 512                0xe590f008,     /* ldr  pc, [r0, #0x08] */
 513        };
 514
 515        /* copy the bootloader */
 516        memcpy(phys_to_virt(PALMTX_STR_BASE), resume, sizeof(resume));
 517}
 518
 519/******************************************************************************
 520 * Machine init
 521 ******************************************************************************/
 522static struct platform_device *devices[] __initdata = {
 523#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
 524        &palmtx_pxa_keys,
 525#endif
 526        &palmtx_backlight,
 527        &power_supply,
 528        &palmtx_asoc,
 529        &palmtx_gpio_vbus,
 530        &palmtx_flash,
 531        &palmtx_nand,
 532};
 533
 534static struct map_desc palmtx_io_desc[] __initdata = {
 535{
 536        .virtual        = PALMTX_PCMCIA_VIRT,
 537        .pfn            = __phys_to_pfn(PALMTX_PCMCIA_PHYS),
 538        .length         = PALMTX_PCMCIA_SIZE,
 539        .type           = MT_DEVICE,
 540}, {
 541        .virtual        = PALMTX_NAND_ALE_VIRT,
 542        .pfn            = __phys_to_pfn(PALMTX_NAND_ALE_PHYS),
 543        .length         = SZ_1M,
 544        .type           = MT_DEVICE,
 545}, {
 546        .virtual        = PALMTX_NAND_CLE_VIRT,
 547        .pfn            = __phys_to_pfn(PALMTX_NAND_CLE_PHYS),
 548        .length         = SZ_1M,
 549        .type           = MT_DEVICE,
 550}
 551};
 552
 553static void __init palmtx_map_io(void)
 554{
 555        pxa_map_io();
 556        iotable_init(palmtx_io_desc, ARRAY_SIZE(palmtx_io_desc));
 557}
 558
 559/* setup udc GPIOs initial state */
 560static void __init palmtx_udc_init(void)
 561{
 562        if (!gpio_request(GPIO_NR_PALMTX_USB_PULLUP, "UDC Vbus")) {
 563                gpio_direction_output(GPIO_NR_PALMTX_USB_PULLUP, 1);
 564                gpio_free(GPIO_NR_PALMTX_USB_PULLUP);
 565        }
 566}
 567
 568
 569static void __init palmtx_init(void)
 570{
 571        pxa2xx_mfp_config(ARRAY_AND_SIZE(palmtx_pin_config));
 572
 573        palmtx_pm_init();
 574        set_pxa_fb_info(&palmtx_lcd_screen);
 575        pxa_set_mci_info(&palmtx_mci_platform_data);
 576        palmtx_udc_init();
 577        pxa_set_ac97_info(&palmtx_ac97_pdata);
 578        pxa_set_ficp_info(&palmtx_ficp_platform_data);
 579        pxa_set_keypad_info(&palmtx_keypad_platform_data);
 580        wm97xx_bat_set_pdata(&wm97xx_batt_pdata);
 581
 582        platform_add_devices(devices, ARRAY_SIZE(devices));
 583}
 584
 585MACHINE_START(PALMTX, "Palm T|X")
 586        .phys_io        = PALMTX_PHYS_IO_START,
 587        .io_pg_offst    = io_p2v(0x40000000),
 588        .boot_params    = 0xa0000100,
 589        .map_io         = palmtx_map_io,
 590        .init_irq       = pxa27x_init_irq,
 591        .timer          = &pxa_timer,
 592        .init_machine   = palmtx_init
 593MACHINE_END
 594