Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add itc type to hdmirx #262

Merged
merged 1 commit into from
Oct 14, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 42 additions & 2 deletions drivers/media/platform/rockchip/hdmirx/rk_hdmirx.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}

Expand All @@ -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;
}
Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand Down