diff options
author | Cai YiWei <cyw@rock-chips.com> | 2018-12-29 17:47:03 +0800 |
---|---|---|
committer | Tao Huang <huangtao@rock-chips.com> | 2019-01-03 19:04:50 +0800 |
commit | b25f7aefe04509ea4dd00d818b197fa15bea161d (patch) | |
tree | c79d4a7579f6aea0308d4887e780d90b1eccc61d /drivers/media | |
parent | 70f89eed1a95f4681ca1d7e294459a83252ae30d (diff) |
media: i2c: tc35874x: support interlace output
Change-Id: I62025a9fcea726791aeed8a5e993e74f2e748d1c
Signed-off-by: Cai YiWei <cyw@rock-chips.com>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/i2c/tc35874x.c | 67 | ||||
-rw-r--r-- | drivers/media/i2c/tc35874x_regs.h | 7 |
2 files changed, 54 insertions, 20 deletions
diff --git a/drivers/media/i2c/tc35874x.c b/drivers/media/i2c/tc35874x.c index 9c7f4270567d..1932bad41602 100644 --- a/drivers/media/i2c/tc35874x.c +++ b/drivers/media/i2c/tc35874x.c @@ -80,14 +80,14 @@ static const struct v4l2_dv_timings_cap tc35874x_timings_cap = { V4L2_INIT_BT_TIMINGS(1, 10000, 1, 10000, 0, 165000000, V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT | V4L2_DV_BT_STD_GTF | V4L2_DV_BT_STD_CVT, - V4L2_DV_BT_CAP_PROGRESSIVE | + V4L2_DV_BT_CAP_PROGRESSIVE | V4L2_DV_BT_CAP_INTERLACED | V4L2_DV_BT_CAP_REDUCED_BLANKING | V4L2_DV_BT_CAP_CUSTOM) }; static u8 EDID_1920x1080_60[] = { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, - 0x52, 0x62, 0x88, 0x88, 0x00, 0x88, 0x88, 0x88, + 0x52, 0x62, 0x01, 0x88, 0x00, 0x88, 0x88, 0x88, 0x1C, 0x15, 0x01, 0x03, 0x80, 0x00, 0x00, 0x78, 0x0A, 0x0D, 0xC9, 0xA0, 0x57, 0x47, 0x98, 0x27, 0x12, 0x48, 0x4C, 0x00, 0x00, 0x00, 0x01, 0x01, @@ -98,10 +98,29 @@ static u8 EDID_1920x1080_60[] = { 0x01, 0x1D, 0x00, 0x72, 0x51, 0xD0, 0x1E, 0x20, 0x6E, 0x28, 0x55, 0x00, 0xC4, 0x8E, 0x21, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x54, - 0x6F, 0x73, 0x68, 0x69, 0x62, 0x61, 0x2D, 0x48, - 0x32, 0x44, 0x0A, 0x20, 0x00, 0x00, 0x00, 0xFD, - 0x00, 0x17, 0x3D, 0x0F, 0x8C, 0x17, 0x00, 0x0A, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x01, 0x92, + 0x37, 0x34, 0x39, 0x2D, 0x66, 0x48, 0x44, 0x37, + 0x32, 0x30, 0x0A, 0x20, 0x00, 0x00, 0x00, 0xFD, + 0x00, 0x14, 0x78, 0x01, 0xFF, 0x1D, 0x00, 0x0A, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x01, 0x7B, +}; + +static u8 EDID_extend[] = { + 0x02, 0x03, 0x1A, 0x71, 0x47, 0x90, 0x04, 0x02, + 0x01, 0x11, 0x22, 0x05, 0x23, 0x09, 0x07, 0x01, + 0x83, 0x01, 0x00, 0x00, 0x65, 0x03, 0x0C, 0x00, + 0x10, 0x00, 0x8C, 0x0A, 0xD0, 0x8A, 0x20, 0xE0, + 0x2D, 0x10, 0x10, 0x3E, 0x96, 0x00, 0x13, 0x8E, + 0x21, 0x00, 0x00, 0x1E, 0xD8, 0x09, 0x80, 0xA0, + 0x20, 0xE0, 0x2D, 0x10, 0x10, 0x60, 0xA2, 0x00, + 0xC4, 0x8E, 0x21, 0x00, 0x00, 0x18, 0x8C, 0x0A, + 0xD0, 0x90, 0x20, 0x40, 0x31, 0x20, 0x0C, 0x40, + 0x55, 0x00, 0x48, 0x39, 0x00, 0x00, 0x00, 0x18, + 0x01, 0x1D, 0x80, 0x18, 0x71, 0x38, 0x2D, 0x40, + 0x58, 0x2C, 0x45, 0x00, 0xC0, 0x6C, 0x00, 0x00, + 0x00, 0x18, 0x01, 0x1D, 0x80, 0x18, 0x71, 0x1C, + 0x16, 0x20, 0x58, 0x2C, 0x25, 0x00, 0xC0, 0x6C, + 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, }; struct tc35874x_state { @@ -589,22 +608,24 @@ static void tc35874x_set_pll(struct v4l2_subdev *sd) u16 pllctl0_new = SET_PLL_PRD(pdata->pll_prd) | SET_PLL_FBD(pdata->pll_fbd); u32 hsck = (pdata->refclk_hz / pdata->pll_prd) * pdata->pll_fbd; + u16 pll_frs; v4l2_dbg(2, debug, sd, "%s:\n", __func__); + if (state->timings.bt.interlaced) + hsck /= 2; + if (hsck > 500000000) + pll_frs = 0x0; + else if (hsck > 250000000) + pll_frs = 0x1; + else if (hsck > 125000000) + pll_frs = 0x2; + else + pll_frs = 0x3; /* Only rewrite when needed (new value or disabled), since rewriting * triggers another format change event. */ - if ((pllctl0 != pllctl0_new) || ((pllctl1 & MASK_PLL_EN) == 0)) { - u16 pll_frs; - - if (hsck > 500000000) - pll_frs = 0x0; - else if (hsck > 250000000) - pll_frs = 0x1; - else if (hsck > 125000000) - pll_frs = 0x2; - else - pll_frs = 0x3; + if (pllctl0 != pllctl0_new || (pllctl1 & MASK_PLL_EN) == 0 || + SET_PLL_FRS(pll_frs) != (pllctl1 & MASK_PLL_FRS)) { v4l2_dbg(1, debug, sd, "%s: updating PLL clock\n", __func__); tc35874x_sleep_mode(sd, true); @@ -1535,7 +1556,9 @@ static int tc35874x_get_fmt(struct v4l2_subdev *sd, format->format.code = state->mbus_fmt_code; format->format.width = state->timings.bt.width; format->format.height = state->timings.bt.height; - format->format.field = V4L2_FIELD_NONE; + format->format.field = + state->timings.bt.interlaced ? + V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE; switch (vi_rep & MASK_VOUT_COLOR_SEL) { case MASK_VOUT_COLOR_RGB_FULL: @@ -1657,11 +1680,17 @@ static int tc35874x_s_edid(struct v4l2_subdev *sd, return 0; } - for (i = 0; i < edid_len; i += EDID_BLOCK_SIZE) + for (i = 0; i < edid_len; i += EDID_BLOCK_SIZE) { i2c_wr(sd, EDID_RAM + i, edid->edid + i, EDID_BLOCK_SIZE); + i2c_wr(sd, EDID_EXT_RAM + i, EDID_extend + i, EDID_BLOCK_SIZE); + } state->edid_blocks_written = edid->blocks; + /* frame count number: FS = FE 1,2,1,2... */ + i2c_wr16(sd, FCCTL, 0x0002); + /* packet id for interlace mode only */ + i2c_wr16(sd, PACKETID1, 0x1e1e); if (tx_5v_power_present(sd)) tc35874x_enable_edid(sd); diff --git a/drivers/media/i2c/tc35874x_regs.h b/drivers/media/i2c/tc35874x_regs.h index b441d2dcfc46..4a21f0d5e0df 100644 --- a/drivers/media/i2c/tc35874x_regs.h +++ b/drivers/media/i2c/tc35874x_regs.h @@ -67,6 +67,10 @@ #define FIFOCTL 0x0006 +#define PACKETID1 0x000C + +#define FCCTL 0x0012 + #define INTSTATUS 0x0014 #define MASK_AMUTE_INT 0x0400 #define MASK_HDMI_INT 0x0200 @@ -678,6 +682,7 @@ #define MASK_MAX_EXCED 0x08 #define EDID_RAM 0x8C00 +#define EDID_EXT_RAM 0x8c80 #define NO_GDB_LIMIT 0x9007 -#endif
\ No newline at end of file +#endif |