2 * Hardware definitions for HP iPAQ Handheld Computers
4 * Copyright 2000-2003 Hewlett-Packard Company.
6 * Use consistent with the GNU GPL is permitted,
7 * provided that this copyright notice is
8 * preserved in its entirety in all copies and derived works.
10 * COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
11 * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
12 * FITNESS FOR ANY PARTICULAR PURPOSE.
14 * Author: Jamey Hicks.
18 * 2003-05-14 Joshua Wise Adapted for the HP iPAQ H1900
19 * 2002-08-23 Jamey Hicks Adapted for use with PXA250-based iPAQs
20 * 2001-10-?? Andrew Christian Added support for iPAQ H3800
21 * and abstracted EGPIO interface.
24 #include <linux/module.h>
25 #include <linux/init.h>
26 #include <linux/kernel.h>
27 #include <linux/tty.h>
28 #include <linux/sched.h>
29 #include <linux/delay.h>
31 #include <linux/lcd.h>
32 #include <linux/backlight.h>
34 #include <video/w100fb.h>
35 #include <linux/platform_device.h>
37 #include <asm/hardware.h>
38 #include <asm/setup.h>
40 #include <asm/mach-types.h>
41 #include <asm/mach/arch.h>
42 #include <asm/arch/htcblueangel-asic.h>
43 #include <asm/arch/pxa-regs.h>
44 #include <asm/arch/pxafb.h>
45 #include "blueangel_lcd.h"
47 #include <linux/soc/asic3_base.h>
49 extern struct platform_device blueangel_asic3
;
52 #define BLUEANGEL_ATI_W3200_PHYS PXA_CS2_PHYS
54 extern int blueangel_boardid
;
56 static struct lcd_device
*blueangel_lcd_device
;
57 static int blueangel_lcd_power
;
60 blueangel_lcd_hw_init_pre(void)
62 printk("blueangel_lcd_hw_init_pre");
63 asic3_set_gpio_out_b (&blueangel_asic3
.dev
, GPIOB_FL_PWR_ON
, GPIOB_FL_PWR_ON
);
65 switch (blueangel_boardid
)
69 asic3_set_gpio_out_b(&blueangel_asic3
.dev
, GPIOB_LCD_PWR1_ON
, 0);
71 asic3_set_gpio_out_b(&blueangel_asic3
.dev
, GPIOB_LCD_PWR2_ON
, GPIOB_LCD_PWR2_ON
);
73 asic3_set_gpio_out_b(&blueangel_asic3
.dev
, GPIOB_LCD_PWR3_ON
, GPIOB_LCD_PWR3_ON
);
75 asic3_set_gpio_out_b(&blueangel_asic3
.dev
, GPIOB_LCD_PWR1_ON
, GPIOB_LCD_PWR1_ON
);
78 asic3_set_gpio_out_b(&blueangel_asic3
.dev
, GPIOB_LCD_PWR2_ON
, GPIOB_LCD_PWR2_ON
);
79 asic3_set_gpio_out_c(&blueangel_asic3
.dev
, GPIOC_LCD_PWR5_ON
, GPIOC_LCD_PWR5_ON
);
86 blueangel_lcd_hw_init_post(void)
88 printk("blueangel_lcd_hw_init_post");
90 switch (blueangel_boardid
)
93 asic3_set_gpio_out_b(&blueangel_asic3
.dev
, GPIOB_LCD_PWR1_ON
, GPIOB_LCD_PWR1_ON
);
95 asic3_set_gpio_out_b(&blueangel_asic3
.dev
, GPIOB_LCD_PWR3_ON
, GPIOB_LCD_PWR3_ON
);
97 asic3_set_gpio_out_c(&blueangel_asic3
.dev
, GPIOC_LCD_PWR4_ON
, GPIOC_LCD_PWR4_ON
);
103 blueangel_lcd_hw_off(void)
105 printk("blueangel_lcd_hw_off\n");
106 asic3_set_gpio_out_b (&blueangel_asic3
.dev
, GPIOB_FL_PWR_ON
, 0);
107 switch (blueangel_boardid
)
110 asic3_set_gpio_out_b(&blueangel_asic3
.dev
, GPIOB_LCD_PWR1_ON
, 0);
111 asic3_set_gpio_out_c(&blueangel_asic3
.dev
, GPIOC_LCD_PWR4_ON
, 0);
112 asic3_set_gpio_out_b(&blueangel_asic3
.dev
, GPIOB_LCD_PWR3_ON
, 0);
113 asic3_set_gpio_out_b(&blueangel_asic3
.dev
, GPIOB_LCD_PWR2_ON
, 0);
114 asic3_set_gpio_out_c(&blueangel_asic3
.dev
, GPIOC_LCD_PWR5_ON
, 0);
119 asic3_set_gpio_out_b(&blueangel_asic3
.dev
, GPIOB_LCD_PWR1_ON
, 0);
121 asic3_set_gpio_out_b(&blueangel_asic3
.dev
, GPIOB_LCD_PWR3_ON
, 0);
123 asic3_set_gpio_out_b(&blueangel_asic3
.dev
, GPIOB_LCD_PWR2_ON
, 0);
128 static int blueangel_lcd_set_power( struct lcd_device
*ld
, int level
)
130 // printk("FB_BLANK_UNBLANK %d FB_BLANK_NORMAL %d\n", FB_BLANK_UNBLANK, FB_BLANK_NORMAL);
131 // printk("FB_BLANK_VSYNC_SUSPEND %d FB_BLANK_HSYNC_SUSPEND %d\n", FB_BLANK_VSYNC_SUSPEND, FB_BLANK_HSYNC_SUSPEND);
132 // printk("FB_BLANK_POWERDOWN %d\n", FB_BLANK_POWERDOWN);
133 // printk("blueangel LCD power %d\n",level);
135 case FB_BLANK_UNBLANK
:
136 case FB_BLANK_NORMAL
:
137 /* no - don't do it! you need to re-initialise the w100
138 * chip. as well. sorry.*/
140 blueangel_lcd_hw_init_pre();
141 blueangel_lcd_hw_init_post();
144 case FB_BLANK_VSYNC_SUSPEND
:
145 case FB_BLANK_HSYNC_SUSPEND
:
147 case FB_BLANK_POWERDOWN
:
148 blueangel_lcd_hw_off();
151 blueangel_lcd_power
=level
;
155 static int blueangel_lcd_get_power(struct lcd_device
*ld
)
157 printk("blueangel_lcd_get_power\n");
158 return blueangel_lcd_power
;
161 static struct lcd_properties blueangel_lcd_props
= {
162 .owner
= THIS_MODULE
,
163 .set_power
= blueangel_lcd_set_power
,
164 .get_power
= blueangel_lcd_get_power
,
168 blueangel_lcd_suspend(struct w100fb_par
*wfb
)
171 ati_gpios
[0] = w100fb_gpio_read(W100_GPIO_PORT_A
);
172 ati_gpios
[1] = w100fb_gpcntl_read(W100_GPIO_PORT_A
);
173 ati_gpios
[2] = w100fb_gpio_read(W100_GPIO_PORT_B
);
174 ati_gpios
[3] = w100fb_gpcntl_read(W100_GPIO_PORT_B
);
175 w100fb_gpio_write(W100_GPIO_PORT_A
, 0xDFE00000 );
176 w100fb_gpcntl_write(W100_GPIO_PORT_A
, 0xFFFF0000 );
177 w100fb_gpio_write(W100_GPIO_PORT_B
, 0x00000000 );
178 w100fb_gpcntl_write(W100_GPIO_PORT_B
, 0xFFFFFFFF );
179 save_bright
= PWM_PWDUTY1
;
182 blueangel_lcd_hw_off();
186 blueangel_lcd_resume_pre(struct w100fb_par
*wfb
)
189 w100fb_gpio_write(W100_GPIO_PORT_A
, ati_gpios
[0] );
190 w100fb_gpcntl_write(W100_GPIO_PORT_A
, ati_gpios
[1] );
191 w100fb_gpio_write(W100_GPIO_PORT_B
, ati_gpios
[2] );
192 w100fb_gpcntl_write(W100_GPIO_PORT_B
, ati_gpios
[3] );
194 LCD_SET_BRIGHT( save_bright
);
196 blueangel_lcd_hw_init_pre();
200 blueangel_lcd_resume_post(struct w100fb_par
*wfb
)
202 blueangel_lcd_hw_init_post();
206 blueangel_lcd_w100_resume(struct w100fb_par
*wfb
) {
207 blueangel_lcd_resume_pre(wfb
);
209 blueangel_lcd_resume_post(wfb
);
213 struct w100_tg_info blueangel_tg_info
= {
214 .suspend
= blueangel_lcd_suspend
,
215 .resume
= blueangel_lcd_w100_resume
,
216 // .resume_pre = blueangel_lcd_resume_pre,
217 // .resume_post = blueangel_lcd_resume_post,
220 static struct w100_gen_regs blueangel_w100_regs
= {
221 .lcd_format
= 0x00000003,
222 .lcdd_cntl1
= 0x00000000,
223 .lcdd_cntl2
= 0x0003ffff,
224 .genlcd_cntl1
= 0x00fff003, // 0x00fff003
225 .genlcd_cntl2
= 0x00000003,
226 .genlcd_cntl3
= 0x000102aa,
229 static struct w100_mode blueangel_w100_modes_4
[] = {
237 .crtc_ss
= 0x80150014,
238 .crtc_ls
= 0xa0fb00f7,
239 .crtc_gs
= 0xc0080007,
240 .crtc_vpos_gs
= 0x80007,
241 .crtc_rev
= 0x0000000a,
242 .crtc_dclk
= 0x81700030,
243 .crtc_gclk
= 0x8015010f,
244 .crtc_goe
= 0x00000000,
246 .pixclk_divider
= 15,
247 .pixclk_divider_rotated
= 15,
248 .pixclk_src
= CLK_SRC_PLL
,
250 .sysclk_src
= CLK_SRC_PLL
,
254 static struct w100_mode blueangel_w100_modes_5
[] = {
262 .crtc_ss
= 0x80150014,
263 .crtc_ls
= 0xa0020110,
264 .crtc_gs
= 0xc0890088,
265 .crtc_vpos_gs
= 0x01450144,
266 .crtc_rev
= 0x0000000a,
267 .crtc_dclk
= 0xa1700030,
268 .crtc_gclk
= 0x8015010f,
269 .crtc_goe
= 0x00000000,
272 .pixclk_divider_rotated
= 4,
273 .pixclk_src
= CLK_SRC_PLL
,
275 .sysclk_src
= CLK_SRC_PLL
,
279 static struct w100_mode blueangel_w100_modes_6
[] = {
287 .crtc_ss
= 0x80150014,
288 .crtc_ls
= 0xa0020110,
289 .crtc_gs
= 0xc0890088,
290 .crtc_vpos_gs
= 0x01450144,
291 .crtc_rev
= 0x0000000a,
292 .crtc_dclk
= 0xa1700030,
293 .crtc_gclk
= 0x8015010f,
294 .crtc_goe
= 0x00000000,
297 .pixclk_divider_rotated
= 4,
298 .pixclk_src
= CLK_SRC_PLL
,
300 .sysclk_src
= CLK_SRC_PLL
,
304 struct w100_mem_info blueangel_mem_info
= {
305 .ext_cntl
= 0x01040010,
306 .sdram_mode_reg
= 0x00250000,
307 .ext_timing_cntl
= 0x00001545,
308 .io_cntl
= 0x7ddd7333,
312 struct w100_bm_mem_info blueangel_bm_mem_info
= {
313 .ext_mem_bw
= 0xfbfd2d07,
314 .offset
= 0x000c0000,
315 .ext_timing_ctl
= 0x00043f7f,
316 .ext_cntl
= 0x00000010,
317 .mode_reg
= 0x006c0000,
318 .io_cntl
= 0x000e0fff,
319 .config
= 0x08300562,
322 static struct w100_gpio_regs blueangel_w100_gpio_info
= {
323 .init_data1
= 0x00000000, // GPIO_DATA
324 .gpio_dir1
= 0xe0000000, // GPIO_CNTL1
325 .gpio_oe1
= 0x003c2000, // GPIO_CNTL2
326 .init_data2
= 0x00000000, // GPIO_DATA2
327 .gpio_dir2
= 0x00000000, // GPIO_CNTL3
328 .gpio_oe2
= 0x00000000, // GPIO_CNTL4
331 static struct w100fb_mach_info blueangel_fb_info
= {
332 .tg
= &blueangel_tg_info
,
333 .mem
= &blueangel_mem_info
,
334 .bm_mem
= &blueangel_bm_mem_info
,
335 .gpio
= &blueangel_w100_gpio_info
,
336 .regs
= &blueangel_w100_regs
,
337 .modelist
= blueangel_w100_modes_6
,
339 .xtal_freq
= 16000000,
343 static struct resource blueangel_fb_resources
[] = {
345 .start
= BLUEANGEL_ATI_W3200_PHYS
,
346 .end
= BLUEANGEL_ATI_W3200_PHYS
+ 0x00ffffff,
347 .flags
= IORESOURCE_MEM
,
351 static struct platform_device blueangel_fb_device
= {
355 .platform_data
= &blueangel_fb_info
,
357 .num_resources
= ARRAY_SIZE( blueangel_fb_resources
),
358 .resource
= blueangel_fb_resources
,
362 blueangel_lcd_probe( struct device
*dev
)
366 printk("in blueangel_lcd_probe\n");
368 blueangel_lcd_device
= lcd_device_register("w100fb", (void *)&blueangel_fb_info
, &blueangel_lcd_props
);
369 if (IS_ERR(blueangel_lcd_device
)) {
370 return PTR_ERR(blueangel_lcd_device
);
373 ret
= platform_device_register( &blueangel_fb_device
);
380 blueangel_lcd_remove( struct device
*dev
)
382 lcd_device_unregister (blueangel_lcd_device
);
383 platform_device_unregister(&blueangel_fb_device
);
388 blueangel_lcd_resume(struct device
*dev
) {
389 blueangel_lcd_hw_init_pre();
391 blueangel_lcd_hw_init_post();
396 struct platform_driver blueangel_lcd_driver
= {
398 .name
= "blueangel-lcd",
399 .bus
= &platform_bus_type
,
400 .probe
= blueangel_lcd_probe
,
401 .remove
= blueangel_lcd_remove
,
402 .resume
= blueangel_lcd_resume
,
408 blueangel_lcd_init (void)
410 printk("blueangel_lcd_init\n");
411 if (! machine_is_blueangel())
414 switch (blueangel_boardid
)
417 blueangel_fb_info
.modelist
=blueangel_w100_modes_4
;
420 blueangel_fb_info
.modelist
=blueangel_w100_modes_5
;
423 blueangel_fb_info
.modelist
=blueangel_w100_modes_6
;
426 printk("blueangel lcd_init: unknown boardid=%d. Using 0x6\n",blueangel_boardid
);
427 blueangel_fb_info
.modelist
=blueangel_w100_modes_6
;
430 return platform_driver_register( &blueangel_lcd_driver
);
436 blueangel_lcd_exit (void)
438 platform_driver_unregister( &blueangel_lcd_driver
);
441 module_init (blueangel_lcd_init
);
442 module_exit (blueangel_lcd_exit
);
443 MODULE_LICENSE("GPL");