diff --git a/drivers/media/platform/rockchip/hdmirx/rk_hdmirx.c b/drivers/media/platform/rockchip/hdmirx/rk_hdmirx.c index 788caa3761852..110e686b55aaf 100644 --- a/drivers/media/platform/rockchip/hdmirx/rk_hdmirx.c +++ b/drivers/media/platform/rockchip/hdmirx/rk_hdmirx.c @@ -226,6 +226,7 @@ struct rk_hdmirx_dev { struct v4l2_ctrl *audio_present_ctrl; struct v4l2_dv_timings timings; struct gpio_desc *hdmirx_det_gpio; + struct v4l2_ctrl *content_type; struct work_struct work_wdt_config; struct delayed_work delayed_work_hotplug; struct delayed_work delayed_work_res_change; @@ -1004,6 +1005,36 @@ static bool hdmirx_check_timing_valid(struct v4l2_bt_timings *bt) return true; } +static void hdmirx_get_avi_infoframe(struct rk_hdmirx_dev *hdmirx_dev) +{ + struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; + union hdmi_infoframe frame = {}; + int err, i, b, itr = 0; + + u8 aviif[3 + 7 * 4]; + u32 val; + + aviif[itr++] = HDMI_INFOFRAME_TYPE_AVI; + val = hdmirx_readl(hdmirx_dev, PKTDEC_AVIIF_PH2_1); + aviif[itr++] = val & 0xff; + aviif[itr++] = (val >> 8) & 0xff; + for (i = 0; i < 7; i++) { + val = hdmirx_readl(hdmirx_dev, PKTDEC_AVIIF_PB3_0 + 4 * i); + for (b = 0; b < 4; b++) + aviif[itr++] = (val >> (8 * b)) & 0xff; + } + err = hdmi_infoframe_unpack(&frame, aviif, sizeof(aviif)); + if (err) { + v4l2_err(v4l2_dev, "failed to unpack AVI infoframe\n"); + return; + } + if (frame.avi.itc) { + v4l2_ctrl_s_ctrl(hdmirx_dev->content_type, frame.avi.content_type); + } else { + v4l2_ctrl_s_ctrl(hdmirx_dev->content_type, V4L2_DV_IT_CONTENT_TYPE_NO_ITC); + } +} + static int hdmirx_get_detected_timings(struct rk_hdmirx_dev *hdmirx_dev, struct v4l2_dv_timings *timings, bool from_dma) { @@ -1038,6 +1069,7 @@ static int hdmirx_get_detected_timings(struct rk_hdmirx_dev *hdmirx_dev, bt->pixelclock = tmds_clk; if (hdmirx_dev->pix_fmt == HDMIRX_YUV420) bt->pixelclock *= 2; + hdmirx_get_avi_infoframe(hdmirx_dev); hdmirx_get_timings(hdmirx_dev, bt, from_dma); v4l2_dbg(2, debug, v4l2_dev, "tmds_clk:%llu, pix_clk:%d\n", tmds_clk, pix_clk); @@ -1689,7 +1721,8 @@ static int hdmirx_wait_lock_and_get_timing(struct rk_hdmirx_dev *hdmirx_dev) hdmirx_phy_config(hdmirx_dev); if (!tx_5v_power_present(hdmirx_dev)) { - //v4l2_err(v4l2_dev, "%s HDMI pull out, return!\n", __func__); + v4l2_ctrl_s_ctrl(hdmirx_dev->content_type, V4L2_DV_IT_CONTENT_TYPE_NO_ITC); + v4l2_err(v4l2_dev, "%s HDMI pull out, return!\n", __func__); return -1; } @@ -1701,6 +1734,7 @@ static int hdmirx_wait_lock_and_get_timing(struct rk_hdmirx_dev *hdmirx_dev) __func__, hdmirx_dev->tmds_clk_ratio); v4l2_err(v4l2_dev, "%s mu_st:%#x, scdc_st:%#x, dma_st10:%#x\n", __func__, mu_status, scdc_status, dma_st10); + v4l2_ctrl_s_ctrl(hdmirx_dev->content_type, V4L2_DV_IT_CONTENT_TYPE_NO_ITC); return -1; } @@ -4846,7 +4880,7 @@ static int hdmirx_probe(struct platform_device *pdev) strscpy(v4l2_dev->name, dev_name(dev), sizeof(v4l2_dev->name)); hdl = &hdmirx_dev->hdl; - v4l2_ctrl_handler_init(hdl, 3); + v4l2_ctrl_handler_init(hdl, 4); hdmirx_dev->detect_tx_5v_ctrl = v4l2_ctrl_new_std(hdl, NULL, V4L2_CID_DV_RX_POWER_PRESENT, 0, 1, 0, 0); @@ -4859,6 +4893,12 @@ static int hdmirx_probe(struct platform_device *pdev) &hdmirx_ctrl_audio_present, NULL); if (hdmirx_dev->audio_present_ctrl) hdmirx_dev->audio_present_ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; + hdmirx_dev->content_type = v4l2_ctrl_new_std_menu(hdl, NULL, + V4L2_CID_DV_RX_IT_CONTENT_TYPE, + V4L2_DV_IT_CONTENT_TYPE_NO_ITC, + 0, + V4L2_DV_IT_CONTENT_TYPE_NO_ITC); + if (hdl->error) { dev_err(dev, "v4l2 ctrl handler init failed!\n"); ret = hdl->error;