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 | |
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>
-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); |