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 struct platform_pwm_backlight_data palmtc_backlight_data = { 170 .pwm_id = 1, 171 .max_brightness = PALMTC_MAX_INTENSITY, 172 .dft_brightness = PALMTC_MAX_INTENSITY, 173 .pwm_period_ns = PALMTC_PERIOD_NS, 174 .enable_gpio = GPIO_NR_PALMTC_BL_POWER, 175}; 176 177static struct platform_device palmtc_backlight = { 178 .name = "pwm-backlight", 179 .dev = { 180 .parent = &pxa25x_device_pwm1.dev, 181 .platform_data = &palmtc_backlight_data, 182 }, 183}; 184 185static void __init palmtc_pwm_init(void) 186{ 187 platform_device_register(&palmtc_backlight); 188} 189#else 190static inline void palmtc_pwm_init(void) {} 191#endif 192 193/****************************************************************************** 194 * IrDA 195 ******************************************************************************/ 196#if defined(CONFIG_IRDA) || defined(CONFIG_IRDA_MODULE) 197static struct pxaficp_platform_data palmtc_ficp_platform_data = { 198 .gpio_pwdown = GPIO_NR_PALMTC_IR_DISABLE, 199 .transceiver_cap = IR_SIRMODE | IR_OFF, 200}; 201 202static void __init palmtc_irda_init(void) 203{ 204 pxa_set_ficp_info(&palmtc_ficp_platform_data); 205} 206#else 207static inline void palmtc_irda_init(void) {} 208#endif 209 210/****************************************************************************** 211 * Keyboard 212 ******************************************************************************/ 213#if defined(CONFIG_KEYBOARD_MATRIX) || defined(CONFIG_KEYBOARD_MATRIX_MODULE) 214static const uint32_t palmtc_matrix_keys[] = { 215 KEY(0, 0, KEY_F1), 216 KEY(0, 1, KEY_X), 217 KEY(0, 2, KEY_POWER), 218 KEY(0, 3, KEY_TAB), 219 KEY(0, 4, KEY_A), 220 KEY(0, 5, KEY_Q), 221 KEY(0, 6, KEY_LEFTSHIFT), 222 KEY(0, 7, KEY_Z), 223 KEY(0, 8, KEY_S), 224 KEY(0, 9, KEY_W), 225 KEY(0, 10, KEY_E), 226 KEY(0, 11, KEY_UP), 227 228 KEY(1, 0, KEY_F2), 229 KEY(1, 1, KEY_DOWN), 230 KEY(1, 3, KEY_D), 231 KEY(1, 4, KEY_C), 232 KEY(1, 5, KEY_F), 233 KEY(1, 6, KEY_R), 234 KEY(1, 7, KEY_SPACE), 235 KEY(1, 8, KEY_V), 236 KEY(1, 9, KEY_G), 237 KEY(1, 10, KEY_T), 238 KEY(1, 11, KEY_LEFT), 239 240 KEY(2, 0, KEY_F3), 241 KEY(2, 1, KEY_LEFTCTRL), 242 KEY(2, 3, KEY_H), 243 KEY(2, 4, KEY_Y), 244 KEY(2, 5, KEY_N), 245 KEY(2, 6, KEY_J), 246 KEY(2, 7, KEY_U), 247 KEY(2, 8, KEY_M), 248 KEY(2, 9, KEY_K), 249 KEY(2, 10, KEY_I), 250 KEY(2, 11, KEY_RIGHT), 251 252 KEY(3, 0, KEY_F4), 253 KEY(3, 1, KEY_ENTER), 254 KEY(3, 3, KEY_DOT), 255 KEY(3, 4, KEY_L), 256 KEY(3, 5, KEY_O), 257 KEY(3, 6, KEY_LEFTALT), 258 KEY(3, 7, KEY_ENTER), 259 KEY(3, 8, KEY_BACKSPACE), 260 KEY(3, 9, KEY_P), 261 KEY(3, 10, KEY_B), 262 KEY(3, 11, KEY_FN), 263}; 264 265const struct matrix_keymap_data palmtc_keymap_data = { 266 .keymap = palmtc_matrix_keys, 267 .keymap_size = ARRAY_SIZE(palmtc_matrix_keys), 268}; 269 270static const unsigned int palmtc_keypad_row_gpios[] = { 271 0, 9, 10, 11 272}; 273 274static const unsigned int palmtc_keypad_col_gpios[] = { 275 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 79, 80 276}; 277 278static struct matrix_keypad_platform_data palmtc_keypad_platform_data = { 279 .keymap_data = &palmtc_keymap_data, 280 .row_gpios = palmtc_keypad_row_gpios, 281 .num_row_gpios = ARRAY_SIZE(palmtc_keypad_row_gpios), 282 .col_gpios = palmtc_keypad_col_gpios, 283 .num_col_gpios = ARRAY_SIZE(palmtc_keypad_col_gpios), 284 .active_low = 1, 285 286 .debounce_ms = 20, 287 .col_scan_delay_us = 5, 288}; 289 290static struct platform_device palmtc_keyboard = { 291 .name = "matrix-keypad", 292 .id = -1, 293 .dev = { 294 .platform_data = &palmtc_keypad_platform_data, 295 }, 296}; 297static void __init palmtc_mkp_init(void) 298{ 299 platform_device_register(&palmtc_keyboard); 300} 301#else 302static inline void palmtc_mkp_init(void) {} 303#endif 304 305/****************************************************************************** 306 * UDC 307 ******************************************************************************/ 308#if defined(CONFIG_USB_PXA25X)||defined(CONFIG_USB_PXA25X_MODULE) 309static struct gpio_vbus_mach_info palmtc_udc_info = { 310 .gpio_vbus = GPIO_NR_PALMTC_USB_DETECT_N, 311 .gpio_vbus_inverted = 1, 312 .gpio_pullup = GPIO_NR_PALMTC_USB_POWER, 313}; 314 315static struct platform_device palmtc_gpio_vbus = { 316 .name = "gpio-vbus", 317 .id = -1, 318 .dev = { 319 .platform_data = &palmtc_udc_info, 320 }, 321}; 322 323static void __init palmtc_udc_init(void) 324{ 325 platform_device_register(&palmtc_gpio_vbus); 326}; 327#else 328static inline void palmtc_udc_init(void) {} 329#endif 330 331/****************************************************************************** 332 * Touchscreen / Battery / GPIO-extender 333 ******************************************************************************/ 334#if defined(CONFIG_TOUCHSCREEN_UCB1400) || \ 335 defined(CONFIG_TOUCHSCREEN_UCB1400_MODULE) 336static struct platform_device palmtc_ucb1400_device = { 337 .name = "ucb1400_core", 338 .id = -1, 339}; 340 341static void __init palmtc_ts_init(void) 342{ 343 pxa_set_ac97_info(NULL); 344 platform_device_register(&palmtc_ucb1400_device); 345} 346#else 347static inline void palmtc_ts_init(void) {} 348#endif 349 350/****************************************************************************** 351 * LEDs 352 ******************************************************************************/ 353#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) 354struct gpio_led palmtc_gpio_leds[] = { 355{ 356 .name = "palmtc:green:user", 357 .default_trigger = "none", 358 .gpio = GPIO_NR_PALMTC_LED_POWER, 359 .active_low = 1, 360}, { 361 .name = "palmtc:vibra:vibra", 362 .default_trigger = "none", 363 .gpio = GPIO_NR_PALMTC_VIBRA_POWER, 364 .active_low = 1, 365} 366 367}; 368 369static struct gpio_led_platform_data palmtc_gpio_led_info = { 370 .leds = palmtc_gpio_leds, 371 .num_leds = ARRAY_SIZE(palmtc_gpio_leds), 372}; 373 374static struct platform_device palmtc_leds = { 375 .name = "leds-gpio", 376 .id = -1, 377 .dev = { 378 .platform_data = &palmtc_gpio_led_info, 379 } 380}; 381 382static void __init palmtc_leds_init(void) 383{ 384 platform_device_register(&palmtc_leds); 385} 386#else 387static inline void palmtc_leds_init(void) {} 388#endif 389 390/****************************************************************************** 391 * NOR Flash 392 ******************************************************************************/ 393#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) 394static struct resource palmtc_flash_resource = { 395 .start = PXA_CS0_PHYS, 396 .end = PXA_CS0_PHYS + SZ_16M - 1, 397 .flags = IORESOURCE_MEM, 398}; 399 400static struct mtd_partition palmtc_flash_parts[] = { 401 { 402 .name = "U-Boot Bootloader", 403 .offset = 0x0, 404 .size = 0x40000, 405 }, 406 { 407 .name = "Linux Kernel", 408 .offset = 0x40000, 409 .size = 0x2c0000, 410 }, 411 { 412 .name = "Filesystem", 413 .offset = 0x300000, 414 .size = 0xcc0000, 415 }, 416 { 417 .name = "U-Boot Environment", 418 .offset = 0xfc0000, 419 .size = MTDPART_SIZ_FULL, 420 }, 421}; 422 423static struct physmap_flash_data palmtc_flash_data = { 424 .width = 4, 425 .parts = palmtc_flash_parts, 426 .nr_parts = ARRAY_SIZE(palmtc_flash_parts), 427}; 428 429static struct platform_device palmtc_flash = { 430 .name = "physmap-flash", 431 .id = -1, 432 .resource = &palmtc_flash_resource, 433 .num_resources = 1, 434 .dev = { 435 .platform_data = &palmtc_flash_data, 436 }, 437}; 438 439static void __init palmtc_nor_init(void) 440{ 441 platform_device_register(&palmtc_flash); 442} 443#else 444static inline void palmtc_nor_init(void) {} 445#endif 446 447/****************************************************************************** 448 * Framebuffer 449 ******************************************************************************/ 450#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) 451static struct pxafb_mode_info palmtc_lcd_modes[] = { 452 { 453 .pixclock = 115384, 454 .xres = 320, 455 .yres = 320, 456 .bpp = 16, 457 458 .left_margin = 27, 459 .right_margin = 7, 460 .upper_margin = 7, 461 .lower_margin = 8, 462 463 .hsync_len = 6, 464 .vsync_len = 1, 465 }, 466}; 467 468static struct pxafb_mach_info palmtc_lcd_screen = { 469 .modes = palmtc_lcd_modes, 470 .num_modes = ARRAY_SIZE(palmtc_lcd_modes), 471 .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL, 472}; 473 474static void __init palmtc_lcd_init(void) 475{ 476 pxa_set_fb_info(NULL, &palmtc_lcd_screen); 477} 478#else 479static inline void palmtc_lcd_init(void) {} 480#endif 481 482/****************************************************************************** 483 * Machine init 484 ******************************************************************************/ 485static void __init palmtc_init(void) 486{ 487 pxa2xx_mfp_config(ARRAY_AND_SIZE(palmtc_pin_config)); 488 489 pxa_set_ffuart_info(NULL); 490 pxa_set_btuart_info(NULL); 491 pxa_set_stuart_info(NULL); 492 pxa_set_hwuart_info(NULL); 493 494 palmtc_mmc_init(); 495 palmtc_keys_init(); 496 palmtc_pwm_init(); 497 palmtc_irda_init(); 498 palmtc_mkp_init(); 499 palmtc_udc_init(); 500 palmtc_ts_init(); 501 palmtc_nor_init(); 502 palmtc_lcd_init(); 503 palmtc_leds_init(); 504}; 505 506MACHINE_START(PALMTC, "Palm Tungsten|C") 507 .atag_offset = 0x100, 508 .map_io = pxa25x_map_io, 509 .nr_irqs = PXA_NR_IRQS, 510 .init_irq = pxa25x_init_irq, 511 .handle_irq = pxa25x_handle_irq, 512 .init_time = pxa_timer_init, 513 .init_machine = palmtc_init, 514 .restart = pxa_restart, 515MACHINE_END 516