diff --git a/drivers/media/i2c/s5kjn1.c b/drivers/media/i2c/s5kjn1.c index 0dcec287890b..df2dd228e9b7 100644 --- a/drivers/media/i2c/s5kjn1.c +++ b/drivers/media/i2c/s5kjn1.c @@ -6,6 +6,9 @@ * * V0.0X01.0X00 init version. * V0.0X01.0X01 adjust supply sequence to suit spec + * V0.0X01.0X02 + * 1. set binning output 32 pixel aligned. + * 2. fix channel info omitted copy from user issue. */ //#define DEBUG #include @@ -31,7 +34,7 @@ #include #include "otp_eeprom.h" -#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x01) +#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x02) #ifndef V4L2_CID_DIGITAL_GAIN #define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN @@ -1435,12 +1438,16 @@ static long s5kjn1_compat_ioctl32(struct v4l2_subdev *sd, ret = -ENOMEM; return ret; } - - ret = s5kjn1_ioctl(sd, cmd, ch_info); + ret = copy_from_user(ch_info, up, sizeof(*ch_info)); if (!ret) { - ret = copy_to_user(up, ch_info, sizeof(*ch_info)); - if (ret) - ret = -EFAULT; + ret = s5kjn1_ioctl(sd, cmd, ch_info); + if (!ret) { + ret = copy_to_user(up, ch_info, sizeof(*ch_info)); + if (ret) + ret = -EFAULT; + } + } else { + ret = -EFAULT; } kfree(ch_info); break; @@ -1750,27 +1757,33 @@ static int s5kjn1_enum_frame_interval(struct v4l2_subdev *sd, fie->reserved[0] = s5kjn1->support_modes[fie->index].hdr_mode; return 0; } -//#define RK356X_TEST -#ifdef RK356X_TEST + #define CROP_START(SRC, DST) (((SRC) - (DST)) / 2 / 4 * 4) -#define DST_WIDTH 4096 -#define DST_HEIGHT 2304 +#define DST_WIDTH 4064 +#define DST_HEIGHT 3072 static int s5kjn1_get_selection(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_selection *sel) { struct s5kjn1 *s5kjn1 = to_s5kjn1(sd); + if (sel->target == V4L2_SEL_TGT_CROP_BOUNDS) { - sel->r.left = CROP_START(s5kjn1->cur_mode->width, DST_WIDTH); - sel->r.width = DST_WIDTH; - sel->r.top = CROP_START(s5kjn1->cur_mode->height, DST_HEIGHT); - sel->r.height = DST_HEIGHT; + if (s5kjn1->cur_mode->width == 4080) { + sel->r.left = CROP_START(s5kjn1->cur_mode->width, DST_WIDTH); + sel->r.width = DST_WIDTH; + sel->r.top = CROP_START(s5kjn1->cur_mode->height, DST_HEIGHT); + sel->r.height = DST_HEIGHT; + } else { + sel->r.left = CROP_START(s5kjn1->cur_mode->width, s5kjn1->cur_mode->width); + sel->r.width = s5kjn1->cur_mode->width; + sel->r.top = CROP_START(s5kjn1->cur_mode->height, s5kjn1->cur_mode->height); + sel->r.height = s5kjn1->cur_mode->height; + } return 0; } return -EINVAL; } -#endif static const struct dev_pm_ops s5kjn1_pm_ops = { SET_RUNTIME_PM_OPS(s5kjn1_runtime_suspend, @@ -1802,9 +1815,7 @@ static const struct v4l2_subdev_pad_ops s5kjn1_pad_ops = { .enum_frame_interval = s5kjn1_enum_frame_interval, .get_fmt = s5kjn1_get_fmt, .set_fmt = s5kjn1_set_fmt, -#ifdef RK356X_TEST .get_selection = s5kjn1_get_selection, -#endif .get_mbus_config = s5kjn1_g_mbus_config, };