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