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:
Jianwei Fan 2024-07-19 11:21:05 +08:00 committed by Tao Huang
commit ae0bee6029
4 changed files with 48 additions and 31 deletions

View file

@ -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;

View file

@ -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);

View file

@ -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

View file

@ -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 */