diff options
| author | Thierry Reding <treding@nvidia.com> | 2013-11-22 13:27:11 -0500 |
|---|---|---|
| committer | Thierry Reding <treding@nvidia.com> | 2013-12-17 12:09:58 -0500 |
| commit | 210fcd9d9cf1ad6ebfae3b46b457e602c8f8cdc2 (patch) | |
| tree | 5cadafe886d2469a968da501b1da26fef22dca93 /drivers/gpu | |
| parent | 280921de7241ee63184c8baa89ec3fe0122dedb3 (diff) | |
drm/panel: Add support for Panasonic VVX10F004B0
The Panasonic VVX10F004B0 is a 10.1" WUXGA TFT LCD panel connected using
four DSI lanes.
Signed-off-by: Thierry Reding <treding@nvidia.com>
Diffstat (limited to 'drivers/gpu')
| -rw-r--r-- | drivers/gpu/drm/panel/panel-simple.c | 94 |
1 files changed, 87 insertions, 7 deletions
diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 767b7bef199f..3e611afc93f4 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | 31 | ||
| 32 | #include <drm/drmP.h> | 32 | #include <drm/drmP.h> |
| 33 | #include <drm/drm_crtc.h> | 33 | #include <drm/drm_crtc.h> |
| 34 | #include <drm/drm_mipi_dsi.h> | ||
| 34 | #include <drm/drm_panel.h> | 35 | #include <drm/drm_panel.h> |
| 35 | 36 | ||
| 36 | struct panel_desc { | 37 | struct panel_desc { |
| @@ -378,6 +379,13 @@ static struct platform_driver panel_simple_platform_driver = { | |||
| 378 | .remove = panel_simple_platform_remove, | 379 | .remove = panel_simple_platform_remove, |
| 379 | }; | 380 | }; |
| 380 | 381 | ||
| 382 | struct panel_desc_dsi { | ||
| 383 | struct panel_desc desc; | ||
| 384 | |||
| 385 | enum mipi_dsi_pixel_format format; | ||
| 386 | unsigned int lanes; | ||
| 387 | }; | ||
| 388 | |||
| 381 | static const struct drm_display_mode panasonic_vvx10f004b00_mode = { | 389 | static const struct drm_display_mode panasonic_vvx10f004b00_mode = { |
| 382 | .clock = 157200, | 390 | .clock = 157200, |
| 383 | .hdisplay = 1920, | 391 | .hdisplay = 1920, |
| @@ -391,23 +399,95 @@ static const struct drm_display_mode panasonic_vvx10f004b00_mode = { | |||
| 391 | .vrefresh = 60, | 399 | .vrefresh = 60, |
| 392 | }; | 400 | }; |
| 393 | 401 | ||
| 394 | static const struct panel_desc panasonic_vvx10f004b00 = { | 402 | static const struct panel_desc_dsi panasonic_vvx10f004b00 = { |
| 395 | .modes = &panasonic_vvx10f004b00_mode, | 403 | .desc = { |
| 396 | .num_modes = 1, | 404 | .modes = &panasonic_vvx10f004b00_mode, |
| 397 | .size = { | 405 | .num_modes = 1, |
| 398 | .width = 217, | 406 | .size = { |
| 399 | .height = 136, | 407 | .width = 217, |
| 408 | .height = 136, | ||
| 409 | }, | ||
| 400 | }, | 410 | }, |
| 411 | .format = MIPI_DSI_FMT_RGB888, | ||
| 412 | .lanes = 4, | ||
| 413 | }; | ||
| 414 | |||
| 415 | static const struct of_device_id dsi_of_match[] = { | ||
| 416 | { | ||
| 417 | .compatible = "panasonic,vvx10f004b00", | ||
| 418 | .data = &panasonic_vvx10f004b00 | ||
| 419 | }, { | ||
| 420 | /* sentinel */ | ||
| 421 | } | ||
| 422 | }; | ||
| 423 | MODULE_DEVICE_TABLE(of, dsi_of_match); | ||
| 424 | |||
| 425 | static int panel_simple_dsi_probe(struct mipi_dsi_device *dsi) | ||
| 426 | { | ||
| 427 | const struct panel_desc_dsi *desc; | ||
| 428 | const struct of_device_id *id; | ||
| 429 | int err; | ||
| 430 | |||
| 431 | id = of_match_node(dsi_of_match, dsi->dev.of_node); | ||
| 432 | if (!id) | ||
| 433 | return -ENODEV; | ||
| 434 | |||
| 435 | desc = id->data; | ||
| 436 | |||
| 437 | err = panel_simple_probe(&dsi->dev, &desc->desc); | ||
| 438 | if (err < 0) | ||
| 439 | return err; | ||
| 440 | |||
| 441 | dsi->format = desc->format; | ||
| 442 | dsi->lanes = desc->lanes; | ||
| 443 | |||
| 444 | return mipi_dsi_attach(dsi); | ||
| 445 | } | ||
| 446 | |||
| 447 | static int panel_simple_dsi_remove(struct mipi_dsi_device *dsi) | ||
| 448 | { | ||
| 449 | int err; | ||
| 450 | |||
| 451 | err = mipi_dsi_detach(dsi); | ||
| 452 | if (err < 0) | ||
| 453 | dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", err); | ||
| 454 | |||
| 455 | return panel_simple_remove(&dsi->dev); | ||
| 456 | } | ||
| 457 | |||
| 458 | static struct mipi_dsi_driver panel_simple_dsi_driver = { | ||
| 459 | .driver = { | ||
| 460 | .name = "panel-simple-dsi", | ||
| 461 | .owner = THIS_MODULE, | ||
| 462 | .of_match_table = dsi_of_match, | ||
| 463 | }, | ||
| 464 | .probe = panel_simple_dsi_probe, | ||
| 465 | .remove = panel_simple_dsi_remove, | ||
| 401 | }; | 466 | }; |
| 402 | 467 | ||
| 403 | static int __init panel_simple_init(void) | 468 | static int __init panel_simple_init(void) |
| 404 | { | 469 | { |
| 405 | return platform_driver_register(&panel_simple_platform_driver); | 470 | int err; |
| 471 | |||
| 472 | err = platform_driver_register(&panel_simple_platform_driver); | ||
| 473 | if (err < 0) | ||
| 474 | return err; | ||
| 475 | |||
| 476 | if (IS_ENABLED(CONFIG_DRM_MIPI_DSI)) { | ||
| 477 | err = mipi_dsi_driver_register(&panel_simple_dsi_driver); | ||
| 478 | if (err < 0) | ||
| 479 | return err; | ||
| 480 | } | ||
| 481 | |||
| 482 | return 0; | ||
| 406 | } | 483 | } |
| 407 | module_init(panel_simple_init); | 484 | module_init(panel_simple_init); |
| 408 | 485 | ||
| 409 | static void __exit panel_simple_exit(void) | 486 | static void __exit panel_simple_exit(void) |
| 410 | { | 487 | { |
| 488 | if (IS_ENABLED(CONFIG_DRM_MIPI_DSI)) | ||
| 489 | mipi_dsi_driver_unregister(&panel_simple_dsi_driver); | ||
| 490 | |||
| 411 | platform_driver_unregister(&panel_simple_platform_driver); | 491 | platform_driver_unregister(&panel_simple_platform_driver); |
| 412 | } | 492 | } |
| 413 | module_exit(panel_simple_exit); | 493 | module_exit(panel_simple_exit); |
