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