diff options
author | Richard Purdie <rpurdie@rpsys.net> | 2006-06-26 03:26:27 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-26 12:58:28 -0400 |
commit | e4423781850025726b6c4e24ba3d93c7ff9cd826 (patch) | |
tree | a154cdf7a39e0554177cd096758f28efcc24c1e1 | |
parent | f8020dc560fde089becc05de1d0ada1f7f46dc51 (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.c | 45 | ||||
-rw-r--r-- | drivers/video/backlight/Kconfig | 8 | ||||
-rw-r--r-- | drivers/video/backlight/Makefile | 2 | ||||
-rw-r--r-- | drivers/video/backlight/locomolcd.c | 123 | ||||
-rw-r--r-- | include/asm-arm/hardware/locomo.h | 5 |
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 | |||
634 | void 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 | |||
1050 | static struct locomo *locomo_chip_driver(struct locomo_dev *ldev); | ||
1051 | |||
1052 | void 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 | ||
53 | config 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 | |||
53 | config BACKLIGHT_HP680 | 61 | config 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 | |||
4 | obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o | 4 | obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o |
5 | obj-$(CONFIG_BACKLIGHT_CORGI) += corgi_bl.o | 5 | obj-$(CONFIG_BACKLIGHT_CORGI) += corgi_bl.o |
6 | obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o | 6 | obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o |
7 | obj-$(CONFIG_SHARP_LOCOMO) += locomolcd.o | 7 | obj-$(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 | ||
30 | static struct backlight_device *locomolcd_bl_device; | ||
28 | static struct locomo_dev *locomolcd_dev; | 31 | static struct locomo_dev *locomolcd_dev; |
32 | static unsigned long locomolcd_flags; | ||
33 | #define LOCOMOLCD_SUSPENDED 0x01 | ||
29 | 34 | ||
30 | static void locomolcd_on(int comadj) | 35 | static 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 | } |
106 | EXPORT_SYMBOL(locomolcd_power); | 109 | EXPORT_SYMBOL(locomolcd_power); |
107 | 110 | ||
108 | static int poodle_lcd_probe(struct locomo_dev *dev) | 111 | |
112 | static int current_intensity; | ||
113 | |||
114 | static 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 | |||
140 | static int locomolcd_get_intensity(struct backlight_device *bd) | ||
141 | { | ||
142 | return current_intensity; | ||
143 | } | ||
144 | |||
145 | static 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 | ||
153 | static 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 | |||
160 | static 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 | |||
171 | static 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 | ||
125 | static int poodle_lcd_remove(struct locomo_dev *dev) | 200 | static 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 | ||
143 | static int __init poodle_lcd_init(void) | 222 | |
223 | static 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 | } |
153 | device_initcall(poodle_lcd_init); | ||
154 | 234 | ||
235 | static void __exit locomolcd_exit(void) | ||
236 | { | ||
237 | locomo_driver_unregister(&poodle_lcd_driver); | ||
238 | } | ||
239 | |||
240 | module_init(locomolcd_init); | ||
241 | module_exit(locomolcd_exit); | ||
242 | |||
243 | MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>, Pavel Machek <pavel@suse.cz>"); | ||
244 | MODULE_DESCRIPTION("Collie LCD driver"); | ||
245 | MODULE_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 */ |
204 | void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int channel); | 206 | void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int channel); |
205 | 207 | ||
208 | /* Frontlight control */ | ||
209 | void locomo_frontlight_set(struct locomo_dev *dev, int duty, int vr, int bpwf); | ||
210 | |||
206 | #endif | 211 | #endif |