From 24f76485b888b3df58a1c5b0f40fbec4f6de7b5a Mon Sep 17 00:00:00 2001 From: hjc Date: Wed, 6 Aug 2014 08:36:51 +0800 Subject: [PATCH] rk3036 hdmi: add support yuv input and output --- .../rockchip/hdmi/chips/rk3036/rk3036_hdmi.c | 22 +++++++++++++++++-- .../rockchip/hdmi/chips/rk3036/rk3036_hdmi.h | 1 + .../hdmi/chips/rk3036/rk3036_hdmi_hw.c | 19 +++++++++++++--- drivers/video/rockchip/hdmi/rk_hdmi.h | 11 ++++++++++ 4 files changed, 48 insertions(+), 5 deletions(-) diff --git a/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdmi.c b/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdmi.c index 6067eec725a3..2ab8c027bcec 100755 --- a/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdmi.c +++ b/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdmi.c @@ -293,10 +293,20 @@ static int rk3036_hdmi_drv_init(struct hdmi *hdmi_drv) return ret; } +static struct rk_hdmi_drvdata rk3036_hdmi_drvdata = { + .soc_type = HDMI_SOC_RK3036, +}; + +static struct rk_hdmi_drvdata rk312x_hdmi_drvdata = { + .soc_type = HDMI_SOC_RK312X, +}; + #if defined(CONFIG_OF) static const struct of_device_id rk3036_hdmi_of_match[] = { - {.compatible = "rockchip,rk3036-hdmi",}, - {.compatible = "rockchip,rk312x-hdmi",}, + {.compatible = "rockchip,rk3036-hdmi", + .data = (void *)&rk3036_hdmi_drvdata, }, + {.compatible = "rockchip,rk312x-hdmi", + .data = (void *)&rk312x_hdmi_drvdata,}, {} }; @@ -308,6 +318,8 @@ static int rk3036_hdmi_probe(struct platform_device *pdev) int ret; struct hdmi *hdmi_drv; struct resource *res; + const struct of_device_id *match; + struct device_node *node = pdev->dev.of_node; hdmi_dev = devm_kzalloc(&pdev->dev, sizeof(struct rk_hdmi_device), GFP_KERNEL); @@ -321,6 +333,12 @@ static int rk3036_hdmi_probe(struct platform_device *pdev) platform_set_drvdata(pdev, hdmi_dev); spin_lock_init(&hdmi_dev->reg_lock); + match = of_match_node(rk3036_hdmi_of_match, node); + hdmi_drv->data = (struct rk_hdmi_drvdata*)match->data; + dev_info(hdmi_drv->dev, "%s,type=%d\n", + __func__,hdmi_drv->data->soc_type); + + #ifdef CONFIG_SWITCH hdmi_drv->switch_hdmi.name = "hdmi"; switch_dev_register(&(hdmi_drv->switch_hdmi)); diff --git a/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdmi.h b/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdmi.h index 9c1d67311b5b..15de55767060 100755 --- a/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdmi.h +++ b/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdmi.h @@ -8,6 +8,7 @@ enum { INPUT_SPDIF }; + #if defined(CONFIG_SND_RK_SOC_HDMI_SPDIF) #define HDMI_CODEC_SOURCE_SELECT INPUT_SPDIF #else diff --git a/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdmi_hw.c b/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdmi_hw.c index 28040182de93..192460827bea 100755 --- a/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdmi_hw.c +++ b/drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdmi_hw.c @@ -219,6 +219,7 @@ static void rk3036_hdmi_config_avi(struct hdmi *hdmi_drv, unsigned char vic, unsigned char output_color) { int i; + int avi_color_mode; char info[SIZE_AVI_INFOFRAME]; struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv, struct rk_hdmi_device, @@ -230,7 +231,15 @@ static void rk3036_hdmi_config_avi(struct hdmi *hdmi_drv, info[1] = 0x02; info[2] = 0x0D; info[3] = info[0] + info[1] + info[2]; - info[4] = (AVI_COLOR_MODE_RGB << 5); + + if (output_color == VIDEO_OUTPUT_RGB444) + avi_color_mode = AVI_COLOR_MODE_RGB; + else if(output_color == VIDEO_OUTPUT_YCBCR444) + avi_color_mode = AVI_COLOR_MODE_YCBCR444; + else if(output_color == VIDEO_OUTPUT_YCBCR422) + avi_color_mode = AVI_COLOR_MODE_YCBCR422; + + info[4] = (avi_color_mode << 5); info[5] = (AVI_COLORIMETRY_NO_DATA << 6) | (AVI_CODED_FRAME_ASPECT_NO_DATA << 4) | @@ -269,8 +278,12 @@ static int rk3036_hdmi_config_video(struct hdmi *hdmi_drv, return -1; } - /* Output RGB as default */ - vpara->output_color = VIDEO_OUTPUT_RGB444; + if (hdmi_drv->data->soc_type == HDMI_SOC_RK3036) { + vpara->input_color = VIDEO_INPUT_COLOR_RGB; + vpara->output_color = VIDEO_OUTPUT_RGB444;/*rk3036 vop only can output rgb fmt*/ + } else if (hdmi_drv->data->soc_type == HDMI_SOC_RK312X) + vpara->input_color = VIDEO_INPUT_COLOR_YCBCR444;/*rk3128 vop can output yuv444 fmt*/ + if (hdmi_drv->pwr_mode == LOWER_PWR) rk3036_hdmi_set_pwr_mode(hdmi_drv, NORMAL); diff --git a/drivers/video/rockchip/hdmi/rk_hdmi.h b/drivers/video/rockchip/hdmi/rk_hdmi.h index 6ff89a998cfc..4f5f9fe1f2dc 100755 --- a/drivers/video/rockchip/hdmi/rk_hdmi.h +++ b/drivers/video/rockchip/hdmi/rk_hdmi.h @@ -48,6 +48,11 @@ enum { HDMI_SOURCE_LCDC1 = 1 }; +enum { + HDMI_SOC_RK3036, + HDMI_SOC_RK312X, + HDMI_SOC_RK3288 +}; /* * If HDMI_ENABLE, system will auto configure output mode according to EDID * If HDMI_DISABLE, system will output mode according to @@ -306,11 +311,17 @@ struct hdmi_video_para { */ }; +struct rk_hdmi_drvdata { + u8 soc_type; + u32 reversed; +}; + struct hdmi { struct device *dev; int id; int irq; struct rk_lcdc_driver *lcdc; + struct rk_hdmi_drvdata *data; #ifdef CONFIG_SWITCH struct switch_dev switch_hdmi; -- 2.34.1