hh.org updates
[hh.org.git] / arch / arm / mach-pxa / magician / magician_lcd.c
blob2299326709b8b87d38519fc01a5c26de8e03cfb5
1 /*
2 * LCD driver for HTC Magician
4 * Copyright (C) 2006, Philipp Zabel
6 * based on previous work by
7 * Giuseppe Zompatori <giuseppe_zompatori@yahoo.it>,
8 * Andrew Zabolotny <zap@homelink.ru>
10 * This file is subject to the terms and conditions of the GNU General Public
11 * License. See the file COPYING in the main directory of this archive for
12 * more details.
14 #include <linux/module.h>
15 #include <linux/init.h>
16 #include <linux/notifier.h>
17 #include <linux/lcd.h>
18 #include <linux/err.h>
19 #include <linux/delay.h>
20 #include <linux/fb.h>
21 #include <linux/platform_device.h>
23 #include <asm/arch/magician.h>
24 #include <asm/mach-types.h>
25 #include <asm/arch/pxa-regs.h>
26 #include <asm/arch/pxafb.h>
28 #include <asm/arch/magician_cpld.h>
30 static int lcd_select;
32 /* Samsung LTP280QV */
33 static struct pxafb_mach_info magician_fb_info_samsung = {
34 .pixclock = 96153,
35 .bpp = 16,
36 .xres = 240,
37 .yres = 320,
38 .hsync_len = 4,
39 .vsync_len = 1,
40 .left_margin = 20,
41 .upper_margin = 7,
42 .right_margin = 8,
43 .lower_margin = 8,
44 .sync = 0,
45 .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
46 .lccr3 = LCCR3_PixFlEdg,
47 .pxafb_backlight_power = NULL,
48 .pxafb_lcd_power = NULL,
51 /* Toppoly TD028STEB1 */
52 static struct pxafb_mach_info magician_fb_info_toppoly = {
53 .pixclock = 96153,
54 .bpp = 16,
55 .xres = 240,
56 .yres = 320,
57 .hsync_len = 11,
58 .vsync_len = 3,
59 .left_margin = 19,
60 .upper_margin = 2,
61 .right_margin = 10,
62 .lower_margin = 2,
63 .sync = 0,
64 .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
65 .lccr3 = LCCR3_PixRsEdg,
66 .pxafb_backlight_power = NULL,
67 .pxafb_lcd_power = NULL,
70 extern struct platform_device magician_cpld;
72 static int lcd_power;
74 static void toppoly_set_power(int power)
76 if (power) {
78 pxa_gpio_mode(GPIO74_LCD_FCLK_MD);
79 pxa_gpio_mode(GPIO75_LCD_LCLK_MD); // done by pxafb
81 magician_egpio_enable(&magician_cpld.dev, 2 /* TOPPOLY_POWER? */);
82 pxa_gpio_mode(104 | GPIO_OUT);
83 pxa_gpio_mode(106 | GPIO_OUT);
84 pxa_gpio_mode(105 | GPIO_OUT);
85 GPSR(106) = GPIO_bit(106);
86 udelay(2000);
87 magician_egpio_enable(&magician_cpld.dev, EGPIO_NR_MAGICIAN_LCD_POWER);
88 udelay(2000);
89 /* LCCR0 = 0x04000081; // <-- already done by pxafb_enable_controller */
90 udelay(2000);
91 GPSR(104) = GPIO_bit(104);
92 udelay(2000);
93 GPSR(105) = GPIO_bit(105);
94 } else {
95 /* LCCR0 = 0x00000000; // <-- will be done by pxafb_disable_controller afterwards?! */
96 udelay(15000);
97 GPCR(105) = GPIO_bit(105);
98 udelay(500);
99 GPCR(104) = GPIO_bit(104);
100 udelay(1000);
101 GPCR(106) = GPIO_bit(106);
102 magician_egpio_disable(&magician_cpld.dev, EGPIO_NR_MAGICIAN_LCD_POWER);
106 #if 0
107 static int magician_lcd_set_power(int power)
109 if (lcd_select)
110 samsung_set_power(power)
111 else
112 toppoly_set_power(power);
114 #endif
116 static int magician_lcd_set_power(struct lcd_device *lm, int level)
118 printk("magician_lcd_set_power(level=%d) called.\n", level);
120 switch (level) {
121 case FB_BLANK_UNBLANK:
122 // toppoly_set_power(1);
123 break;
124 case FB_BLANK_VSYNC_SUSPEND:
125 case FB_BLANK_HSYNC_SUSPEND:
126 break;
127 case FB_BLANK_NORMAL:
128 case FB_BLANK_POWERDOWN:
129 // toppoly_set_power(0);
130 break;
133 lcd_power = level;
135 return 0;
138 static int magician_lcd_get_power(struct lcd_device *lm)
140 return lcd_power;
143 struct lcd_properties magician_lcd_properties = {
144 .owner = THIS_MODULE,
145 .set_power = magician_lcd_set_power,
146 .get_power = magician_lcd_get_power,
149 static struct lcd_device *pxafb_lcd_device;
151 static int magician_lcd_probe(struct device *dev)
153 volatile u8 *p;
155 printk(KERN_NOTICE "HTC Magician LCD driver\n");
157 /* Check which LCD we have */
158 p = (volatile u8 *)ioremap_nocache(PXA_CS3_PHYS, 0x1000);
159 if (p) {
160 lcd_select = p[14] & 0x8;
161 printk("magician_lcd: lcd_select = %d (%s)\n", lcd_select,
162 lcd_select ? "samsung" : "toppoly");
163 iounmap((void *)p);
164 } else
165 printk("magician_lcd: lcd_select ioremap failed\n");
167 if (lcd_select)
168 set_pxa_fb_info(&magician_fb_info_samsung);
169 else
170 set_pxa_fb_info(&magician_fb_info_toppoly);
172 pxafb_lcd_device =
173 lcd_device_register("pxafb", NULL, &magician_lcd_properties);
174 if (IS_ERR(pxafb_lcd_device))
175 return PTR_ERR(pxafb_lcd_device);
177 return 0;
180 static int magician_lcd_remove(struct device *dev)
182 lcd_device_unregister(pxafb_lcd_device);
184 return 0;
187 #ifdef CONFIG_PM
188 static int magician_lcd_suspend(struct device *dev, pm_message_t state)
190 return 0;
193 static int magician_lcd_resume(struct device *dev)
195 return 0;
197 #endif
199 static struct device_driver magician_lcd_driver = {
200 .name = "magician-lcd",
201 .bus = &platform_bus_type,
202 .probe = magician_lcd_probe,
203 .remove = magician_lcd_remove,
204 #ifdef CONFIG_PM
205 .suspend = magician_lcd_suspend,
206 .resume = magician_lcd_resume,
207 #endif
210 static __init int magician_lcd_init(void)
212 if (!machine_is_magician())
213 return -ENODEV;
215 return driver_register(&magician_lcd_driver);
218 static __exit void magician_lcd_exit(void)
220 driver_unregister(&magician_lcd_driver);
223 module_init(magician_lcd_init);
224 module_exit(magician_lcd_exit);
226 MODULE_AUTHOR("Philipp Zabel");
227 MODULE_DESCRIPTION("HTC Magician LCD driver");
228 MODULE_LICENSE("GPL");