hh.org updates
[hh.org.git] / arch / arm / mach-pxa / aximx5 / aximx5_lcd.c
bloba0a3bc48ae1e8d1fd3c73a8dcd99cf6aaaf76859
1 /*
2 * MediaQ 1132 LCD controller initialization for Dell Axim X5.
4 * Copyright © 2003 Andrew Zabolotny <zap@homelink.ru>
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive for
8 * more details.
9 */
11 #include <linux/module.h>
12 #include <linux/init.h>
13 #include <linux/kernel.h>
14 #include <linux/tty.h>
15 #include <linux/sched.h>
16 #include <linux/delay.h>
17 #include <linux/pm.h>
18 #include <linux/lcd.h>
19 #include <linux/fb.h>
20 #include <linux/device.h>
21 #include <linux/soc-old.h>
22 #include <linux/err.h>
24 #include <asm/arch/pxa-regs.h>
25 #include <asm/arch/aximx5-gpio.h>
26 #include "../drivers/soc/mq11xx.h"
28 #if 0
29 # define debug(s, args...) printk (KERN_INFO s, ##args)
30 #else
31 # define debug(s, args...)
32 #endif
33 #define debug_func(s, args...) debug ("%s: " s, __FUNCTION__, ##args)
35 static int aximx5_lcd_set_power (struct lcd_device *ld, int state)
37 struct mediaq11xx_base *mq_base = class_get_devdata (&ld->class_dev);
38 int lcdfp_state = mq_base->get_power (mq_base, MEDIAQ_11XX_FP_DEVICE_ID) ? 1 : 0;
39 int fpctl_state = mq_base->get_power (mq_base, MEDIAQ_11XX_FB_DEVICE_ID) ? 1 : 0;
41 int new_lcdfp_state = (state < 1) ? 1 : 0;
42 int new_fpctl_state = (state < 4) ? 1 : 0;
44 debug_func ("state:%d\n", state);
46 if (new_lcdfp_state != lcdfp_state)
47 mq_base->set_power (mq_base, MEDIAQ_11XX_FP_DEVICE_ID, new_lcdfp_state);
48 if (new_fpctl_state != fpctl_state)
49 mq_base->set_power (mq_base, MEDIAQ_11XX_FB_DEVICE_ID, new_fpctl_state);
51 if (new_lcdfp_state)
52 /* MediaQ GPIO 1 seems connected to flat-panel power */
53 mq_base->set_GPIO (mq_base, GPIO_NR_AXIMX5_MQ1132_FP_ENABLE, MQ_GPIO_OUT1);
54 else
55 /* Output '0' to MQ1132 GPIO 1 */
56 mq_base->set_GPIO (mq_base, GPIO_NR_AXIMX5_MQ1132_FP_ENABLE, MQ_GPIO_OUT0);
58 return 0;
61 static int aximx5_lcd_get_power (struct lcd_device *ld)
63 struct mediaq11xx_base *mq_base = class_get_devdata (&ld->class_dev);
64 int lcdfp_state = mq_base->get_power (mq_base, MEDIAQ_11XX_FP_DEVICE_ID);
65 int fpctl_state = mq_base->get_power (mq_base, MEDIAQ_11XX_FB_DEVICE_ID);
67 debug_func ("\n");
69 if (lcdfp_state == 0) {
70 if (fpctl_state == 0)
71 return 4;
72 else
73 return 2;
75 return 0;
78 static int
79 aximx5_lcd_set_contrast (struct lcd_device *ld, int contrast)
81 struct mediaq11xx_base *mq_base = class_get_devdata (&ld->class_dev);
82 u32 x;
84 debug_func ("contrast:%d\n", contrast);
86 /* Well... this is kind of tricky but here's how it works:
87 * On 24-bit TFT panels the R,G,B channels are output via
88 * the FD0..FD23 MQ1132' outputs. There are separate enable
89 * bits for these pins in FP07R, which we will use.
90 * Basically we just mask out (setting them to '1')
91 * the lowest 1..8 bits of every color component thus
92 * effectively reducing the number of bits for them.
94 if (contrast > 7)
95 contrast = 7;
96 contrast = 7 ^ contrast;
98 x = (1 << contrast) - 1;
100 mq_base->regs->FP.pin_output_data |= 0x00ffffff;
101 mq_base->regs->FP.pin_output_select_1 =
102 (mq_base->regs->FP.pin_output_select_1 & 0xff000000) |
103 x | (x << 8) | (x << 16);
105 return 0;
108 static int
109 aximx5_lcd_get_contrast (struct lcd_device *ld)
111 struct mediaq11xx_base *mq_base = class_get_devdata (&ld->class_dev);
112 u32 c, x;
114 debug_func ("\n");
116 x = (mq_base->regs->FP.pin_output_select_1 & 0x7f);
117 for (c = 7; x; x >>= 1, c--)
119 return c;
122 /*-------------------// Flat panel driver for SoC device //------------------*/
124 static struct lcd_properties mq11xx_fb0_lcd = {
125 .owner = THIS_MODULE,
126 .get_power = aximx5_lcd_get_power,
127 .set_power = aximx5_lcd_set_power,
128 .max_contrast = 7,
129 .get_contrast = aximx5_lcd_get_contrast,
130 .set_contrast = aximx5_lcd_set_contrast,
133 static struct lcd_device *mqfb_lcd_device;
135 static int aximx5_fp_probe (struct device *dev)
137 struct mediaq11xx_base *mq_base =
138 (struct mediaq11xx_base *)dev->platform_data;
140 mqfb_lcd_device = lcd_device_register ("mq11xx_fb0", mq_base,
141 &mq11xx_fb0_lcd);
142 if (IS_ERR (mqfb_lcd_device)) {
143 return PTR_ERR (mqfb_lcd_device);
146 return 0;
149 static int aximx5_fp_remove (struct device *dev)
151 debug_func ("\n");
153 lcd_device_unregister (mqfb_lcd_device);
155 return 0;
158 static int aximx5_fp_suspend (struct device *dev, pm_message_t state)
160 debug_func ("\n");
161 return 0;
164 static int aximx5_fp_resume (struct device *dev)
166 debug_func ("\n");
167 return 0;
170 //static platform_device_id aximx5_fp_device_ids[] = { MEDIAQ_11XX_FP_DEVICE_ID, 0 };
172 struct device_driver aximx5_fp_device_driver = {
173 .name = "mq11xx_lcd",
174 .probe = aximx5_fp_probe,
175 .remove = aximx5_fp_remove,
176 .suspend = aximx5_fp_suspend,
177 .resume = aximx5_fp_resume
180 static int __init
181 aximx5_fp_init(void)
183 debug_func ("\n");
184 return driver_register (&aximx5_fp_device_driver);
187 static void __exit
188 aximx5_fp_exit(void)
190 debug_func ("\n");
191 driver_unregister (&aximx5_fp_device_driver);
194 module_init(aximx5_fp_init);
195 module_exit(aximx5_fp_exit);
197 MODULE_AUTHOR("Andrew Zabolotny <zap@homelink.ru>");
198 MODULE_DESCRIPTION("LCD driver for Dell Axim X5");
199 MODULE_LICENSE("GPL");