linux/arch/arm/mach-pxa/treo680.c
<<
>>
Prefs
   1/*
   2 * Hardware definitions for Palm Treo 680
   3 *
   4 * Author:     Tomas Cech <sleep_walker@suse.cz>
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation.
   9 *
  10 * (find more info at www.hackndev.com)
  11 *
  12 */
  13
  14#include <linux/platform_device.h>
  15#include <linux/delay.h>
  16#include <linux/irq.h>
  17#include <linux/gpio_keys.h>
  18#include <linux/input.h>
  19#include <linux/pda_power.h>
  20#include <linux/pwm_backlight.h>
  21#include <linux/gpio.h>
  22#include <linux/wm97xx_batt.h>
  23#include <linux/power_supply.h>
  24#include <linux/sysdev.h>
  25#include <linux/w1-gpio.h>
  26
  27#include <asm/mach-types.h>
  28#include <asm/mach/arch.h>
  29#include <asm/mach/map.h>
  30
  31#include <mach/pxa27x.h>
  32#include <mach/pxa27x-udc.h>
  33#include <mach/audio.h>
  34#include <mach/treo680.h>
  35#include <mach/mmc.h>
  36#include <mach/pxafb.h>
  37#include <mach/irda.h>
  38#include <mach/pxa27x_keypad.h>
  39#include <mach/udc.h>
  40#include <mach/ohci.h>
  41#include <mach/pxa2xx-regs.h>
  42#include <mach/palmasoc.h>
  43#include <mach/camera.h>
  44
  45#include <sound/pxa2xx-lib.h>
  46
  47#include "generic.h"
  48#include "devices.h"
  49
  50/******************************************************************************
  51 * Pin configuration
  52 ******************************************************************************/
  53static unsigned long treo680_pin_config[] __initdata = {
  54        /* MMC */
  55        GPIO32_MMC_CLK,
  56        GPIO92_MMC_DAT_0,
  57        GPIO109_MMC_DAT_1,
  58        GPIO110_MMC_DAT_2,
  59        GPIO111_MMC_DAT_3,
  60        GPIO112_MMC_CMD,
  61        GPIO33_GPIO,                            /* SD read only */
  62        GPIO113_GPIO,                           /* SD detect */
  63
  64        /* AC97 */
  65        GPIO28_AC97_BITCLK,
  66        GPIO29_AC97_SDATA_IN_0,
  67        GPIO30_AC97_SDATA_OUT,
  68        GPIO31_AC97_SYNC,
  69        GPIO89_AC97_SYSCLK,
  70        GPIO95_AC97_nRESET,
  71
  72        /* IrDA */
  73        GPIO46_FICP_RXD,
  74        GPIO47_FICP_TXD,
  75
  76        /* PWM */
  77        GPIO16_PWM0_OUT,
  78
  79        /* USB */
  80        GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH,       /* usb detect */
  81
  82        /* MATRIX KEYPAD */
  83        GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
  84        GPIO101_KP_MKIN_1,
  85        GPIO102_KP_MKIN_2,
  86        GPIO97_KP_MKIN_3,
  87        GPIO98_KP_MKIN_4,
  88        GPIO99_KP_MKIN_5,
  89        GPIO91_KP_MKIN_6,
  90        GPIO13_KP_MKIN_7,
  91        GPIO103_KP_MKOUT_0 | MFP_LPM_DRIVE_HIGH,
  92        GPIO104_KP_MKOUT_1,
  93        GPIO105_KP_MKOUT_2,
  94        GPIO106_KP_MKOUT_3,
  95        GPIO107_KP_MKOUT_4,
  96        GPIO108_KP_MKOUT_5,
  97        GPIO96_KP_MKOUT_6,
  98        GPIO93_KP_DKIN_0 | WAKEUP_ON_LEVEL_HIGH,        /* Hotsync button */
  99
 100        /* LCD */
 101        GPIO58_LCD_LDD_0,
 102        GPIO59_LCD_LDD_1,
 103        GPIO60_LCD_LDD_2,
 104        GPIO61_LCD_LDD_3,
 105        GPIO62_LCD_LDD_4,
 106        GPIO63_LCD_LDD_5,
 107        GPIO64_LCD_LDD_6,
 108        GPIO65_LCD_LDD_7,
 109        GPIO66_LCD_LDD_8,
 110        GPIO67_LCD_LDD_9,
 111        GPIO68_LCD_LDD_10,
 112        GPIO69_LCD_LDD_11,
 113        GPIO70_LCD_LDD_12,
 114        GPIO71_LCD_LDD_13,
 115        GPIO72_LCD_LDD_14,
 116        GPIO73_LCD_LDD_15,
 117        GPIO74_LCD_FCLK,
 118        GPIO75_LCD_LCLK,
 119        GPIO76_LCD_PCLK,
 120
 121        /* Quick Capture Interface */
 122        GPIO84_CIF_FV,
 123        GPIO85_CIF_LV,
 124        GPIO53_CIF_MCLK,
 125        GPIO54_CIF_PCLK,
 126        GPIO81_CIF_DD_0,
 127        GPIO55_CIF_DD_1,
 128        GPIO51_CIF_DD_2,
 129        GPIO50_CIF_DD_3,
 130        GPIO52_CIF_DD_4,
 131        GPIO48_CIF_DD_5,
 132        GPIO17_CIF_DD_6,
 133        GPIO12_CIF_DD_7,
 134
 135        /* I2C */
 136        GPIO117_I2C_SCL,
 137        GPIO118_I2C_SDA,
 138
 139        /* GSM */
 140        GPIO14_GPIO | WAKEUP_ON_EDGE_BOTH,      /* GSM host wake up */
 141        GPIO34_FFUART_RXD,
 142        GPIO35_FFUART_CTS,
 143        GPIO39_FFUART_TXD,
 144        GPIO41_FFUART_RTS,
 145
 146        /* MISC. */
 147        GPIO0_GPIO | WAKEUP_ON_EDGE_BOTH,       /* external power detect */
 148        GPIO15_GPIO | WAKEUP_ON_EDGE_BOTH,      /* silent switch */
 149        GPIO116_GPIO,                           /* headphone detect */
 150        GPIO11_GPIO | WAKEUP_ON_EDGE_BOTH,      /* bluetooth host wake up */
 151};
 152
 153/******************************************************************************
 154 * SD/MMC card controller
 155 ******************************************************************************/
 156static struct pxamci_platform_data treo680_mci_platform_data = {
 157        .ocr_mask               = MMC_VDD_32_33 | MMC_VDD_33_34,
 158        .gpio_card_detect       = GPIO_NR_TREO680_SD_DETECT_N,
 159        .gpio_card_ro           = GPIO_NR_TREO680_SD_READONLY,
 160        .gpio_power             = GPIO_NR_TREO680_SD_POWER,
 161};
 162
 163/******************************************************************************
 164 * GPIO keyboard
 165 ******************************************************************************/
 166static unsigned int treo680_matrix_keys[] = {
 167        KEY(0, 0, KEY_F8),              /* Red/Off/Power */
 168        KEY(0, 1, KEY_LEFT),
 169        KEY(0, 2, KEY_LEFTCTRL),        /* Alternate */
 170        KEY(0, 3, KEY_L),
 171        KEY(0, 4, KEY_A),
 172        KEY(0, 5, KEY_Q),
 173        KEY(0, 6, KEY_P),
 174
 175        KEY(1, 0, KEY_RIGHTCTRL),       /* Menu */
 176        KEY(1, 1, KEY_RIGHT),
 177        KEY(1, 2, KEY_LEFTSHIFT),       /* Left shift */
 178        KEY(1, 3, KEY_Z),
 179        KEY(1, 4, KEY_S),
 180        KEY(1, 5, KEY_W),
 181
 182        KEY(2, 0, KEY_F1),              /* Phone */
 183        KEY(2, 1, KEY_UP),
 184        KEY(2, 2, KEY_0),
 185        KEY(2, 3, KEY_X),
 186        KEY(2, 4, KEY_D),
 187        KEY(2, 5, KEY_E),
 188
 189        KEY(3, 0, KEY_F10),             /* Calendar */
 190        KEY(3, 1, KEY_DOWN),
 191        KEY(3, 2, KEY_SPACE),
 192        KEY(3, 3, KEY_C),
 193        KEY(3, 4, KEY_F),
 194        KEY(3, 5, KEY_R),
 195
 196        KEY(4, 0, KEY_F12),             /* Mail */
 197        KEY(4, 1, KEY_KPENTER),
 198        KEY(4, 2, KEY_RIGHTALT),        /* Alt */
 199        KEY(4, 3, KEY_V),
 200        KEY(4, 4, KEY_G),
 201        KEY(4, 5, KEY_T),
 202
 203        KEY(5, 0, KEY_F9),              /* Home */
 204        KEY(5, 1, KEY_PAGEUP),          /* Side up */
 205        KEY(5, 2, KEY_DOT),
 206        KEY(5, 3, KEY_B),
 207        KEY(5, 4, KEY_H),
 208        KEY(5, 5, KEY_Y),
 209
 210        KEY(6, 0, KEY_TAB),             /* Side Activate */
 211        KEY(6, 1, KEY_PAGEDOWN),        /* Side down */
 212        KEY(6, 2, KEY_ENTER),
 213        KEY(6, 3, KEY_N),
 214        KEY(6, 4, KEY_J),
 215        KEY(6, 5, KEY_U),
 216
 217        KEY(7, 0, KEY_F6),              /* Green/Call */
 218        KEY(7, 1, KEY_O),
 219        KEY(7, 2, KEY_BACKSPACE),
 220        KEY(7, 3, KEY_M),
 221        KEY(7, 4, KEY_K),
 222        KEY(7, 5, KEY_I),
 223};
 224
 225static struct pxa27x_keypad_platform_data treo680_keypad_platform_data = {
 226        .matrix_key_rows        = 8,
 227        .matrix_key_cols        = 7,
 228        .matrix_key_map         = treo680_matrix_keys,
 229        .matrix_key_map_size    = ARRAY_SIZE(treo680_matrix_keys),
 230        .direct_key_map         = { KEY_CONNECT },
 231        .direct_key_num         = 1,
 232
 233        .debounce_interval      = 30,
 234};
 235
 236/******************************************************************************
 237 * aSoC audio
 238 ******************************************************************************/
 239
 240static pxa2xx_audio_ops_t treo680_ac97_pdata = {
 241        .reset_gpio     = 95,
 242};
 243
 244/******************************************************************************
 245 * Backlight
 246 ******************************************************************************/
 247static int treo680_backlight_init(struct device *dev)
 248{
 249        int ret;
 250
 251        ret = gpio_request(GPIO_NR_TREO680_BL_POWER, "BL POWER");
 252        if (ret)
 253                goto err;
 254        ret = gpio_direction_output(GPIO_NR_TREO680_BL_POWER, 0);
 255        if (ret)
 256                goto err2;
 257
 258        return 0;
 259
 260err2:
 261        gpio_free(GPIO_NR_TREO680_BL_POWER);
 262err:
 263        return ret;
 264}
 265
 266static int treo680_backlight_notify(int brightness)
 267{
 268        gpio_set_value(GPIO_NR_TREO680_BL_POWER, brightness);
 269        return TREO680_MAX_INTENSITY - brightness;
 270};
 271
 272static void treo680_backlight_exit(struct device *dev)
 273{
 274        gpio_free(GPIO_NR_TREO680_BL_POWER);
 275}
 276
 277static struct platform_pwm_backlight_data treo680_backlight_data = {
 278        .pwm_id         = 0,
 279        .max_brightness = TREO680_MAX_INTENSITY,
 280        .dft_brightness = TREO680_DEFAULT_INTENSITY,
 281        .pwm_period_ns  = TREO680_PERIOD_NS,
 282        .init           = treo680_backlight_init,
 283        .notify         = treo680_backlight_notify,
 284        .exit           = treo680_backlight_exit,
 285};
 286
 287static struct platform_device treo680_backlight = {
 288        .name   = "pwm-backlight",
 289        .dev    = {
 290                .parent         = &pxa27x_device_pwm0.dev,
 291                .platform_data  = &treo680_backlight_data,
 292        },
 293};
 294
 295/******************************************************************************
 296 * IrDA
 297 ******************************************************************************/
 298static struct pxaficp_platform_data treo680_ficp_info = {
 299        .gpio_pwdown            = GPIO_NR_TREO680_IR_EN,
 300        .transceiver_cap        = IR_SIRMODE | IR_OFF,
 301};
 302
 303/******************************************************************************
 304 * UDC
 305 ******************************************************************************/
 306static struct pxa2xx_udc_mach_info treo680_udc_info __initdata = {
 307        .gpio_vbus              = GPIO_NR_TREO680_USB_DETECT,
 308        .gpio_vbus_inverted     = 1,
 309        .gpio_pullup            = GPIO_NR_TREO680_USB_PULLUP,
 310};
 311
 312
 313/******************************************************************************
 314 * USB host
 315 ******************************************************************************/
 316static struct pxaohci_platform_data treo680_ohci_info = {
 317        .port_mode    = PMM_PERPORT_MODE,
 318        .flags        = ENABLE_PORT1 | ENABLE_PORT3,
 319        .power_budget = 0,
 320};
 321
 322/******************************************************************************
 323 * Power supply
 324 ******************************************************************************/
 325static int power_supply_init(struct device *dev)
 326{
 327        int ret;
 328
 329        ret = gpio_request(GPIO_NR_TREO680_POWER_DETECT, "CABLE_STATE_AC");
 330        if (ret)
 331                goto err1;
 332        ret = gpio_direction_input(GPIO_NR_TREO680_POWER_DETECT);
 333        if (ret)
 334                goto err2;
 335
 336        return 0;
 337
 338err2:
 339        gpio_free(GPIO_NR_TREO680_POWER_DETECT);
 340err1:
 341        return ret;
 342}
 343
 344static int treo680_is_ac_online(void)
 345{
 346        return gpio_get_value(GPIO_NR_TREO680_POWER_DETECT);
 347}
 348
 349static void power_supply_exit(struct device *dev)
 350{
 351        gpio_free(GPIO_NR_TREO680_POWER_DETECT);
 352}
 353
 354static char *treo680_supplicants[] = {
 355        "main-battery",
 356};
 357
 358static struct pda_power_pdata power_supply_info = {
 359        .init            = power_supply_init,
 360        .is_ac_online    = treo680_is_ac_online,
 361        .exit            = power_supply_exit,
 362        .supplied_to     = treo680_supplicants,
 363        .num_supplicants = ARRAY_SIZE(treo680_supplicants),
 364};
 365
 366static struct platform_device power_supply = {
 367        .name = "pda-power",
 368        .id   = -1,
 369        .dev  = {
 370                .platform_data = &power_supply_info,
 371        },
 372};
 373
 374/******************************************************************************
 375 * Vibra and LEDs
 376 ******************************************************************************/
 377static struct gpio_led gpio_leds[] = {
 378        {
 379                .name                   = "treo680:vibra:vibra",
 380                .default_trigger        = "none",
 381                .gpio                   = GPIO_NR_TREO680_VIBRATE_EN,
 382        },
 383        {
 384                .name                   = "treo680:green:led",
 385                .default_trigger        = "mmc0",
 386                .gpio                   = GPIO_NR_TREO680_GREEN_LED,
 387        },
 388        {
 389                .name                   = "treo680:keybbl:keybbl",
 390                .default_trigger        = "none",
 391                .gpio                   = GPIO_NR_TREO680_KEYB_BL,
 392        },
 393};
 394
 395static struct gpio_led_platform_data gpio_led_info = {
 396        .leds           = gpio_leds,
 397        .num_leds       = ARRAY_SIZE(gpio_leds),
 398};
 399
 400static struct platform_device treo680_leds = {
 401        .name   = "leds-gpio",
 402        .id     = -1,
 403        .dev    = {
 404                .platform_data  = &gpio_led_info,
 405        }
 406};
 407
 408
 409/******************************************************************************
 410 * Framebuffer
 411 ******************************************************************************/
 412/* TODO: add support for 324x324 */
 413static struct pxafb_mode_info treo680_lcd_modes[] = {
 414{
 415        .pixclock               = 86538,
 416        .xres                   = 320,
 417        .yres                   = 320,
 418        .bpp                    = 16,
 419
 420        .left_margin            = 20,
 421        .right_margin           = 8,
 422        .upper_margin           = 8,
 423        .lower_margin           = 5,
 424
 425        .hsync_len              = 4,
 426        .vsync_len              = 1,
 427},
 428};
 429
 430static void treo680_lcd_power(int on, struct fb_var_screeninfo *info)
 431{
 432        gpio_set_value(GPIO_NR_TREO680_BL_POWER, on);
 433}
 434
 435static struct pxafb_mach_info treo680_lcd_screen = {
 436        .modes          = treo680_lcd_modes,
 437        .num_modes      = ARRAY_SIZE(treo680_lcd_modes),
 438        .lcd_conn       = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
 439};
 440
 441/******************************************************************************
 442 * Power management - standby
 443 ******************************************************************************/
 444static void __init treo680_pm_init(void)
 445{
 446        static u32 resume[] = {
 447                0xe3a00101,     /* mov  r0,     #0x40000000 */
 448                0xe380060f,     /* orr  r0, r0, #0x00f00000 */
 449                0xe590f008,     /* ldr  pc, [r0, #0x08] */
 450        };
 451
 452        /* this is where the bootloader jumps */
 453        memcpy(phys_to_virt(TREO680_STR_BASE), resume, sizeof(resume));
 454}
 455
 456/******************************************************************************
 457 * Machine init
 458 ******************************************************************************/
 459static struct platform_device *devices[] __initdata = {
 460        &treo680_backlight,
 461        &treo680_leds,
 462        &power_supply,
 463};
 464
 465/* setup udc GPIOs initial state */
 466static void __init treo680_udc_init(void)
 467{
 468        if (!gpio_request(GPIO_NR_TREO680_USB_PULLUP, "UDC Vbus")) {
 469                gpio_direction_output(GPIO_NR_TREO680_USB_PULLUP, 1);
 470                gpio_free(GPIO_NR_TREO680_USB_PULLUP);
 471        }
 472}
 473
 474static void __init treo680_lcd_power_init(void)
 475{
 476        int ret;
 477
 478        ret = gpio_request(GPIO_NR_TREO680_LCD_POWER, "LCD POWER");
 479        if (ret) {
 480                pr_err("Treo680: LCD power GPIO request failed!\n");
 481                return;
 482        }
 483
 484        ret = gpio_direction_output(GPIO_NR_TREO680_LCD_POWER, 0);
 485        if (ret) {
 486                pr_err("Treo680: setting LCD power GPIO direction failed!\n");
 487                gpio_free(GPIO_NR_TREO680_LCD_POWER);
 488                return;
 489        }
 490
 491        treo680_lcd_screen.pxafb_lcd_power = treo680_lcd_power;
 492}
 493
 494static void __init treo680_init(void)
 495{
 496        treo680_pm_init();
 497        pxa2xx_mfp_config(ARRAY_AND_SIZE(treo680_pin_config));
 498        pxa_set_keypad_info(&treo680_keypad_platform_data);
 499        treo680_lcd_power_init();
 500        set_pxa_fb_info(&treo680_lcd_screen);
 501        pxa_set_mci_info(&treo680_mci_platform_data);
 502        treo680_udc_init();
 503        pxa_set_udc_info(&treo680_udc_info);
 504        pxa_set_ac97_info(&treo680_ac97_pdata);
 505        pxa_set_ficp_info(&treo680_ficp_info);
 506        pxa_set_ohci_info(&treo680_ohci_info);
 507
 508        platform_add_devices(devices, ARRAY_SIZE(devices));
 509}
 510
 511MACHINE_START(TREO680, "Palm Treo 680")
 512        .phys_io        = TREO680_PHYS_IO_START,
 513        .io_pg_offst    = io_p2v(0x40000000),
 514        .boot_params    = 0xa0000100,
 515        .map_io         = pxa_map_io,
 516        .init_irq       = pxa27x_init_irq,
 517        .timer          = &pxa_timer,
 518        .init_machine   = treo680_init,
 519MACHINE_END
 520
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.