Merge branch 'x86/asm' into x86/urgent
[pandora-kernel.git] / drivers / video / omap2 / displays / panel-sharp-ls037v7dw01.c
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/regulator/consumer.h>
24 #include <linux/err.h>
25
26 #include <plat/display.h>
27
28 struct sharp_data {
29         /* XXX This regulator should actually be in SDP board file, not here,
30          * as it doesn't actually power the LCD, but something else that
31          * affects the output to LCD (I think. Somebody clarify). It doesn't do
32          * harm here, as SDP is the only board using this currently */
33         struct regulator *vdvi_reg;
34 };
35
36 static struct omap_video_timings sharp_ls_timings = {
37         .x_res = 480,
38         .y_res = 640,
39
40         .pixel_clock    = 19200,
41
42         .hsw            = 2,
43         .hfp            = 1,
44         .hbp            = 28,
45
46         .vsw            = 1,
47         .vfp            = 1,
48         .vbp            = 1,
49 };
50
51 static int sharp_ls_panel_probe(struct omap_dss_device *dssdev)
52 {
53         struct sharp_data *sd;
54
55         dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
56                 OMAP_DSS_LCD_IHS;
57         dssdev->panel.acb = 0x28;
58         dssdev->panel.timings = sharp_ls_timings;
59
60         sd = kzalloc(sizeof(*sd), GFP_KERNEL);
61         if (!sd)
62                 return -ENOMEM;
63
64         dev_set_drvdata(&dssdev->dev, sd);
65
66         sd->vdvi_reg = regulator_get(&dssdev->dev, "vdvi");
67         if (IS_ERR(sd->vdvi_reg)) {
68                 kfree(sd);
69                 pr_err("failed to get VDVI regulator\n");
70                 return PTR_ERR(sd->vdvi_reg);
71         }
72
73         return 0;
74 }
75
76 static void sharp_ls_panel_remove(struct omap_dss_device *dssdev)
77 {
78         struct sharp_data *sd = dev_get_drvdata(&dssdev->dev);
79
80         regulator_put(sd->vdvi_reg);
81
82         kfree(sd);
83 }
84
85 static int sharp_ls_panel_enable(struct omap_dss_device *dssdev)
86 {
87         struct sharp_data *sd = dev_get_drvdata(&dssdev->dev);
88         int r = 0;
89
90         /* wait couple of vsyncs until enabling the LCD */
91         msleep(50);
92
93         regulator_enable(sd->vdvi_reg);
94
95         if (dssdev->platform_enable)
96                 r = dssdev->platform_enable(dssdev);
97
98         return r;
99 }
100
101 static void sharp_ls_panel_disable(struct omap_dss_device *dssdev)
102 {
103         struct sharp_data *sd = dev_get_drvdata(&dssdev->dev);
104
105         if (dssdev->platform_disable)
106                 dssdev->platform_disable(dssdev);
107
108         regulator_disable(sd->vdvi_reg);
109
110         /* wait at least 5 vsyncs after disabling the LCD */
111
112         msleep(100);
113 }
114
115 static int sharp_ls_panel_suspend(struct omap_dss_device *dssdev)
116 {
117         sharp_ls_panel_disable(dssdev);
118         return 0;
119 }
120
121 static int sharp_ls_panel_resume(struct omap_dss_device *dssdev)
122 {
123         return sharp_ls_panel_enable(dssdev);
124 }
125
126 static struct omap_dss_driver sharp_ls_driver = {
127         .probe          = sharp_ls_panel_probe,
128         .remove         = sharp_ls_panel_remove,
129
130         .enable         = sharp_ls_panel_enable,
131         .disable        = sharp_ls_panel_disable,
132         .suspend        = sharp_ls_panel_suspend,
133         .resume         = sharp_ls_panel_resume,
134
135         .driver         = {
136                 .name   = "sharp_ls_panel",
137                 .owner  = THIS_MODULE,
138         },
139 };
140
141 static int __init sharp_ls_panel_drv_init(void)
142 {
143         return omap_dss_register_driver(&sharp_ls_driver);
144 }
145
146 static void __exit sharp_ls_panel_drv_exit(void)
147 {
148         omap_dss_unregister_driver(&sharp_ls_driver);
149 }
150
151 module_init(sharp_ls_panel_drv_init);
152 module_exit(sharp_ls_panel_drv_exit);
153 MODULE_LICENSE("GPL");