aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2008-07-14 16:28:25 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2008-07-14 18:34:46 -0400
commit53ffe3b440aa85af6fc4eda09b2d44bcdd312d4d (patch)
treee3ee2f392c5f73c855367cee998fc2e5774fa267 /drivers/video
parentf0006314d37639714da9658cf4ff3f1f9f420764 (diff)
parentcabb352a6455c3550f157909196845f533b0f374 (diff)
[ARM] Merge most of the PXA work for initial merge
This includes PXA work up to the SPI changes for the initial merge, since e172274ccc55d20536fbdceb6131f38e288541e0 depends on the SPI tree being merged. Conflicts: arch/arm/configs/em_x270_defconfig arch/arm/configs/xm_x270_defconfig
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/backlight/Kconfig7
-rw-r--r--drivers/video/backlight/Makefile1
-rw-r--r--drivers/video/backlight/pwm_bl.c185
-rw-r--r--drivers/video/pxafb.c44
4 files changed, 237 insertions, 0 deletions
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index dcd8073c2369..30bf7f2f1635 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -112,3 +112,10 @@ config BACKLIGHT_CARILLO_RANCH
112 help 112 help
113 If you have a Intel LE80578 (Carillo Ranch) say Y to enable the 113 If you have a Intel LE80578 (Carillo Ranch) say Y to enable the
114 backlight driver. 114 backlight driver.
115
116config BACKLIGHT_PWM
117 tristate "Generic PWM based Backlight Driver"
118 depends on BACKLIGHT_CLASS_DEVICE && HAVE_PWM
119 help
120 If you have a LCD backlight adjustable by PWM, say Y to enable
121 this driver.
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 33f6c7cecc73..b51a7cd12500 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -10,3 +10,4 @@ obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o
10obj-$(CONFIG_BACKLIGHT_OMAP1) += omap1_bl.o 10obj-$(CONFIG_BACKLIGHT_OMAP1) += omap1_bl.o
11obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o 11obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o
12obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o 12obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o
13obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
new file mode 100644
index 000000000000..6338d0e2fe07
--- /dev/null
+++ b/drivers/video/backlight/pwm_bl.c
@@ -0,0 +1,185 @@
1/*
2 * linux/drivers/video/backlight/pwm_bl.c
3 *
4 * simple PWM based backlight control, board code has to setup
5 * 1) pin configuration so PWM waveforms can output
6 * 2) platform_data casts to the PWM id (0/1/2/3 on PXA)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/platform_device.h>
17#include <linux/fb.h>
18#include <linux/backlight.h>
19#include <linux/err.h>
20#include <linux/pwm.h>
21#include <linux/pwm_backlight.h>
22
23struct pwm_bl_data {
24 struct pwm_device *pwm;
25 unsigned int period;
26 int (*notify)(int brightness);
27};
28
29static int pwm_backlight_update_status(struct backlight_device *bl)
30{
31 struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev);
32 int brightness = bl->props.brightness;
33 int max = bl->props.max_brightness;
34
35 if (bl->props.power != FB_BLANK_UNBLANK)
36 brightness = 0;
37
38 if (bl->props.fb_blank != FB_BLANK_UNBLANK)
39 brightness = 0;
40
41 if (pb->notify)
42 brightness = pb->notify(brightness);
43
44 if (brightness == 0) {
45 pwm_config(pb->pwm, 0, pb->period);
46 pwm_disable(pb->pwm);
47 } else {
48 pwm_config(pb->pwm, brightness * pb->period / max, pb->period);
49 pwm_enable(pb->pwm);
50 }
51 return 0;
52}
53
54static int pwm_backlight_get_brightness(struct backlight_device *bl)
55{
56 return bl->props.brightness;
57}
58
59static struct backlight_ops pwm_backlight_ops = {
60 .update_status = pwm_backlight_update_status,
61 .get_brightness = pwm_backlight_get_brightness,
62};
63
64static int pwm_backlight_probe(struct platform_device *pdev)
65{
66 struct platform_pwm_backlight_data *data = pdev->dev.platform_data;
67 struct backlight_device *bl;
68 struct pwm_bl_data *pb;
69 int ret;
70
71 if (!data)
72 return -EINVAL;
73
74 if (data->init) {
75 ret = data->init(&pdev->dev);
76 if (ret < 0)
77 return ret;
78 }
79
80 pb = kzalloc(sizeof(*pb), GFP_KERNEL);
81 if (!pb) {
82 ret = -ENOMEM;
83 goto err_alloc;
84 }
85
86 pb->period = data->pwm_period_ns;
87 pb->notify = data->notify;
88
89 pb->pwm = pwm_request(data->pwm_id, "backlight");
90 if (IS_ERR(pb->pwm)) {
91 dev_err(&pdev->dev, "unable to request PWM for backlight\n");
92 ret = PTR_ERR(pb->pwm);
93 goto err_pwm;
94 }
95
96 bl = backlight_device_register(pdev->name, &pdev->dev,
97 pb, &pwm_backlight_ops);
98 if (IS_ERR(bl)) {
99 dev_err(&pdev->dev, "failed to register backlight\n");
100 ret = PTR_ERR(bl);
101 goto err_bl;
102 }
103
104 bl->props.max_brightness = data->max_brightness;
105 bl->props.brightness = data->dft_brightness;
106 backlight_update_status(bl);
107
108 platform_set_drvdata(pdev, bl);
109 return 0;
110
111err_bl:
112 pwm_free(pb->pwm);
113err_pwm:
114 kfree(pb);
115err_alloc:
116 if (data->exit)
117 data->exit(&pdev->dev);
118 return ret;
119}
120
121static int pwm_backlight_remove(struct platform_device *pdev)
122{
123 struct platform_pwm_backlight_data *data = pdev->dev.platform_data;
124 struct backlight_device *bl = platform_get_drvdata(pdev);
125 struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev);
126
127 backlight_device_unregister(bl);
128 pwm_config(pb->pwm, 0, pb->period);
129 pwm_disable(pb->pwm);
130 pwm_free(pb->pwm);
131 kfree(pb);
132 if (data->exit)
133 data->exit(&pdev->dev);
134 return 0;
135}
136
137#ifdef CONFIG_PM
138static int pwm_backlight_suspend(struct platform_device *pdev,
139 pm_message_t state)
140{
141 struct backlight_device *bl = platform_get_drvdata(pdev);
142 struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev);
143
144 pwm_config(pb->pwm, 0, pb->period);
145 pwm_disable(pb->pwm);
146 return 0;
147}
148
149static int pwm_backlight_resume(struct platform_device *pdev)
150{
151 struct backlight_device *bl = platform_get_drvdata(pdev);
152
153 backlight_update_status(bl);
154 return 0;
155}
156#else
157#define pwm_backlight_suspend NULL
158#define pwm_backlight_resume NULL
159#endif
160
161static struct platform_driver pwm_backlight_driver = {
162 .driver = {
163 .name = "pwm-backlight",
164 .owner = THIS_MODULE,
165 },
166 .probe = pwm_backlight_probe,
167 .remove = pwm_backlight_remove,
168 .suspend = pwm_backlight_suspend,
169 .resume = pwm_backlight_resume,
170};
171
172static int __init pwm_backlight_init(void)
173{
174 return platform_driver_register(&pwm_backlight_driver);
175}
176module_init(pwm_backlight_init);
177
178static void __exit pwm_backlight_exit(void)
179{
180 platform_driver_unregister(&pwm_backlight_driver);
181}
182module_exit(pwm_backlight_exit);
183
184MODULE_DESCRIPTION("PWM based Backlight Driver");
185MODULE_LICENSE("GPL");
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index fafe7db20d6d..d0746261c957 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -1792,11 +1792,49 @@ failed:
1792 return ret; 1792 return ret;
1793} 1793}
1794 1794
1795static int __devexit pxafb_remove(struct platform_device *dev)
1796{
1797 struct pxafb_info *fbi = platform_get_drvdata(dev);
1798 struct resource *r;
1799 int irq;
1800 struct fb_info *info;
1801
1802 if (!fbi)
1803 return 0;
1804
1805 info = &fbi->fb;
1806
1807 unregister_framebuffer(info);
1808
1809 pxafb_disable_controller(fbi);
1810
1811 if (fbi->fb.cmap.len)
1812 fb_dealloc_cmap(&fbi->fb.cmap);
1813
1814 irq = platform_get_irq(dev, 0);
1815 free_irq(irq, fbi);
1816
1817 dma_free_writecombine(&dev->dev, fbi->map_size,
1818 fbi->map_cpu, fbi->map_dma);
1819
1820 iounmap(fbi->mmio_base);
1821
1822 r = platform_get_resource(dev, IORESOURCE_MEM, 0);
1823 release_mem_region(r->start, r->end - r->start + 1);
1824
1825 clk_put(fbi->clk);
1826 kfree(fbi);
1827
1828 return 0;
1829}
1830
1795static struct platform_driver pxafb_driver = { 1831static struct platform_driver pxafb_driver = {
1796 .probe = pxafb_probe, 1832 .probe = pxafb_probe,
1833 .remove = pxafb_remove,
1797 .suspend = pxafb_suspend, 1834 .suspend = pxafb_suspend,
1798 .resume = pxafb_resume, 1835 .resume = pxafb_resume,
1799 .driver = { 1836 .driver = {
1837 .owner = THIS_MODULE,
1800 .name = "pxa2xx-fb", 1838 .name = "pxa2xx-fb",
1801 }, 1839 },
1802}; 1840};
@@ -1809,7 +1847,13 @@ static int __init pxafb_init(void)
1809 return platform_driver_register(&pxafb_driver); 1847 return platform_driver_register(&pxafb_driver);
1810} 1848}
1811 1849
1850static void __exit pxafb_exit(void)
1851{
1852 platform_driver_unregister(&pxafb_driver);
1853}
1854
1812module_init(pxafb_init); 1855module_init(pxafb_init);
1856module_exit(pxafb_exit);
1813 1857
1814MODULE_DESCRIPTION("loadable framebuffer driver for PXA"); 1858MODULE_DESCRIPTION("loadable framebuffer driver for PXA");
1815MODULE_LICENSE("GPL"); 1859MODULE_LICENSE("GPL");