linux/arch/arm/mach-pxa/palmtreo.c
<<
>>
Prefs
   1/*
   2 * Hardware definitions for Palm Treo smartphones
   3 *
   4 * currently supported:
   5 *     Palm Treo 680 (GSM)
   6 *     Palm Centro 685 (GSM)
   7 *
   8 * Author:     Tomas Cech <sleep_walker@suse.cz>
   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 * (find more info at www.hackndev.com)
  15 *
  16 */
  17
  18#include <linux/platform_device.h>
  19#include <linux/delay.h>
  20#include <linux/irq.h>
  21#include <linux/gpio_keys.h>
  22#include <linux/input.h>
  23#include <linux/memblock.h>
  24#include <linux/pda_power.h>
  25#include <linux/pwm_backlight.h>
  26#include <linux/gpio.h>
  27#include <linux/power_supply.h>
  28#include <linux/w1-gpio.h>
  29
  30#include <asm/mach-types.h>
  31#include <asm/mach/arch.h>
  32#include <asm/mach/map.h>
  33
  34#include <mach/pxa27x.h>
  35#include <mach/pxa27x-udc.h>
  36#include <mach/audio.h>
  37#include <mach/palmtreo.h>
  38#include <linux/platform_data/mmc-pxamci.h>
  39#include <linux/platform_data/video-pxafb.h>
  40#include <linux/platform_data/irda-pxaficp.h>
  41#include <linux/platform_data/keypad-pxa27x.h>
  42#include <mach/udc.h>
  43#include <linux/platform_data/usb-ohci-pxa27x.h>
  44#include <mach/pxa2xx-regs.h>
  45#include <linux/platform_data/asoc-palm27x.h>
  46#include <linux/platform_data/camera-pxa.h>
  47#include <mach/palm27x.h>
  48
  49#include <sound/pxa2xx-lib.h>
  50
  51#include "generic.h"
  52#include "devices.h"
  53
  54/******************************************************************************
  55 * Pin configuration
  56 ******************************************************************************/
  57static unsigned long treo_pin_config[] __initdata = {
  58        /* MMC */
  59        GPIO32_MMC_CLK,
  60        GPIO92_MMC_DAT_0,
  61        GPIO109_MMC_DAT_1,
  62        GPIO110_MMC_DAT_2,
  63        GPIO111_MMC_DAT_3,
  64        GPIO112_MMC_CMD,
  65        GPIO113_GPIO,                           /* SD detect */
  66
  67        /* AC97 */
  68        GPIO28_AC97_BITCLK,
  69        GPIO29_AC97_SDATA_IN_0,
  70        GPIO30_AC97_SDATA_OUT,
  71        GPIO31_AC97_SYNC,
  72        GPIO89_AC97_SYSCLK,
  73        GPIO95_AC97_nRESET,
  74
  75        /* IrDA */
  76        GPIO46_FICP_RXD,
  77        GPIO47_FICP_TXD,
  78
  79        /* PWM */
  80        GPIO16_PWM0_OUT,
  81
  82        /* USB */
  83        GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH,       /* usb detect */
  84
  85        /* MATRIX KEYPAD */
  86        GPIO101_KP_MKIN_1,
  87        GPIO102_KP_MKIN_2,
  88        GPIO97_KP_MKIN_3,
  89        GPIO98_KP_MKIN_4,
  90        GPIO91_KP_MKIN_6,
  91        GPIO13_KP_MKIN_7,
  92        GPIO103_KP_MKOUT_0 | MFP_LPM_DRIVE_HIGH,
  93        GPIO104_KP_MKOUT_1,
  94        GPIO105_KP_MKOUT_2,
  95        GPIO106_KP_MKOUT_3,
  96        GPIO107_KP_MKOUT_4,
  97        GPIO108_KP_MKOUT_5,
  98        GPIO96_KP_MKOUT_6,
  99        GPIO93_KP_DKIN_0 | WAKEUP_ON_LEVEL_HIGH,        /* Hotsync button */
 100
 101        /* Quick Capture Interface */
 102        GPIO84_CIF_FV,
 103        GPIO85_CIF_LV,
 104        GPIO53_CIF_MCLK,
 105        GPIO54_CIF_PCLK,
 106        GPIO81_CIF_DD_0,
 107        GPIO55_CIF_DD_1,
 108        GPIO51_CIF_DD_2,
 109        GPIO50_CIF_DD_3,
 110        GPIO52_CIF_DD_4,
 111        GPIO48_CIF_DD_5,
 112        GPIO17_CIF_DD_6,
 113        GPIO12_CIF_DD_7,
 114
 115        /* I2C */
 116        GPIO117_I2C_SCL,
 117        GPIO118_I2C_SDA,
 118
 119        /* GSM */
 120        GPIO14_GPIO | WAKEUP_ON_EDGE_BOTH,      /* GSM host wake up */
 121        GPIO34_FFUART_RXD,
 122        GPIO35_FFUART_CTS,
 123        GPIO39_FFUART_TXD,
 124        GPIO41_FFUART_RTS,
 125
 126        /* MISC. */
 127        GPIO0_GPIO | WAKEUP_ON_EDGE_BOTH,       /* external power detect */
 128        GPIO15_GPIO | WAKEUP_ON_EDGE_BOTH,      /* silent switch */
 129        GPIO116_GPIO,                           /* headphone detect */
 130        GPIO11_GPIO | WAKEUP_ON_EDGE_BOTH,      /* bluetooth host wake up */
 131};
 132
 133#ifdef CONFIG_MACH_TREO680
 134static unsigned long treo680_pin_config[] __initdata = {
 135        GPIO33_GPIO,    /* SD read only */
 136
 137        /* MATRIX KEYPAD - different wake up source */
 138        GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
 139        GPIO99_KP_MKIN_5,
 140
 141        /* LCD... L_BIAS alt fn not configured on Treo680; is GPIO instead */
 142        GPIOxx_LCD_16BPP,
 143        GPIO74_LCD_FCLK,
 144        GPIO75_LCD_LCLK,
 145        GPIO76_LCD_PCLK,
 146};
 147#endif /* CONFIG_MACH_TREO680 */
 148
 149#ifdef CONFIG_MACH_CENTRO
 150static unsigned long centro685_pin_config[] __initdata = {
 151        /* Bluetooth attached to BT UART*/
 152        MFP_CFG_OUT(GPIO80, AF0, DRIVE_LOW),    /* power: LOW = off */
 153        GPIO42_BTUART_RXD,
 154        GPIO43_BTUART_TXD,
 155        GPIO44_BTUART_CTS,
 156        GPIO45_BTUART_RTS,
 157
 158        /* MATRIX KEYPAD - different wake up source */
 159        GPIO100_KP_MKIN_0,
 160        GPIO99_KP_MKIN_5 | WAKEUP_ON_LEVEL_HIGH,
 161
 162        /* LCD */
 163        GPIOxx_LCD_TFT_16BPP,
 164};
 165#endif /* CONFIG_MACH_CENTRO */
 166
 167/******************************************************************************
 168 * GPIO keyboard
 169 ******************************************************************************/
 170#if IS_ENABLED(CONFIG_KEYBOARD_PXA27x)
 171static unsigned int treo680_matrix_keys[] = {
 172        KEY(0, 0, KEY_F8),              /* Red/Off/Power */
 173        KEY(0, 1, KEY_LEFT),
 174        KEY(0, 2, KEY_LEFTCTRL),        /* Alternate */
 175        KEY(0, 3, KEY_L),
 176        KEY(0, 4, KEY_A),
 177        KEY(0, 5, KEY_Q),
 178        KEY(0, 6, KEY_P),
 179
 180        KEY(1, 0, KEY_RIGHTCTRL),       /* Menu */
 181        KEY(1, 1, KEY_RIGHT),
 182        KEY(1, 2, KEY_LEFTSHIFT),       /* Left shift */
 183        KEY(1, 3, KEY_Z),
 184        KEY(1, 4, KEY_S),
 185        KEY(1, 5, KEY_W),
 186
 187        KEY(2, 0, KEY_F1),              /* Phone */
 188        KEY(2, 1, KEY_UP),
 189        KEY(2, 2, KEY_0),
 190        KEY(2, 3, KEY_X),
 191        KEY(2, 4, KEY_D),
 192        KEY(2, 5, KEY_E),
 193
 194        KEY(3, 0, KEY_F10),             /* Calendar */
 195        KEY(3, 1, KEY_DOWN),
 196        KEY(3, 2, KEY_SPACE),
 197        KEY(3, 3, KEY_C),
 198        KEY(3, 4, KEY_F),
 199        KEY(3, 5, KEY_R),
 200
 201        KEY(4, 0, KEY_F12),             /* Mail */
 202        KEY(4, 1, KEY_KPENTER),
 203        KEY(4, 2, KEY_RIGHTALT),        /* Alt */
 204        KEY(4, 3, KEY_V),
 205        KEY(4, 4, KEY_G),
 206        KEY(4, 5, KEY_T),
 207
 208        KEY(5, 0, KEY_F9),              /* Home */
 209        KEY(5, 1, KEY_PAGEUP),          /* Side up */
 210        KEY(5, 2, KEY_DOT),
 211        KEY(5, 3, KEY_B),
 212        KEY(5, 4, KEY_H),
 213        KEY(5, 5, KEY_Y),
 214
 215        KEY(6, 0, KEY_TAB),             /* Side Activate */
 216        KEY(6, 1, KEY_PAGEDOWN),        /* Side down */
 217        KEY(6, 2, KEY_ENTER),
 218        KEY(6, 3, KEY_N),
 219        KEY(6, 4, KEY_J),
 220        KEY(6, 5, KEY_U),
 221
 222        KEY(7, 0, KEY_F6),              /* Green/Call */
 223        KEY(7, 1, KEY_O),
 224        KEY(7, 2, KEY_BACKSPACE),
 225        KEY(7, 3, KEY_M),
 226        KEY(7, 4, KEY_K),
 227        KEY(7, 5, KEY_I),
 228};
 229
 230static unsigned int centro_matrix_keys[] = {
 231        KEY(0, 0, KEY_F9),              /* Home */
 232        KEY(0, 1, KEY_LEFT),
 233        KEY(0, 2, KEY_LEFTCTRL),        /* Alternate */
 234        KEY(0, 3, KEY_L),
 235        KEY(0, 4, KEY_A),
 236        KEY(0, 5, KEY_Q),
 237        KEY(0, 6, KEY_P),
 238
 239        KEY(1, 0, KEY_RIGHTCTRL),       /* Menu */
 240        KEY(1, 1, KEY_RIGHT),
 241        KEY(1, 2, KEY_LEFTSHIFT),       /* Left shift */
 242        KEY(1, 3, KEY_Z),
 243        KEY(1, 4, KEY_S),
 244        KEY(1, 5, KEY_W),
 245
 246        KEY(2, 0, KEY_F1),              /* Phone */
 247        KEY(2, 1, KEY_UP),
 248        KEY(2, 2, KEY_0),
 249        KEY(2, 3, KEY_X),
 250        KEY(2, 4, KEY_D),
 251        KEY(2, 5, KEY_E),
 252
 253        KEY(3, 0, KEY_F10),             /* Calendar */
 254        KEY(3, 1, KEY_DOWN),
 255        KEY(3, 2, KEY_SPACE),
 256        KEY(3, 3, KEY_C),
 257        KEY(3, 4, KEY_F),
 258        KEY(3, 5, KEY_R),
 259
 260        KEY(4, 0, KEY_F12),             /* Mail */
 261        KEY(4, 1, KEY_KPENTER),
 262        KEY(4, 2, KEY_RIGHTALT),        /* Alt */
 263        KEY(4, 3, KEY_V),
 264        KEY(4, 4, KEY_G),
 265        KEY(4, 5, KEY_T),
 266
 267        KEY(5, 0, KEY_F8),              /* Red/Off/Power */
 268        KEY(5, 1, KEY_PAGEUP),          /* Side up */
 269        KEY(5, 2, KEY_DOT),
 270        KEY(5, 3, KEY_B),
 271        KEY(5, 4, KEY_H),
 272        KEY(5, 5, KEY_Y),
 273
 274        KEY(6, 0, KEY_TAB),             /* Side Activate */
 275        KEY(6, 1, KEY_PAGEDOWN),        /* Side down */
 276        KEY(6, 2, KEY_ENTER),
 277        KEY(6, 3, KEY_N),
 278        KEY(6, 4, KEY_J),
 279        KEY(6, 5, KEY_U),
 280
 281        KEY(7, 0, KEY_F6),              /* Green/Call */
 282        KEY(7, 1, KEY_O),
 283        KEY(7, 2, KEY_BACKSPACE),
 284        KEY(7, 3, KEY_M),
 285        KEY(7, 4, KEY_K),
 286        KEY(7, 5, KEY_I),
 287};
 288
 289static struct pxa27x_keypad_platform_data treo680_keypad_pdata = {
 290        .matrix_key_rows        = 8,
 291        .matrix_key_cols        = 7,
 292        .matrix_key_map         = treo680_matrix_keys,
 293        .matrix_key_map_size    = ARRAY_SIZE(treo680_matrix_keys),
 294        .direct_key_map         = { KEY_CONNECT },
 295        .direct_key_num         = 1,
 296
 297        .debounce_interval      = 30,
 298};
 299
 300static void __init palmtreo_kpc_init(void)
 301{
 302        static struct pxa27x_keypad_platform_data *data = &treo680_keypad_pdata;
 303
 304        if (machine_is_centro()) {
 305                data->matrix_key_map = centro_matrix_keys;
 306                data->matrix_key_map_size = ARRAY_SIZE(centro_matrix_keys);
 307        }
 308
 309        pxa_set_keypad_info(&treo680_keypad_pdata);
 310}
 311#else
 312static inline void palmtreo_kpc_init(void) {}
 313#endif
 314
 315/******************************************************************************
 316 * USB host
 317 ******************************************************************************/
 318#if IS_ENABLED(CONFIG_USB_OHCI_HCD)
 319static struct pxaohci_platform_data treo680_ohci_info = {
 320        .port_mode    = PMM_PERPORT_MODE,
 321        .flags        = ENABLE_PORT1 | ENABLE_PORT3,
 322        .power_budget = 0,
 323};
 324
 325static void __init palmtreo_uhc_init(void)
 326{
 327        if (machine_is_treo680())
 328                pxa_set_ohci_info(&treo680_ohci_info);
 329}
 330#else
 331static inline void palmtreo_uhc_init(void) {}
 332#endif
 333
 334/******************************************************************************
 335 * Vibra and LEDs
 336 ******************************************************************************/
 337static struct gpio_led treo680_gpio_leds[] = {
 338        {
 339                .name                   = "treo680:vibra:vibra",
 340                .default_trigger        = "none",
 341                .gpio                   = GPIO_NR_TREO680_VIBRATE_EN,
 342        },
 343        {
 344                .name                   = "treo680:green:led",
 345                .default_trigger        = "mmc0",
 346                .gpio                   = GPIO_NR_TREO_GREEN_LED,
 347        },
 348        {
 349                .name                   = "treo680:white:keybbl",
 350                .default_trigger        = "none",
 351                .gpio                   = GPIO_NR_TREO680_KEYB_BL,
 352        },
 353};
 354
 355static struct gpio_led_platform_data treo680_gpio_led_info = {
 356        .leds           = treo680_gpio_leds,
 357        .num_leds       = ARRAY_SIZE(treo680_gpio_leds),
 358};
 359
 360static struct gpio_led centro_gpio_leds[] = {
 361        {
 362                .name                   = "centro:vibra:vibra",
 363                .default_trigger        = "none",
 364                .gpio                   = GPIO_NR_CENTRO_VIBRATE_EN,
 365        },
 366        {
 367                .name                   = "centro:green:led",
 368                .default_trigger        = "mmc0",
 369                .gpio                   = GPIO_NR_TREO_GREEN_LED,
 370        },
 371        {
 372                .name                   = "centro:white:keybbl",
 373                .default_trigger        = "none",
 374                .active_low             = 1,
 375                .gpio                   = GPIO_NR_CENTRO_KEYB_BL,
 376        },
 377};
 378
 379static struct gpio_led_platform_data centro_gpio_led_info = {
 380        .leds           = centro_gpio_leds,
 381        .num_leds       = ARRAY_SIZE(centro_gpio_leds),
 382};
 383
 384static struct platform_device palmtreo_leds = {
 385        .name   = "leds-gpio",
 386        .id     = -1,
 387};
 388
 389static void __init palmtreo_leds_init(void)
 390{
 391        if (machine_is_centro())
 392                palmtreo_leds.dev.platform_data = &centro_gpio_led_info;
 393        else if (machine_is_treo680())
 394                palmtreo_leds.dev.platform_data = &treo680_gpio_led_info;
 395
 396        platform_device_register(&palmtreo_leds);
 397}
 398
 399/******************************************************************************
 400 * diskonchip docg4 flash
 401 ******************************************************************************/
 402#if defined(CONFIG_MACH_TREO680)
 403/* REVISIT: does the centro have this device also? */
 404#if IS_ENABLED(CONFIG_MTD_NAND_DOCG4)
 405static struct resource docg4_resources[] = {
 406        {
 407                .start  = 0x00000000,
 408                .end    = 0x00001FFF,
 409                .flags  = IORESOURCE_MEM,
 410        },
 411};
 412
 413static struct platform_device treo680_docg4_flash = {
 414        .name   = "docg4",
 415        .id     = -1,
 416        .resource = docg4_resources,
 417        .num_resources = ARRAY_SIZE(docg4_resources),
 418};
 419
 420static void __init treo680_docg4_flash_init(void)
 421{
 422        platform_device_register(&treo680_docg4_flash);
 423}
 424#else
 425static inline void treo680_docg4_flash_init(void) {}
 426#endif
 427#endif
 428
 429/******************************************************************************
 430 * Machine init
 431 ******************************************************************************/
 432static void __init treo_reserve(void)
 433{
 434        memblock_reserve(0xa0000000, 0x1000);
 435        memblock_reserve(0xa2000000, 0x1000);
 436}
 437
 438static void __init palmphone_common_init(void)
 439{
 440        pxa2xx_mfp_config(ARRAY_AND_SIZE(treo_pin_config));
 441        pxa_set_ffuart_info(NULL);
 442        pxa_set_btuart_info(NULL);
 443        pxa_set_stuart_info(NULL);
 444        palm27x_pm_init(TREO_STR_BASE);
 445        palm27x_lcd_init(GPIO_NR_TREO_BL_POWER, &palm_320x320_new_lcd_mode);
 446        palm27x_udc_init(GPIO_NR_TREO_USB_DETECT, GPIO_NR_TREO_USB_PULLUP, 1);
 447        palm27x_irda_init(GPIO_NR_TREO_IR_EN);
 448        palm27x_ac97_init(-1, -1, -1, 95);
 449        palm27x_pwm_init(GPIO_NR_TREO_BL_POWER, -1);
 450        palm27x_power_init(GPIO_NR_TREO_POWER_DETECT, -1);
 451        palm27x_pmic_init();
 452        palmtreo_kpc_init();
 453        palmtreo_uhc_init();
 454        palmtreo_leds_init();
 455}
 456
 457#ifdef CONFIG_MACH_TREO680
 458void __init treo680_gpio_init(void)
 459{
 460        unsigned int gpio;
 461
 462        /* drive all three lcd gpios high initially */
 463        const unsigned long lcd_flags = GPIOF_INIT_HIGH | GPIOF_DIR_OUT;
 464
 465        /*
 466         * LCD GPIO initialization...
 467         */
 468
 469        /*
 470         * This is likely the power to the lcd.  Toggling it low/high appears to
 471         * turn the lcd off/on.  Can be toggled after lcd is initialized without
 472         * any apparent adverse effects to the lcd operation.  Note that this
 473         * gpio line is used by the lcd controller as the L_BIAS signal, but
 474         * treo680 configures it as gpio.
 475         */
 476        gpio = GPIO_NR_TREO680_LCD_POWER;
 477        if (gpio_request_one(gpio, lcd_flags, "LCD power") < 0)
 478                goto fail;
 479
 480        /*
 481         * These two are called "enables", for lack of a better understanding.
 482         * If either of these are toggled after the lcd is initialized, the
 483         * image becomes degraded.  N.B. The IPL shipped with the treo
 484         * configures GPIO_NR_TREO680_LCD_EN_N as output and drives it high.  If
 485         * the IPL is ever reprogrammed, this initialization may be need to be
 486         * revisited.
 487         */
 488        gpio = GPIO_NR_TREO680_LCD_EN;
 489        if (gpio_request_one(gpio, lcd_flags, "LCD enable") < 0)
 490                goto fail;
 491        gpio = GPIO_NR_TREO680_LCD_EN_N;
 492        if (gpio_request_one(gpio, lcd_flags, "LCD enable_n") < 0)
 493                goto fail;
 494
 495        /* driving this low turns LCD on */
 496        gpio_set_value(GPIO_NR_TREO680_LCD_EN_N, 0);
 497
 498        return;
 499 fail:
 500        pr_err("gpio %d initialization failed\n", gpio);
 501        gpio_free(GPIO_NR_TREO680_LCD_POWER);
 502        gpio_free(GPIO_NR_TREO680_LCD_EN);
 503        gpio_free(GPIO_NR_TREO680_LCD_EN_N);
 504}
 505
 506static void __init treo680_init(void)
 507{
 508        pxa2xx_mfp_config(ARRAY_AND_SIZE(treo680_pin_config));
 509        palmphone_common_init();
 510        treo680_gpio_init();
 511        palm27x_mmc_init(GPIO_NR_TREO_SD_DETECT_N, GPIO_NR_TREO680_SD_READONLY,
 512                        GPIO_NR_TREO680_SD_POWER, 0);
 513        treo680_docg4_flash_init();
 514}
 515#endif
 516
 517#ifdef CONFIG_MACH_CENTRO
 518static void __init centro_init(void)
 519{
 520        pxa2xx_mfp_config(ARRAY_AND_SIZE(centro685_pin_config));
 521        palmphone_common_init();
 522        palm27x_mmc_init(GPIO_NR_TREO_SD_DETECT_N, -1,
 523                        GPIO_NR_CENTRO_SD_POWER, 1);
 524}
 525#endif
 526
 527#ifdef CONFIG_MACH_TREO680
 528MACHINE_START(TREO680, "Palm Treo 680")
 529        .atag_offset    = 0x100,
 530        .map_io         = pxa27x_map_io,
 531        .reserve        = treo_reserve,
 532        .nr_irqs        = PXA_NR_IRQS,
 533        .init_irq       = pxa27x_init_irq,
 534        .handle_irq       = pxa27x_handle_irq,
 535        .init_time      = pxa_timer_init,
 536        .init_machine   = treo680_init,
 537        .restart        = pxa_restart,
 538MACHINE_END
 539#endif
 540
 541#ifdef CONFIG_MACH_CENTRO
 542MACHINE_START(CENTRO, "Palm Centro 685")
 543        .atag_offset    = 0x100,
 544        .map_io         = pxa27x_map_io,
 545        .reserve        = treo_reserve,
 546        .nr_irqs        = PXA_NR_IRQS,
 547        .init_irq       = pxa27x_init_irq,
 548        .handle_irq       = pxa27x_handle_irq,
 549        .init_time      = pxa_timer_init,
 550        .init_machine   = centro_init,
 551        .restart        = pxa_restart,
 552MACHINE_END
 553#endif
 554