aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Purdie <rpurdie@rpsys.net>2006-06-26 03:26:27 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-26 12:58:28 -0400
commite4423781850025726b6c4e24ba3d93c7ff9cd826 (patch)
treea154cdf7a39e0554177cd096758f28efcc24c1e1
parentf8020dc560fde089becc05de1d0ada1f7f46dc51 (diff)
[PATCH] backlight: LOCOMO Backlight Driver updates
Add backlight intensity control to the LOCOMO lcd/backlight driver using the backlight class and add basic power management support. This is a reimplementation and improvement of patches by John Lenz and Pavel Machek Signed-off-by: Richard Purdie <rpurdie@rpsys.net> Signed-off-by: Antonino Daplas <adaplas@pol.net> Cc: Pavel Machek <pavel@ucw.cz> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--arch/arm/common/locomo.c45
-rw-r--r--drivers/video/backlight/Kconfig8
-rw-r--r--drivers/video/backlight/Makefile2
-rw-r--r--drivers/video/backlight/locomolcd.c123
-rw-r--r--include/asm-arm/hardware/locomo.h5
5 files changed, 146 insertions, 37 deletions
diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c
index a7dc1370695b..0dafba3a701d 100644
--- a/arch/arm/common/locomo.c
+++ b/arch/arm/common/locomo.c
@@ -629,21 +629,6 @@ static int locomo_resume(struct platform_device *dev)
629#endif 629#endif
630 630
631 631
632#define LCM_ALC_EN 0x8000
633
634void frontlight_set(struct locomo *lchip, int duty, int vr, int bpwf)
635{
636 unsigned long flags;
637
638 spin_lock_irqsave(&lchip->lock, flags);
639 locomo_writel(bpwf, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS);
640 udelay(100);
641 locomo_writel(duty, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALD);
642 locomo_writel(bpwf | LCM_ALC_EN, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS);
643 spin_unlock_irqrestore(&lchip->lock, flags);
644}
645
646
647/** 632/**
648 * locomo_probe - probe for a single LoCoMo chip. 633 * locomo_probe - probe for a single LoCoMo chip.
649 * @phys_addr: physical address of device. 634 * @phys_addr: physical address of device.
@@ -698,14 +683,10 @@ __locomo_probe(struct device *me, struct resource *mem, int irq)
698 , lchip->base + LOCOMO_GPD); 683 , lchip->base + LOCOMO_GPD);
699 locomo_writel(0, lchip->base + LOCOMO_GIE); 684 locomo_writel(0, lchip->base + LOCOMO_GIE);
700 685
701 /* FrontLight */ 686 /* Frontlight */
702 locomo_writel(0, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS); 687 locomo_writel(0, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS);
703 locomo_writel(0, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALD); 688 locomo_writel(0, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALD);
704 689
705 /* Same constants can be used for collie and poodle
706 (depending on CONFIG options in original sharp code)? */
707 frontlight_set(lchip, 163, 0, 148);
708
709 /* Longtime timer */ 690 /* Longtime timer */
710 locomo_writel(0, lchip->base + LOCOMO_LTINT); 691 locomo_writel(0, lchip->base + LOCOMO_LTINT);
711 /* SPI */ 692 /* SPI */
@@ -1063,6 +1044,30 @@ void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int
1063} 1044}
1064 1045
1065/* 1046/*
1047 * Frontlight control
1048 */
1049
1050static struct locomo *locomo_chip_driver(struct locomo_dev *ldev);
1051
1052void locomo_frontlight_set(struct locomo_dev *dev, int duty, int vr, int bpwf)
1053{
1054 unsigned long flags;
1055 struct locomo *lchip = locomo_chip_driver(dev);
1056
1057 if (vr)
1058 locomo_gpio_write(dev, LOCOMO_GPIO_FL_VR, 1);
1059 else
1060 locomo_gpio_write(dev, LOCOMO_GPIO_FL_VR, 0);
1061
1062 spin_lock_irqsave(&lchip->lock, flags);
1063 locomo_writel(bpwf, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS);
1064 udelay(100);
1065 locomo_writel(duty, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALD);
1066 locomo_writel(bpwf | LOCOMO_ALC_EN, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS);
1067 spin_unlock_irqrestore(&lchip->lock, flags);
1068}
1069
1070/*
1066 * LoCoMo "Register Access Bus." 1071 * LoCoMo "Register Access Bus."
1067 * 1072 *
1068 * We model this as a regular bus type, and hang devices directly 1073 * We model this as a regular bus type, and hang devices directly
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index b895eaaa73fd..02f15297a021 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -50,6 +50,14 @@ config BACKLIGHT_CORGI
50 If you have a Sharp Zaurus SL-C7xx, SL-Cxx00 or SL-6000x say y to enable the 50 If you have a Sharp Zaurus SL-C7xx, SL-Cxx00 or SL-6000x say y to enable the
51 backlight driver. 51 backlight driver.
52 52
53config BACKLIGHT_LOCOMO
54 tristate "Sharp LOCOMO LCD/Backlight Driver"
55 depends on BACKLIGHT_DEVICE && SHARP_LOCOMO
56 default y
57 help
58 If you have a Sharp Zaurus SL-5500 (Collie) or SL-5600 (Poodle) say y to
59 enable the LCD/backlight driver.
60
53config BACKLIGHT_HP680 61config BACKLIGHT_HP680
54 tristate "HP Jornada 680 Backlight Driver" 62 tristate "HP Jornada 680 Backlight Driver"
55 depends on BACKLIGHT_DEVICE && SH_HP6XX 63 depends on BACKLIGHT_DEVICE && SH_HP6XX
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 744210c38e74..65e5553fc849 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -4,4 +4,4 @@ obj-$(CONFIG_LCD_CLASS_DEVICE) += lcd.o
4obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o 4obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o
5obj-$(CONFIG_BACKLIGHT_CORGI) += corgi_bl.o 5obj-$(CONFIG_BACKLIGHT_CORGI) += corgi_bl.o
6obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o 6obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o
7obj-$(CONFIG_SHARP_LOCOMO) += locomolcd.o 7obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o
diff --git a/drivers/video/backlight/locomolcd.c b/drivers/video/backlight/locomolcd.c
index 60831bb23685..bd879b7ec119 100644
--- a/drivers/video/backlight/locomolcd.c
+++ b/drivers/video/backlight/locomolcd.c
@@ -17,6 +17,8 @@
17#include <linux/delay.h> 17#include <linux/delay.h>
18#include <linux/device.h> 18#include <linux/device.h>
19#include <linux/interrupt.h> 19#include <linux/interrupt.h>
20#include <linux/fb.h>
21#include <linux/backlight.h>
20 22
21#include <asm/hardware/locomo.h> 23#include <asm/hardware/locomo.h>
22#include <asm/irq.h> 24#include <asm/irq.h>
@@ -25,7 +27,10 @@
25 27
26#include "../../../arch/arm/mach-sa1100/generic.h" 28#include "../../../arch/arm/mach-sa1100/generic.h"
27 29
30static struct backlight_device *locomolcd_bl_device;
28static struct locomo_dev *locomolcd_dev; 31static struct locomo_dev *locomolcd_dev;
32static unsigned long locomolcd_flags;
33#define LOCOMOLCD_SUSPENDED 0x01
29 34
30static void locomolcd_on(int comadj) 35static void locomolcd_on(int comadj)
31{ 36{
@@ -89,12 +94,10 @@ void locomolcd_power(int on)
89 } 94 }
90 95
91 /* read comadj */ 96 /* read comadj */
92 if (comadj == -1) { 97 if (comadj == -1 && machine_is_collie())
93 if (machine_is_poodle()) 98 comadj = 128;
94 comadj = 118; 99 if (comadj == -1 && machine_is_poodle())
95 if (machine_is_collie()) 100 comadj = 118;
96 comadj = 128;
97 }
98 101
99 if (on) 102 if (on)
100 locomolcd_on(comadj); 103 locomolcd_on(comadj);
@@ -105,26 +108,100 @@ void locomolcd_power(int on)
105} 108}
106EXPORT_SYMBOL(locomolcd_power); 109EXPORT_SYMBOL(locomolcd_power);
107 110
108static int poodle_lcd_probe(struct locomo_dev *dev) 111
112static int current_intensity;
113
114static int locomolcd_set_intensity(struct backlight_device *bd)
115{
116 int intensity = bd->props->brightness;
117
118 if (bd->props->power != FB_BLANK_UNBLANK)
119 intensity = 0;
120 if (bd->props->fb_blank != FB_BLANK_UNBLANK)
121 intensity = 0;
122 if (locomolcd_flags & LOCOMOLCD_SUSPENDED)
123 intensity = 0;
124
125 switch (intensity) {
126 /* AC and non-AC are handled differently, but produce same results in sharp code? */
127 case 0: locomo_frontlight_set(locomolcd_dev, 0, 0, 161); break;
128 case 1: locomo_frontlight_set(locomolcd_dev, 117, 0, 161); break;
129 case 2: locomo_frontlight_set(locomolcd_dev, 163, 0, 148); break;
130 case 3: locomo_frontlight_set(locomolcd_dev, 194, 0, 161); break;
131 case 4: locomo_frontlight_set(locomolcd_dev, 194, 1, 161); break;
132
133 default:
134 return -ENODEV;
135 }
136 current_intensity = intensity;
137 return 0;
138}
139
140static int locomolcd_get_intensity(struct backlight_device *bd)
141{
142 return current_intensity;
143}
144
145static struct backlight_properties locomobl_data = {
146 .owner = THIS_MODULE,
147 .get_brightness = locomolcd_get_intensity,
148 .update_status = locomolcd_set_intensity,
149 .max_brightness = 4,
150};
151
152#ifdef CONFIG_PM
153static int locomolcd_suspend(struct locomo_dev *dev, pm_message_t state)
154{
155 locomolcd_flags |= LOCOMOLCD_SUSPENDED;
156 locomolcd_set_intensity(locomolcd_bl_device);
157 return 0;
158}
159
160static int locomolcd_resume(struct locomo_dev *dev)
161{
162 locomolcd_flags &= ~LOCOMOLCD_SUSPENDED;
163 locomolcd_set_intensity(locomolcd_bl_device);
164 return 0;
165}
166#else
167#define locomolcd_suspend NULL
168#define locomolcd_resume NULL
169#endif
170
171static int locomolcd_probe(struct locomo_dev *dev)
109{ 172{
110 unsigned long flags; 173 unsigned long flags;
111 174
112 local_irq_save(flags); 175 local_irq_save(flags);
113 locomolcd_dev = dev; 176 locomolcd_dev = dev;
114 177
178 locomo_gpio_set_dir(dev, LOCOMO_GPIO_FL_VR, 0);
179
115 /* the poodle_lcd_power function is called for the first time 180 /* the poodle_lcd_power function is called for the first time
116 * from fs_initcall, which is before locomo is activated. 181 * from fs_initcall, which is before locomo is activated.
117 * We need to recall poodle_lcd_power here*/ 182 * We need to recall poodle_lcd_power here*/
118#ifdef CONFIG_MACH_POODLE 183 if (machine_is_poodle())
119 locomolcd_power(1); 184 locomolcd_power(1);
120#endif 185
121 local_irq_restore(flags); 186 local_irq_restore(flags);
187
188 locomolcd_bl_device = backlight_device_register("locomo-bl", NULL, &locomobl_data);
189
190 if (IS_ERR (locomolcd_bl_device))
191 return PTR_ERR (locomolcd_bl_device);
192
193 /* Set up frontlight so that screen is readable */
194 locomobl_data.brightness = 2;
195 locomolcd_set_intensity(locomolcd_bl_device);
196
122 return 0; 197 return 0;
123} 198}
124 199
125static int poodle_lcd_remove(struct locomo_dev *dev) 200static int locomolcd_remove(struct locomo_dev *dev)
126{ 201{
127 unsigned long flags; 202 unsigned long flags;
203
204 backlight_device_unregister(locomolcd_bl_device);
128 local_irq_save(flags); 205 local_irq_save(flags);
129 locomolcd_dev = NULL; 206 locomolcd_dev = NULL;
130 local_irq_restore(flags); 207 local_irq_restore(flags);
@@ -136,19 +213,33 @@ static struct locomo_driver poodle_lcd_driver = {
136 .name = "locomo-backlight", 213 .name = "locomo-backlight",
137 }, 214 },
138 .devid = LOCOMO_DEVID_BACKLIGHT, 215 .devid = LOCOMO_DEVID_BACKLIGHT,
139 .probe = poodle_lcd_probe, 216 .probe = locomolcd_probe,
140 .remove = poodle_lcd_remove, 217 .remove = locomolcd_remove,
218 .suspend = locomolcd_suspend,
219 .resume = locomolcd_resume,
141}; 220};
142 221
143static int __init poodle_lcd_init(void) 222
223static int __init locomolcd_init(void)
144{ 224{
145 int ret = locomo_driver_register(&poodle_lcd_driver); 225 int ret = locomo_driver_register(&poodle_lcd_driver);
146 if (ret) return ret; 226 if (ret)
227 return ret;
147 228
148#ifdef CONFIG_SA1100_COLLIE 229#ifdef CONFIG_SA1100_COLLIE
149 sa1100fb_lcd_power = locomolcd_power; 230 sa1100fb_lcd_power = locomolcd_power;
150#endif 231#endif
151 return 0; 232 return 0;
152} 233}
153device_initcall(poodle_lcd_init);
154 234
235static void __exit locomolcd_exit(void)
236{
237 locomo_driver_unregister(&poodle_lcd_driver);
238}
239
240module_init(locomolcd_init);
241module_exit(locomolcd_exit);
242
243MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>, Pavel Machek <pavel@suse.cz>");
244MODULE_DESCRIPTION("Collie LCD driver");
245MODULE_LICENSE("GPL");
diff --git a/include/asm-arm/hardware/locomo.h b/include/asm-arm/hardware/locomo.h
index 5f10048ec54e..22dfb1737768 100644
--- a/include/asm-arm/hardware/locomo.h
+++ b/include/asm-arm/hardware/locomo.h
@@ -111,6 +111,8 @@
111#define LOCOMO_ALS 0x00 /* Adjust light cycle */ 111#define LOCOMO_ALS 0x00 /* Adjust light cycle */
112#define LOCOMO_ALD 0x04 /* Adjust light duty */ 112#define LOCOMO_ALD 0x04 /* Adjust light duty */
113 113
114#define LOCOMO_ALC_EN 0x8000
115
114/* Backlight controller: TFT signal */ 116/* Backlight controller: TFT signal */
115#define LOCOMO_BACKLIGHT 0x38 117#define LOCOMO_BACKLIGHT 0x38
116#define LOCOMO_TC 0x00 /* TFT control signal */ 118#define LOCOMO_TC 0x00 /* TFT control signal */
@@ -203,4 +205,7 @@ void locomo_gpio_write(struct locomo_dev *ldev, unsigned int bits, unsigned int
203/* M62332 control function */ 205/* M62332 control function */
204void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int channel); 206void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int channel);
205 207
208/* Frontlight control */
209void locomo_frontlight_set(struct locomo_dev *dev, int duty, int vr, int bpwf);
210
206#endif 211#endif