• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/drivers/video/omap2/displays/
1/*
2 * LCD panel driver for Sharp LS037V7DW01
3 *
4 * Copyright (C) 2008 Nokia Corporation
5 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published by
9 * the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/module.h>
21#include <linux/delay.h>
22#include <linux/device.h>
23#include <linux/backlight.h>
24#include <linux/fb.h>
25#include <linux/err.h>
26#include <linux/slab.h>
27
28#include <plat/display.h>
29
30struct sharp_data {
31	struct backlight_device *bl;
32};
33
34static struct omap_video_timings sharp_ls_timings = {
35	.x_res = 480,
36	.y_res = 640,
37
38	.pixel_clock	= 19200,
39
40	.hsw		= 2,
41	.hfp		= 1,
42	.hbp		= 28,
43
44	.vsw		= 1,
45	.vfp		= 1,
46	.vbp		= 1,
47};
48
49static int sharp_ls_bl_update_status(struct backlight_device *bl)
50{
51	struct omap_dss_device *dssdev = dev_get_drvdata(&bl->dev);
52	int level;
53
54	if (!dssdev->set_backlight)
55		return -EINVAL;
56
57	if (bl->props.fb_blank == FB_BLANK_UNBLANK &&
58			bl->props.power == FB_BLANK_UNBLANK)
59		level = bl->props.brightness;
60	else
61		level = 0;
62
63	return dssdev->set_backlight(dssdev, level);
64}
65
66static int sharp_ls_bl_get_brightness(struct backlight_device *bl)
67{
68	if (bl->props.fb_blank == FB_BLANK_UNBLANK &&
69			bl->props.power == FB_BLANK_UNBLANK)
70		return bl->props.brightness;
71
72	return 0;
73}
74
75static const struct backlight_ops sharp_ls_bl_ops = {
76	.get_brightness = sharp_ls_bl_get_brightness,
77	.update_status  = sharp_ls_bl_update_status,
78};
79
80
81
82static int sharp_ls_panel_probe(struct omap_dss_device *dssdev)
83{
84	struct backlight_properties props;
85	struct backlight_device *bl;
86	struct sharp_data *sd;
87	int r;
88
89	dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
90		OMAP_DSS_LCD_IHS;
91	dssdev->panel.acb = 0x28;
92	dssdev->panel.timings = sharp_ls_timings;
93
94	sd = kzalloc(sizeof(*sd), GFP_KERNEL);
95	if (!sd)
96		return -ENOMEM;
97
98	dev_set_drvdata(&dssdev->dev, sd);
99
100	memset(&props, 0, sizeof(struct backlight_properties));
101	props.max_brightness = dssdev->max_backlight_level;
102
103	bl = backlight_device_register("sharp-ls", &dssdev->dev, dssdev,
104			&sharp_ls_bl_ops, &props);
105	if (IS_ERR(bl)) {
106		r = PTR_ERR(bl);
107		kfree(sd);
108		return r;
109	}
110	sd->bl = bl;
111
112	bl->props.fb_blank = FB_BLANK_UNBLANK;
113	bl->props.power = FB_BLANK_UNBLANK;
114	bl->props.brightness = dssdev->max_backlight_level;
115	r = sharp_ls_bl_update_status(bl);
116	if (r < 0)
117		dev_err(&dssdev->dev, "failed to set lcd brightness\n");
118
119	return 0;
120}
121
122static void sharp_ls_panel_remove(struct omap_dss_device *dssdev)
123{
124	struct sharp_data *sd = dev_get_drvdata(&dssdev->dev);
125	struct backlight_device *bl = sd->bl;
126
127	bl->props.power = FB_BLANK_POWERDOWN;
128	sharp_ls_bl_update_status(bl);
129	backlight_device_unregister(bl);
130
131	kfree(sd);
132}
133
134static int sharp_ls_power_on(struct omap_dss_device *dssdev)
135{
136	int r = 0;
137
138	r = omapdss_dpi_display_enable(dssdev);
139	if (r)
140		goto err0;
141
142	/* wait couple of vsyncs until enabling the LCD */
143	msleep(50);
144
145	if (dssdev->platform_enable) {
146		r = dssdev->platform_enable(dssdev);
147		if (r)
148			goto err1;
149	}
150
151	return 0;
152err1:
153	omapdss_dpi_display_disable(dssdev);
154err0:
155	return r;
156}
157
158static void sharp_ls_power_off(struct omap_dss_device *dssdev)
159{
160	if (dssdev->platform_disable)
161		dssdev->platform_disable(dssdev);
162
163	/* wait at least 5 vsyncs after disabling the LCD */
164
165	msleep(100);
166
167	omapdss_dpi_display_disable(dssdev);
168}
169
170static int sharp_ls_panel_enable(struct omap_dss_device *dssdev)
171{
172	int r;
173	r = sharp_ls_power_on(dssdev);
174	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
175	return r;
176}
177
178static void sharp_ls_panel_disable(struct omap_dss_device *dssdev)
179{
180	sharp_ls_power_off(dssdev);
181	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
182}
183
184static int sharp_ls_panel_suspend(struct omap_dss_device *dssdev)
185{
186	sharp_ls_power_off(dssdev);
187	dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
188	return 0;
189}
190
191static int sharp_ls_panel_resume(struct omap_dss_device *dssdev)
192{
193	int r;
194	r = sharp_ls_power_on(dssdev);
195	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
196	return r;
197}
198
199static struct omap_dss_driver sharp_ls_driver = {
200	.probe		= sharp_ls_panel_probe,
201	.remove		= sharp_ls_panel_remove,
202
203	.enable		= sharp_ls_panel_enable,
204	.disable	= sharp_ls_panel_disable,
205	.suspend	= sharp_ls_panel_suspend,
206	.resume		= sharp_ls_panel_resume,
207
208	.driver         = {
209		.name   = "sharp_ls_panel",
210		.owner  = THIS_MODULE,
211	},
212};
213
214static int __init sharp_ls_panel_drv_init(void)
215{
216	return omap_dss_register_driver(&sharp_ls_driver);
217}
218
219static void __exit sharp_ls_panel_drv_exit(void)
220{
221	omap_dss_unregister_driver(&sharp_ls_driver);
222}
223
224module_init(sharp_ls_panel_drv_init);
225module_exit(sharp_ls_panel_drv_exit);
226MODULE_LICENSE("GPL");
227