summaryrefslogtreecommitdiff
path: root/drivers/video/fbdev
diff options
context:
space:
mode:
authorTatenda Chipeperekwa <tatendac@codeaurora.org>2016-08-16 14:24:18 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2016-08-21 14:04:55 -0700
commitfdae3117e039d120d7453f0eb89cc6cfc6c457c9 (patch)
treecd97a446daf308fdbc09b00a512c95cb986bfd00 /drivers/video/fbdev
parent9ec9267905e8e712eba27c106c96e78c6da3e56f (diff)
msm: mdss: use external display as wrapper for operations
Use the external display as a wrapper for operations making it necessary for clients to only need a pointer to the external display platform device. The external display will implement the book keeping required to map operations to the correct display interface. CRs-Fixed: 1009284 Change-Id: I1f817e0c720dda0a9b1778f6aad653218ff9be60 Signed-off-by: Tatenda Chipeperekwa <tatendac@codeaurora.org>
Diffstat (limited to 'drivers/video/fbdev')
-rw-r--r--drivers/video/fbdev/msm/mdss_hdmi_tx.c3
-rw-r--r--drivers/video/fbdev/msm/msm_ext_display.c129
2 files changed, 128 insertions, 4 deletions
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_tx.c b/drivers/video/fbdev/msm/mdss_hdmi_tx.c
index 3e4e2f74a32e..3b4bc8acdd10 100644
--- a/drivers/video/fbdev/msm/mdss_hdmi_tx.c
+++ b/drivers/video/fbdev/msm/mdss_hdmi_tx.c
@@ -1915,6 +1915,7 @@ static int hdmi_tx_init_ext_disp(struct hdmi_tx_ctrl *hdmi_ctrl)
hdmi_ctrl->ext_audio_data.type = EXT_DISPLAY_TYPE_HDMI;
hdmi_ctrl->ext_audio_data.kobj = hdmi_ctrl->kobj;
+ hdmi_ctrl->ext_audio_data.pdev = hdmi_ctrl->pdev;
hdmi_ctrl->ext_audio_data.codec_ops.audio_info_setup =
hdmi_tx_audio_info_setup;
hdmi_ctrl->ext_audio_data.codec_ops.get_audio_edid_blk =
@@ -2978,7 +2979,7 @@ int msm_hdmi_register_audio_codec(struct platform_device *pdev,
if (!hdmi_ctrl || !ops) {
DEV_ERR("%s: invalid input\n", __func__);
- return -ENODEV;
+ return -EPROBE_DEFER;
}
ret = msm_ext_disp_register_audio_codec(hdmi_ctrl->ext_pdev, ops);
diff --git a/drivers/video/fbdev/msm/msm_ext_display.c b/drivers/video/fbdev/msm/msm_ext_display.c
index a21242870a35..903cab1ac059 100644
--- a/drivers/video/fbdev/msm/msm_ext_display.c
+++ b/drivers/video/fbdev/msm/msm_ext_display.c
@@ -380,6 +380,88 @@ end:
return ret;
}
+static int msm_ext_disp_get_intf_data_helper(struct platform_device *pdev,
+ struct msm_ext_disp_init_data **data)
+{
+ int ret = 0;
+ struct msm_ext_disp *ext_disp = NULL;
+
+ if (!pdev) {
+ pr_err("No platform device\n");
+ ret = -ENODEV;
+ goto end;
+ }
+
+ ext_disp = platform_get_drvdata(pdev);
+ if (!ext_disp) {
+ pr_err("No drvdata found\n");
+ ret = -ENODEV;
+ goto end;
+ }
+
+ mutex_lock(&ext_disp->lock);
+
+ if (ext_disp->current_disp == EXT_DISPLAY_TYPE_MAX) {
+ ret = -EINVAL;
+ pr_err("No display connected\n");
+ goto error;
+ }
+
+ ret = msm_ext_disp_get_intf_data(ext_disp, ext_disp->current_disp,
+ data);
+ if (ret)
+ goto error;
+error:
+ mutex_unlock(&ext_disp->lock);
+end:
+ return ret;
+}
+static int msm_ext_disp_cable_status(struct platform_device *pdev, u32 vote)
+{
+ int ret = 0;
+ struct msm_ext_disp_init_data *data = NULL;
+
+ ret = msm_ext_disp_get_intf_data_helper(pdev, &data);
+ if (ret || !data)
+ goto end;
+
+ ret = data->codec_ops.cable_status(data->pdev, vote);
+
+end:
+ return ret;
+}
+
+static int msm_ext_disp_get_audio_edid_blk(struct platform_device *pdev,
+ struct msm_ext_disp_audio_edid_blk *blk)
+{
+ int ret = 0;
+ struct msm_ext_disp_init_data *data = NULL;
+
+ ret = msm_ext_disp_get_intf_data_helper(pdev, &data);
+ if (ret || !data)
+ goto end;
+
+ ret = data->codec_ops.get_audio_edid_blk(data->pdev, blk);
+
+end:
+ return ret;
+}
+
+static int msm_ext_disp_audio_info_setup(struct platform_device *pdev,
+ struct msm_ext_disp_audio_setup_params *params)
+{
+ int ret = 0;
+ struct msm_ext_disp_init_data *data = NULL;
+
+ ret = msm_ext_disp_get_intf_data_helper(pdev, &data);
+ if (ret || !data)
+ goto end;
+
+ ret = data->codec_ops.audio_info_setup(data->pdev, params);
+
+end:
+ return ret;
+}
static int msm_ext_disp_get_intf_id(struct platform_device *pdev)
{
@@ -456,11 +538,11 @@ static int msm_ext_disp_notify(struct platform_device *pdev,
if (new_state == EXT_DISPLAY_CABLE_CONNECT && ext_disp->ops) {
ext_disp->ops->audio_info_setup =
- data->codec_ops.audio_info_setup;
+ msm_ext_disp_audio_info_setup;
ext_disp->ops->get_audio_edid_blk =
- data->codec_ops.get_audio_edid_blk;
+ msm_ext_disp_get_audio_edid_blk;
ext_disp->ops->cable_status =
- data->codec_ops.cable_status;
+ msm_ext_disp_cable_status;
ext_disp->ops->get_intf_id =
msm_ext_disp_get_intf_id;
}
@@ -590,6 +672,33 @@ end:
return ret;
}
+static int msm_ext_disp_validate_intf(struct msm_ext_disp_init_data *init_data)
+{
+ if (!init_data) {
+ pr_err("Invalid init_data\n");
+ return -EINVAL;
+ }
+
+ if (!init_data->pdev) {
+ pr_err("Invalid display intf pdev\n");
+ return -EINVAL;
+ }
+
+ if (!init_data->kobj) {
+ pr_err("Invalid display intf kobj\n");
+ return -EINVAL;
+ }
+
+ if (!init_data->codec_ops.get_audio_edid_blk ||
+ !init_data->codec_ops.cable_status ||
+ !init_data->codec_ops.audio_info_setup) {
+ pr_err("Invalid codec operation pointers\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
int msm_ext_disp_register_intf(struct platform_device *pdev,
struct msm_ext_disp_init_data *init_data)
{
@@ -610,6 +719,10 @@ int msm_ext_disp_register_intf(struct platform_device *pdev,
mutex_lock(&ext_disp->lock);
+ ret = msm_ext_disp_validate_intf(init_data);
+ if (ret)
+ goto end;
+
ret = msm_ext_disp_get_intf_data(ext_disp, init_data->type, &data);
if (!ret) {
pr_debug("Display (%s) already registered\n",
@@ -675,6 +788,14 @@ static int msm_ext_disp_probe(struct platform_device *pdev)
if (ret)
goto switch_dev_failure;
+ ret = of_platform_populate(of_node, NULL, NULL, &pdev->dev);
+ if (ret) {
+ pr_err("Failed to add child devices. Error = %d\n", ret);
+ goto child_node_failure;
+ } else {
+ pr_debug("%s: Added child devices.\n", __func__);
+ }
+
mutex_init(&ext_disp->lock);
INIT_LIST_HEAD(&ext_disp->display_list);
@@ -682,6 +803,8 @@ static int msm_ext_disp_probe(struct platform_device *pdev)
return ret;
+child_node_failure:
+ msm_ext_disp_switch_dev_unregister(ext_disp);
switch_dev_failure:
devm_kfree(&ext_disp->pdev->dev, ext_disp);
end: