diff options
author | Benjamin Gaignard <benjamin.gaignard@linaro.org> | 2014-09-08 09:52:08 -0400 |
---|---|---|
committer | Benjamin Gaignard <benjamin.gaignard@linaro.org> | 2014-12-11 07:57:59 -0500 |
commit | 41a14623bd7345017b62f167110cf95808a4891a (patch) | |
tree | f58661d4f62bb1f81632899cdd354218732b0344 | |
parent | f41c2581bc2b6b21f774596845952a7cb4c15c74 (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.txt | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/sti/sti_hdmi.c | 40 | ||||
-rw-r--r-- | drivers/gpu/drm/sti/sti_hdmi.h | 1 |
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 | ||
73 | sti-hda: | 74 | sti-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 | ||
481 | static int sti_hdmi_connector_get_modes(struct drm_connector *connector) | 481 | static 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: | |||
662 | err_connector: | 669 | err_connector: |
663 | drm_bridge_cleanup(bridge); | 670 | drm_bridge_cleanup(bridge); |
664 | drm_connector_cleanup(drm_connector); | 671 | drm_connector_cleanup(drm_connector); |
672 | err_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 | ||
789 | static int sti_hdmi_remove(struct platform_device *pdev) | 798 | static 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 | ||
67 | u32 hdmi_read(struct sti_hdmi *hdmi, int offset); | 68 | u32 hdmi_read(struct sti_hdmi *hdmi, int offset); |