aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2013-05-31 05:14:01 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2013-06-17 07:32:51 -0400
commit922ae890a993e8f5ca1ef776b4c8856d0aa7de25 (patch)
tree73cacdde707e3fe56bbb84c58336cdedaecfb4df /drivers/video/omap2
parentf92f168f8dc33c8db100fdd0c4ccfb26adedce61 (diff)
OMAPDSS: Add Sharp LS037V7DW01 panel driver
Add Sharp LS037V7DW01 panel driver which uses the new DSS device model and DSS ops. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/video/omap2')
-rw-r--r--drivers/video/omap2/displays-new/Kconfig6
-rw-r--r--drivers/video/omap2/displays-new/Makefile1
-rw-r--r--drivers/video/omap2/displays-new/panel-sharp-ls037v7dw01.c324
3 files changed, 331 insertions, 0 deletions
diff --git a/drivers/video/omap2/displays-new/Kconfig b/drivers/video/omap2/displays-new/Kconfig
index 3dd8bf947e16..917db6e7966c 100644
--- a/drivers/video/omap2/displays-new/Kconfig
+++ b/drivers/video/omap2/displays-new/Kconfig
@@ -49,4 +49,10 @@ config DISPLAY_PANEL_LGPHILIPS_LB035Q02
49 depends on SPI 49 depends on SPI
50 help 50 help
51 LCD Panel used on the Gumstix Overo Palo35 51 LCD Panel used on the Gumstix Overo Palo35
52
53config DISPLAY_PANEL_SHARP_LS037V7DW01
54 tristate "Sharp LS037V7DW01 LCD Panel"
55 depends on BACKLIGHT_CLASS_DEVICE
56 help
57 LCD Panel used in TI's SDP3430 and EVM boards
52endmenu 58endmenu
diff --git a/drivers/video/omap2/displays-new/Makefile b/drivers/video/omap2/displays-new/Makefile
index a5ec42f1d87d..dde7b8ddda0b 100644
--- a/drivers/video/omap2/displays-new/Makefile
+++ b/drivers/video/omap2/displays-new/Makefile
@@ -7,3 +7,4 @@ obj-$(CONFIG_DISPLAY_PANEL_DPI) += panel-dpi.o
7obj-$(CONFIG_DISPLAY_PANEL_DSI_CM) += panel-dsi-cm.o 7obj-$(CONFIG_DISPLAY_PANEL_DSI_CM) += panel-dsi-cm.o
8obj-$(CONFIG_DISPLAY_PANEL_SONY_ACX565AKM) += panel-sony-acx565akm.o 8obj-$(CONFIG_DISPLAY_PANEL_SONY_ACX565AKM) += panel-sony-acx565akm.o
9obj-$(CONFIG_DISPLAY_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o 9obj-$(CONFIG_DISPLAY_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o
10obj-$(CONFIG_DISPLAY_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o
diff --git a/drivers/video/omap2/displays-new/panel-sharp-ls037v7dw01.c b/drivers/video/omap2/displays-new/panel-sharp-ls037v7dw01.c
new file mode 100644
index 000000000000..72a4fb5aa6b1
--- /dev/null
+++ b/drivers/video/omap2/displays-new/panel-sharp-ls037v7dw01.c
@@ -0,0 +1,324 @@
1/*
2 * LCD panel driver for Sharp LS037V7DW01
3 *
4 * Copyright (C) 2013 Texas Instruments
5 * Author: Tomi Valkeinen <tomi.valkeinen@ti.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
12#include <linux/delay.h>
13#include <linux/gpio.h>
14#include <linux/module.h>
15#include <linux/platform_device.h>
16#include <linux/slab.h>
17
18#include <video/omapdss.h>
19#include <video/omap-panel-data.h>
20
21struct panel_drv_data {
22 struct omap_dss_device dssdev;
23 struct omap_dss_device *in;
24
25 int data_lines;
26
27 struct omap_video_timings videomode;
28
29 int resb_gpio;
30 int ini_gpio;
31 int mo_gpio;
32 int lr_gpio;
33 int ud_gpio;
34};
35
36static const 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 .vsync_level = OMAPDSS_SIG_ACTIVE_LOW,
51 .hsync_level = OMAPDSS_SIG_ACTIVE_LOW,
52 .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
53 .de_level = OMAPDSS_SIG_ACTIVE_HIGH,
54 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
55};
56
57#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
58
59static int sharp_ls_connect(struct omap_dss_device *dssdev)
60{
61 struct panel_drv_data *ddata = to_panel_data(dssdev);
62 struct omap_dss_device *in = ddata->in;
63 int r;
64
65 if (omapdss_device_is_connected(dssdev))
66 return 0;
67
68 r = in->ops.dpi->connect(in, dssdev);
69 if (r)
70 return r;
71
72 return 0;
73}
74
75static void sharp_ls_disconnect(struct omap_dss_device *dssdev)
76{
77 struct panel_drv_data *ddata = to_panel_data(dssdev);
78 struct omap_dss_device *in = ddata->in;
79
80 if (!omapdss_device_is_connected(dssdev))
81 return;
82
83 in->ops.dpi->disconnect(in, dssdev);
84}
85
86static int sharp_ls_enable(struct omap_dss_device *dssdev)
87{
88 struct panel_drv_data *ddata = to_panel_data(dssdev);
89 struct omap_dss_device *in = ddata->in;
90 int r;
91
92 if (!omapdss_device_is_connected(dssdev))
93 return -ENODEV;
94
95 if (omapdss_device_is_enabled(dssdev))
96 return 0;
97
98 in->ops.dpi->set_data_lines(in, ddata->data_lines);
99 in->ops.dpi->set_timings(in, &ddata->videomode);
100
101 r = in->ops.dpi->enable(in);
102 if (r)
103 return r;
104
105 /* wait couple of vsyncs until enabling the LCD */
106 msleep(50);
107
108 if (gpio_is_valid(ddata->resb_gpio))
109 gpio_set_value_cansleep(ddata->resb_gpio, 1);
110
111 if (gpio_is_valid(ddata->ini_gpio))
112 gpio_set_value_cansleep(ddata->ini_gpio, 1);
113
114 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
115
116 return 0;
117}
118
119static void sharp_ls_disable(struct omap_dss_device *dssdev)
120{
121 struct panel_drv_data *ddata = to_panel_data(dssdev);
122 struct omap_dss_device *in = ddata->in;
123
124 if (!omapdss_device_is_enabled(dssdev))
125 return;
126
127 if (gpio_is_valid(ddata->ini_gpio))
128 gpio_set_value_cansleep(ddata->ini_gpio, 0);
129
130 if (gpio_is_valid(ddata->resb_gpio))
131 gpio_set_value_cansleep(ddata->resb_gpio, 0);
132
133 /* wait at least 5 vsyncs after disabling the LCD */
134
135 msleep(100);
136
137 in->ops.dpi->disable(in);
138
139 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
140}
141
142static void sharp_ls_set_timings(struct omap_dss_device *dssdev,
143 struct omap_video_timings *timings)
144{
145 struct panel_drv_data *ddata = to_panel_data(dssdev);
146 struct omap_dss_device *in = ddata->in;
147
148 ddata->videomode = *timings;
149 dssdev->panel.timings = *timings;
150
151 in->ops.dpi->set_timings(in, timings);
152}
153
154static void sharp_ls_get_timings(struct omap_dss_device *dssdev,
155 struct omap_video_timings *timings)
156{
157 struct panel_drv_data *ddata = to_panel_data(dssdev);
158
159 *timings = ddata->videomode;
160}
161
162static int sharp_ls_check_timings(struct omap_dss_device *dssdev,
163 struct omap_video_timings *timings)
164{
165 struct panel_drv_data *ddata = to_panel_data(dssdev);
166 struct omap_dss_device *in = ddata->in;
167
168 return in->ops.dpi->check_timings(in, timings);
169}
170
171static struct omap_dss_driver sharp_ls_ops = {
172 .connect = sharp_ls_connect,
173 .disconnect = sharp_ls_disconnect,
174
175 .enable = sharp_ls_enable,
176 .disable = sharp_ls_disable,
177
178 .set_timings = sharp_ls_set_timings,
179 .get_timings = sharp_ls_get_timings,
180 .check_timings = sharp_ls_check_timings,
181
182 .get_resolution = omapdss_default_get_resolution,
183};
184
185static int sharp_ls_probe_pdata(struct platform_device *pdev)
186{
187 const struct panel_sharp_ls037v7dw01_platform_data *pdata;
188 struct panel_drv_data *ddata = platform_get_drvdata(pdev);
189 struct omap_dss_device *dssdev, *in;
190
191 pdata = dev_get_platdata(&pdev->dev);
192
193 in = omap_dss_find_output(pdata->source);
194 if (in == NULL) {
195 dev_err(&pdev->dev, "failed to find video source '%s'\n",
196 pdata->source);
197 return -EPROBE_DEFER;
198 }
199
200 ddata->in = in;
201
202 ddata->data_lines = pdata->data_lines;
203
204 dssdev = &ddata->dssdev;
205 dssdev->name = pdata->name;
206
207 ddata->resb_gpio = pdata->resb_gpio;
208 ddata->ini_gpio = pdata->ini_gpio;
209 ddata->mo_gpio = pdata->mo_gpio;
210 ddata->lr_gpio = pdata->lr_gpio;
211 ddata->ud_gpio = pdata->ud_gpio;
212
213 return 0;
214}
215
216static int sharp_ls_probe(struct platform_device *pdev)
217{
218 struct panel_drv_data *ddata;
219 struct omap_dss_device *dssdev;
220 int r;
221
222 ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
223 if (ddata == NULL)
224 return -ENOMEM;
225
226 platform_set_drvdata(pdev, ddata);
227
228 if (dev_get_platdata(&pdev->dev)) {
229 r = sharp_ls_probe_pdata(pdev);
230 if (r)
231 return r;
232 } else {
233 return -ENODEV;
234 }
235
236 if (gpio_is_valid(ddata->mo_gpio)) {
237 r = devm_gpio_request_one(&pdev->dev, ddata->mo_gpio,
238 GPIOF_OUT_INIT_LOW, "lcd MO");
239 if (r)
240 goto err_gpio;
241 }
242
243 if (gpio_is_valid(ddata->lr_gpio)) {
244 r = devm_gpio_request_one(&pdev->dev, ddata->lr_gpio,
245 GPIOF_OUT_INIT_HIGH, "lcd LR");
246 if (r)
247 goto err_gpio;
248 }
249
250 if (gpio_is_valid(ddata->ud_gpio)) {
251 r = devm_gpio_request_one(&pdev->dev, ddata->ud_gpio,
252 GPIOF_OUT_INIT_HIGH, "lcd UD");
253 if (r)
254 goto err_gpio;
255 }
256
257 if (gpio_is_valid(ddata->resb_gpio)) {
258 r = devm_gpio_request_one(&pdev->dev, ddata->resb_gpio,
259 GPIOF_OUT_INIT_LOW, "lcd RESB");
260 if (r)
261 goto err_gpio;
262 }
263
264 if (gpio_is_valid(ddata->ini_gpio)) {
265 r = devm_gpio_request_one(&pdev->dev, ddata->ini_gpio,
266 GPIOF_OUT_INIT_LOW, "lcd INI");
267 if (r)
268 goto err_gpio;
269 }
270
271 ddata->videomode = sharp_ls_timings;
272
273 dssdev = &ddata->dssdev;
274 dssdev->dev = &pdev->dev;
275 dssdev->driver = &sharp_ls_ops;
276 dssdev->type = OMAP_DISPLAY_TYPE_DPI;
277 dssdev->owner = THIS_MODULE;
278 dssdev->panel.timings = ddata->videomode;
279 dssdev->phy.dpi.data_lines = ddata->data_lines;
280
281 r = omapdss_register_display(dssdev);
282 if (r) {
283 dev_err(&pdev->dev, "Failed to register panel\n");
284 goto err_reg;
285 }
286
287 return 0;
288
289err_reg:
290err_gpio:
291 omap_dss_put_device(ddata->in);
292 return r;
293}
294
295static int __exit sharp_ls_remove(struct platform_device *pdev)
296{
297 struct panel_drv_data *ddata = platform_get_drvdata(pdev);
298 struct omap_dss_device *dssdev = &ddata->dssdev;
299 struct omap_dss_device *in = ddata->in;
300
301 omapdss_unregister_display(dssdev);
302
303 sharp_ls_disable(dssdev);
304 sharp_ls_disconnect(dssdev);
305
306 omap_dss_put_device(in);
307
308 return 0;
309}
310
311static struct platform_driver sharp_ls_driver = {
312 .probe = sharp_ls_probe,
313 .remove = __exit_p(sharp_ls_remove),
314 .driver = {
315 .name = "panel-sharp-ls037v7dw01",
316 .owner = THIS_MODULE,
317 },
318};
319
320module_platform_driver(sharp_ls_driver);
321
322MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>");
323MODULE_DESCRIPTION("Sharp LS037V7DW01 Panel Driver");
324MODULE_LICENSE("GPL");