hh.org updates
[hh.org.git] / arch / arm / mach-pxa / h1900 / h1900_lcd.c
blob53257d503a47be7627397ef55a0662982c1bba5c
1 /*
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 * Copyright (C) 2003-2004 Joshua Wise
15 * Copyright (C) 2005 Pawel Kolodziejski
17 * History:
19 * 2004-06-01 Joshua Wise Adapted to new LED API
20 * 2004-06-01 Joshua Wise Re-adapted for hp iPAQ h1900
21 * ????-??-?? ? Converted to h3900_lcd.c
22 * 2003-05-14 Joshua Wise Adapted for the HP iPAQ H1900
23 * 2002-08-23 Jamey Hicks Adapted for use with PXA250-based iPAQs
24 * 2001-10-?? Andrew Christian Added support for iPAQ H3800
25 * and abstracted EGPIO interface.
29 #include <linux/module.h>
30 #include <linux/init.h>
31 #include <linux/kernel.h>
32 #include <linux/tty.h>
33 #include <linux/sched.h>
34 #include <linux/delay.h>
35 #include <linux/pm.h>
36 #include <linux/lcd.h>
37 #include <linux/backlight.h>
38 #include <linux/fb.h>
39 #include <linux/err.h>
40 #include <linux/platform_device.h>
42 #include <asm/mach-types.h>
43 #include <asm/hardware.h>
44 #include <asm/setup.h>
46 #include <asm/arch/pxafb.h>
47 #include <asm/mach/arch.h>
48 #include <asm/arch/pxa-regs.h>
49 #include <asm/arch/h1900-asic.h>
50 #include <asm/arch/h1900-gpio.h>
51 #include <asm/arch/ipaq.h>
53 #include <linux/soc/asic3_base.h>
55 static int lcd_power;
56 static int backlight_power;
58 extern struct platform_device pxafb_device;
59 extern struct platform_device h1900_asic3;
60 #define asic3 &h1900_asic3.dev
62 int h1900_lcd_set_power(struct lcd_device *lm, int level)
64 switch (level) {
65 case FB_BLANK_UNBLANK:
66 case FB_BLANK_NORMAL:
67 asic3_set_gpio_out_c(asic3, GPIO3_H1900_LCD_5V, GPIO3_H1900_LCD_5V);
68 mdelay(20);
69 asic3_set_gpio_out_c(asic3, GPIO3_H1900_LCD_PCI, GPIO3_H1900_LCD_PCI);
70 mdelay(20);
71 asic3_set_gpio_out_c(asic3, GPIO3_H1900_LCD_3V, GPIO3_H1900_LCD_3V);
72 GPSR(GPIO_NR_H1900_VGL_EN) = GPIO_bit(GPIO_NR_H1900_VGL_EN);
73 GPSR(GPIO_NR_H1900_LCD_SOMETHING) = GPIO_bit(GPIO_NR_H1900_LCD_SOMETHING);
74 mdelay(10);
75 break;
76 case FB_BLANK_VSYNC_SUSPEND:
77 case FB_BLANK_HSYNC_SUSPEND:
78 break;
79 case FB_BLANK_POWERDOWN:
80 GPCR(GPIO_NR_H1900_LCD_SOMETHING) = GPIO_bit(GPIO_NR_H1900_LCD_SOMETHING);
81 GPCR(GPIO_NR_H1900_VGL_EN) = GPIO_bit(GPIO_NR_H1900_VGL_EN);
82 mdelay(1);
83 asic3_set_gpio_out_c(asic3, GPIO3_H1900_LCD_3V, 0);
84 asic3_set_gpio_out_c(asic3, GPIO3_H1900_LCD_PCI, 0);
85 asic3_set_gpio_out_c(asic3, GPIO3_H1900_LCD_5V, 0);
86 break;
89 lcd_power = level;
91 return 0;
94 static int h1900_lcd_get_power(struct lcd_device *lm)
96 return lcd_power;
99 int h1900_backlight_set_power(struct backlight_device *bl, int level)
101 switch (level) {
102 case FB_BLANK_UNBLANK:
103 case FB_BLANK_NORMAL:
104 GPSR(GPIO_NR_H1900_LCD_PWM) = GPIO_bit(GPIO_NR_H1900_LCD_PWM);
105 CKEN |= CKEN0_PWM0;
106 mdelay(50);
107 asic3_set_gpio_out_c(asic3, GPIO3_H1900_BACKLIGHT_POWER, GPIO3_H1900_BACKLIGHT_POWER);
108 break;
109 case FB_BLANK_VSYNC_SUSPEND:
110 case FB_BLANK_HSYNC_SUSPEND:
111 break;
112 case FB_BLANK_POWERDOWN:
113 GPCR(GPIO_NR_H1900_LCD_PWM) = GPIO_bit(GPIO_NR_H1900_LCD_PWM);
114 CKEN &= ~CKEN0_PWM0;
115 asic3_set_gpio_out_c(asic3, GPIO3_H1900_BACKLIGHT_POWER, 0);
116 break;
119 backlight_power = level;
121 return 0;
124 static int h1900_backlight_get_power(struct backlight_device *bl)
126 return backlight_power;
129 int h1900_backlight_set_brightness(struct backlight_device *bm, int value)
131 PWM_CTRL0 = 0;
132 PWM_PWDUTY0 = (value * 183) / 255;
133 PWM_PERVAL0 = 183;
135 return 0;
138 int h1900_backlight_get_brightness(struct backlight_device *bm)
140 return (PWM_PWDUTY0 * 255) / 183;
143 static struct lcd_properties h1900_lcd_properties = {
144 .owner = THIS_MODULE,
145 .set_power = h1900_lcd_set_power,
146 .get_power = h1900_lcd_get_power,
149 static struct backlight_properties h1900_backlight_properties = {
150 .owner = THIS_MODULE,
151 .set_power = h1900_backlight_set_power,
152 .get_power = h1900_backlight_get_power,
153 .max_brightness = 255,
154 .set_brightness = h1900_backlight_set_brightness,
155 .get_brightness = h1900_backlight_get_brightness,
158 static struct lcd_device *pxafb_lcd_device;
159 static struct backlight_device *pxafb_backlight_device;
161 struct pm_save_data {
162 int brightness;
165 static int h1900_lcd_probe(struct device *dev)
167 pxafb_lcd_device = lcd_device_register("pxafb", NULL, &h1900_lcd_properties);
169 if (IS_ERR(pxafb_lcd_device))
170 return PTR_ERR(pxafb_lcd_device);
171 pxafb_backlight_device = backlight_device_register("pxafb", NULL, &h1900_backlight_properties);
172 if (IS_ERR(pxafb_backlight_device)) {
173 lcd_device_unregister(pxafb_lcd_device);
174 return PTR_ERR(pxafb_backlight_device);
177 h1900_backlight_set_brightness(pxafb_backlight_device, 100);
179 return 0;
182 static int h1900_lcd_remove(struct device *dev)
184 lcd_device_unregister(pxafb_lcd_device);
185 backlight_device_unregister(pxafb_backlight_device);
187 return 0;
190 #ifdef CONFIG_PM
191 static int h1900_lcd_suspend(struct device *dev, pm_message_t state)
193 struct pm_save_data *save;
195 save = kmalloc(sizeof(struct pm_save_data), GFP_KERNEL);
196 if (!save)
197 return -ENOMEM;
199 dev->power.saved_state = save;
201 save->brightness = h1900_backlight_get_brightness(NULL);
203 return 0;
206 static int h1900_lcd_resume(struct device *dev)
208 struct pm_save_data *save;
210 save = (struct pm_save_data *)dev->power.saved_state;
211 if (!save)
212 return 0;
214 h1900_backlight_set_brightness(NULL, save->brightness);
216 return 0;
218 #endif
220 static struct device_driver h1900_lcd_driver = {
221 .name = "h1900-lcd",
222 .bus = &platform_bus_type,
223 .probe = h1900_lcd_probe,
224 .remove = h1900_lcd_remove,
225 #ifdef CONFIG_PM
226 .suspend = h1900_lcd_suspend,
227 .resume = h1900_lcd_resume,
228 #endif
231 static __init int h1900_lcd_init(void)
233 if (!machine_is_h1900())
234 return -ENODEV;
236 return driver_register(&h1900_lcd_driver);
239 static __exit void h1900_lcd_exit(void)
241 driver_unregister(&h1900_lcd_driver);
244 module_init(h1900_lcd_init);
245 module_exit(h1900_lcd_exit);
247 MODULE_LICENSE("GPL");
248 MODULE_AUTHOR("Pawel Kolodziejski");
249 MODULE_DESCRIPTION("iPAQ h1910/h1915 LCD driver glue");