diff options
-rw-r--r-- | drivers/video/backlight/Kconfig | 7 | ||||
-rw-r--r-- | drivers/video/backlight/Makefile | 1 | ||||
-rw-r--r-- | drivers/video/backlight/platform_lcd.c | 172 | ||||
-rw-r--r-- | include/video/platform_lcd.h | 21 |
4 files changed, 201 insertions, 0 deletions
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index a5b3a92ffdc1..b289e197e55d 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig | |||
@@ -53,6 +53,13 @@ config LCD_VGG2432A4 | |||
53 | If you have a VGG2432A4 panel based on the ILI9320 controller chip | 53 | If you have a VGG2432A4 panel based on the ILI9320 controller chip |
54 | then say y to include a power driver for it. | 54 | then say y to include a power driver for it. |
55 | 55 | ||
56 | config LCD_PLATFORM | ||
57 | tristate "Platform LCD controls" | ||
58 | depends on LCD_CLASS_DEVICE | ||
59 | help | ||
60 | This driver provides a platform-device registered LCD power | ||
61 | control interface. | ||
62 | |||
56 | # | 63 | # |
57 | # Backlight | 64 | # Backlight |
58 | # | 65 | # |
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index 366d84e380cf..7d31c14088aa 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile | |||
@@ -3,6 +3,7 @@ | |||
3 | obj-$(CONFIG_LCD_CLASS_DEVICE) += lcd.o | 3 | obj-$(CONFIG_LCD_CLASS_DEVICE) += lcd.o |
4 | obj-$(CONFIG_LCD_LTV350QV) += ltv350qv.o | 4 | obj-$(CONFIG_LCD_LTV350QV) += ltv350qv.o |
5 | obj-$(CONFIG_LCD_ILI9320) += ili9320.o | 5 | obj-$(CONFIG_LCD_ILI9320) += ili9320.o |
6 | obj-$(CONFIG_LCD_PLATFORM) += platform_lcd.o | ||
6 | obj-$(CONFIG_LCD_VGG2432A4) += vgg2432a4.o | 7 | obj-$(CONFIG_LCD_VGG2432A4) += vgg2432a4.o |
7 | 8 | ||
8 | obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o | 9 | obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o |
diff --git a/drivers/video/backlight/platform_lcd.c b/drivers/video/backlight/platform_lcd.c new file mode 100644 index 000000000000..72d44dbfce82 --- /dev/null +++ b/drivers/video/backlight/platform_lcd.c | |||
@@ -0,0 +1,172 @@ | |||
1 | /* drivers/video/backlight/platform_lcd.c | ||
2 | * | ||
3 | * Copyright 2008 Simtec Electronics | ||
4 | * Ben Dooks <ben@simtec.co.uk> | ||
5 | * | ||
6 | * Generic platform-device LCD power control interface. | ||
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 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/fb.h> | ||
17 | #include <linux/backlight.h> | ||
18 | #include <linux/lcd.h> | ||
19 | |||
20 | #include <video/platform_lcd.h> | ||
21 | |||
22 | struct platform_lcd { | ||
23 | struct device *us; | ||
24 | struct lcd_device *lcd; | ||
25 | struct plat_lcd_data *pdata; | ||
26 | |||
27 | unsigned int power; | ||
28 | unsigned int suspended : 1; | ||
29 | }; | ||
30 | |||
31 | static inline struct platform_lcd *to_our_lcd(struct lcd_device *lcd) | ||
32 | { | ||
33 | return lcd_get_data(lcd); | ||
34 | } | ||
35 | |||
36 | static int platform_lcd_get_power(struct lcd_device *lcd) | ||
37 | { | ||
38 | struct platform_lcd *plcd = to_our_lcd(lcd); | ||
39 | |||
40 | return plcd->power; | ||
41 | } | ||
42 | |||
43 | static int platform_lcd_set_power(struct lcd_device *lcd, int power) | ||
44 | { | ||
45 | struct platform_lcd *plcd = to_our_lcd(lcd); | ||
46 | int lcd_power = 1; | ||
47 | |||
48 | if (power == FB_BLANK_POWERDOWN || plcd->suspended) | ||
49 | lcd_power = 0; | ||
50 | |||
51 | plcd->pdata->set_power(plcd->pdata, lcd_power); | ||
52 | plcd->power = power; | ||
53 | |||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | static int platform_lcd_match(struct lcd_device *lcd, struct fb_info *info) | ||
58 | { | ||
59 | struct platform_lcd *plcd = to_our_lcd(lcd); | ||
60 | struct plat_lcd_data *pdata = plcd->pdata; | ||
61 | |||
62 | if (pdata->match_fb) | ||
63 | return pdata->match_fb(pdata, info); | ||
64 | |||
65 | return plcd->us->parent == info->device; | ||
66 | } | ||
67 | |||
68 | static struct lcd_ops platform_lcd_ops = { | ||
69 | .get_power = platform_lcd_get_power, | ||
70 | .set_power = platform_lcd_set_power, | ||
71 | .check_fb = platform_lcd_match, | ||
72 | }; | ||
73 | |||
74 | static int __devinit platform_lcd_probe(struct platform_device *pdev) | ||
75 | { | ||
76 | struct plat_lcd_data *pdata; | ||
77 | struct platform_lcd *plcd; | ||
78 | struct device *dev = &pdev->dev; | ||
79 | int err; | ||
80 | |||
81 | pdata = pdev->dev.platform_data; | ||
82 | if (!pdata) { | ||
83 | dev_err(dev, "no platform data supplied\n"); | ||
84 | return -EINVAL; | ||
85 | } | ||
86 | |||
87 | plcd = kzalloc(sizeof(struct platform_lcd), GFP_KERNEL); | ||
88 | if (!plcd) { | ||
89 | dev_err(dev, "no memory for state\n"); | ||
90 | return -ENOMEM; | ||
91 | } | ||
92 | |||
93 | plcd->us = dev; | ||
94 | plcd->pdata = pdata; | ||
95 | plcd->lcd = lcd_device_register("platform-lcd", dev, | ||
96 | plcd, &platform_lcd_ops); | ||
97 | if (IS_ERR(plcd->lcd)) { | ||
98 | dev_err(dev, "cannot register lcd device\n"); | ||
99 | err = PTR_ERR(plcd->lcd); | ||
100 | goto err_mem; | ||
101 | } | ||
102 | |||
103 | platform_set_drvdata(pdev, plcd); | ||
104 | return 0; | ||
105 | |||
106 | err_mem: | ||
107 | kfree(plcd); | ||
108 | return err; | ||
109 | } | ||
110 | |||
111 | static int __devexit platform_lcd_remove(struct platform_device *pdev) | ||
112 | { | ||
113 | struct platform_lcd *plcd = platform_get_drvdata(pdev); | ||
114 | |||
115 | lcd_device_unregister(plcd->lcd); | ||
116 | kfree(plcd); | ||
117 | |||
118 | return 0; | ||
119 | } | ||
120 | |||
121 | #ifdef CONFIG_PM | ||
122 | static int platform_lcd_suspend(struct platform_device *pdev, pm_message_t st) | ||
123 | { | ||
124 | struct platform_lcd *plcd = platform_get_drvdata(pdev); | ||
125 | |||
126 | plcd->suspended = 1; | ||
127 | platform_lcd_set_power(plcd->lcd, plcd->power); | ||
128 | |||
129 | return 0; | ||
130 | } | ||
131 | |||
132 | static int platform_lcd_resume(struct platform_device *pdev) | ||
133 | { | ||
134 | struct platform_lcd *plcd = platform_get_drvdata(pdev); | ||
135 | |||
136 | plcd->suspended = 0; | ||
137 | platform_lcd_set_power(plcd->lcd, plcd->power); | ||
138 | |||
139 | return 0; | ||
140 | } | ||
141 | #else | ||
142 | #define platform_lcd_suspend NULL | ||
143 | #define platform_lcd_resume NULL | ||
144 | #endif | ||
145 | |||
146 | static struct platform_driver platform_lcd_driver = { | ||
147 | .driver = { | ||
148 | .name = "platform-lcd", | ||
149 | .owner = THIS_MODULE, | ||
150 | }, | ||
151 | .probe = platform_lcd_probe, | ||
152 | .remove = __devexit_p(platform_lcd_remove), | ||
153 | .suspend = platform_lcd_suspend, | ||
154 | .resume = platform_lcd_resume, | ||
155 | }; | ||
156 | |||
157 | static int __init platform_lcd_init(void) | ||
158 | { | ||
159 | return platform_driver_register(&platform_lcd_driver); | ||
160 | } | ||
161 | |||
162 | static void __exit platform_lcd_cleanup(void) | ||
163 | { | ||
164 | platform_driver_unregister(&platform_lcd_driver); | ||
165 | } | ||
166 | |||
167 | module_init(platform_lcd_init); | ||
168 | module_exit(platform_lcd_cleanup); | ||
169 | |||
170 | MODULE_AUTHOR("Ben Dooks <ben-linux@fluff.org>"); | ||
171 | MODULE_LICENSE("GPL v2"); | ||
172 | MODULE_ALIAS("platform:platform-lcd"); | ||
diff --git a/include/video/platform_lcd.h b/include/video/platform_lcd.h new file mode 100644 index 000000000000..ad3bdfe743b2 --- /dev/null +++ b/include/video/platform_lcd.h | |||
@@ -0,0 +1,21 @@ | |||
1 | /* include/video/platform_lcd.h | ||
2 | * | ||
3 | * Copyright 2008 Simtec Electronics | ||
4 | * Ben Dooks <ben@simtec.co.uk> | ||
5 | * | ||
6 | * Generic platform-device LCD power control interface. | ||
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 | |||
14 | struct plat_lcd_data; | ||
15 | struct fb_info; | ||
16 | |||
17 | struct plat_lcd_data { | ||
18 | void (*set_power)(struct plat_lcd_data *, unsigned int power); | ||
19 | int (*match_fb)(struct plat_lcd_data *, struct fb_info *); | ||
20 | }; | ||
21 | |||