linux/arch/arm/mach-pxa/palmld.c
<<
>>
Prefs
   1/*
   2 * Hardware definitions for Palm LifeDrive
   3 *
   4 * Author:     Marek Vasut <marek.vasut@gmail.com>
   5 *
   6 * Based on work of:
   7 *              Alex Osborne <ato@meshy.org>
   8 *
   9 * This program is free software; you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License version 2 as
  11 * published by the Free Software Foundation.
  12 *
  13 * (find more info at www.hackndev.com)
  14 *
  15 */
  16
  17#include <linux/platform_device.h>
  18#include <linux/delay.h>
  19#include <linux/irq.h>
  20#include <linux/gpio_keys.h>
  21#include <linux/input.h>
  22#include <linux/pda_power.h>
  23#include <linux/pwm_backlight.h>
  24#include <linux/gpio.h>
  25#include <linux/wm97xx_batt.h>
  26#include <linux/power_supply.h>
  27#include <linux/sysdev.h>
  28#include <linux/mtd/mtd.h>
  29#include <linux/mtd/partitions.h>
  30#include <linux/mtd/physmap.h>
  31
  32#include <asm/mach-types.h>
  33#include <asm/mach/arch.h>
  34#include <asm/mach/map.h>
  35
  36#include <mach/pxa27x.h>
  37#include <mach/audio.h>
  38#include <mach/palmld.h>
  39#include <mach/mmc.h>
  40#include <mach/pxafb.h>
  41#include <mach/irda.h>
  42#include <mach/pxa27x_keypad.h>
  43#include <mach/palmasoc.h>
  44
  45#include "generic.h"
  46#include "devices.h"
  47
  48/******************************************************************************
  49 * Pin configuration
  50 ******************************************************************************/
  51static unsigned long palmld_pin_config[] __initdata = {
  52        /* MMC */
  53        GPIO32_MMC_CLK,
  54        GPIO92_MMC_DAT_0,
  55        GPIO109_MMC_DAT_1,
  56        GPIO110_MMC_DAT_2,
  57        GPIO111_MMC_DAT_3,
  58        GPIO112_MMC_CMD,
  59        GPIO14_GPIO,    /* SD detect */
  60        GPIO114_GPIO,   /* SD power */
  61        GPIO116_GPIO,   /* SD r/o switch */
  62
  63        /* AC97 */
  64        GPIO28_AC97_BITCLK,
  65        GPIO29_AC97_SDATA_IN_0,
  66        GPIO30_AC97_SDATA_OUT,
  67        GPIO31_AC97_SYNC,
  68        GPIO89_AC97_SYSCLK,
  69        GPIO95_AC97_nRESET,
  70
  71        /* IrDA */
  72        GPIO108_GPIO,   /* ir disable */
  73        GPIO46_FICP_RXD,
  74        GPIO47_FICP_TXD,
  75
  76        /* MATRIX KEYPAD */
  77        GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
  78        GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH,
  79        GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH,
  80        GPIO97_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH,
  81        GPIO103_KP_MKOUT_0,
  82        GPIO104_KP_MKOUT_1,
  83        GPIO105_KP_MKOUT_2,
  84
  85        /* LCD */
  86        GPIO58_LCD_LDD_0,
  87        GPIO59_LCD_LDD_1,
  88        GPIO60_LCD_LDD_2,
  89        GPIO61_LCD_LDD_3,
  90        GPIO62_LCD_LDD_4,
  91        GPIO63_LCD_LDD_5,
  92        GPIO64_LCD_LDD_6,
  93        GPIO65_LCD_LDD_7,
  94        GPIO66_LCD_LDD_8,
  95        GPIO67_LCD_LDD_9,
  96        GPIO68_LCD_LDD_10,
  97        GPIO69_LCD_LDD_11,
  98        GPIO70_LCD_LDD_12,
  99        GPIO71_LCD_LDD_13,
 100        GPIO72_LCD_LDD_14,
 101        GPIO73_LCD_LDD_15,
 102        GPIO74_LCD_FCLK,
 103        GPIO75_LCD_LCLK,
 104        GPIO76_LCD_PCLK,
 105        GPIO77_LCD_BIAS,
 106
 107        /* PWM */
 108        GPIO16_PWM0_OUT,
 109
 110        /* GPIO KEYS */
 111        GPIO10_GPIO,    /* hotsync button */
 112        GPIO12_GPIO,    /* power switch */
 113        GPIO15_GPIO,    /* lock switch */
 114
 115        /* LEDs */
 116        GPIO52_GPIO,    /* green led */
 117        GPIO94_GPIO,    /* orange led */
 118
 119        /* PCMCIA */
 120        GPIO48_nPOE,
 121        GPIO49_nPWE,
 122        GPIO50_nPIOR,
 123        GPIO51_nPIOW,
 124        GPIO85_nPCE_1,
 125        GPIO54_nPCE_2,
 126        GPIO79_PSKTSEL,
 127        GPIO55_nPREG,
 128        GPIO56_nPWAIT,
 129        GPIO57_nIOIS16,
 130        GPIO36_GPIO,    /* wifi power */
 131        GPIO38_GPIO,    /* wifi ready */
 132        GPIO81_GPIO,    /* wifi reset */
 133
 134        /* FFUART */
 135        GPIO34_FFUART_RXD,
 136        GPIO39_FFUART_TXD,
 137
 138        /* HDD */
 139        GPIO98_GPIO,    /* HDD reset */
 140        GPIO115_GPIO,   /* HDD power */
 141
 142        /* MISC */
 143        GPIO13_GPIO,    /* earphone detect */
 144};
 145
 146/******************************************************************************
 147 * NOR Flash
 148 ******************************************************************************/
 149static struct mtd_partition palmld_partitions[] = {
 150        {
 151                .name           = "Flash",
 152                .offset         = 0x00000000,
 153                .size           = MTDPART_SIZ_FULL,
 154                .mask_flags     = 0
 155        }
 156};
 157
 158static struct physmap_flash_data palmld_flash_data[] = {
 159        {
 160                .width          = 2,                    /* bankwidth in bytes */
 161                .parts          = palmld_partitions,
 162                .nr_parts       = ARRAY_SIZE(palmld_partitions)
 163        }
 164};
 165
 166static struct resource palmld_flash_resource = {
 167        .start  = PXA_CS0_PHYS,
 168        .end    = PXA_CS0_PHYS + SZ_4M - 1,
 169        .flags  = IORESOURCE_MEM,
 170};
 171
 172static struct platform_device palmld_flash = {
 173        .name           = "physmap-flash",
 174        .id             = 0,
 175        .resource       = &palmld_flash_resource,
 176        .num_resources  = 1,
 177        .dev            = {
 178                .platform_data = palmld_flash_data,
 179        },
 180};
 181
 182/******************************************************************************
 183 * SD/MMC card controller
 184 ******************************************************************************/
 185static struct pxamci_platform_data palmld_mci_platform_data = {
 186        .ocr_mask               = MMC_VDD_32_33 | MMC_VDD_33_34,
 187        .gpio_card_detect       = GPIO_NR_PALMLD_SD_DETECT_N,
 188        .gpio_card_ro           = GPIO_NR_PALMLD_SD_READONLY,
 189        .gpio_power             = GPIO_NR_PALMLD_SD_POWER,
 190        .detect_delay           = 20,
 191};
 192
 193/******************************************************************************
 194 * GPIO keyboard
 195 ******************************************************************************/
 196static unsigned int palmld_matrix_keys[] = {
 197        KEY(0, 1, KEY_F2),
 198        KEY(0, 2, KEY_UP),
 199
 200        KEY(1, 0, KEY_F3),
 201        KEY(1, 1, KEY_F4),
 202        KEY(1, 2, KEY_RIGHT),
 203
 204        KEY(2, 0, KEY_F1),
 205        KEY(2, 1, KEY_F5),
 206        KEY(2, 2, KEY_DOWN),
 207
 208        KEY(3, 0, KEY_F6),
 209        KEY(3, 1, KEY_ENTER),
 210        KEY(3, 2, KEY_LEFT),
 211};
 212
 213static struct pxa27x_keypad_platform_data palmld_keypad_platform_data = {
 214        .matrix_key_rows        = 4,
 215        .matrix_key_cols        = 3,
 216        .matrix_key_map         = palmld_matrix_keys,
 217        .matrix_key_map_size    = ARRAY_SIZE(palmld_matrix_keys),
 218
 219        .debounce_interval      = 30,
 220};
 221
 222/******************************************************************************
 223 * GPIO keys
 224 ******************************************************************************/
 225static struct gpio_keys_button palmld_pxa_buttons[] = {
 226        {KEY_F8, GPIO_NR_PALMLD_HOTSYNC_BUTTON_N, 1, "HotSync Button" },
 227        {KEY_F9, GPIO_NR_PALMLD_LOCK_SWITCH, 0, "Lock Switch" },
 228        {KEY_POWER, GPIO_NR_PALMLD_POWER_SWITCH, 0, "Power Switch" },
 229};
 230
 231static struct gpio_keys_platform_data palmld_pxa_keys_data = {
 232        .buttons        = palmld_pxa_buttons,
 233        .nbuttons       = ARRAY_SIZE(palmld_pxa_buttons),
 234};
 235
 236static struct platform_device palmld_pxa_keys = {
 237        .name   = "gpio-keys",
 238        .id     = -1,
 239        .dev    = {
 240                .platform_data = &palmld_pxa_keys_data,
 241        },
 242};
 243
 244/******************************************************************************
 245 * Backlight
 246 ******************************************************************************/
 247static int palmld_backlight_init(struct device *dev)
 248{
 249        int ret;
 250
 251        ret = gpio_request(GPIO_NR_PALMLD_BL_POWER, "BL POWER");
 252        if (ret)
 253                goto err;
 254        ret = gpio_direction_output(GPIO_NR_PALMLD_BL_POWER, 0);
 255        if (ret)
 256                goto err2;
 257        ret = gpio_request(GPIO_NR_PALMLD_LCD_POWER, "LCD POWER");
 258        if (ret)
 259                goto err2;
 260        ret = gpio_direction_output(GPIO_NR_PALMLD_LCD_POWER, 0);
 261        if (ret)
 262                goto err3;
 263
 264        return 0;
 265err3:
 266        gpio_free(GPIO_NR_PALMLD_LCD_POWER);
 267err2:
 268        gpio_free(GPIO_NR_PALMLD_BL_POWER);
 269err:
 270        return ret;
 271}
 272
 273static int palmld_backlight_notify(int brightness)
 274{
 275        gpio_set_value(GPIO_NR_PALMLD_BL_POWER, brightness);
 276        gpio_set_value(GPIO_NR_PALMLD_LCD_POWER, brightness);
 277        return brightness;
 278}
 279
 280static void palmld_backlight_exit(struct device *dev)
 281{
 282        gpio_free(GPIO_NR_PALMLD_BL_POWER);
 283        gpio_free(GPIO_NR_PALMLD_LCD_POWER);
 284}
 285
 286static struct platform_pwm_backlight_data palmld_backlight_data = {
 287        .pwm_id         = 0,
 288        .max_brightness = PALMLD_MAX_INTENSITY,
 289        .dft_brightness = PALMLD_MAX_INTENSITY,
 290        .pwm_period_ns  = PALMLD_PERIOD_NS,
 291        .init           = palmld_backlight_init,
 292        .notify         = palmld_backlight_notify,
 293        .exit           = palmld_backlight_exit,
 294};
 295
 296static struct platform_device palmld_backlight = {
 297        .name   = "pwm-backlight",
 298        .dev    = {
 299                .parent         = &pxa27x_device_pwm0.dev,
 300                .platform_data  = &palmld_backlight_data,
 301        },
 302};
 303
 304/******************************************************************************
 305 * IrDA
 306 ******************************************************************************/
 307static struct pxaficp_platform_data palmld_ficp_platform_data = {
 308        .gpio_pwdown            = GPIO_NR_PALMLD_IR_DISABLE,
 309        .transceiver_cap        = IR_SIRMODE | IR_OFF,
 310};
 311
 312/******************************************************************************
 313 * LEDs
 314 ******************************************************************************/
 315struct gpio_led gpio_leds[] = {
 316{
 317        .name                   = "palmld:green:led",
 318        .default_trigger        = "none",
 319        .gpio                   = GPIO_NR_PALMLD_LED_GREEN,
 320}, {
 321        .name                   = "palmld:amber:led",
 322        .default_trigger        = "none",
 323        .gpio                   = GPIO_NR_PALMLD_LED_AMBER,
 324},
 325};
 326
 327static struct gpio_led_platform_data gpio_led_info = {
 328        .leds           = gpio_leds,
 329        .num_leds       = ARRAY_SIZE(gpio_leds),
 330};
 331
 332static struct platform_device palmld_leds = {
 333        .name   = "leds-gpio",
 334        .id     = -1,
 335        .dev    = {
 336                .platform_data  = &gpio_led_info,
 337        }
 338};
 339
 340/******************************************************************************
 341 * Power supply
 342 ******************************************************************************/
 343static int power_supply_init(struct device *dev)
 344{
 345        int ret;
 346
 347        ret = gpio_request(GPIO_NR_PALMLD_POWER_DETECT, "CABLE_STATE_AC");
 348        if (ret)
 349                goto err1;
 350        ret = gpio_direction_input(GPIO_NR_PALMLD_POWER_DETECT);
 351        if (ret)
 352                goto err2;
 353
 354        ret = gpio_request(GPIO_NR_PALMLD_USB_DETECT_N, "CABLE_STATE_USB");
 355        if (ret)
 356                goto err2;
 357        ret = gpio_direction_input(GPIO_NR_PALMLD_USB_DETECT_N);
 358        if (ret)
 359                goto err3;
 360
 361        return 0;
 362
 363err3:
 364        gpio_free(GPIO_NR_PALMLD_USB_DETECT_N);
 365err2:
 366        gpio_free(GPIO_NR_PALMLD_POWER_DETECT);
 367err1:
 368        return ret;
 369}
 370
 371static int palmld_is_ac_online(void)
 372{
 373        return gpio_get_value(GPIO_NR_PALMLD_POWER_DETECT);
 374}
 375
 376static int palmld_is_usb_online(void)
 377{
 378        return !gpio_get_value(GPIO_NR_PALMLD_USB_DETECT_N);
 379}
 380
 381static void power_supply_exit(struct device *dev)
 382{
 383        gpio_free(GPIO_NR_PALMLD_USB_DETECT_N);
 384        gpio_free(GPIO_NR_PALMLD_POWER_DETECT);
 385}
 386
 387static char *palmld_supplicants[] = {
 388        "main-battery",
 389};
 390
 391static struct pda_power_pdata power_supply_info = {
 392        .init            = power_supply_init,
 393        .is_ac_online    = palmld_is_ac_online,
 394        .is_usb_online   = palmld_is_usb_online,
 395        .exit            = power_supply_exit,
 396        .supplied_to     = palmld_supplicants,
 397        .num_supplicants = ARRAY_SIZE(palmld_supplicants),
 398};
 399
 400static struct platform_device power_supply = {
 401        .name = "pda-power",
 402        .id   = -1,
 403        .dev  = {
 404                .platform_data = &power_supply_info,
 405        },
 406};
 407
 408/******************************************************************************
 409 * WM97xx battery
 410 ******************************************************************************/
 411static struct wm97xx_batt_info wm97xx_batt_pdata = {
 412        .batt_aux       = WM97XX_AUX_ID3,
 413        .temp_aux       = WM97XX_AUX_ID2,
 414        .charge_gpio    = -1,
 415        .max_voltage    = PALMLD_BAT_MAX_VOLTAGE,
 416        .min_voltage    = PALMLD_BAT_MIN_VOLTAGE,
 417        .batt_mult      = 1000,
 418        .batt_div       = 414,
 419        .temp_mult      = 1,
 420        .temp_div       = 1,
 421        .batt_tech      = POWER_SUPPLY_TECHNOLOGY_LIPO,
 422        .batt_name      = "main-batt",
 423};
 424
 425/******************************************************************************
 426 * aSoC audio
 427 ******************************************************************************/
 428static struct palm27x_asoc_info palmld_asoc_pdata = {
 429        .jack_gpio      = GPIO_NR_PALMLD_EARPHONE_DETECT,
 430};
 431
 432static pxa2xx_audio_ops_t palmld_ac97_pdata = {
 433        .reset_gpio     = 95,
 434};
 435
 436static struct platform_device palmld_asoc = {
 437        .name = "palm27x-asoc",
 438        .id   = -1,
 439        .dev  = {
 440                .platform_data = &palmld_asoc_pdata,
 441        },
 442};
 443
 444/******************************************************************************
 445 * HDD
 446 ******************************************************************************/
 447static struct platform_device palmld_hdd = {
 448        .name   = "pata_palmld",
 449        .id     = -1,
 450};
 451
 452/******************************************************************************
 453 * Framebuffer
 454 ******************************************************************************/
 455static struct pxafb_mode_info palmld_lcd_modes[] = {
 456{
 457        .pixclock       = 57692,
 458        .xres           = 320,
 459        .yres           = 480,
 460        .bpp            = 16,
 461
 462        .left_margin    = 32,
 463        .right_margin   = 1,
 464        .upper_margin   = 7,
 465        .lower_margin   = 1,
 466
 467        .hsync_len      = 4,
 468        .vsync_len      = 1,
 469},
 470};
 471
 472static struct pxafb_mach_info palmld_lcd_screen = {
 473        .modes          = palmld_lcd_modes,
 474        .num_modes      = ARRAY_SIZE(palmld_lcd_modes),
 475        .lcd_conn       = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
 476};
 477
 478/******************************************************************************
 479 * Power management - standby
 480 ******************************************************************************/
 481static void __init palmld_pm_init(void)
 482{
 483        static u32 resume[] = {
 484                0xe3a00101,     /* mov  r0,     #0x40000000 */
 485                0xe380060f,     /* orr  r0, r0, #0x00f00000 */
 486                0xe590f008,     /* ldr  pc, [r0, #0x08] */
 487        };
 488
 489        /* copy the bootloader */
 490        memcpy(phys_to_virt(PALMLD_STR_BASE), resume, sizeof(resume));
 491}
 492
 493/******************************************************************************
 494 * Machine init
 495 ******************************************************************************/
 496static struct platform_device *devices[] __initdata = {
 497#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
 498        &palmld_pxa_keys,
 499#endif
 500        &palmld_backlight,
 501        &palmld_leds,
 502        &power_supply,
 503        &palmld_asoc,
 504        &palmld_hdd,
 505        &palmld_flash,
 506};
 507
 508static struct map_desc palmld_io_desc[] __initdata = {
 509{
 510        .virtual        = PALMLD_IDE_VIRT,
 511        .pfn            = __phys_to_pfn(PALMLD_IDE_PHYS),
 512        .length         = PALMLD_IDE_SIZE,
 513        .type           = MT_DEVICE
 514},
 515{
 516        .virtual        = PALMLD_USB_VIRT,
 517        .pfn            = __phys_to_pfn(PALMLD_USB_PHYS),
 518        .length         = PALMLD_USB_SIZE,
 519        .type           = MT_DEVICE
 520},
 521};
 522
 523static void __init palmld_map_io(void)
 524{
 525        pxa_map_io();
 526        iotable_init(palmld_io_desc, ARRAY_SIZE(palmld_io_desc));
 527}
 528
 529static void __init palmld_init(void)
 530{
 531        pxa2xx_mfp_config(ARRAY_AND_SIZE(palmld_pin_config));
 532
 533        palmld_pm_init();
 534        set_pxa_fb_info(&palmld_lcd_screen);
 535        pxa_set_mci_info(&palmld_mci_platform_data);
 536        pxa_set_ac97_info(&palmld_ac97_pdata);
 537        pxa_set_ficp_info(&palmld_ficp_platform_data);
 538        pxa_set_keypad_info(&palmld_keypad_platform_data);
 539        wm97xx_bat_set_pdata(&wm97xx_batt_pdata);
 540
 541        platform_add_devices(devices, ARRAY_SIZE(devices));
 542}
 543
 544MACHINE_START(PALMLD, "Palm LifeDrive")
 545        .phys_io        = PALMLD_PHYS_IO_START,
 546        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
 547        .boot_params    = 0xa0000100,
 548        .map_io         = palmld_map_io,
 549        .init_irq       = pxa27x_init_irq,
 550        .timer          = &pxa_timer,
 551        .init_machine   = palmld_init
 552MACHINE_END
 553
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.