diff options
author | Tomasz Stanislawski <t.stanislaws@samsung.com> | 2011-09-21 12:23:05 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-02-28 16:27:32 -0500 |
commit | 5145aa76e6f6d5562f931cc719683002be7a0f81 (patch) | |
tree | c4b63d265ba285350589d0b2209a57ea504afeff /drivers/media/video/s5p-tv/hdmi_drv.c | |
parent | 350f2f4dad64b61376f08abfcdd7a339503ae6b8 (diff) |
[media] v4l: s5p-tv: hdmi: integrate with MHL
Adding support for using MHL (SiI9234 or other) chip if its configuration was
passed to HDMI by platfrom data.
Signed-off-by: Tomasz Stanislawski <t.stanislaws@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/s5p-tv/hdmi_drv.c')
-rw-r--r-- | drivers/media/video/s5p-tv/hdmi_drv.c | 52 |
1 files changed, 45 insertions, 7 deletions
diff --git a/drivers/media/video/s5p-tv/hdmi_drv.c b/drivers/media/video/s5p-tv/hdmi_drv.c index 821136ccd172..4865d25a0e57 100644 --- a/drivers/media/video/s5p-tv/hdmi_drv.c +++ b/drivers/media/video/s5p-tv/hdmi_drv.c | |||
@@ -67,6 +67,8 @@ struct hdmi_device { | |||
67 | struct v4l2_device v4l2_dev; | 67 | struct v4l2_device v4l2_dev; |
68 | /** subdev of HDMIPHY interface */ | 68 | /** subdev of HDMIPHY interface */ |
69 | struct v4l2_subdev *phy_sd; | 69 | struct v4l2_subdev *phy_sd; |
70 | /** subdev of MHL interface */ | ||
71 | struct v4l2_subdev *mhl_sd; | ||
70 | /** configuration of current graphic mode */ | 72 | /** configuration of current graphic mode */ |
71 | const struct hdmi_preset_conf *cur_conf; | 73 | const struct hdmi_preset_conf *cur_conf; |
72 | /** current preset */ | 74 | /** current preset */ |
@@ -572,7 +574,15 @@ static int hdmi_streamon(struct hdmi_device *hdev) | |||
572 | if (tries == 0) { | 574 | if (tries == 0) { |
573 | dev_err(dev, "hdmiphy's pll could not reach steady state.\n"); | 575 | dev_err(dev, "hdmiphy's pll could not reach steady state.\n"); |
574 | v4l2_subdev_call(hdev->phy_sd, video, s_stream, 0); | 576 | v4l2_subdev_call(hdev->phy_sd, video, s_stream, 0); |
575 | hdmi_dumpregs(hdev, "s_stream"); | 577 | hdmi_dumpregs(hdev, "hdmiphy - s_stream"); |
578 | return -EIO; | ||
579 | } | ||
580 | |||
581 | /* starting MHL */ | ||
582 | ret = v4l2_subdev_call(hdev->mhl_sd, video, s_stream, 1); | ||
583 | if (hdev->mhl_sd && ret) { | ||
584 | v4l2_subdev_call(hdev->phy_sd, video, s_stream, 0); | ||
585 | hdmi_dumpregs(hdev, "mhl - s_stream"); | ||
576 | return -EIO; | 586 | return -EIO; |
577 | } | 587 | } |
578 | 588 | ||
@@ -603,6 +613,7 @@ static int hdmi_streamoff(struct hdmi_device *hdev) | |||
603 | clk_set_parent(res->sclk_hdmi, res->sclk_pixel); | 613 | clk_set_parent(res->sclk_hdmi, res->sclk_pixel); |
604 | clk_enable(res->sclk_hdmi); | 614 | clk_enable(res->sclk_hdmi); |
605 | 615 | ||
616 | v4l2_subdev_call(hdev->mhl_sd, video, s_stream, 0); | ||
606 | v4l2_subdev_call(hdev->phy_sd, video, s_stream, 0); | 617 | v4l2_subdev_call(hdev->phy_sd, video, s_stream, 0); |
607 | 618 | ||
608 | hdmi_dumpregs(hdev, "streamoff"); | 619 | hdmi_dumpregs(hdev, "streamoff"); |
@@ -724,6 +735,7 @@ static int hdmi_runtime_suspend(struct device *dev) | |||
724 | struct hdmi_device *hdev = sd_to_hdmi_dev(sd); | 735 | struct hdmi_device *hdev = sd_to_hdmi_dev(sd); |
725 | 736 | ||
726 | dev_dbg(dev, "%s\n", __func__); | 737 | dev_dbg(dev, "%s\n", __func__); |
738 | v4l2_subdev_call(hdev->mhl_sd, core, s_power, 0); | ||
727 | hdmi_resource_poweroff(&hdev->res); | 739 | hdmi_resource_poweroff(&hdev->res); |
728 | return 0; | 740 | return 0; |
729 | } | 741 | } |
@@ -742,6 +754,11 @@ static int hdmi_runtime_resume(struct device *dev) | |||
742 | if (ret) | 754 | if (ret) |
743 | goto fail; | 755 | goto fail; |
744 | 756 | ||
757 | /* starting MHL */ | ||
758 | ret = v4l2_subdev_call(hdev->mhl_sd, core, s_power, 1); | ||
759 | if (hdev->mhl_sd && ret) | ||
760 | goto fail; | ||
761 | |||
745 | dev_dbg(dev, "poweron succeed\n"); | 762 | dev_dbg(dev, "poweron succeed\n"); |
746 | 763 | ||
747 | return 0; | 764 | return 0; |
@@ -852,7 +869,7 @@ static int __devinit hdmi_probe(struct platform_device *pdev) | |||
852 | { | 869 | { |
853 | struct device *dev = &pdev->dev; | 870 | struct device *dev = &pdev->dev; |
854 | struct resource *res; | 871 | struct resource *res; |
855 | struct i2c_adapter *phy_adapter; | 872 | struct i2c_adapter *adapter; |
856 | struct v4l2_subdev *sd; | 873 | struct v4l2_subdev *sd; |
857 | struct hdmi_device *hdmi_dev = NULL; | 874 | struct hdmi_device *hdmi_dev = NULL; |
858 | struct s5p_hdmi_platform_data *pdata = dev->platform_data; | 875 | struct s5p_hdmi_platform_data *pdata = dev->platform_data; |
@@ -927,23 +944,44 @@ static int __devinit hdmi_probe(struct platform_device *pdev) | |||
927 | goto fail_vdev; | 944 | goto fail_vdev; |
928 | } | 945 | } |
929 | 946 | ||
930 | phy_adapter = i2c_get_adapter(pdata->hdmiphy_bus); | 947 | adapter = i2c_get_adapter(pdata->hdmiphy_bus); |
931 | if (phy_adapter == NULL) { | 948 | if (adapter == NULL) { |
932 | dev_err(dev, "adapter request failed\n"); | 949 | dev_err(dev, "hdmiphy adapter request failed\n"); |
933 | ret = -ENXIO; | 950 | ret = -ENXIO; |
934 | goto fail_vdev; | 951 | goto fail_vdev; |
935 | } | 952 | } |
936 | 953 | ||
937 | hdmi_dev->phy_sd = v4l2_i2c_new_subdev_board(&hdmi_dev->v4l2_dev, | 954 | hdmi_dev->phy_sd = v4l2_i2c_new_subdev_board(&hdmi_dev->v4l2_dev, |
938 | phy_adapter, pdata->hdmiphy_info, NULL); | 955 | adapter, pdata->hdmiphy_info, NULL); |
939 | /* on failure or not adapter is no longer useful */ | 956 | /* on failure or not adapter is no longer useful */ |
940 | i2c_put_adapter(phy_adapter); | 957 | i2c_put_adapter(adapter); |
941 | if (hdmi_dev->phy_sd == NULL) { | 958 | if (hdmi_dev->phy_sd == NULL) { |
942 | dev_err(dev, "missing subdev for hdmiphy\n"); | 959 | dev_err(dev, "missing subdev for hdmiphy\n"); |
943 | ret = -ENODEV; | 960 | ret = -ENODEV; |
944 | goto fail_vdev; | 961 | goto fail_vdev; |
945 | } | 962 | } |
946 | 963 | ||
964 | /* initialization of MHL interface if present */ | ||
965 | if (pdata->mhl_info) { | ||
966 | adapter = i2c_get_adapter(pdata->mhl_bus); | ||
967 | if (adapter == NULL) { | ||
968 | dev_err(dev, "MHL adapter request failed\n"); | ||
969 | ret = -ENXIO; | ||
970 | goto fail_vdev; | ||
971 | } | ||
972 | |||
973 | hdmi_dev->mhl_sd = v4l2_i2c_new_subdev_board( | ||
974 | &hdmi_dev->v4l2_dev, adapter, | ||
975 | pdata->mhl_info, NULL); | ||
976 | /* on failure or not adapter is no longer useful */ | ||
977 | i2c_put_adapter(adapter); | ||
978 | if (hdmi_dev->mhl_sd == NULL) { | ||
979 | dev_err(dev, "missing subdev for MHL\n"); | ||
980 | ret = -ENODEV; | ||
981 | goto fail_vdev; | ||
982 | } | ||
983 | } | ||
984 | |||
947 | clk_enable(hdmi_dev->res.hdmi); | 985 | clk_enable(hdmi_dev->res.hdmi); |
948 | 986 | ||
949 | pm_runtime_enable(dev); | 987 | pm_runtime_enable(dev); |