]> Git Repo - linux.git/blob - drivers/gpu/drm/bridge/lvds-encoder.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
[linux.git] / drivers / gpu / drm / bridge / lvds-encoder.c
1 /*
2  * Copyright (C) 2016 Laurent Pinchart <[email protected]>
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of
7  * the License, or (at your option) any later version.
8  */
9
10 #include <drm/drmP.h>
11 #include <drm/drm_bridge.h>
12 #include <drm/drm_panel.h>
13
14 #include <linux/of_graph.h>
15
16 static int lvds_encoder_probe(struct platform_device *pdev)
17 {
18         struct device_node *port;
19         struct device_node *endpoint;
20         struct device_node *panel_node;
21         struct drm_panel *panel;
22         struct drm_bridge *bridge;
23
24         /* Locate the panel DT node. */
25         port = of_graph_get_port_by_id(pdev->dev.of_node, 1);
26         if (!port) {
27                 dev_dbg(&pdev->dev, "port 1 not found\n");
28                 return -ENXIO;
29         }
30
31         endpoint = of_get_child_by_name(port, "endpoint");
32         of_node_put(port);
33         if (!endpoint) {
34                 dev_dbg(&pdev->dev, "no endpoint for port 1\n");
35                 return -ENXIO;
36         }
37
38         panel_node = of_graph_get_remote_port_parent(endpoint);
39         of_node_put(endpoint);
40         if (!panel_node) {
41                 dev_dbg(&pdev->dev, "no remote endpoint for port 1\n");
42                 return -ENXIO;
43         }
44
45         panel = of_drm_find_panel(panel_node);
46         of_node_put(panel_node);
47         if (!panel) {
48                 dev_dbg(&pdev->dev, "panel not found, deferring probe\n");
49                 return -EPROBE_DEFER;
50         }
51
52         bridge = drm_panel_bridge_add(panel, DRM_MODE_CONNECTOR_LVDS);
53         if (IS_ERR(bridge))
54                 return PTR_ERR(bridge);
55
56         platform_set_drvdata(pdev, bridge);
57
58         return 0;
59 }
60
61 static int lvds_encoder_remove(struct platform_device *pdev)
62 {
63         struct drm_bridge *bridge = platform_get_drvdata(pdev);
64
65         drm_bridge_remove(bridge);
66
67         return 0;
68 }
69
70 static const struct of_device_id lvds_encoder_match[] = {
71         { .compatible = "lvds-encoder" },
72         { .compatible = "thine,thc63lvdm83d" },
73         {},
74 };
75 MODULE_DEVICE_TABLE(of, lvds_encoder_match);
76
77 static struct platform_driver lvds_encoder_driver = {
78         .probe  = lvds_encoder_probe,
79         .remove = lvds_encoder_remove,
80         .driver         = {
81                 .name           = "lvds-encoder",
82                 .of_match_table = lvds_encoder_match,
83         },
84 };
85 module_platform_driver(lvds_encoder_driver);
86
87 MODULE_AUTHOR("Laurent Pinchart <[email protected]>");
88 MODULE_DESCRIPTION("Transparent parallel to LVDS encoder");
89 MODULE_LICENSE("GPL");
This page took 0.041295 seconds and 4 git commands to generate.