diff --git a/drivers/media/i2c/imx258.c b/drivers/media/i2c/imx258.c index 8eb03aab1a67..751887cc0971 100644 --- a/drivers/media/i2c/imx258.c +++ b/drivers/media/i2c/imx258.c @@ -129,6 +129,7 @@ struct imx258 { struct imx258_otp_info *otp; struct rkmodule_inf module_inf; struct rkmodule_awb_cfg awb_cfg; + struct rkmodule_lsc_cfg lsc_cfg; }; #define to_imx258(sd) container_of(sd, struct imx258, subdev) @@ -962,14 +963,22 @@ static void imx258_get_module_inf(struct imx258 *imx258, imx258_get_otp(otp, inf); } -static void imx258_set_module_inf(struct imx258 *imx258, - struct rkmodule_awb_cfg *cfg) +static void imx258_set_awb_cfg(struct imx258 *imx258, + struct rkmodule_awb_cfg *cfg) { mutex_lock(&imx258->mutex); memcpy(&imx258->awb_cfg, cfg, sizeof(*cfg)); mutex_unlock(&imx258->mutex); } +static void imx258_set_lsc_cfg(struct imx258 *imx258, + struct rkmodule_lsc_cfg *cfg) +{ + mutex_lock(&imx258->mutex); + memcpy(&imx258->lsc_cfg, cfg, sizeof(*cfg)); + mutex_unlock(&imx258->mutex); +} + static long imx258_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { struct imx258 *imx258 = to_imx258(sd); @@ -980,7 +989,10 @@ static long imx258_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) imx258_get_module_inf(imx258, (struct rkmodule_inf *)arg); break; case RKMODULE_AWB_CFG: - imx258_set_module_inf(imx258, (struct rkmodule_awb_cfg *)arg); + imx258_set_awb_cfg(imx258, (struct rkmodule_awb_cfg *)arg); + break; + case RKMODULE_LSC_CFG: + imx258_set_lsc_cfg(imx258, (struct rkmodule_lsc_cfg *)arg); break; default: ret = -ENOTTY; @@ -996,7 +1008,8 @@ static long imx258_compat_ioctl32(struct v4l2_subdev *sd, { void __user *up = compat_ptr(arg); struct rkmodule_inf *inf; - struct rkmodule_awb_cfg *cfg; + struct rkmodule_awb_cfg *awb_cfg; + struct rkmodule_lsc_cfg *lsc_cfg; long ret = 0; switch (cmd) { @@ -1013,16 +1026,28 @@ static long imx258_compat_ioctl32(struct v4l2_subdev *sd, kfree(inf); break; case RKMODULE_AWB_CFG: - cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); - if (!cfg) { + awb_cfg = kzalloc(sizeof(*awb_cfg), GFP_KERNEL); + if (!awb_cfg) { ret = -ENOMEM; return ret; } - ret = copy_from_user(cfg, up, sizeof(*cfg)); + ret = copy_from_user(awb_cfg, up, sizeof(*awb_cfg)); if (!ret) - ret = imx258_ioctl(sd, cmd, cfg); - kfree(cfg); + ret = imx258_ioctl(sd, cmd, awb_cfg); + kfree(awb_cfg); + break; + case RKMODULE_LSC_CFG: + lsc_cfg = kzalloc(sizeof(*lsc_cfg), GFP_KERNEL); + if (!lsc_cfg) { + ret = -ENOMEM; + return ret; + } + + ret = copy_from_user(lsc_cfg, up, sizeof(*lsc_cfg)); + if (!ret) + ret = imx258_ioctl(sd, cmd, lsc_cfg); + kfree(lsc_cfg); break; default: ret = -ENOTTY; @@ -1039,21 +1064,21 @@ static int imx258_apply_otp(struct imx258 *imx258) struct i2c_client *client = imx258->client; struct imx258_otp_info *otp_ptr = imx258->otp; struct rkmodule_awb_cfg *awb_cfg = &imx258->awb_cfg; - u32 golden_bg_ratio; - u32 golden_rg_ratio; - u32 golden_g_value; + struct rkmodule_lsc_cfg *lsc_cfg = &imx258->lsc_cfg; + u32 golden_bg_ratio = 0; + u32 golden_rg_ratio = 0; + u32 golden_g_value = 0; u32 bg_ratio; u32 rg_ratio; //u32 g_value; u32 i; - if (!imx258->awb_cfg.enable) - return 0; - - golden_g_value = (awb_cfg->golden_gb_value + - awb_cfg->golden_gr_value) / 2; - golden_bg_ratio = awb_cfg->golden_b_value * 0x400 / golden_g_value; - golden_rg_ratio = awb_cfg->golden_r_value * 0x400 / golden_g_value; + if (awb_cfg->enable) { + golden_g_value = (awb_cfg->golden_gb_value + + awb_cfg->golden_gr_value) / 2; + golden_bg_ratio = awb_cfg->golden_b_value * 0x400 / golden_g_value; + golden_rg_ratio = awb_cfg->golden_r_value * 0x400 / golden_g_value; + } /* apply OTP WB Calibration */ if ((otp_ptr->flag & 0x40) && golden_bg_ratio && golden_rg_ratio) { rg_ratio = otp_ptr->rg_ratio; @@ -1103,7 +1128,7 @@ static int imx258_apply_otp(struct imx258 *imx258) } /* apply OTP Lenc Calibration */ - if (otp_ptr->flag & 0x10) { + if ((otp_ptr->flag & 0x10) && lsc_cfg->enable) { for (i = 0; i < 504; i++) { imx258_write_reg(client, 0xA300 + i, IMX258_REG_VALUE_08BIT, otp_ptr->lenc[i]); diff --git a/drivers/media/i2c/ov8858.c b/drivers/media/i2c/ov8858.c index ce73f5b03f7a..a7d916d209a7 100644 --- a/drivers/media/i2c/ov8858.c +++ b/drivers/media/i2c/ov8858.c @@ -190,6 +190,7 @@ struct ov8858 { const char *len_name; struct rkmodule_inf module_inf; struct rkmodule_awb_cfg awb_cfg; + struct rkmodule_lsc_cfg lsc_cfg; }; #define to_ov8858(sd) container_of(sd, struct ov8858, subdev) @@ -1380,7 +1381,7 @@ static const char * const ov8858_test_pattern_menu[] = { /* Write registers up to 4 at a time */ static int ov8858_write_reg(struct i2c_client *client, u16 reg, - u32 len, u32 val) + u32 len, u32 val) { u32 buf_i, val_i; u8 buf[6]; @@ -1408,7 +1409,7 @@ static int ov8858_write_reg(struct i2c_client *client, u16 reg, } static int ov8858_write_array(struct i2c_client *client, - const struct regval *regs) + const struct regval *regs) { u32 i; int ret = 0; @@ -1423,7 +1424,7 @@ static int ov8858_write_array(struct i2c_client *client, /* Read registers up to 4 at a time */ static int ov8858_read_reg(struct i2c_client *client, u16 reg, - unsigned int len, u32 *val) + unsigned int len, u32 *val) { struct i2c_msg msgs[2]; u8 *data_be_p; @@ -1457,7 +1458,7 @@ static int ov8858_read_reg(struct i2c_client *client, u16 reg, } static int ov8858_get_reso_dist(const struct ov8858_mode *mode, - struct v4l2_mbus_framefmt *framefmt) + struct v4l2_mbus_framefmt *framefmt) { return abs(mode->width - framefmt->width) + abs(mode->height - framefmt->height); @@ -1465,7 +1466,7 @@ static int ov8858_get_reso_dist(const struct ov8858_mode *mode, static const struct ov8858_mode * ov8858_find_best_fit(struct ov8858 *ov8858, - struct v4l2_subdev_format *fmt) + struct v4l2_subdev_format *fmt) { struct v4l2_mbus_framefmt *framefmt = &fmt->format; int dist; @@ -1485,7 +1486,7 @@ ov8858_find_best_fit(struct ov8858 *ov8858, } static int ov8858_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_format *fmt) { struct ov8858 *ov8858 = to_ov8858(sd); @@ -1523,8 +1524,8 @@ static int ov8858_set_fmt(struct v4l2_subdev *sd, } static int ov8858_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, - struct v4l2_subdev_format *fmt) + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *fmt) { struct ov8858 *ov8858 = to_ov8858(sd); const struct ov8858_mode *mode = ov8858->cur_mode; @@ -1549,8 +1550,8 @@ static int ov8858_get_fmt(struct v4l2_subdev *sd, } static int ov8858_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, - struct v4l2_subdev_mbus_code_enum *code) + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) { if (code->index != 0) return -EINVAL; @@ -1560,7 +1561,7 @@ static int ov8858_enum_mbus_code(struct v4l2_subdev *sd, } static int ov8858_enum_frame_sizes(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_frame_size_enum *fse) { struct ov8858 *ov8858 = to_ov8858(sd); @@ -1595,7 +1596,7 @@ static int ov8858_enable_test_pattern(struct ov8858 *ov8858, u32 pattern) } static int ov8858_g_frame_interval(struct v4l2_subdev *sd, - struct v4l2_subdev_frame_interval *fi) + struct v4l2_subdev_frame_interval *fi) { struct ov8858 *ov8858 = to_ov8858(sd); const struct ov8858_mode *mode = ov8858->cur_mode; @@ -1776,14 +1777,22 @@ static void ov8858_get_module_inf(struct ov8858 *ov8858, } } -static void ov8858_set_module_inf(struct ov8858 *ov8858, - struct rkmodule_awb_cfg *cfg) +static void ov8858_set_awb_cfg(struct ov8858 *ov8858, + struct rkmodule_awb_cfg *cfg) { mutex_lock(&ov8858->mutex); memcpy(&ov8858->awb_cfg, cfg, sizeof(*cfg)); mutex_unlock(&ov8858->mutex); } +static void ov8858_set_lsc_cfg(struct ov8858 *ov8858, + struct rkmodule_lsc_cfg *cfg) +{ + mutex_lock(&ov8858->mutex); + memcpy(&ov8858->lsc_cfg, cfg, sizeof(*cfg)); + mutex_unlock(&ov8858->mutex); +} + static long ov8858_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { struct ov8858 *ov8858 = to_ov8858(sd); @@ -1794,7 +1803,10 @@ static long ov8858_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) ov8858_get_module_inf(ov8858, (struct rkmodule_inf *)arg); break; case RKMODULE_AWB_CFG: - ov8858_set_module_inf(ov8858, (struct rkmodule_awb_cfg *)arg); + ov8858_set_awb_cfg(ov8858, (struct rkmodule_awb_cfg *)arg); + break; + case RKMODULE_LSC_CFG: + ov8858_set_lsc_cfg(ov8858, (struct rkmodule_lsc_cfg *)arg); break; default: ret = -ENOTTY; @@ -1810,7 +1822,8 @@ static long ov8858_compat_ioctl32(struct v4l2_subdev *sd, { void __user *up = compat_ptr(arg); struct rkmodule_inf *inf; - struct rkmodule_awb_cfg *cfg; + struct rkmodule_awb_cfg *awb_cfg; + struct rkmodule_lsc_cfg *lsc_cfg; long ret = 0; switch (cmd) { @@ -1827,16 +1840,28 @@ static long ov8858_compat_ioctl32(struct v4l2_subdev *sd, kfree(inf); break; case RKMODULE_AWB_CFG: - cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); - if (!cfg) { + awb_cfg = kzalloc(sizeof(*awb_cfg), GFP_KERNEL); + if (!awb_cfg) { ret = -ENOMEM; return ret; } - ret = copy_from_user(cfg, up, sizeof(*cfg)); + ret = copy_from_user(awb_cfg, up, sizeof(*awb_cfg)); if (!ret) - ret = ov8858_ioctl(sd, cmd, cfg); - kfree(cfg); + ret = ov8858_ioctl(sd, cmd, awb_cfg); + kfree(awb_cfg); + break; + case RKMODULE_LSC_CFG: + lsc_cfg = kzalloc(sizeof(*lsc_cfg), GFP_KERNEL); + if (!lsc_cfg) { + ret = -ENOMEM; + return ret; + } + + ret = copy_from_user(lsc_cfg, up, sizeof(*lsc_cfg)); + if (!ret) + ret = ov8858_ioctl(sd, cmd, lsc_cfg); + kfree(lsc_cfg); break; default: ret = -ENOTTY; @@ -1854,18 +1879,18 @@ static int ov8858_apply_otp_r1a(struct ov8858 *ov8858) struct i2c_client *client = ov8858->client; struct ov8858_otp_info_r1a *otp_ptr = ov8858->otp_r1a; struct rkmodule_awb_cfg *awb_cfg = &ov8858->awb_cfg; - u32 golden_bg_ratio; - u32 golden_rg_ratio; - u32 golden_g_value; + struct rkmodule_lsc_cfg *lsc_cfg = &ov8858->lsc_cfg; + u32 golden_bg_ratio = 0; + u32 golden_rg_ratio = 0; + u32 golden_g_value = 0; u32 i; - if (!ov8858->awb_cfg.enable) - return 0; - - golden_g_value = (awb_cfg->golden_gb_value + - awb_cfg->golden_gr_value) / 2; - golden_bg_ratio = awb_cfg->golden_b_value * 0x200 / golden_g_value; - golden_rg_ratio = awb_cfg->golden_r_value * 0x200 / golden_g_value; + if (awb_cfg->enable) { + golden_g_value = (awb_cfg->golden_gb_value + + awb_cfg->golden_gr_value) / 2; + golden_bg_ratio = awb_cfg->golden_b_value * 0x200 / golden_g_value; + golden_rg_ratio = awb_cfg->golden_r_value * 0x200 / golden_g_value; + } /* apply OTP WB Calibration */ if ((otp_ptr->flag & 0x40) && golden_bg_ratio && golden_rg_ratio) { @@ -1924,7 +1949,7 @@ static int ov8858_apply_otp_r1a(struct ov8858 *ov8858) } /* apply OTP Lenc Calibration */ - if (otp_ptr->flag & 0x10) { + if ((otp_ptr->flag & 0x10) && lsc_cfg->enable) { ov8858_read_1byte(client, 0x5000, &temp); temp = 0x80 | temp; ov8858_write_1byte(client, 0x5000, temp); @@ -1945,18 +1970,18 @@ static int ov8858_apply_otp_r2a(struct ov8858 *ov8858) struct i2c_client *client = ov8858->client; struct ov8858_otp_info_r2a *otp_ptr = ov8858->otp_r2a; struct rkmodule_awb_cfg *awb_cfg = &ov8858->awb_cfg; - u32 golden_bg_ratio; - u32 golden_rg_ratio; - u32 golden_g_value; + struct rkmodule_lsc_cfg *lsc_cfg = &ov8858->lsc_cfg; + u32 golden_bg_ratio = 0; + u32 golden_rg_ratio = 0; + u32 golden_g_value = 0; u32 i; - if (!ov8858->awb_cfg.enable) - return 0; - - golden_g_value = (awb_cfg->golden_gb_value + - awb_cfg->golden_gr_value) / 2; - golden_bg_ratio = awb_cfg->golden_b_value * 0x200 / golden_g_value; - golden_rg_ratio = awb_cfg->golden_r_value * 0x200 / golden_g_value; + if (awb_cfg->enable) { + golden_g_value = (awb_cfg->golden_gb_value + + awb_cfg->golden_gr_value) / 2; + golden_bg_ratio = awb_cfg->golden_b_value * 0x200 / golden_g_value; + golden_rg_ratio = awb_cfg->golden_r_value * 0x200 / golden_g_value; + } /* apply OTP WB Calibration */ if ((otp_ptr->flag & 0xC0) && golden_bg_ratio && golden_rg_ratio) { @@ -1997,7 +2022,7 @@ static int ov8858_apply_otp_r2a(struct ov8858 *ov8858) } /* apply OTP Lenc Calibration */ - if (otp_ptr->flag & 0x10) { + if ((otp_ptr->flag & 0x10) && lsc_cfg->enable) { ov8858_read_1byte(client, 0x5000, &temp); temp = 0x80 | temp; ov8858_write_1byte(client, 0x5000, temp); @@ -2048,17 +2073,17 @@ static int __ov8858_start_stream(struct ov8858 *ov8858) return ret; return ov8858_write_reg(ov8858->client, - OV8858_REG_CTRL_MODE, - OV8858_REG_VALUE_08BIT, - OV8858_MODE_STREAMING); + OV8858_REG_CTRL_MODE, + OV8858_REG_VALUE_08BIT, + OV8858_MODE_STREAMING); } static int __ov8858_stop_stream(struct ov8858 *ov8858) { return ov8858_write_reg(ov8858->client, - OV8858_REG_CTRL_MODE, - OV8858_REG_VALUE_08BIT, - OV8858_MODE_SW_STANDBY); + OV8858_REG_CTRL_MODE, + OV8858_REG_VALUE_08BIT, + OV8858_MODE_SW_STANDBY); } static int ov8858_s_stream(struct v4l2_subdev *sd, int on) @@ -2295,9 +2320,9 @@ static int ov8858_set_ctrl(struct v4l2_ctrl *ctrl) (ctrl->val >> OV8858_GAIN_H_SHIFT) & OV8858_GAIN_H_MASK); ret |= ov8858_write_reg(ov8858->client, - OV8858_REG_GAIN_L, - OV8858_REG_VALUE_08BIT, - ctrl->val & OV8858_GAIN_L_MASK); + OV8858_REG_GAIN_L, + OV8858_REG_VALUE_08BIT, + ctrl->val & OV8858_GAIN_L_MASK); break; case V4L2_CID_VBLANK: ret = ov8858_write_reg(ov8858->client, @@ -2582,7 +2607,7 @@ static int ov8858_otp_read_r2a(struct ov8858 *ov8858) ((temp >> 6) & 0x03); ov8858_read_1byte(client, addr + 1, &otp_ptr->vcm_end); otp_ptr->vcm_end = (otp_ptr->vcm_end << 2) | - ((temp >> 4) & 0x03); + ((temp >> 4) & 0x03); otp_ptr->vcm_dir = (temp >> 2) & 0x03; } @@ -2678,7 +2703,6 @@ static int ov8858_check_sensor_id(struct ov8858 *ov8858, OV8858_REG_VALUE_24BIT, &id); if (id != CHIP_ID) { dev_err(dev, "Unexpected sensor id(%06x), ret(%d)\n", id, ret); - //while(1); return ret; } diff --git a/drivers/media/platform/rockchip/isp1/version.h b/drivers/media/platform/rockchip/isp1/version.h index ef0ad89a5b56..b8b50ec13f7b 100644 --- a/drivers/media/platform/rockchip/isp1/version.h +++ b/drivers/media/platform/rockchip/isp1/version.h @@ -35,8 +35,12 @@ *21. check for capture S_FMT; *22. raw patch with default sensor fmt&size; * + *v0.1.2: + *1. fix reset on too high isp_clk rate will result in bus dead; + *2. add RKMODULE_LSC_CFG ioctl; + * */ -#define RKISP1_DRIVER_VERSION KERNEL_VERSION(0, 1, 0x1) +#define RKISP1_DRIVER_VERSION KERNEL_VERSION(0, 1, 0x2) #endif diff --git a/include/uapi/linux/rk-camera-module.h b/include/uapi/linux/rk-camera-module.h index 3cb1df9a361d..9883565799e7 100644 --- a/include/uapi/linux/rk-camera-module.h +++ b/include/uapi/linux/rk-camera-module.h @@ -26,6 +26,9 @@ #define RKMODULE_AF_CFG \ _IOW('V', BASE_VIDIOC_PRIVATE + 2, struct rkmodule_af_cfg) +#define RKMODULE_LSC_CFG \ + _IOW('V', BASE_VIDIOC_PRIVATE + 3, struct rkmodule_lsc_cfg) + /** * struct rkmodule_base_inf - module base information * @@ -132,4 +135,12 @@ struct rkmodule_af_cfg { __u32 vcm_dir; } __attribute__ ((packed)); +/** + * struct rkmodule_lsc_cfg + * + */ +struct rkmodule_lsc_cfg { + __u32 enable; +} __attribute__ ((packed)); + #endif /* _UAPI_RKMODULE_CAMERA_H */