diff options
-rw-r--r-- | drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c | 102 |
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 | ||
21 | struct panel_drv_data { | 23 | struct 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 | ||
267 | static 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 | |||
287 | static 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 | |||
252 | static int sharp_ls_probe(struct platform_device *pdev) | 336 | static 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 | ||
399 | static const struct of_device_id sharp_ls_of_match[] = { | ||
400 | { .compatible = "omapdss,sharp,ls037v7dw01", }, | ||
401 | {}, | ||
402 | }; | ||
403 | |||
404 | MODULE_DEVICE_TABLE(of, sharp_ls_of_match); | ||
405 | |||
311 | static struct platform_driver sharp_ls_driver = { | 406 | static 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 | ||