aboutsummaryrefslogtreecommitdiff
path: root/drivers/video/mcde
diff options
context:
space:
mode:
authorMarcel Tunnissen <Marcel.Tuennissen@stericsson.com>2011-03-10 09:19:12 +0100
committerPhilippe Langlais <philippe.langlais@linaro.org>2011-07-22 15:42:23 +0200
commit9cbb8d9e3c3b2c3312d14ce26e00d4f2d3350059 (patch)
tree30835b1cacd7018b4513ad7b2b4e20540b9c16a4 /drivers/video/mcde
parent858ac7f2fad5c96b77bf19af60a98382af67245c (diff)
video: mcde: Fix field swap for CVBS by AV8100
Fixes the problem that the interlaced fields are swapped sometimes after configuring CVBS out through AV8100. ST-Ericsson ID: ER 323997 Linux-next: ST-Ericsson ID: ER 282779 ST-Ericsson FOSS-OUT ID: Trivial Change-Id: I1ff10612f05fce1cdd1d991b50513a93153730e4 Signed-off-by: Marcel Tunnissen <Marcel.Tuennissen@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/18327 Tested-by: Marcel TUNNISSEN <marcel.tuennissen@stericsson.com> Reviewed-by: Jimmy RUBIN <jimmy.rubin@stericsson.com> Reviewed-by: Dan JOHANSSON <dan.johansson@stericsson.com> Reviewed-by: Per PERSSON <per.xb.persson@stericsson.com>
Diffstat (limited to 'drivers/video/mcde')
-rw-r--r--drivers/video/mcde/display-av8100.c141
1 files changed, 61 insertions, 80 deletions
diff --git a/drivers/video/mcde/display-av8100.c b/drivers/video/mcde/display-av8100.c
index b8d6c8806b5..163af1c3361 100644
--- a/drivers/video/mcde/display-av8100.c
+++ b/drivers/video/mcde/display-av8100.c
@@ -348,7 +348,6 @@ static int hdmi_set_video_mode(
struct mcde_display_device *dev, struct mcde_video_mode *video_mode)
{
int ret;
- bool update = 0;
union av8100_configuration av8100_config;
struct mcde_display_hdmi_platform_data *pdata = dev->dev.platform_data;
struct display_driver_data *driver_data = dev_get_drvdata(&dev->dev);
@@ -437,15 +436,35 @@ static int hdmi_set_video_mode(
return -EFAULT;
}
- /* Set HDMI mode to OFF */
- av8100_config.hdmi_format.hdmi_mode = AV8100_HDMI_OFF;
- av8100_config.hdmi_format.dvi_format = AV8100_DVI_CTRL_CTL0;
- av8100_config.hdmi_format.hdmi_format = AV8100_HDMI;
- if (av8100_conf_prep(AV8100_COMMAND_HDMI, &av8100_config))
+ /*
+ * Don't look at dev->port->hdmi_sdtv_switch; it states only which
+ * one should be started, not which one is currently working
+ */
+ if (av8100_conf_get(AV8100_COMMAND_HDMI, &av8100_config))
return -EFAULT;
+ if (av8100_config.hdmi_format.hdmi_mode == AV8100_HDMI_ON) {
+ /* Set HDMI mode to OFF */
+ av8100_config.hdmi_format.hdmi_mode = AV8100_HDMI_OFF;
+ av8100_config.hdmi_format.dvi_format = AV8100_DVI_CTRL_CTL0;
+ av8100_config.hdmi_format.hdmi_format = AV8100_HDMI;
+ if (av8100_conf_prep(AV8100_COMMAND_HDMI, &av8100_config))
+ return -EFAULT;
- if (av8100_conf_w(AV8100_COMMAND_HDMI, NULL, NULL, I2C_INTERFACE))
+ if (av8100_conf_w(AV8100_COMMAND_HDMI, NULL, NULL,
+ I2C_INTERFACE))
+ return -EFAULT;
+ }
+ if (av8100_conf_get(AV8100_COMMAND_DENC, &av8100_config))
return -EFAULT;
+ if (av8100_config.denc_format.enable) {
+ /* Turn off DENC */
+ av8100_config.denc_format.enable = 0;
+ if (av8100_conf_prep(AV8100_COMMAND_DENC, &av8100_config))
+ return -EFAULT;
+ if (av8100_conf_w(AV8100_COMMAND_DENC, NULL, NULL,
+ I2C_INTERFACE))
+ return -EFAULT;
+ }
/* Get current av8100 video output format */
ret = av8100_conf_get(AV8100_COMMAND_VIDEO_OUTPUT_FORMAT,
@@ -618,55 +637,6 @@ static int hdmi_set_video_mode(
return ret;
}
- /* Get current av8100 video denc settings format */
- ret = av8100_conf_get(AV8100_COMMAND_DENC,
- &av8100_config);
- if (ret) {
- dev_err(&dev->dev, "%s:av8100_conf_get "
- "AV8100_COMMAND_DENC failed\n", __func__);
- return ret;
- }
-
- if (dev->port->hdmi_sdtv_switch == SDTV_SWITCH) {
- update = true;
- if (dev->video_mode.yres == NATIVE_YRES_SDTV) {
- av8100_config.denc_format.standard_selection =
- AV8100_PAL_BDGHI;
- av8100_config.denc_format.cvbs_video_format =
- AV8100_CVBS_625;
- } else {
- av8100_config.denc_format.standard_selection =
- AV8100_NTSC_M;
- av8100_config.denc_format.cvbs_video_format =
- AV8100_CVBS_525;
- }
- } else
- update = (av8100_config.denc_format.enable != 0);
-
- if (update) {
- if (dev->port->hdmi_sdtv_switch == SDTV_SWITCH)
- av8100_config.denc_format.enable = 1;
- else
- av8100_config.denc_format.enable = 0;
-
- ret = av8100_conf_prep(AV8100_COMMAND_DENC,
- &av8100_config);
- if (ret) {
- dev_err(&dev->dev, "%s:av8100_conf_prep "
- "AV8100_COMMAND_DENC failed\n", __func__);
- return ret;
- }
-
- /* TODO: prepare depending on OUT fmt */
- ret = av8100_conf_w(AV8100_COMMAND_DENC,
- NULL, NULL, I2C_INTERFACE);
- if (ret) {
- dev_err(&dev->dev, "%s:av8100_conf_w "
- "AV8100_COMMAND_DENC failed\n", __func__);
- return ret;
- }
- }
-
dev->update_flags |= UPDATE_FLAG_VIDEO_MODE;
dev->first_update = true;
@@ -748,31 +718,36 @@ static int hdmi_on_first_update(struct mcde_display_device *dev)
dev->first_update = false;
- /* Get current av8100 video denc settings format */
- ret = av8100_conf_get(AV8100_COMMAND_DENC,
- &av8100_config);
- if (ret) {
- dev_err(&dev->dev, "%s:av8100_conf_get "
- "AV8100_COMMAND_DENC failed\n", __func__);
- return ret;
- }
-
/*
+ * Prepare HDMI configuration
* Avoid simultaneous output of DENC and HDMI.
* Only one of them should be enabled.
+ * Note HDMI and DENC are always turned off in set_video_mode.
*/
- if (av8100_config.denc_format.enable)
- av8100_config.hdmi_format.hdmi_mode = AV8100_HDMI_OFF;
- else
+ if (dev->port->hdmi_sdtv_switch == SDTV_SWITCH) {
+ av8100_config.denc_format.enable = 1;
+ if (dev->video_mode.yres == NATIVE_YRES_SDTV) {
+ av8100_config.denc_format.standard_selection =
+ AV8100_PAL_BDGHI;
+ av8100_config.denc_format.cvbs_video_format =
+ AV8100_CVBS_625;
+ } else {
+ av8100_config.denc_format.standard_selection =
+ AV8100_NTSC_M;
+ av8100_config.denc_format.cvbs_video_format =
+ AV8100_CVBS_525;
+ }
+ ret = av8100_conf_prep(AV8100_COMMAND_DENC, &av8100_config);
+ } else {
av8100_config.hdmi_format.hdmi_mode = AV8100_HDMI_ON;
+ av8100_config.hdmi_format.hdmi_format = AV8100_HDMI;
+ av8100_config.hdmi_format.dvi_format = AV8100_DVI_CTRL_CTL0;
+ ret = av8100_conf_prep(AV8100_COMMAND_HDMI, &av8100_config);
+ }
- av8100_config.hdmi_format.hdmi_format = AV8100_HDMI;
- av8100_config.hdmi_format.dvi_format = AV8100_DVI_CTRL_CTL0;
-
- ret = av8100_conf_prep(AV8100_COMMAND_HDMI, &av8100_config);
if (ret) {
dev_err(&dev->dev, "%s:av8100_conf_prep "
- "AV8100_COMMAND_HDMI failed\n", __func__);
+ "AV8100_COMMAND_HDMI/DENC failed\n", __func__);
return ret;
}
@@ -784,11 +759,16 @@ static int hdmi_on_first_update(struct mcde_display_device *dev)
return ret;
}
- ret = av8100_conf_w(AV8100_COMMAND_HDMI, NULL,
- NULL, I2C_INTERFACE);
+ if (dev->port->hdmi_sdtv_switch == SDTV_SWITCH)
+ ret = av8100_conf_w(AV8100_COMMAND_DENC, NULL, NULL,
+ I2C_INTERFACE);
+ else
+ ret = av8100_conf_w(AV8100_COMMAND_HDMI, NULL, NULL,
+ I2C_INTERFACE);
if (ret) {
dev_err(&dev->dev, "%s:av8100_conf_w "
- "AV8100_COMMAND_HDMI failed\n", __func__);
+ "AV8100_COMMAND_HDMI/DENC failed\n", __func__);
+ return ret;
}
return ret;
@@ -802,7 +782,7 @@ static int hdmi_set_power_mode(struct mcde_display_device *ddev,
/* OFF -> STANDBY */
if (ddev->power_mode == MCDE_DISPLAY_PM_OFF &&
- power_mode != MCDE_DISPLAY_PM_OFF) {
+ power_mode != MCDE_DISPLAY_PM_OFF) {
if (ddev->platform_enable) {
ret = ddev->platform_enable(ddev);
if (ret)
@@ -823,19 +803,20 @@ static int hdmi_set_power_mode(struct mcde_display_device *ddev,
}
/* STANDBY -> ON */
if (ddev->power_mode == MCDE_DISPLAY_PM_STANDBY &&
- power_mode == MCDE_DISPLAY_PM_ON) {
+ power_mode == MCDE_DISPLAY_PM_ON) {
+
ddev->power_mode = MCDE_DISPLAY_PM_ON;
goto set_power_and_exit;
}
/* ON -> STANDBY */
else if (ddev->power_mode == MCDE_DISPLAY_PM_ON &&
- power_mode <= MCDE_DISPLAY_PM_STANDBY) {
+ power_mode <= MCDE_DISPLAY_PM_STANDBY) {
ddev->power_mode = MCDE_DISPLAY_PM_STANDBY;
}
/* STANDBY -> OFF */
if (ddev->power_mode == MCDE_DISPLAY_PM_STANDBY &&
- power_mode == MCDE_DISPLAY_PM_OFF) {
+ power_mode == MCDE_DISPLAY_PM_OFF) {
memset(&(ddev->video_mode), 0, sizeof(struct mcde_video_mode));
ret = av8100_powerdown();
if (ret)