saar.c revision f0a83701399123b0e95cc4d949fcccf9941fd190
1/* 2 * linux/arch/arm/mach-pxa/saar.c 3 * 4 * Support for the Marvell PXA930 Handheld Platform (aka SAAR) 5 * 6 * Copyright (C) 2007-2008 Marvell International Ltd. 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * publishhed by the Free Software Foundation. 11 */ 12 13#include <linux/module.h> 14#include <linux/kernel.h> 15#include <linux/interrupt.h> 16#include <linux/init.h> 17#include <linux/platform_device.h> 18#include <linux/clk.h> 19#include <linux/gpio.h> 20#include <linux/delay.h> 21#include <linux/fb.h> 22#include <linux/i2c.h> 23#include <linux/smc91x.h> 24#include <linux/mfd/da903x.h> 25 26#include <asm/mach-types.h> 27#include <asm/mach/arch.h> 28 29#include <mach/pxa930.h> 30#include <plat/i2c.h> 31#include <mach/pxafb.h> 32 33#include "devices.h" 34#include "generic.h" 35 36#define GPIO_LCD_RESET (16) 37 38/* SAAR MFP configurations */ 39static mfp_cfg_t saar_mfp_cfg[] __initdata = { 40 /* LCD */ 41 GPIO23_LCD_DD0, 42 GPIO24_LCD_DD1, 43 GPIO25_LCD_DD2, 44 GPIO26_LCD_DD3, 45 GPIO27_LCD_DD4, 46 GPIO28_LCD_DD5, 47 GPIO29_LCD_DD6, 48 GPIO44_LCD_DD7, 49 GPIO21_LCD_CS, 50 GPIO22_LCD_VSYNC, 51 GPIO17_LCD_FCLK_RD, 52 GPIO18_LCD_LCLK_A0, 53 GPIO19_LCD_PCLK_WR, 54 GPIO16_GPIO, /* LCD reset */ 55 56 /* Ethernet */ 57 DF_nCS1_nCS3, 58 GPIO97_GPIO, 59}; 60 61#define SAAR_ETH_PHYS (0x14000000) 62 63static struct resource smc91x_resources[] = { 64 [0] = { 65 .start = (SAAR_ETH_PHYS + 0x300), 66 .end = (SAAR_ETH_PHYS + 0xfffff), 67 .flags = IORESOURCE_MEM, 68 }, 69 [1] = { 70 .start = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO97)), 71 .end = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO97)), 72 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, 73 } 74}; 75 76static struct smc91x_platdata saar_smc91x_info = { 77 .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT | SMC91X_USE_DMA, 78}; 79 80static struct platform_device smc91x_device = { 81 .name = "smc91x", 82 .id = 0, 83 .num_resources = ARRAY_SIZE(smc91x_resources), 84 .resource = smc91x_resources, 85 .dev = { 86 .platform_data = &saar_smc91x_info, 87 }, 88}; 89 90#if defined(CONFIG_FB_PXA) || (CONFIG_FB_PXA_MODULE) 91static uint16_t lcd_power_on[] = { 92 /* single frame */ 93 SMART_CMD_NOOP, 94 SMART_CMD(0x00), 95 SMART_DELAY(0), 96 97 SMART_CMD_NOOP, 98 SMART_CMD(0x00), 99 SMART_DELAY(0), 100 101 SMART_CMD_NOOP, 102 SMART_CMD(0x00), 103 SMART_DELAY(0), 104 105 SMART_CMD_NOOP, 106 SMART_CMD(0x00), 107 SMART_DELAY(10), 108 109 /* calibration control */ 110 SMART_CMD(0x00), 111 SMART_CMD(0xA4), 112 SMART_DAT(0x80), 113 SMART_DAT(0x01), 114 SMART_DELAY(150), 115 116 /*Power-On Init sequence*/ 117 SMART_CMD(0x00), /* output ctrl */ 118 SMART_CMD(0x01), 119 SMART_DAT(0x01), 120 SMART_DAT(0x00), 121 SMART_CMD(0x00), /* wave ctrl */ 122 SMART_CMD(0x02), 123 SMART_DAT(0x07), 124 SMART_DAT(0x00), 125 SMART_CMD(0x00), 126 SMART_CMD(0x03), /* entry mode */ 127 SMART_DAT(0xD0), 128 SMART_DAT(0x30), 129 SMART_CMD(0x00), 130 SMART_CMD(0x08), /* display ctrl 2 */ 131 SMART_DAT(0x08), 132 SMART_DAT(0x08), 133 SMART_CMD(0x00), 134 SMART_CMD(0x09), /* display ctrl 3 */ 135 SMART_DAT(0x04), 136 SMART_DAT(0x2F), 137 SMART_CMD(0x00), 138 SMART_CMD(0x0A), /* display ctrl 4 */ 139 SMART_DAT(0x00), 140 SMART_DAT(0x08), 141 SMART_CMD(0x00), 142 SMART_CMD(0x0D), /* Frame Marker position */ 143 SMART_DAT(0x00), 144 SMART_DAT(0x08), 145 SMART_CMD(0x00), 146 SMART_CMD(0x60), /* Driver output control */ 147 SMART_DAT(0x27), 148 SMART_DAT(0x00), 149 SMART_CMD(0x00), 150 SMART_CMD(0x61), /* Base image display control */ 151 SMART_DAT(0x00), 152 SMART_DAT(0x01), 153 SMART_CMD(0x00), 154 SMART_CMD(0x30), /* Y settings 30h-3Dh */ 155 SMART_DAT(0x07), 156 SMART_DAT(0x07), 157 SMART_CMD(0x00), 158 SMART_CMD(0x31), 159 SMART_DAT(0x00), 160 SMART_DAT(0x07), 161 SMART_CMD(0x00), 162 SMART_CMD(0x32), /* Timing(3), ASW HOLD=0.5CLK */ 163 SMART_DAT(0x04), 164 SMART_DAT(0x00), 165 SMART_CMD(0x00), 166 SMART_CMD(0x33), /* Timing(4), CKV ST=0CLK, CKV ED=1CLK */ 167 SMART_DAT(0x03), 168 SMART_DAT(0x03), 169 SMART_CMD(0x00), 170 SMART_CMD(0x34), 171 SMART_DAT(0x00), 172 SMART_DAT(0x00), 173 SMART_CMD(0x00), 174 SMART_CMD(0x35), 175 SMART_DAT(0x02), 176 SMART_DAT(0x05), 177 SMART_CMD(0x00), 178 SMART_CMD(0x36), 179 SMART_DAT(0x1F), 180 SMART_DAT(0x1F), 181 SMART_CMD(0x00), 182 SMART_CMD(0x37), 183 SMART_DAT(0x07), 184 SMART_DAT(0x07), 185 SMART_CMD(0x00), 186 SMART_CMD(0x38), 187 SMART_DAT(0x00), 188 SMART_DAT(0x07), 189 SMART_CMD(0x00), 190 SMART_CMD(0x39), 191 SMART_DAT(0x04), 192 SMART_DAT(0x00), 193 SMART_CMD(0x00), 194 SMART_CMD(0x3A), 195 SMART_DAT(0x03), 196 SMART_DAT(0x03), 197 SMART_CMD(0x00), 198 SMART_CMD(0x3B), 199 SMART_DAT(0x00), 200 SMART_DAT(0x00), 201 SMART_CMD(0x00), 202 SMART_CMD(0x3C), 203 SMART_DAT(0x02), 204 SMART_DAT(0x05), 205 SMART_CMD(0x00), 206 SMART_CMD(0x3D), 207 SMART_DAT(0x1F), 208 SMART_DAT(0x1F), 209 SMART_CMD(0x00), /* Display control 1 */ 210 SMART_CMD(0x07), 211 SMART_DAT(0x00), 212 SMART_DAT(0x01), 213 SMART_CMD(0x00), /* Power control 5 */ 214 SMART_CMD(0x17), 215 SMART_DAT(0x00), 216 SMART_DAT(0x01), 217 SMART_CMD(0x00), /* Power control 1 */ 218 SMART_CMD(0x10), 219 SMART_DAT(0x10), 220 SMART_DAT(0xB0), 221 SMART_CMD(0x00), /* Power control 2 */ 222 SMART_CMD(0x11), 223 SMART_DAT(0x01), 224 SMART_DAT(0x30), 225 SMART_CMD(0x00), /* Power control 3 */ 226 SMART_CMD(0x12), 227 SMART_DAT(0x01), 228 SMART_DAT(0x9E), 229 SMART_CMD(0x00), /* Power control 4 */ 230 SMART_CMD(0x13), 231 SMART_DAT(0x17), 232 SMART_DAT(0x00), 233 SMART_CMD(0x00), /* Power control 3 */ 234 SMART_CMD(0x12), 235 SMART_DAT(0x01), 236 SMART_DAT(0xBE), 237 SMART_DELAY(100), 238 239 /* display mode : 240*320 */ 240 SMART_CMD(0x00), /* RAM address set(H) 0*/ 241 SMART_CMD(0x20), 242 SMART_DAT(0x00), 243 SMART_DAT(0x00), 244 SMART_CMD(0x00), /* RAM address set(V) 4*/ 245 SMART_CMD(0x21), 246 SMART_DAT(0x00), 247 SMART_DAT(0x00), 248 SMART_CMD(0x00), /* Start of Window RAM address set(H) 8*/ 249 SMART_CMD(0x50), 250 SMART_DAT(0x00), 251 SMART_DAT(0x00), 252 SMART_CMD(0x00), /* End of Window RAM address set(H) 12*/ 253 SMART_CMD(0x51), 254 SMART_DAT(0x00), 255 SMART_DAT(0xEF), 256 SMART_CMD(0x00), /* Start of Window RAM address set(V) 16*/ 257 SMART_CMD(0x52), 258 SMART_DAT(0x00), 259 SMART_DAT(0x00), 260 SMART_CMD(0x00), /* End of Window RAM address set(V) 20*/ 261 SMART_CMD(0x53), 262 SMART_DAT(0x01), 263 SMART_DAT(0x3F), 264 SMART_CMD(0x00), /* Panel interface control 1 */ 265 SMART_CMD(0x90), 266 SMART_DAT(0x00), 267 SMART_DAT(0x1A), 268 SMART_CMD(0x00), /* Panel interface control 2 */ 269 SMART_CMD(0x92), 270 SMART_DAT(0x04), 271 SMART_DAT(0x00), 272 SMART_CMD(0x00), /* Panel interface control 3 */ 273 SMART_CMD(0x93), 274 SMART_DAT(0x00), 275 SMART_DAT(0x05), 276 SMART_DELAY(20), 277}; 278 279static uint16_t lcd_panel_on[] = { 280 SMART_CMD(0x00), 281 SMART_CMD(0x07), 282 SMART_DAT(0x00), 283 SMART_DAT(0x21), 284 SMART_DELAY(1), 285 286 SMART_CMD(0x00), 287 SMART_CMD(0x07), 288 SMART_DAT(0x00), 289 SMART_DAT(0x61), 290 SMART_DELAY(100), 291 292 SMART_CMD(0x00), 293 SMART_CMD(0x07), 294 SMART_DAT(0x01), 295 SMART_DAT(0x73), 296 SMART_DELAY(1), 297}; 298 299static uint16_t lcd_panel_off[] = { 300 SMART_CMD(0x00), 301 SMART_CMD(0x07), 302 SMART_DAT(0x00), 303 SMART_DAT(0x72), 304 SMART_DELAY(40), 305 306 SMART_CMD(0x00), 307 SMART_CMD(0x07), 308 SMART_DAT(0x00), 309 SMART_DAT(0x01), 310 SMART_DELAY(1), 311 312 SMART_CMD(0x00), 313 SMART_CMD(0x07), 314 SMART_DAT(0x00), 315 SMART_DAT(0x00), 316 SMART_DELAY(1), 317}; 318 319static uint16_t lcd_power_off[] = { 320 SMART_CMD(0x00), 321 SMART_CMD(0x10), 322 SMART_DAT(0x00), 323 SMART_DAT(0x80), 324 325 SMART_CMD(0x00), 326 SMART_CMD(0x11), 327 SMART_DAT(0x01), 328 SMART_DAT(0x60), 329 330 SMART_CMD(0x00), 331 SMART_CMD(0x12), 332 SMART_DAT(0x01), 333 SMART_DAT(0xAE), 334 SMART_DELAY(40), 335 336 SMART_CMD(0x00), 337 SMART_CMD(0x10), 338 SMART_DAT(0x00), 339 SMART_DAT(0x00), 340}; 341 342static uint16_t update_framedata[] = { 343 /* set display ram: 240*320 */ 344 SMART_CMD(0x00), /* RAM address set(H) 0*/ 345 SMART_CMD(0x20), 346 SMART_DAT(0x00), 347 SMART_DAT(0x00), 348 SMART_CMD(0x00), /* RAM address set(V) 4*/ 349 SMART_CMD(0x21), 350 SMART_DAT(0x00), 351 SMART_DAT(0x00), 352 SMART_CMD(0x00), /* Start of Window RAM address set(H) 8 */ 353 SMART_CMD(0x50), 354 SMART_DAT(0x00), 355 SMART_DAT(0x00), 356 SMART_CMD(0x00), /* End of Window RAM address set(H) 12 */ 357 SMART_CMD(0x51), 358 SMART_DAT(0x00), 359 SMART_DAT(0xEF), 360 SMART_CMD(0x00), /* Start of Window RAM address set(V) 16 */ 361 SMART_CMD(0x52), 362 SMART_DAT(0x00), 363 SMART_DAT(0x00), 364 SMART_CMD(0x00), /* End of Window RAM address set(V) 20 */ 365 SMART_CMD(0x53), 366 SMART_DAT(0x01), 367 SMART_DAT(0x3F), 368 369 /* wait for vsync cmd before transferring frame data */ 370 SMART_CMD_WAIT_FOR_VSYNC, 371 372 /* write ram */ 373 SMART_CMD(0x00), 374 SMART_CMD(0x22), 375 376 /* write frame data */ 377 SMART_CMD_WRITE_FRAME, 378}; 379 380static void ltm022a97a_lcd_power(int on, struct fb_var_screeninfo *var) 381{ 382 static int pin_requested = 0; 383 struct fb_info *info = container_of(var, struct fb_info, var); 384 int err; 385 386 if (!pin_requested) { 387 err = gpio_request(GPIO_LCD_RESET, "lcd reset"); 388 if (err) { 389 pr_err("failed to request gpio for LCD reset\n"); 390 return; 391 } 392 393 gpio_direction_output(GPIO_LCD_RESET, 0); 394 pin_requested = 1; 395 } 396 397 if (on) { 398 gpio_set_value(GPIO_LCD_RESET, 0); msleep(100); 399 gpio_set_value(GPIO_LCD_RESET, 1); msleep(10); 400 401 pxafb_smart_queue(info, ARRAY_AND_SIZE(lcd_power_on)); 402 pxafb_smart_queue(info, ARRAY_AND_SIZE(lcd_panel_on)); 403 } else { 404 pxafb_smart_queue(info, ARRAY_AND_SIZE(lcd_panel_off)); 405 pxafb_smart_queue(info, ARRAY_AND_SIZE(lcd_power_off)); 406 } 407 408 err = pxafb_smart_flush(info); 409 if (err) 410 pr_err("%s: timed out\n", __func__); 411} 412 413static void ltm022a97a_update(struct fb_info *info) 414{ 415 pxafb_smart_queue(info, ARRAY_AND_SIZE(update_framedata)); 416 pxafb_smart_flush(info); 417} 418 419static struct pxafb_mode_info toshiba_ltm022a97a_modes[] = { 420 [0] = { 421 .xres = 240, 422 .yres = 320, 423 .bpp = 16, 424 .a0csrd_set_hld = 30, 425 .a0cswr_set_hld = 30, 426 .wr_pulse_width = 30, 427 .rd_pulse_width = 30, 428 .op_hold_time = 30, 429 .cmd_inh_time = 60, 430 431 /* L_LCLK_A0 and L_LCLK_RD active low */ 432 .sync = FB_SYNC_HOR_HIGH_ACT | 433 FB_SYNC_VERT_HIGH_ACT, 434 }, 435}; 436 437static struct pxafb_mach_info saar_lcd_info = { 438 .modes = toshiba_ltm022a97a_modes, 439 .num_modes = 1, 440 .lcd_conn = LCD_SMART_PANEL_8BPP | LCD_PCLK_EDGE_FALL, 441 .pxafb_lcd_power = ltm022a97a_lcd_power, 442 .smart_update = ltm022a97a_update, 443}; 444 445static void __init saar_init_lcd(void) 446{ 447 set_pxa_fb_info(&saar_lcd_info); 448} 449#else 450static inline void saar_init_lcd(void) {} 451#endif 452 453#if defined(CONFIG_I2C_PXA) || defined(CONFIG_I2C_PXA_MODULE) 454static struct da903x_subdev_info saar_da9034_subdevs[] = { 455 [0] = { 456 .name = "da903x-backlight", 457 .id = DA9034_ID_WLED, 458 }, 459}; 460 461static struct da903x_platform_data saar_da9034_info = { 462 .num_subdevs = ARRAY_SIZE(saar_da9034_subdevs), 463 .subdevs = saar_da9034_subdevs, 464}; 465 466static struct i2c_board_info saar_i2c_info[] = { 467 [0] = { 468 .type = "da9034", 469 .addr = 0x34, 470 .platform_data = &saar_da9034_info, 471 .irq = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO83)), 472 }, 473}; 474 475static void __init saar_init_i2c(void) 476{ 477 pxa_set_i2c_info(NULL); 478 i2c_register_board_info(0, ARRAY_AND_SIZE(saar_i2c_info)); 479} 480#else 481static inline void saar_init_i2c(void) {} 482#endif 483static void __init saar_init(void) 484{ 485 /* initialize MFP configurations */ 486 pxa3xx_mfp_config(ARRAY_AND_SIZE(saar_mfp_cfg)); 487 488 platform_device_register(&smc91x_device); 489 490 saar_init_i2c(); 491 saar_init_lcd(); 492} 493 494MACHINE_START(SAAR, "PXA930 Handheld Platform (aka SAAR)") 495 /* Maintainer: Eric Miao <eric.miao@marvell.com> */ 496 .phys_io = 0x40000000, 497 .boot_params = 0xa0000100, 498 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, 499 .map_io = pxa_map_io, 500 .init_irq = pxa3xx_init_irq, 501 .timer = &pxa_timer, 502 .init_machine = saar_init, 503MACHINE_END 504