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