linux/arch/arm/mach-pxa/palmtc.c
<<
>>
Prefs
   1/*
   2 * linux/arch/arm/mach-pxa/palmtc.c
   3 *
   4 * Support for the Palm Tungsten|C
   5 *
   6 * Author:      Marek Vasut <marek.vasut@gmail.com>
   7 *
   8 * Based on work of:
   9 *              Petr Blaha <p3t3@centrum.cz>
  10 *              Chetan S. Kumar <shivakumar.chetan@gmail.com>
  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
  17#include <linux/platform_device.h>
  18#include <linux/delay.h>
  19#include <linux/irq.h>
  20#include <linux/input.h>
  21#include <linux/pwm_backlight.h>
  22#include <linux/gpio.h>
  23#include <linux/input/matrix_keypad.h>
  24#include <linux/ucb1400.h>
  25#include <linux/power_supply.h>
  26#include <linux/gpio_keys.h>
  27#include <linux/mtd/physmap.h>
  28#include <linux/usb/gpio_vbus.h>
  29
  30#include <asm/mach-types.h>
  31#include <asm/mach/arch.h>
  32#include <asm/mach/map.h>
  33
  34#include <mach/pxa25x.h>
  35#include <mach/audio.h>
  36#include <mach/palmtc.h>
  37#include <linux/platform_data/mmc-pxamci.h>
  38#include <linux/platform_data/video-pxafb.h>
  39#include <linux/platform_data/irda-pxaficp.h>
  40#include <mach/udc.h>
  41
  42#include "generic.h"
  43#include "devices.h"
  44
  45/******************************************************************************
  46 * Pin configuration
  47 ******************************************************************************/
  48static unsigned long palmtc_pin_config[] __initdata = {
  49        /* MMC */
  50        GPIO6_MMC_CLK,
  51        GPIO8_MMC_CS0,
  52        GPIO12_GPIO,    /* detect */
  53        GPIO32_GPIO,    /* power */
  54        GPIO54_GPIO,    /* r/o switch */
  55
  56        /* PCMCIA */
  57        GPIO52_nPCE_1,
  58        GPIO53_nPCE_2,
  59        GPIO50_nPIOR,
  60        GPIO51_nPIOW,
  61        GPIO49_nPWE,
  62        GPIO48_nPOE,
  63        GPIO52_nPCE_1,
  64        GPIO53_nPCE_2,
  65        GPIO57_nIOIS16,
  66        GPIO56_nPWAIT,
  67
  68        /* AC97 */
  69        GPIO28_AC97_BITCLK,
  70        GPIO29_AC97_SDATA_IN_0,
  71        GPIO30_AC97_SDATA_OUT,
  72        GPIO31_AC97_SYNC,
  73
  74        /* IrDA */
  75        GPIO45_GPIO,    /* ir disable */
  76        GPIO46_FICP_RXD,
  77        GPIO47_FICP_TXD,
  78
  79        /* PWM */
  80        GPIO17_PWM1_OUT,
  81
  82        /* USB */
  83        GPIO4_GPIO,     /* detect */
  84        GPIO36_GPIO,    /* pullup */
  85
  86        /* LCD */
  87        GPIOxx_LCD_TFT_16BPP,
  88
  89        /* MATRIX KEYPAD */
  90        GPIO0_GPIO | WAKEUP_ON_EDGE_BOTH,       /* in 0 */
  91        GPIO9_GPIO | WAKEUP_ON_EDGE_BOTH,       /* in 1 */
  92        GPIO10_GPIO | WAKEUP_ON_EDGE_BOTH,      /* in 2 */
  93        GPIO11_GPIO | WAKEUP_ON_EDGE_BOTH,      /* in 3 */
  94        GPIO18_GPIO | MFP_LPM_DRIVE_LOW,        /* out 0 */
  95        GPIO19_GPIO | MFP_LPM_DRIVE_LOW,        /* out 1 */
  96        GPIO20_GPIO | MFP_LPM_DRIVE_LOW,        /* out 2 */
  97        GPIO21_GPIO | MFP_LPM_DRIVE_LOW,        /* out 3 */
  98        GPIO22_GPIO | MFP_LPM_DRIVE_LOW,        /* out 4 */
  99        GPIO23_GPIO | MFP_LPM_DRIVE_LOW,        /* out 5 */
 100        GPIO24_GPIO | MFP_LPM_DRIVE_LOW,        /* out 6 */
 101        GPIO25_GPIO | MFP_LPM_DRIVE_LOW,        /* out 7 */
 102        GPIO26_GPIO | MFP_LPM_DRIVE_LOW,        /* out 8 */
 103        GPIO27_GPIO | MFP_LPM_DRIVE_LOW,        /* out 9 */
 104        GPIO79_GPIO | MFP_LPM_DRIVE_LOW,        /* out 10 */
 105        GPIO80_GPIO | MFP_LPM_DRIVE_LOW,        /* out 11 */
 106
 107        /* PXA GPIO KEYS */
 108        GPIO7_GPIO | WAKEUP_ON_EDGE_BOTH,       /* hotsync button on cradle */
 109
 110        /* MISC */
 111        GPIO1_RST,      /* reset */
 112        GPIO2_GPIO,     /* earphone detect */
 113        GPIO16_GPIO,    /* backlight switch */
 114};
 115
 116/******************************************************************************
 117 * SD/MMC card controller
 118 ******************************************************************************/
 119#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
 120static struct pxamci_platform_data palmtc_mci_platform_data = {
 121        .ocr_mask               = MMC_VDD_32_33 | MMC_VDD_33_34,
 122        .gpio_power             = GPIO_NR_PALMTC_SD_POWER,
 123        .gpio_card_ro           = GPIO_NR_PALMTC_SD_READONLY,
 124        .gpio_card_detect       = GPIO_NR_PALMTC_SD_DETECT_N,
 125        .detect_delay_ms        = 200,
 126};
 127
 128static void __init palmtc_mmc_init(void)
 129{
 130        pxa_set_mci_info(&palmtc_mci_platform_data);
 131}
 132#else
 133static inline void palmtc_mmc_init(void) {}
 134#endif
 135
 136/******************************************************************************
 137 * GPIO keys
 138 ******************************************************************************/
 139#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
 140static struct gpio_keys_button palmtc_pxa_buttons[] = {
 141        {KEY_F8, GPIO_NR_PALMTC_HOTSYNC_BUTTON, 1, "HotSync Button", EV_KEY, 1},
 142};
 143
 144static struct gpio_keys_platform_data palmtc_pxa_keys_data = {
 145        .buttons        = palmtc_pxa_buttons,
 146        .nbuttons       = ARRAY_SIZE(palmtc_pxa_buttons),
 147};
 148
 149static struct platform_device palmtc_pxa_keys = {
 150        .name   = "gpio-keys",
 151        .id     = -1,
 152        .dev    = {
 153                .platform_data = &palmtc_pxa_keys_data,
 154        },
 155};
 156
 157static void __init palmtc_keys_init(void)
 158{
 159        platform_device_register(&palmtc_pxa_keys);
 160}
 161#else
 162static inline void palmtc_keys_init(void) {}
 163#endif
 164
 165/******************************************************************************
 166 * Backlight
 167 ******************************************************************************/
 168#if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE)
 169static int palmtc_backlight_init(struct device *dev)
 170{
 171        int ret;
 172
 173        ret = gpio_request(GPIO_NR_PALMTC_BL_POWER, "BL POWER");
 174        if (ret)
 175                goto err;
 176        ret = gpio_direction_output(GPIO_NR_PALMTC_BL_POWER, 1);
 177        if (ret)
 178                goto err2;
 179
 180        return 0;
 181
 182err2:
 183        gpio_free(GPIO_NR_PALMTC_BL_POWER);
 184err:
 185        return ret;
 186}
 187
 188static int palmtc_backlight_notify(struct device *dev, int brightness)
 189{
 190        /* backlight is on when GPIO16 AF0 is high */
 191        gpio_set_value(GPIO_NR_PALMTC_BL_POWER, brightness);
 192        return brightness;
 193}
 194
 195static void palmtc_backlight_exit(struct device *dev)
 196{
 197        gpio_free(GPIO_NR_PALMTC_BL_POWER);
 198}
 199
 200static struct platform_pwm_backlight_data palmtc_backlight_data = {
 201        .pwm_id         = 1,
 202        .max_brightness = PALMTC_MAX_INTENSITY,
 203        .dft_brightness = PALMTC_MAX_INTENSITY,
 204        .pwm_period_ns  = PALMTC_PERIOD_NS,
 205        .init           = palmtc_backlight_init,
 206        .notify         = palmtc_backlight_notify,
 207        .exit           = palmtc_backlight_exit,
 208};
 209
 210static struct platform_device palmtc_backlight = {
 211        .name   = "pwm-backlight",
 212        .dev    = {
 213                .parent         = &pxa25x_device_pwm1.dev,
 214                .platform_data  = &palmtc_backlight_data,
 215        },
 216};
 217
 218static void __init palmtc_pwm_init(void)
 219{
 220        platform_device_register(&palmtc_backlight);
 221}
 222#else
 223static inline void palmtc_pwm_init(void) {}
 224#endif
 225
 226/******************************************************************************
 227 * IrDA
 228 ******************************************************************************/
 229#if defined(CONFIG_IRDA) || defined(CONFIG_IRDA_MODULE)
 230static struct pxaficp_platform_data palmtc_ficp_platform_data = {
 231        .gpio_pwdown            = GPIO_NR_PALMTC_IR_DISABLE,
 232        .transceiver_cap        = IR_SIRMODE | IR_OFF,
 233};
 234
 235static void __init palmtc_irda_init(void)
 236{
 237        pxa_set_ficp_info(&palmtc_ficp_platform_data);
 238}
 239#else
 240static inline void palmtc_irda_init(void) {}
 241#endif
 242
 243/******************************************************************************
 244 * Keyboard
 245 ******************************************************************************/
 246#if defined(CONFIG_KEYBOARD_MATRIX) || defined(CONFIG_KEYBOARD_MATRIX_MODULE)
 247static const uint32_t palmtc_matrix_keys[] = {
 248        KEY(0, 0, KEY_F1),
 249        KEY(0, 1, KEY_X),
 250        KEY(0, 2, KEY_POWER),
 251        KEY(0, 3, KEY_TAB),
 252        KEY(0, 4, KEY_A),
 253        KEY(0, 5, KEY_Q),
 254        KEY(0, 6, KEY_LEFTSHIFT),
 255        KEY(0, 7, KEY_Z),
 256        KEY(0, 8, KEY_S),
 257        KEY(0, 9, KEY_W),
 258        KEY(0, 10, KEY_E),
 259        KEY(0, 11, KEY_UP),
 260
 261        KEY(1, 0, KEY_F2),
 262        KEY(1, 1, KEY_DOWN),
 263        KEY(1, 3, KEY_D),
 264        KEY(1, 4, KEY_C),
 265        KEY(1, 5, KEY_F),
 266        KEY(1, 6, KEY_R),
 267        KEY(1, 7, KEY_SPACE),
 268        KEY(1, 8, KEY_V),
 269        KEY(1, 9, KEY_G),
 270        KEY(1, 10, KEY_T),
 271        KEY(1, 11, KEY_LEFT),
 272
 273        KEY(2, 0, KEY_F3),
 274        KEY(2, 1, KEY_LEFTCTRL),
 275        KEY(2, 3, KEY_H),
 276        KEY(2, 4, KEY_Y),
 277        KEY(2, 5, KEY_N),
 278        KEY(2, 6, KEY_J),
 279        KEY(2, 7, KEY_U),
 280        KEY(2, 8, KEY_M),
 281        KEY(2, 9, KEY_K),
 282        KEY(2, 10, KEY_I),
 283        KEY(2, 11, KEY_RIGHT),
 284
 285        KEY(3, 0, KEY_F4),
 286        KEY(3, 1, KEY_ENTER),
 287        KEY(3, 3, KEY_DOT),
 288        KEY(3, 4, KEY_L),
 289        KEY(3, 5, KEY_O),
 290        KEY(3, 6, KEY_LEFTALT),
 291        KEY(3, 7, KEY_ENTER),
 292        KEY(3, 8, KEY_BACKSPACE),
 293        KEY(3, 9, KEY_P),
 294        KEY(3, 10, KEY_B),
 295        KEY(3, 11, KEY_FN),
 296};
 297
 298const struct matrix_keymap_data palmtc_keymap_data = {
 299        .keymap                 = palmtc_matrix_keys,
 300        .keymap_size            = ARRAY_SIZE(palmtc_matrix_keys),
 301};
 302
 303static const unsigned int palmtc_keypad_row_gpios[] = {
 304        0, 9, 10, 11
 305};
 306
 307static const unsigned int palmtc_keypad_col_gpios[] = {
 308        18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 79, 80
 309};
 310
 311static struct matrix_keypad_platform_data palmtc_keypad_platform_data = {
 312        .keymap_data    = &palmtc_keymap_data,
 313        .row_gpios      = palmtc_keypad_row_gpios,
 314        .num_row_gpios  = ARRAY_SIZE(palmtc_keypad_row_gpios),
 315        .col_gpios      = palmtc_keypad_col_gpios,
 316        .num_col_gpios  = ARRAY_SIZE(palmtc_keypad_col_gpios),
 317        .active_low     = 1,
 318
 319        .debounce_ms            = 20,
 320        .col_scan_delay_us      = 5,
 321};
 322
 323static struct platform_device palmtc_keyboard = {
 324        .name   = "matrix-keypad",
 325        .id     = -1,
 326        .dev    = {
 327                .platform_data = &palmtc_keypad_platform_data,
 328        },
 329};
 330static void __init palmtc_mkp_init(void)
 331{
 332        platform_device_register(&palmtc_keyboard);
 333}
 334#else
 335static inline void palmtc_mkp_init(void) {}
 336#endif
 337
 338/******************************************************************************
 339 * UDC
 340 ******************************************************************************/
 341#if defined(CONFIG_USB_PXA25X)||defined(CONFIG_USB_PXA25X_MODULE)
 342static struct gpio_vbus_mach_info palmtc_udc_info = {
 343        .gpio_vbus              = GPIO_NR_PALMTC_USB_DETECT_N,
 344        .gpio_vbus_inverted     = 1,
 345        .gpio_pullup            = GPIO_NR_PALMTC_USB_POWER,
 346};
 347
 348static struct platform_device palmtc_gpio_vbus = {
 349        .name   = "gpio-vbus",
 350        .id     = -1,
 351        .dev    = {
 352                .platform_data  = &palmtc_udc_info,
 353        },
 354};
 355
 356static void __init palmtc_udc_init(void)
 357{
 358        platform_device_register(&palmtc_gpio_vbus);
 359};
 360#else
 361static inline void palmtc_udc_init(void) {}
 362#endif
 363
 364/******************************************************************************
 365 * Touchscreen / Battery / GPIO-extender
 366 ******************************************************************************/
 367#if     defined(CONFIG_TOUCHSCREEN_UCB1400) || \
 368        defined(CONFIG_TOUCHSCREEN_UCB1400_MODULE)
 369static struct platform_device palmtc_ucb1400_device = {
 370        .name   = "ucb1400_core",
 371        .id     = -1,
 372};
 373
 374static void __init palmtc_ts_init(void)
 375{
 376        pxa_set_ac97_info(NULL);
 377        platform_device_register(&palmtc_ucb1400_device);
 378}
 379#else
 380static inline void palmtc_ts_init(void) {}
 381#endif
 382
 383/******************************************************************************
 384 * LEDs
 385 ******************************************************************************/
 386#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
 387struct gpio_led palmtc_gpio_leds[] = {
 388{
 389        .name                   = "palmtc:green:user",
 390        .default_trigger        = "none",
 391        .gpio                   = GPIO_NR_PALMTC_LED_POWER,
 392        .active_low             = 1,
 393}, {
 394        .name                   = "palmtc:vibra:vibra",
 395        .default_trigger        = "none",
 396        .gpio                   = GPIO_NR_PALMTC_VIBRA_POWER,
 397        .active_low             = 1,
 398}
 399
 400};
 401
 402static struct gpio_led_platform_data palmtc_gpio_led_info = {
 403        .leds           = palmtc_gpio_leds,
 404        .num_leds       = ARRAY_SIZE(palmtc_gpio_leds),
 405};
 406
 407static struct platform_device palmtc_leds = {
 408        .name   = "leds-gpio",
 409        .id     = -1,
 410        .dev    = {
 411                .platform_data  = &palmtc_gpio_led_info,
 412        }
 413};
 414
 415static void __init palmtc_leds_init(void)
 416{
 417        platform_device_register(&palmtc_leds);
 418}
 419#else
 420static inline void palmtc_leds_init(void) {}
 421#endif
 422
 423/******************************************************************************
 424 * NOR Flash
 425 ******************************************************************************/
 426#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
 427static struct resource palmtc_flash_resource = {
 428        .start  = PXA_CS0_PHYS,
 429        .end    = PXA_CS0_PHYS + SZ_16M - 1,
 430        .flags  = IORESOURCE_MEM,
 431};
 432
 433static struct mtd_partition palmtc_flash_parts[] = {
 434        {
 435                .name   = "U-Boot Bootloader",
 436                .offset = 0x0,
 437                .size   = 0x40000,
 438        },
 439        {
 440                .name   = "Linux Kernel",
 441                .offset = 0x40000,
 442                .size   = 0x2c0000,
 443        },
 444        {
 445                .name   = "Filesystem",
 446                .offset = 0x300000,
 447                .size   = 0xcc0000,
 448        },
 449        {
 450                .name   = "U-Boot Environment",
 451                .offset = 0xfc0000,
 452                .size   = MTDPART_SIZ_FULL,
 453        },
 454};
 455
 456static struct physmap_flash_data palmtc_flash_data = {
 457        .width          = 4,
 458        .parts          = palmtc_flash_parts,
 459        .nr_parts       = ARRAY_SIZE(palmtc_flash_parts),
 460};
 461
 462static struct platform_device palmtc_flash = {
 463        .name           = "physmap-flash",
 464        .id             = -1,
 465        .resource       = &palmtc_flash_resource,
 466        .num_resources  = 1,
 467        .dev = {
 468                .platform_data  = &palmtc_flash_data,
 469        },
 470};
 471
 472static void __init palmtc_nor_init(void)
 473{
 474        platform_device_register(&palmtc_flash);
 475}
 476#else
 477static inline void palmtc_nor_init(void) {}
 478#endif
 479
 480/******************************************************************************
 481 * Framebuffer
 482 ******************************************************************************/
 483#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
 484static struct pxafb_mode_info palmtc_lcd_modes[] = {
 485        {
 486                .pixclock       = 115384,
 487                .xres           = 320,
 488                .yres           = 320,
 489                .bpp            = 16,
 490
 491                .left_margin    = 27,
 492                .right_margin   = 7,
 493                .upper_margin   = 7,
 494                .lower_margin   = 8,
 495
 496                .hsync_len      = 6,
 497                .vsync_len      = 1,
 498        },
 499};
 500
 501static struct pxafb_mach_info palmtc_lcd_screen = {
 502        .modes                  = palmtc_lcd_modes,
 503        .num_modes              = ARRAY_SIZE(palmtc_lcd_modes),
 504        .lcd_conn               = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
 505};
 506
 507static void __init palmtc_lcd_init(void)
 508{
 509        pxa_set_fb_info(NULL, &palmtc_lcd_screen);
 510}
 511#else
 512static inline void palmtc_lcd_init(void) {}
 513#endif
 514
 515/******************************************************************************
 516 * Machine init
 517 ******************************************************************************/
 518static void __init palmtc_init(void)
 519{
 520        pxa2xx_mfp_config(ARRAY_AND_SIZE(palmtc_pin_config));
 521
 522        pxa_set_ffuart_info(NULL);
 523        pxa_set_btuart_info(NULL);
 524        pxa_set_stuart_info(NULL);
 525        pxa_set_hwuart_info(NULL);
 526
 527        palmtc_mmc_init();
 528        palmtc_keys_init();
 529        palmtc_pwm_init();
 530        palmtc_irda_init();
 531        palmtc_mkp_init();
 532        palmtc_udc_init();
 533        palmtc_ts_init();
 534        palmtc_nor_init();
 535        palmtc_lcd_init();
 536        palmtc_leds_init();
 537};
 538
 539MACHINE_START(PALMTC, "Palm Tungsten|C")
 540        .atag_offset    = 0x100,
 541        .map_io         = pxa25x_map_io,
 542        .nr_irqs        = PXA_NR_IRQS,
 543        .init_irq       = pxa25x_init_irq,
 544        .handle_irq     = pxa25x_handle_irq,
 545        .init_time      = pxa_timer_init,
 546        .init_machine   = palmtc_init,
 547        .restart        = pxa_restart,
 548MACHINE_END
 549