aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Gaignard <benjamin.gaignard@linaro.org>2014-09-08 09:52:08 -0400
committerBenjamin Gaignard <benjamin.gaignard@linaro.org>2014-12-11 07:57:59 -0500
commit41a14623bd7345017b62f167110cf95808a4891a (patch)
treef58661d4f62bb1f81632899cdd354218732b0344
parentf41c2581bc2b6b21f774596845952a7cb4c15c74 (diff)
drm: sti: allow to change hdmi ddc i2c adapter
Depending of the board configuration i2c for ddc could change, this patch allow to use a phandle to specify which i2c controller to use. Signed-off-by: Benjamin Gaignard <benjamin.gaignard@linaro.org>
-rw-r--r--Documentation/devicetree/bindings/gpu/st,stih4xx.txt1
-rw-r--r--drivers/gpu/drm/sti/sti_hdmi.c40
-rw-r--r--drivers/gpu/drm/sti/sti_hdmi.h1
3 files changed, 29 insertions, 13 deletions
diff --git a/Documentation/devicetree/bindings/gpu/st,stih4xx.txt b/Documentation/devicetree/bindings/gpu/st,stih4xx.txt
index 2d150c311a05..8885d9e203fc 100644
--- a/Documentation/devicetree/bindings/gpu/st,stih4xx.txt
+++ b/Documentation/devicetree/bindings/gpu/st,stih4xx.txt
@@ -69,6 +69,7 @@ STMicroelectronics stih4xx platforms
69 - clock-names: names of the clocks listed in clocks property in the same 69 - clock-names: names of the clocks listed in clocks property in the same
70 order. 70 order.
71 - hdmi,hpd-gpio: gpio id to detect if an hdmi cable is plugged or not. 71 - hdmi,hpd-gpio: gpio id to detect if an hdmi cable is plugged or not.
72 - ddc: phandle of an I2C controller used for DDC EDID probing
72 73
73sti-hda: 74sti-hda:
74 Required properties: 75 Required properties:
diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c
index b22968c08d1f..fed1b5fe4842 100644
--- a/drivers/gpu/drm/sti/sti_hdmi.c
+++ b/drivers/gpu/drm/sti/sti_hdmi.c
@@ -480,17 +480,15 @@ static const struct drm_bridge_funcs sti_hdmi_bridge_funcs = {
480 480
481static int sti_hdmi_connector_get_modes(struct drm_connector *connector) 481static int sti_hdmi_connector_get_modes(struct drm_connector *connector)
482{ 482{
483 struct i2c_adapter *i2c_adap; 483 struct sti_hdmi_connector *hdmi_connector
484 = to_sti_hdmi_connector(connector);
485 struct sti_hdmi *hdmi = hdmi_connector->hdmi;
484 struct edid *edid; 486 struct edid *edid;
485 int count; 487 int count;
486 488
487 DRM_DEBUG_DRIVER("\n"); 489 DRM_DEBUG_DRIVER("\n");
488 490
489 i2c_adap = i2c_get_adapter(1); 491 edid = drm_get_edid(connector, hdmi->ddc_adapt);
490 if (!i2c_adap)
491 goto fail;
492
493 edid = drm_get_edid(connector, i2c_adap);
494 if (!edid) 492 if (!edid)
495 goto fail; 493 goto fail;
496 494
@@ -603,29 +601,38 @@ static int sti_hdmi_bind(struct device *dev, struct device *master, void *data)
603 struct sti_hdmi_connector *connector; 601 struct sti_hdmi_connector *connector;
604 struct drm_connector *drm_connector; 602 struct drm_connector *drm_connector;
605 struct drm_bridge *bridge; 603 struct drm_bridge *bridge;
606 struct i2c_adapter *i2c_adap; 604 struct device_node *ddc;
607 int err; 605 int err;
608 606
609 i2c_adap = i2c_get_adapter(1); 607 ddc = of_parse_phandle(dev->of_node, "ddc", 0);
610 if (!i2c_adap) 608 if (ddc) {
611 return -EPROBE_DEFER; 609 hdmi->ddc_adapt = of_find_i2c_adapter_by_node(ddc);
610 if (!hdmi->ddc_adapt) {
611 err = -EPROBE_DEFER;
612 of_node_put(ddc);
613 return err;
614 }
615
616 of_node_put(ddc);
617 }
612 618
613 /* Set the drm device handle */ 619 /* Set the drm device handle */
614 hdmi->drm_dev = drm_dev; 620 hdmi->drm_dev = drm_dev;
615 621
616 encoder = sti_hdmi_find_encoder(drm_dev); 622 encoder = sti_hdmi_find_encoder(drm_dev);
617 if (!encoder) 623 if (!encoder)
618 return -ENOMEM; 624 goto err_adapt;
619 625
620 connector = devm_kzalloc(dev, sizeof(*connector), GFP_KERNEL); 626 connector = devm_kzalloc(dev, sizeof(*connector), GFP_KERNEL);
621 if (!connector) 627 if (!connector)
622 return -ENOMEM; 628 goto err_adapt;
629
623 630
624 connector->hdmi = hdmi; 631 connector->hdmi = hdmi;
625 632
626 bridge = devm_kzalloc(dev, sizeof(*bridge), GFP_KERNEL); 633 bridge = devm_kzalloc(dev, sizeof(*bridge), GFP_KERNEL);
627 if (!bridge) 634 if (!bridge)
628 return -ENOMEM; 635 goto err_adapt;
629 636
630 bridge->driver_private = hdmi; 637 bridge->driver_private = hdmi;
631 drm_bridge_init(drm_dev, bridge, &sti_hdmi_bridge_funcs); 638 drm_bridge_init(drm_dev, bridge, &sti_hdmi_bridge_funcs);
@@ -662,6 +669,8 @@ err_sysfs:
662err_connector: 669err_connector:
663 drm_bridge_cleanup(bridge); 670 drm_bridge_cleanup(bridge);
664 drm_connector_cleanup(drm_connector); 671 drm_connector_cleanup(drm_connector);
672err_adapt:
673 put_device(&hdmi->ddc_adapt->dev);
665 return -EINVAL; 674 return -EINVAL;
666} 675}
667 676
@@ -788,6 +797,11 @@ static int sti_hdmi_probe(struct platform_device *pdev)
788 797
789static int sti_hdmi_remove(struct platform_device *pdev) 798static int sti_hdmi_remove(struct platform_device *pdev)
790{ 799{
800 struct sti_hdmi *hdmi = dev_get_drvdata(&pdev->dev);
801
802 if (hdmi->ddc_adapt)
803 put_device(&hdmi->ddc_adapt->dev);
804
791 component_del(&pdev->dev, &sti_hdmi_ops); 805 component_del(&pdev->dev, &sti_hdmi_ops);
792 return 0; 806 return 0;
793} 807}
diff --git a/drivers/gpu/drm/sti/sti_hdmi.h b/drivers/gpu/drm/sti/sti_hdmi.h
index 61bec6557ceb..d00a3e0d807f 100644
--- a/drivers/gpu/drm/sti/sti_hdmi.h
+++ b/drivers/gpu/drm/sti/sti_hdmi.h
@@ -62,6 +62,7 @@ struct sti_hdmi {
62 wait_queue_head_t wait_event; 62 wait_queue_head_t wait_event;
63 bool event_received; 63 bool event_received;
64 struct reset_control *reset; 64 struct reset_control *reset;
65 struct i2c_adapter *ddc_adapt;
65}; 66};
66 67
67u32 hdmi_read(struct sti_hdmi *hdmi, int offset); 68u32 hdmi_read(struct sti_hdmi *hdmi, int offset);