sync hh.org
[hh.org.git] / arch / arm / mach-pxa / himalaya / himalaya_lcd.c
blob014837c4d19e3eb662677e51bb0143444ba41936
1 /*
2 * LCD support for iPAQ HIMALAYA
4 * Copyright (c) 2005 Ian Molton
5 * Copyright (c) 2005 SDG Systems, LLC
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file COPYING in the main directory of this archive for
9 * more details.
11 * 04-Jan-2005 Todd Blumer <todd@sdgsystems.com>
12 * Developed from iPAQ H5400
13 * 11-Mar-2005 Ian Molton <spyro@f2s.com>
15 #include <linux/init.h>
16 #include <linux/kernel.h>
17 #include <linux/platform_device.h>
18 #include <linux/lcd.h>
19 #include <linux/fb.h>
20 #include <linux/err.h>
21 #include <linux/delay.h>
23 #include <video/w100fb.h>
25 #include <asm/mach-types.h>
26 #include <asm/hardware.h>
27 #include <asm/mach/arch.h>
29 #include <asm/arch/pxa-regs.h>
30 #include <asm/arch-pxa/himalaya_asic.h>
31 #include <linux/soc/asic3_base.h>
32 #include <asm/hardware/ipaq-asic3.h>
34 extern struct platform_device himalaya_asic3;
36 /* ATI Imageon 3220 Graphics */
37 #define HIMALAYA_ATI_W3220_PHYS PXA_CS2_PHYS
39 static int lcd_power;
41 static void
42 lcd_hw_init( void )
44 asic3_set_gpio_out_b(&himalaya_asic3.dev, GPIOB_LCD_5V_ON, 0);
45 asic3_set_gpio_out_b(&himalaya_asic3.dev, GPIOB_LCD_ON, 0);
46 asic3_set_gpio_out_b(&himalaya_asic3.dev, GPIOB_LCD_NV_ON, 0);
47 asic3_set_gpio_out_b(&himalaya_asic3.dev, GPIOB_LCD_9V_ON, 0);
49 msleep(500);
51 asic3_set_gpio_out_b(&himalaya_asic3.dev, GPIOB_LCD_ON, GPIOB_LCD_ON);
52 msleep(17);
54 asic3_set_gpio_out_b(&himalaya_asic3.dev, GPIOB_LCD_NV_ON, GPIOB_LCD_NV_ON);
55 #if 0
56 himalaya_init_ATI();
57 #endif
58 msleep(30);
60 asic3_set_gpio_out_b(&himalaya_asic3.dev, GPIOB_LCD_9V_ON, GPIOB_LCD_9V_ON);
61 msleep(30);
63 asic3_set_gpio_out_b(&himalaya_asic3.dev, GPIOB_LCD_5V_ON, GPIOB_LCD_5V_ON);
64 msleep(30);
67 static void
68 lcd_hw_off( void )
70 asic3_set_gpio_out_b(&himalaya_asic3.dev, GPIOB_LCD_ON, 0);
71 mdelay(10);
72 asic3_set_gpio_out_b(&himalaya_asic3.dev, GPIOB_LCD_9V_ON, 0);
73 mdelay(10);
74 asic3_set_gpio_out_b(&himalaya_asic3.dev, GPIOB_LCD_5V_ON, 0);
75 mdelay(10);
76 asic3_set_gpio_out_b(&himalaya_asic3.dev, GPIOB_LCD_NV_ON, 0);
79 static int
80 himalaya_lcd_set_power( struct lcd_device *lm, int level )
82 switch (level) {
83 case FB_BLANK_UNBLANK:
84 case FB_BLANK_NORMAL:
85 lcd_hw_init();
86 break;
87 case FB_BLANK_VSYNC_SUSPEND:
88 case FB_BLANK_HSYNC_SUSPEND:
89 break;
90 case FB_BLANK_POWERDOWN:
91 lcd_hw_off();
92 break;
94 lcd_power = level;
95 return 0;
98 static int
99 himalaya_lcd_get_power( struct lcd_device *lm )
101 return lcd_power;
104 static struct lcd_properties w3220_fb0_lcd = {
105 .owner = THIS_MODULE,
106 .get_power = himalaya_lcd_get_power,
107 .set_power = himalaya_lcd_set_power,
110 static struct lcd_device *atifb_lcd_dev;
112 #ifdef CONFIG_PM
114 unsigned long ati_gpios[4];
116 static void
117 himalaya_lcd_suspend( struct w100fb_par *wfb )
119 ati_gpios[0] = w100fb_gpio_read(W100_GPIO_PORT_A);
120 ati_gpios[1] = w100fb_gpcntl_read(W100_GPIO_PORT_A);
121 ati_gpios[2] = w100fb_gpio_read(W100_GPIO_PORT_B);
122 ati_gpios[3] = w100fb_gpcntl_read(W100_GPIO_PORT_B);
123 w100fb_gpio_write(W100_GPIO_PORT_A, 0xDFE00000 );
124 w100fb_gpcntl_write(W100_GPIO_PORT_A, 0xFFFF0000 );
125 w100fb_gpio_write(W100_GPIO_PORT_B, 0x00000000 );
126 w100fb_gpcntl_write(W100_GPIO_PORT_B, 0xFFFFFFFF );
127 lcd_hw_off();
130 static void
131 himalaya_lcd_resume( struct w100fb_par *wfb )
133 w100fb_gpio_write(W100_GPIO_PORT_A, ati_gpios[0] );
134 w100fb_gpcntl_write(W100_GPIO_PORT_A, ati_gpios[1] );
135 w100fb_gpio_write(W100_GPIO_PORT_B, ati_gpios[2] );
136 w100fb_gpcntl_write(W100_GPIO_PORT_B, ati_gpios[3] );
137 lcd_hw_init();
140 #else
141 #define himalaya_lcd_resume NULL
142 #define himalaya_lcd_suspend NULL
143 #endif
145 struct w100_tg_info himalaya_tg_info = {
146 .suspend = himalaya_lcd_suspend,
147 .resume = himalaya_lcd_resume,
150 // W3220_VGA QVGA
151 static struct w100_gen_regs himalaya_w100_regs = {
152 .lcd_format = 0x00000003,
153 .lcdd_cntl1 = 0x00000000,
154 .lcdd_cntl2 = 0x0003ffff,
155 .genlcd_cntl1 = 0x00fff003, // 0x00abf003 for hx4700
156 .genlcd_cntl2 = 0x00000003,
157 .genlcd_cntl3 = 0x000102aa,
160 static struct w100_mode himalaya_w100_modes[] = {
163 .xres = 480,
164 .yres = 640,
165 .left_margin = 15,
166 .right_margin = 16,
167 .upper_margin = 8,
168 .lower_margin = 7,
169 .crtc_ss = 0x00000000,
170 .crtc_ls = 0xa1ff01f9, // 0x21ff01f9,
171 .crtc_gs = 0xc0000000, // 0x40000000,
172 .crtc_vpos_gs = 0x0000028f,
173 .crtc_ps1_active = 0x00000000, // 0x41060010
174 .crtc_rev = 0,
175 .crtc_dclk = 0x80000000,
176 .crtc_gclk = 0x040a0104,
177 .crtc_goe = 0,
178 .pll_freq = 95,
179 .pixclk_divider = 4,
180 .pixclk_divider_rotated = 4,
181 .pixclk_src = CLK_SRC_PLL,
182 .sysclk_divider = 0,
183 .sysclk_src = CLK_SRC_PLL,
187 .xres = 240,
188 .yres = 320,
189 .left_margin = 9,
190 .right_margin = 8,
191 .upper_margin = 5,
192 .lower_margin = 4,
193 .crtc_ss = 0x80150014,
194 .crtc_ls = 0xa0fb00f7,
195 .crtc_gs = 0xc0080007,
196 .crtc_vpos_gs = 0x00080007,
197 .crtc_rev = 0x0000000a,
198 .crtc_dclk = 0xa1700030,
199 .crtc_gclk = 0x8015010f,
200 .crtc_goe = 0x00000000,
201 .pll_freq = 95,
202 .pixclk_divider = 0xb,
203 .pixclk_divider_rotated = 4,
204 .pixclk_src = CLK_SRC_PLL,
205 .sysclk_divider = 1,
206 .sysclk_src = CLK_SRC_PLL,
210 struct w100_mem_info himalaya_mem_info = {
211 .ext_cntl = 0x09640011,
212 .sdram_mode_reg = 0x00600021,
213 .ext_timing_cntl = 0x1a001545, // 0x15001545,
214 .io_cntl = 0x7ddd7333,
215 .size = 0x1fffff,
218 struct w100_bm_mem_info himalaya_bm_mem_info = {
219 .ext_mem_bw = 0x50413e01,
220 .offset = 0,
221 .ext_timing_ctl = 0x00043f7f,
222 .ext_cntl = 0x00000010,
223 .mode_reg = 0x00250000,
224 .io_cntl = 0x0fff0000,
225 .config = 0x08301480,
228 static struct w100_gpio_regs himalaya_w100_gpio_info = {
229 .init_data1 = 0xdfe00100, // GPIO_DATA
230 .gpio_dir1 = 0xffff0000, // GPIO_CNTL1
231 .gpio_oe1 = 0x00000000, // GPIO_CNTL2
232 .init_data2 = 0x00000000, // GPIO_DATA2
233 .gpio_dir2 = 0x00000000, // GPIO_CNTL3
234 .gpio_oe2 = 0x00000000, // GPIO_CNTL4
237 static struct w100fb_mach_info himalaya_fb_info = {
238 .tg = &himalaya_tg_info,
239 .mem = &himalaya_mem_info,
240 .bm_mem = &himalaya_bm_mem_info,
241 .gpio = &himalaya_w100_gpio_info,
242 .regs = &himalaya_w100_regs,
243 .modelist = himalaya_w100_modes,
244 .num_modes = 1,
245 .xtal_freq = 14318000,
246 .xtal_dbl = 1,
250 static struct resource himalaya_fb_resources[] = {
251 [0] = {
252 .start = HIMALAYA_ATI_W3220_PHYS,
253 .end = HIMALAYA_ATI_W3220_PHYS + 0x00ffffff,
254 .flags = IORESOURCE_MEM,
258 static struct platform_device himalaya_fb_device = {
259 .name = "w100fb",
260 .id = -1,
261 .dev = {
262 .platform_data = &himalaya_fb_info,
264 .num_resources = ARRAY_SIZE( himalaya_fb_resources ),
265 .resource = himalaya_fb_resources,
268 static int
269 himalaya_lcd_probe( struct platform_device *dev )
271 lcd_hw_init();
272 return 0;
275 static int
276 himalaya_lcd_remove( struct platform_device *dev )
278 return 0;
281 static struct platform_driver himalaya_lcd_driver = {
282 .driver = {
283 .name = "himalaya-lcd",
285 .probe = himalaya_lcd_probe,
286 .remove = himalaya_lcd_remove,
290 static int __init
291 himalaya_lcd_init( void )
293 int ret;
295 printk( KERN_INFO "himalaya LCD Driver\n" );
296 if (!machine_is_himalaya())
297 return -ENODEV;
298 ret = platform_device_register( &himalaya_fb_device );
299 if (ret != 0)
300 return ret;
302 atifb_lcd_dev = lcd_device_register( "w100fb", (void *)&himalaya_fb_info,
303 &w3220_fb0_lcd );
304 if (IS_ERR( atifb_lcd_dev ))
305 return PTR_ERR( atifb_lcd_dev );
307 return platform_driver_register( &himalaya_lcd_driver );
311 static void __exit
312 himalaya_lcd_exit( void )
314 lcd_device_unregister( atifb_lcd_dev );
315 platform_device_unregister( &himalaya_fb_device );
316 platform_driver_unregister( &himalaya_lcd_driver );
319 module_init( himalaya_lcd_init );
320 module_exit( himalaya_lcd_exit );
322 MODULE_AUTHOR( "Todd Blumer, SDG Systems, LLC; Luke Kenneth Casson Leighton" );
323 MODULE_DESCRIPTION( "Framebuffer driver for iPAQ himalaya" );
324 MODULE_LICENSE( "GPL" );
326 /* vim600: set noexpandtab sw=8 ts=8 :*/