media: i2c: rk628: fix user set csc color range
Change-Id: Ibc35c8bbbc54c9b4de4977d9500083afa2857b36 Signed-off-by: Jianwei Fan <jianwei.fan@rock-chips.com>
This commit is contained in:
parent
af06e7267a
commit
ae0bee6029
4 changed files with 48 additions and 31 deletions
|
|
@ -62,12 +62,6 @@ enum tx_mode_type {
|
|||
DSI_MODE,
|
||||
};
|
||||
|
||||
enum output_color_range {
|
||||
OUT_RANGE_AUTO = 0,
|
||||
OUT_RANGE_LIMIT = 1,
|
||||
OUT_RANGE_FULL = 2,
|
||||
};
|
||||
|
||||
struct rk628_plat_data {
|
||||
int bus_fmt;
|
||||
int tx_mode;
|
||||
|
|
@ -138,7 +132,7 @@ struct rk628_csi {
|
|||
bool is_streaming;
|
||||
bool csi_ints_en;
|
||||
bool dual_mipi_use;
|
||||
int output_range;
|
||||
enum user_color_range user_color_range;
|
||||
};
|
||||
|
||||
struct rk628_csi_mode {
|
||||
|
|
@ -816,13 +810,13 @@ static void rk628_dsi_set_scs(struct rk628_csi *csi)
|
|||
|
||||
color_range = rk628_hdmirx_get_range(csi->rk628);
|
||||
rk628_i2c_write(csi->rk628, GRF_CSC_CTRL_CON, SW_YUV2VYU_SWP(0));
|
||||
if (csi->output_range == OUT_RANGE_AUTO)
|
||||
if (csi->user_color_range == COLOR_RANGE_AUTO)
|
||||
rk628_post_process_csc_en(csi->rk628,
|
||||
color_range == HDMIRX_LIMIT_RANGE ? false : true);
|
||||
else if (csi->output_range == OUT_RANGE_LIMIT)
|
||||
rk628_post_process_csc_en(csi->rk628, false);
|
||||
color_range == HDMIRX_LIMIT_RANGE ? false : true, true);
|
||||
else if (csi->user_color_range == COLOR_RANGE_LIMIT)
|
||||
rk628_post_process_csc_en(csi->rk628, false, true);
|
||||
else
|
||||
rk628_post_process_csc_en(csi->rk628, true);
|
||||
rk628_post_process_csc_en(csi->rk628, true, true);
|
||||
}
|
||||
|
||||
/* if avi packet is not stable, reset ctrl*/
|
||||
|
|
@ -1173,13 +1167,13 @@ static void rk628_csi_set_csi(struct v4l2_subdev *sd)
|
|||
|
||||
color_range = rk628_hdmirx_get_range(csi->rk628);
|
||||
rk628_i2c_write(csi->rk628, GRF_CSC_CTRL_CON, SW_YUV2VYU_SWP(1));
|
||||
if (csi->output_range == OUT_RANGE_AUTO)
|
||||
if (csi->user_color_range == COLOR_RANGE_AUTO)
|
||||
rk628_post_process_csc_en(csi->rk628,
|
||||
color_range == HDMIRX_LIMIT_RANGE ? false : true);
|
||||
else if (csi->output_range == OUT_RANGE_LIMIT)
|
||||
rk628_post_process_csc_en(csi->rk628, false);
|
||||
color_range == HDMIRX_LIMIT_RANGE ? false : true, true);
|
||||
else if (csi->user_color_range == COLOR_RANGE_LIMIT)
|
||||
rk628_post_process_csc_en(csi->rk628, false, true);
|
||||
else
|
||||
rk628_post_process_csc_en(csi->rk628, true);
|
||||
rk628_post_process_csc_en(csi->rk628, true, true);
|
||||
}
|
||||
/* if avi packet is not stable, reset ctrl*/
|
||||
if (!avi_rdy) {
|
||||
|
|
@ -2456,6 +2450,21 @@ static void rk628_csi_reset_streaming(struct v4l2_subdev *sd, int on)
|
|||
fps_calc(&csi->timings.bt));
|
||||
}
|
||||
|
||||
static void rk628_csi_set_color_range(struct v4l2_subdev *sd)
|
||||
{
|
||||
struct rk628_csi *csi = to_csi(sd);
|
||||
u8 color_range;
|
||||
|
||||
color_range = rk628_hdmirx_get_range(csi->rk628);
|
||||
if (csi->user_color_range == COLOR_RANGE_AUTO)
|
||||
rk628_post_process_csc_en(csi->rk628,
|
||||
color_range == HDMIRX_LIMIT_RANGE ? false : true, true);
|
||||
else if (csi->user_color_range == COLOR_RANGE_LIMIT)
|
||||
rk628_post_process_csc_en(csi->rk628, false, true);
|
||||
else
|
||||
rk628_post_process_csc_en(csi->rk628, true, true);
|
||||
}
|
||||
|
||||
static long rk628_csi_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
|
||||
{
|
||||
struct rk628_csi *csi = to_csi(sd);
|
||||
|
|
@ -2540,9 +2549,13 @@ static long rk628_csi_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
|
|||
case RKMODULE_GET_DSI_MODE:
|
||||
*(int *)arg = csi->dsi.vid_mode;
|
||||
break;
|
||||
case RK_HDMIRX_CMD_SET_OUTPUT_RANGE:
|
||||
csi->output_range = *((int *)arg);
|
||||
v4l2_dbg(1, debug, sd, "set output_range: %d\n", csi->output_range);
|
||||
case RK_HDMIRX_CMD_SET_COLOR_RANGE:
|
||||
csi->user_color_range = *((int *)arg);
|
||||
if (csi->user_color_range > COLOR_RANGE_FULL ||
|
||||
csi->user_color_range < COLOR_RANGE_AUTO)
|
||||
csi->user_color_range = COLOR_RANGE_AUTO;
|
||||
v4l2_info(sd, "user set color range: %d\n", csi->user_color_range);
|
||||
rk628_csi_set_color_range(sd);
|
||||
break;
|
||||
default:
|
||||
ret = -ENOIOCTLCMD;
|
||||
|
|
@ -2887,7 +2900,7 @@ static long rk628_csi_compat_ioctl32(struct v4l2_subdev *sd,
|
|||
}
|
||||
kfree(seq);
|
||||
break;
|
||||
case RK_HDMIRX_CMD_SET_OUTPUT_RANGE:
|
||||
case RK_HDMIRX_CMD_SET_COLOR_RANGE:
|
||||
ret = copy_from_user(&is_full_range, up, sizeof(int));
|
||||
if (!ret)
|
||||
ret = rk628_csi_ioctl(sd, cmd, &is_full_range);
|
||||
|
|
@ -3216,7 +3229,7 @@ static int rk628_csi_probe_of(struct rk628_csi *csi)
|
|||
csi->nosignal = true;
|
||||
csi->stream_state = 0;
|
||||
csi->avi_rcv_rdy = false;
|
||||
csi->output_range = OUT_RANGE_AUTO;
|
||||
csi->user_color_range = COLOR_RANGE_AUTO;
|
||||
|
||||
ret = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -1608,7 +1608,8 @@ static u8 rk628_get_output_color_space(struct rk628 *rk628, u8 input_color_space
|
|||
}
|
||||
}
|
||||
|
||||
static void rk628_post_process_csc(struct rk628 *rk628, bool is_output_full_range)
|
||||
static void rk628_post_process_csc(struct rk628 *rk628,
|
||||
bool is_input_full_range, bool is_output_full_range)
|
||||
{
|
||||
enum bus_format in_fmt, out_fmt;
|
||||
struct post_csc_coef csc_coef = {};
|
||||
|
|
@ -1623,14 +1624,11 @@ static void rk628_post_process_csc(struct rk628 *rk628, bool is_output_full_rang
|
|||
else if (out_fmt == BUS_FMT_RGB)
|
||||
rk628_i2c_write(rk628, GRF_CSC_CTRL_CON, SW_Y2R_EN(1));
|
||||
} else {
|
||||
u8 in_color_range, in_color_space, output_color_space;
|
||||
u8 in_color_space, output_color_space;
|
||||
enum color_space_type input_color_space;
|
||||
bool is_input_full_range;
|
||||
|
||||
in_color_range = rk628_hdmirx_get_range(rk628);
|
||||
in_color_space = rk628_hdmirx_get_color_space(rk628);
|
||||
input_color_space = rk628_csc_color_space_convert(in_color_space, in_fmt);
|
||||
is_input_full_range = (in_color_range == HDMIRX_LIMIT_RANGE) ? false : true;
|
||||
output_color_space = rk628_get_output_color_space(rk628, input_color_space);
|
||||
|
||||
rockchip_calc_post_csc(rk628, &csc_coef, is_input_full_range,
|
||||
|
|
@ -1718,9 +1716,9 @@ void rk628_post_process_pattern_node(struct rk628 *rk628)
|
|||
}
|
||||
EXPORT_SYMBOL(rk628_post_process_pattern_node);
|
||||
|
||||
void rk628_post_process_csc_en(struct rk628 *rk628, bool output_full_range)
|
||||
void rk628_post_process_csc_en(struct rk628 *rk628, bool input_full_range, bool output_full_range)
|
||||
{
|
||||
rk628_post_process_csc(rk628, output_full_range);
|
||||
rk628_post_process_csc(rk628, input_full_range, output_full_range);
|
||||
rk628_i2c_write(rk628, GRF_SCALER_CON0, SCL_EN(1));
|
||||
}
|
||||
EXPORT_SYMBOL(rk628_post_process_csc_en);
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
#ifndef POST_PROCESS_H
|
||||
#define POST_PROCESS_H
|
||||
|
||||
void rk628_post_process_csc_en(struct rk628 *rk628, bool output_full_range);
|
||||
void rk628_post_process_csc_en(struct rk628 *rk628, bool input_full_range, bool output_full_range);
|
||||
void rk628_post_process_csc_dis(struct rk628 *rk628);
|
||||
void rk628_post_process_pattern_node(struct rk628 *rk628);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -58,6 +58,12 @@ enum hdmirx_edid_mode {
|
|||
HDMIRX_EDID_4K60HZ_YUV420,
|
||||
};
|
||||
|
||||
enum user_color_range {
|
||||
COLOR_RANGE_AUTO = 0,
|
||||
COLOR_RANGE_LIMIT = 1,
|
||||
COLOR_RANGE_FULL = 2,
|
||||
};
|
||||
|
||||
/* Private v4l2 ioctl */
|
||||
#define RK_HDMIRX_CMD_GET_FPS \
|
||||
_IOR('V', BASE_VIDIOC_PRIVATE + 0, int)
|
||||
|
|
@ -104,7 +110,7 @@ enum hdmirx_edid_mode {
|
|||
#define RK_HDMIRX_CMD_GET_HDCP_ENC_STATUS \
|
||||
_IOR('V', BASE_VIDIOC_PRIVATE + 14, __u8)
|
||||
|
||||
#define RK_HDMIRX_CMD_SET_OUTPUT_RANGE \
|
||||
#define RK_HDMIRX_CMD_SET_COLOR_RANGE \
|
||||
_IOW('V', BASE_VIDIOC_PRIVATE + 15, int)
|
||||
|
||||
/* Private v4l2 event */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue