diff options
Diffstat (limited to 'drivers/video/fbdev/omap2/displays-new/panel-lgphilips-lb035q02.c')
-rw-r--r-- | drivers/video/fbdev/omap2/displays-new/panel-lgphilips-lb035q02.c | 77 |
1 files changed, 62 insertions, 15 deletions
diff --git a/drivers/video/fbdev/omap2/displays-new/panel-lgphilips-lb035q02.c b/drivers/video/fbdev/omap2/displays-new/panel-lgphilips-lb035q02.c index 2e6b513222d9..cc5b5124e0b4 100644 --- a/drivers/video/fbdev/omap2/displays-new/panel-lgphilips-lb035q02.c +++ b/drivers/video/fbdev/omap2/displays-new/panel-lgphilips-lb035q02.c | |||
@@ -50,9 +50,10 @@ struct panel_drv_data { | |||
50 | 50 | ||
51 | struct omap_video_timings videomode; | 51 | struct omap_video_timings videomode; |
52 | 52 | ||
53 | int reset_gpio; | 53 | /* used for non-DT boot, to be removed */ |
54 | int backlight_gpio; | 54 | int backlight_gpio; |
55 | int enable_gpio; | 55 | |
56 | struct gpio_desc *enable_gpio; | ||
56 | }; | 57 | }; |
57 | 58 | ||
58 | #define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev) | 59 | #define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev) |
@@ -158,15 +159,16 @@ static int lb035q02_enable(struct omap_dss_device *dssdev) | |||
158 | if (omapdss_device_is_enabled(dssdev)) | 159 | if (omapdss_device_is_enabled(dssdev)) |
159 | return 0; | 160 | return 0; |
160 | 161 | ||
161 | in->ops.dpi->set_data_lines(in, ddata->data_lines); | 162 | if (ddata->data_lines) |
163 | in->ops.dpi->set_data_lines(in, ddata->data_lines); | ||
162 | in->ops.dpi->set_timings(in, &ddata->videomode); | 164 | in->ops.dpi->set_timings(in, &ddata->videomode); |
163 | 165 | ||
164 | r = in->ops.dpi->enable(in); | 166 | r = in->ops.dpi->enable(in); |
165 | if (r) | 167 | if (r) |
166 | return r; | 168 | return r; |
167 | 169 | ||
168 | if (gpio_is_valid(ddata->enable_gpio)) | 170 | if (ddata->enable_gpio) |
169 | gpio_set_value_cansleep(ddata->enable_gpio, 1); | 171 | gpiod_set_value_cansleep(ddata->enable_gpio, 1); |
170 | 172 | ||
171 | if (gpio_is_valid(ddata->backlight_gpio)) | 173 | if (gpio_is_valid(ddata->backlight_gpio)) |
172 | gpio_set_value_cansleep(ddata->backlight_gpio, 1); | 174 | gpio_set_value_cansleep(ddata->backlight_gpio, 1); |
@@ -184,8 +186,8 @@ static void lb035q02_disable(struct omap_dss_device *dssdev) | |||
184 | if (!omapdss_device_is_enabled(dssdev)) | 186 | if (!omapdss_device_is_enabled(dssdev)) |
185 | return; | 187 | return; |
186 | 188 | ||
187 | if (gpio_is_valid(ddata->enable_gpio)) | 189 | if (ddata->enable_gpio) |
188 | gpio_set_value_cansleep(ddata->enable_gpio, 0); | 190 | gpiod_set_value_cansleep(ddata->enable_gpio, 0); |
189 | 191 | ||
190 | if (gpio_is_valid(ddata->backlight_gpio)) | 192 | if (gpio_is_valid(ddata->backlight_gpio)) |
191 | gpio_set_value_cansleep(ddata->backlight_gpio, 0); | 193 | gpio_set_value_cansleep(ddata->backlight_gpio, 0); |
@@ -243,6 +245,7 @@ static int lb035q02_probe_pdata(struct spi_device *spi) | |||
243 | const struct panel_lb035q02_platform_data *pdata; | 245 | const struct panel_lb035q02_platform_data *pdata; |
244 | struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev); | 246 | struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev); |
245 | struct omap_dss_device *dssdev, *in; | 247 | struct omap_dss_device *dssdev, *in; |
248 | int r; | ||
246 | 249 | ||
247 | pdata = dev_get_platdata(&spi->dev); | 250 | pdata = dev_get_platdata(&spi->dev); |
248 | 251 | ||
@@ -260,10 +263,48 @@ static int lb035q02_probe_pdata(struct spi_device *spi) | |||
260 | dssdev = &ddata->dssdev; | 263 | dssdev = &ddata->dssdev; |
261 | dssdev->name = pdata->name; | 264 | dssdev->name = pdata->name; |
262 | 265 | ||
263 | ddata->enable_gpio = pdata->enable_gpio; | 266 | r = devm_gpio_request_one(&spi->dev, pdata->enable_gpio, |
267 | GPIOF_OUT_INIT_LOW, "panel enable"); | ||
268 | if (r) | ||
269 | goto err_gpio; | ||
270 | |||
271 | ddata->enable_gpio = gpio_to_desc(pdata->enable_gpio); | ||
272 | |||
264 | ddata->backlight_gpio = pdata->backlight_gpio; | 273 | ddata->backlight_gpio = pdata->backlight_gpio; |
265 | 274 | ||
266 | return 0; | 275 | return 0; |
276 | err_gpio: | ||
277 | omap_dss_put_device(ddata->in); | ||
278 | return r; | ||
279 | } | ||
280 | |||
281 | static int lb035q02_probe_of(struct spi_device *spi) | ||
282 | { | ||
283 | struct device_node *node = spi->dev.of_node; | ||
284 | struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev); | ||
285 | struct omap_dss_device *in; | ||
286 | struct gpio_desc *gpio; | ||
287 | |||
288 | gpio = devm_gpiod_get(&spi->dev, "enable"); | ||
289 | if (IS_ERR(gpio)) { | ||
290 | dev_err(&spi->dev, "failed to parse enable gpio\n"); | ||
291 | return PTR_ERR(gpio); | ||
292 | } else { | ||
293 | gpiod_direction_output(gpio, 0); | ||
294 | ddata->enable_gpio = gpio; | ||
295 | } | ||
296 | |||
297 | ddata->backlight_gpio = -ENOENT; | ||
298 | |||
299 | in = omapdss_of_find_source_for_first_ep(node); | ||
300 | if (IS_ERR(in)) { | ||
301 | dev_err(&spi->dev, "failed to find video source\n"); | ||
302 | return PTR_ERR(in); | ||
303 | } | ||
304 | |||
305 | ddata->in = in; | ||
306 | |||
307 | return 0; | ||
267 | } | 308 | } |
268 | 309 | ||
269 | static int lb035q02_panel_spi_probe(struct spi_device *spi) | 310 | static int lb035q02_panel_spi_probe(struct spi_device *spi) |
@@ -284,17 +325,14 @@ static int lb035q02_panel_spi_probe(struct spi_device *spi) | |||
284 | r = lb035q02_probe_pdata(spi); | 325 | r = lb035q02_probe_pdata(spi); |
285 | if (r) | 326 | if (r) |
286 | return r; | 327 | return r; |
328 | } else if (spi->dev.of_node) { | ||
329 | r = lb035q02_probe_of(spi); | ||
330 | if (r) | ||
331 | return r; | ||
287 | } else { | 332 | } else { |
288 | return -ENODEV; | 333 | return -ENODEV; |
289 | } | 334 | } |
290 | 335 | ||
291 | if (gpio_is_valid(ddata->enable_gpio)) { | ||
292 | r = devm_gpio_request_one(&spi->dev, ddata->enable_gpio, | ||
293 | GPIOF_OUT_INIT_LOW, "panel enable"); | ||
294 | if (r) | ||
295 | goto err_gpio; | ||
296 | } | ||
297 | |||
298 | if (gpio_is_valid(ddata->backlight_gpio)) { | 336 | if (gpio_is_valid(ddata->backlight_gpio)) { |
299 | r = devm_gpio_request_one(&spi->dev, ddata->backlight_gpio, | 337 | r = devm_gpio_request_one(&spi->dev, ddata->backlight_gpio, |
300 | GPIOF_OUT_INIT_LOW, "panel backlight"); | 338 | GPIOF_OUT_INIT_LOW, "panel backlight"); |
@@ -342,17 +380,26 @@ static int lb035q02_panel_spi_remove(struct spi_device *spi) | |||
342 | return 0; | 380 | return 0; |
343 | } | 381 | } |
344 | 382 | ||
383 | static const struct of_device_id lb035q02_of_match[] = { | ||
384 | { .compatible = "omapdss,lgphilips,lb035q02", }, | ||
385 | {}, | ||
386 | }; | ||
387 | |||
388 | MODULE_DEVICE_TABLE(of, lb035q02_of_match); | ||
389 | |||
345 | static struct spi_driver lb035q02_spi_driver = { | 390 | static struct spi_driver lb035q02_spi_driver = { |
346 | .probe = lb035q02_panel_spi_probe, | 391 | .probe = lb035q02_panel_spi_probe, |
347 | .remove = lb035q02_panel_spi_remove, | 392 | .remove = lb035q02_panel_spi_remove, |
348 | .driver = { | 393 | .driver = { |
349 | .name = "panel_lgphilips_lb035q02", | 394 | .name = "panel_lgphilips_lb035q02", |
350 | .owner = THIS_MODULE, | 395 | .owner = THIS_MODULE, |
396 | .of_match_table = lb035q02_of_match, | ||
351 | }, | 397 | }, |
352 | }; | 398 | }; |
353 | 399 | ||
354 | module_spi_driver(lb035q02_spi_driver); | 400 | module_spi_driver(lb035q02_spi_driver); |
355 | 401 | ||
402 | MODULE_ALIAS("spi:lgphilips,lb035q02"); | ||
356 | MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>"); | 403 | MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>"); |
357 | MODULE_DESCRIPTION("LG.Philips LB035Q02 LCD Panel driver"); | 404 | MODULE_DESCRIPTION("LG.Philips LB035Q02 LCD Panel driver"); |
358 | MODULE_LICENSE("GPL"); | 405 | MODULE_LICENSE("GPL"); |