aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c102
1 files changed, 99 insertions, 3 deletions
diff --git a/drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c b/drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c
index 015d49300f2f..f1f72ce50a17 100644
--- a/drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c
@@ -12,15 +12,18 @@
12#include <linux/delay.h> 12#include <linux/delay.h>
13#include <linux/gpio.h> 13#include <linux/gpio.h>
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/of.h>
16#include <linux/of_gpio.h>
15#include <linux/platform_device.h> 17#include <linux/platform_device.h>
16#include <linux/slab.h> 18#include <linux/slab.h>
17 19#include <linux/regulator/consumer.h>
18#include <video/omapdss.h> 20#include <video/omapdss.h>
19#include <video/omap-panel-data.h> 21#include <video/omap-panel-data.h>
20 22
21struct panel_drv_data { 23struct panel_drv_data {
22 struct omap_dss_device dssdev; 24 struct omap_dss_device dssdev;
23 struct omap_dss_device *in; 25 struct omap_dss_device *in;
26 struct regulator *vcc;
24 27
25 int data_lines; 28 int data_lines;
26 29
@@ -95,12 +98,21 @@ static int sharp_ls_enable(struct omap_dss_device *dssdev)
95 if (omapdss_device_is_enabled(dssdev)) 98 if (omapdss_device_is_enabled(dssdev))
96 return 0; 99 return 0;
97 100
98 in->ops.dpi->set_data_lines(in, ddata->data_lines); 101 if (ddata->data_lines)
102 in->ops.dpi->set_data_lines(in, ddata->data_lines);
99 in->ops.dpi->set_timings(in, &ddata->videomode); 103 in->ops.dpi->set_timings(in, &ddata->videomode);
100 104
105 if (ddata->vcc) {
106 r = regulator_enable(ddata->vcc);
107 if (r != 0)
108 return r;
109 }
110
101 r = in->ops.dpi->enable(in); 111 r = in->ops.dpi->enable(in);
102 if (r) 112 if (r) {
113 regulator_disable(ddata->vcc);
103 return r; 114 return r;
115 }
104 116
105 /* wait couple of vsyncs until enabling the LCD */ 117 /* wait couple of vsyncs until enabling the LCD */
106 msleep(50); 118 msleep(50);
@@ -136,6 +148,9 @@ static void sharp_ls_disable(struct omap_dss_device *dssdev)
136 148
137 in->ops.dpi->disable(in); 149 in->ops.dpi->disable(in);
138 150
151 if (ddata->vcc)
152 regulator_disable(ddata->vcc);
153
139 dssdev->state = OMAP_DSS_DISPLAY_DISABLED; 154 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
140} 155}
141 156
@@ -249,6 +264,75 @@ static int sharp_ls_probe_pdata(struct platform_device *pdev)
249 return 0; 264 return 0;
250} 265}
251 266
267static int sharp_ls_get_gpio_of(struct device *dev, int index, int val,
268 const char *desc, struct gpio_desc **gpiod)
269{
270 struct gpio_desc *gd;
271 int r;
272
273 *gpiod = NULL;
274
275 gd = devm_gpiod_get_index(dev, desc, index);
276 if (IS_ERR(gd))
277 return PTR_ERR(gd) == -ENOENT ? 0 : PTR_ERR(gd);
278
279 r = gpiod_direction_output(gd, val);
280 if (r)
281 return r;
282
283 *gpiod = gd;
284 return 0;
285}
286
287static int sharp_ls_probe_of(struct platform_device *pdev)
288{
289 struct panel_drv_data *ddata = platform_get_drvdata(pdev);
290 struct device_node *node = pdev->dev.of_node;
291 struct omap_dss_device *in;
292 int r;
293
294 ddata->vcc = devm_regulator_get(&pdev->dev, "envdd");
295 if (IS_ERR(ddata->vcc)) {
296 dev_err(&pdev->dev, "failed to get regulator\n");
297 return PTR_ERR(ddata->vcc);
298 }
299
300 /* lcd INI */
301 r = sharp_ls_get_gpio_of(&pdev->dev, 0, 0, "enable", &ddata->ini_gpio);
302 if (r)
303 return r;
304
305 /* lcd RESB */
306 r = sharp_ls_get_gpio_of(&pdev->dev, 0, 0, "reset", &ddata->resb_gpio);
307 if (r)
308 return r;
309
310 /* lcd MO */
311 r = sharp_ls_get_gpio_of(&pdev->dev, 0, 0, "mode", &ddata->mo_gpio);
312 if (r)
313 return r;
314
315 /* lcd LR */
316 r = sharp_ls_get_gpio_of(&pdev->dev, 1, 1, "mode", &ddata->lr_gpio);
317 if (r)
318 return r;
319
320 /* lcd UD */
321 r = sharp_ls_get_gpio_of(&pdev->dev, 2, 1, "mode", &ddata->ud_gpio);
322 if (r)
323 return r;
324
325 in = omapdss_of_find_source_for_first_ep(node);
326 if (IS_ERR(in)) {
327 dev_err(&pdev->dev, "failed to find video source\n");
328 return PTR_ERR(in);
329 }
330
331 ddata->in = in;
332
333 return 0;
334}
335
252static int sharp_ls_probe(struct platform_device *pdev) 336static int sharp_ls_probe(struct platform_device *pdev)
253{ 337{
254 struct panel_drv_data *ddata; 338 struct panel_drv_data *ddata;
@@ -265,6 +349,10 @@ static int sharp_ls_probe(struct platform_device *pdev)
265 r = sharp_ls_probe_pdata(pdev); 349 r = sharp_ls_probe_pdata(pdev);
266 if (r) 350 if (r)
267 return r; 351 return r;
352 } else if (pdev->dev.of_node) {
353 r = sharp_ls_probe_of(pdev);
354 if (r)
355 return r;
268 } else { 356 } else {
269 return -ENODEV; 357 return -ENODEV;
270 } 358 }
@@ -308,12 +396,20 @@ static int __exit sharp_ls_remove(struct platform_device *pdev)
308 return 0; 396 return 0;
309} 397}
310 398
399static const struct of_device_id sharp_ls_of_match[] = {
400 { .compatible = "omapdss,sharp,ls037v7dw01", },
401 {},
402};
403
404MODULE_DEVICE_TABLE(of, sharp_ls_of_match);
405
311static struct platform_driver sharp_ls_driver = { 406static struct platform_driver sharp_ls_driver = {
312 .probe = sharp_ls_probe, 407 .probe = sharp_ls_probe,
313 .remove = __exit_p(sharp_ls_remove), 408 .remove = __exit_p(sharp_ls_remove),
314 .driver = { 409 .driver = {
315 .name = "panel-sharp-ls037v7dw01", 410 .name = "panel-sharp-ls037v7dw01",
316 .owner = THIS_MODULE, 411 .owner = THIS_MODULE,
412 .of_match_table = sharp_ls_of_match,
317 }, 413 },
318}; 414};
319 415