mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-30 18:47:06 +00:00
857 lines
30 KiB
Diff
857 lines
30 KiB
Diff
|
From f36d458104101050478e290919ef4f05fbde0b3e Mon Sep 17 00:00:00 2001
|
||
|
From: "zejian.su" <zejian.su@starfivetech.com>
|
||
|
Date: Mon, 3 Jul 2023 16:52:13 +0800
|
||
|
Subject: [PATCH 094/116] Add 16 ISP controls, remove the frame SYNC event to
|
||
|
video7 (SC) These controls are: WB, CAR, CCM, CFA, CTC, DBC, DNYUV, GMARGB,
|
||
|
LCCF, OBC, OECF, R2Y, SAT, SHRP, YCRV, SC
|
||
|
|
||
|
---
|
||
|
.../platform/starfive/v4l2_driver/stf_isp.c | 628 ++++++++++++++++++
|
||
|
.../platform/starfive/v4l2_driver/stf_video.c | 22 +
|
||
|
.../platform/starfive/v4l2_driver/stf_vin.c | 16 +-
|
||
|
include/uapi/linux/jh7110-isp.h | 48 +-
|
||
|
4 files changed, 706 insertions(+), 8 deletions(-)
|
||
|
|
||
|
--- a/drivers/media/platform/starfive/v4l2_driver/stf_isp.c
|
||
|
+++ b/drivers/media/platform/starfive/v4l2_driver/stf_isp.c
|
||
|
@@ -195,6 +195,41 @@ static const char * const test_pattern_m
|
||
|
"Color squares w/ rolling bar",
|
||
|
};
|
||
|
|
||
|
+enum isp_modules_index {
|
||
|
+ imi_obc = 0,
|
||
|
+ imi_oecf,
|
||
|
+ imi_lccf,
|
||
|
+ imi_awb,
|
||
|
+ imi_dbc,
|
||
|
+ imi_ctc,
|
||
|
+ imi_cfa,
|
||
|
+ imi_car,
|
||
|
+ imi_ccm,
|
||
|
+ imi_gmargb,
|
||
|
+ imi_r2y,
|
||
|
+ imi_ycrv,
|
||
|
+ imi_shrp,
|
||
|
+ imi_dnyuv,
|
||
|
+ imi_sat,
|
||
|
+ imi_sc
|
||
|
+};
|
||
|
+
|
||
|
+#define MODULE_ENABLE_REGISTER0 0x10
|
||
|
+#define MODULE_ENABLE_REGISTER1 0xa08
|
||
|
+
|
||
|
+struct module_register_info {
|
||
|
+ __u32 en_reg;
|
||
|
+ __u32 en_nbit;
|
||
|
+ __u32 cfg_reg;
|
||
|
+};
|
||
|
+
|
||
|
+static const struct module_register_info mod_reg_info[] = {
|
||
|
+ {MODULE_ENABLE_REGISTER0, 2, 0x034}, {MODULE_ENABLE_REGISTER0, 4, 0x100}, {MODULE_ENABLE_REGISTER0, 6, 0x050}, {MODULE_ENABLE_REGISTER0, 7, 0x280},
|
||
|
+ {MODULE_ENABLE_REGISTER1, 22, 0xa14}, {MODULE_ENABLE_REGISTER1, 21, 0xa10}, {MODULE_ENABLE_REGISTER1, 1, 0xa1c}, {MODULE_ENABLE_REGISTER1, 2, 0x000},
|
||
|
+ {MODULE_ENABLE_REGISTER1, 3, 0xc40}, {MODULE_ENABLE_REGISTER1, 4, 0xe00}, {MODULE_ENABLE_REGISTER1, 5, 0xe40}, {MODULE_ENABLE_REGISTER1, 19, 0xf00},
|
||
|
+ {MODULE_ENABLE_REGISTER1, 7, 0xe80}, {MODULE_ENABLE_REGISTER1, 17, 0xc00}, {MODULE_ENABLE_REGISTER1, 8, 0xa30}, {MODULE_ENABLE_REGISTER0, 17, 0x09c}
|
||
|
+};
|
||
|
+
|
||
|
#define ISP_TEST_ENABLE BIT(7)
|
||
|
#define ISP_TEST_ROLLING BIT(6) /* rolling horizontal bar */
|
||
|
#define ISP_TEST_TRANSPARENT BIT(5)
|
||
|
@@ -260,6 +295,401 @@ static int isp_g_volatile_ctrl(struct v4
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
+#define CREATE_REG_VALUE_FUNCTION(type) \
|
||
|
+ static u32 create_reg_value_##type(const type * value, s32 size, u32 mask, s32 nbits) { \
|
||
|
+ s32 npos = 0; \
|
||
|
+ u32 res = 0; \
|
||
|
+ s32 sz = size; \
|
||
|
+ s32 i = 0; \
|
||
|
+ if(size * nbits > 32) sz = 32 / nbits; \
|
||
|
+ for(i = 0; i < sz; i++, npos += nbits, value++) res |= (u32)(value[0] & mask) << npos; \
|
||
|
+ return res; \
|
||
|
+}
|
||
|
+
|
||
|
+CREATE_REG_VALUE_FUNCTION(u8);
|
||
|
+CREATE_REG_VALUE_FUNCTION(u16);
|
||
|
+#define CREATE_REG_VALUE(type, value, size, mask, nbits) create_reg_value_##type(value, size, mask, nbits)
|
||
|
+
|
||
|
+#define FILL_ISP_REGS_FUNC(type) \
|
||
|
+static void fill_isp_regs_##type(void __iomem *ispbase, u32 offset, const type * value, s32 size, u32 mask, u32 nbits) { \
|
||
|
+ s32 i; \
|
||
|
+ for(i = 0; i < size; i++, value++) \
|
||
|
+ reg_write(ispbase, offset + i * 4, (u32)(value[0] & mask) << nbits); \
|
||
|
+}
|
||
|
+FILL_ISP_REGS_FUNC(u32);
|
||
|
+FILL_ISP_REGS_FUNC(u8);
|
||
|
+FILL_ISP_REGS_FUNC(u16);
|
||
|
+
|
||
|
+#define FILL_ISP_REGS(type, ispbase, offset, value, size, mask, nbits) \
|
||
|
+ fill_isp_regs_##type(ispbase, offset, value, size, mask, nbits)
|
||
|
+
|
||
|
+static int isp_set_ctrl_wb(struct stf_isp_dev *isp_dev, const void * value)
|
||
|
+{
|
||
|
+ const struct module_register_info * reg_info = &mod_reg_info[imi_awb];
|
||
|
+ const struct jh7110_isp_wb_setting * setting = (const struct jh7110_isp_wb_setting *)value;
|
||
|
+ const struct jh7110_isp_wb_gain * gains = &setting->gains;
|
||
|
+ u32 r_g = (((u32)gains->gain_r << 16) | gains->gain_r) & 0x03ff03ff;
|
||
|
+ u32 g_g = (((u32)gains->gain_g << 16) | gains->gain_g) & 0x03ff03ff;
|
||
|
+ u32 b_g = (((u32)gains->gain_b << 16) | gains->gain_b) & 0x03ff03ff;
|
||
|
+ u32 reg_addr = reg_info->cfg_reg + 16 * sizeof(u32);
|
||
|
+ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
|
||
|
+ void __iomem *ispbase = vin->isp_base;
|
||
|
+
|
||
|
+ reg_write(ispbase, reg_addr, r_g);
|
||
|
+ reg_write(ispbase, reg_addr + 1 * 4, r_g);
|
||
|
+ reg_write(ispbase, reg_addr + 2 * 4, g_g);
|
||
|
+ reg_write(ispbase, reg_addr + 3 * 4, g_g);
|
||
|
+ reg_write(ispbase, reg_addr + 4 * 4, g_g);
|
||
|
+ reg_write(ispbase, reg_addr + 5 * 4, g_g);
|
||
|
+ reg_write(ispbase, reg_addr + 6 * 4, b_g);
|
||
|
+ reg_write(ispbase, reg_addr + 7 * 4, b_g);
|
||
|
+ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static int isp_set_ctrl_car(struct stf_isp_dev *isp_dev, const void * value)
|
||
|
+{
|
||
|
+ const struct module_register_info * reg_info = &mod_reg_info[imi_car];
|
||
|
+ const struct jh7110_isp_car_setting * setting = (const struct jh7110_isp_car_setting *)value;
|
||
|
+ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
|
||
|
+ void __iomem *ispbase = vin->isp_base;
|
||
|
+
|
||
|
+ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static int isp_set_ctrl_ccm(struct stf_isp_dev *isp_dev, const void * value)
|
||
|
+{
|
||
|
+ const struct module_register_info * reg_info = &mod_reg_info[imi_ccm];
|
||
|
+ const struct jh7110_isp_ccm_setting * setting = (const struct jh7110_isp_ccm_setting *)value;
|
||
|
+ const struct jh7110_isp_ccm_smlow * ccm = (const struct jh7110_isp_ccm_smlow *)(&(setting->ccm_smlow));
|
||
|
+ u32 reg_addr = reg_info->cfg_reg + 12 * sizeof(u32);
|
||
|
+ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
|
||
|
+ void __iomem *ispbase = vin->isp_base;
|
||
|
+
|
||
|
+ reg_write(ispbase, reg_info->cfg_reg, 6 << 16);
|
||
|
+ FILL_ISP_REGS(u32, ispbase, reg_addr, (u32 *)ccm, 12, 0x7ff, 0);
|
||
|
+
|
||
|
+ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static int isp_set_ctrl_cfa(struct stf_isp_dev *isp_dev, const void * value)
|
||
|
+{
|
||
|
+ const struct module_register_info * reg_info = &mod_reg_info[imi_cfa];
|
||
|
+ const struct jh7110_isp_cfa_setting * setting = (const struct jh7110_isp_cfa_setting *)value;
|
||
|
+ const struct jh7110_isp_cfa_params * cfg = (const struct jh7110_isp_cfa_params *)(&(setting->settings));
|
||
|
+ u32 reg_addr = reg_info->cfg_reg;
|
||
|
+ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
|
||
|
+ void __iomem *ispbase = vin->isp_base;
|
||
|
+
|
||
|
+ reg_write(ispbase, reg_addr, ((u32)(cfg->cross_cov & 0x3) << 4) | (cfg->hv_width & 0xf));
|
||
|
+ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static int isp_set_ctrl_ctc(struct stf_isp_dev *isp_dev, const void * value)
|
||
|
+{
|
||
|
+ const struct module_register_info * reg_info = &mod_reg_info[imi_ctc];
|
||
|
+ const struct jh7110_isp_ctc_setting * setting = (const struct jh7110_isp_ctc_setting *)value;
|
||
|
+ const struct jh7110_isp_ctc_params * cfg = (const struct jh7110_isp_ctc_params *)(&(setting->settings));
|
||
|
+ u32 reg_addr = reg_info->cfg_reg;
|
||
|
+ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
|
||
|
+ void __iomem *ispbase = vin->isp_base;
|
||
|
+ u32 reg_value = (u32)(((cfg->saf_mode & 1) << 1) | (cfg->daf_mode & 1)) << 30;
|
||
|
+
|
||
|
+ reg_value |= ((u32)(cfg->max_gt & 0x3ff) << 16) | (cfg->min_gt & 0x3ff);
|
||
|
+ reg_write(ispbase, reg_addr, reg_value);
|
||
|
+ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static int isp_set_ctrl_dbc(struct stf_isp_dev *isp_dev, const void * value)
|
||
|
+{
|
||
|
+ const struct module_register_info * reg_info = &mod_reg_info[imi_dbc];
|
||
|
+ const struct jh7110_isp_dbc_setting * setting = (const struct jh7110_isp_dbc_setting *)value;
|
||
|
+ const struct jh7110_isp_dbc_params * cfg = (const struct jh7110_isp_dbc_params *)(&(setting->settings));
|
||
|
+ u32 reg_addr = reg_info->cfg_reg;
|
||
|
+ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
|
||
|
+ void __iomem *ispbase = vin->isp_base;
|
||
|
+
|
||
|
+ reg_write(ispbase, reg_addr, ((u32)(cfg->bad_gt & 0x3ff) << 16) | (cfg->bad_xt & 0x3ff));
|
||
|
+ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static int isp_set_ctrl_dnyuv(struct stf_isp_dev *isp_dev, const void * value)
|
||
|
+{
|
||
|
+ const struct module_register_info * reg_info = &mod_reg_info[imi_dnyuv];
|
||
|
+ const struct jh7110_isp_dnyuv_setting * setting = (const struct jh7110_isp_dnyuv_setting *)value;
|
||
|
+ const struct jh7110_isp_dnyuv_params * cfg = (const struct jh7110_isp_dnyuv_params *)(&(setting->settings));
|
||
|
+ u32 reg_addr = reg_info->cfg_reg;
|
||
|
+ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
|
||
|
+ void __iomem *ispbase = vin->isp_base;
|
||
|
+
|
||
|
+ reg_write(ispbase, reg_addr, CREATE_REG_VALUE(u8, cfg->y_sweight, 6, 0x7, 4));
|
||
|
+ reg_write(ispbase, reg_addr + 4, CREATE_REG_VALUE(u8, &cfg->y_sweight[6], 4, 0x7, 4));
|
||
|
+ reg_write(ispbase, reg_addr + 8, CREATE_REG_VALUE(u8, cfg->uv_sweight, 6, 0x7, 4));
|
||
|
+ reg_write(ispbase, reg_addr + 12, CREATE_REG_VALUE(u8, &cfg->uv_sweight[6], 4, 0x7, 4));
|
||
|
+ reg_write(ispbase, reg_addr + 16, CREATE_REG_VALUE(u16, &cfg->y_curve[0], 2, 0x3ff, 16));
|
||
|
+ reg_write(ispbase, reg_addr + 20, CREATE_REG_VALUE(u16, &cfg->y_curve[2], 2, 0x3ff, 16));
|
||
|
+ reg_write(ispbase, reg_addr + 24, CREATE_REG_VALUE(u16, &cfg->y_curve[4], 2, 0x3ff, 16));
|
||
|
+ reg_write(ispbase, reg_addr + 28, CREATE_REG_VALUE(u16, &cfg->uv_curve[0], 2, 0x3ff, 16));
|
||
|
+ reg_write(ispbase, reg_addr + 32, CREATE_REG_VALUE(u16, &cfg->uv_curve[2], 2, 0x3ff, 16));
|
||
|
+ reg_write(ispbase, reg_addr + 36, CREATE_REG_VALUE(u16, &cfg->uv_curve[4], 2, 0x3ff, 16));
|
||
|
+
|
||
|
+ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static int isp_set_ctrl_gmargb(struct stf_isp_dev *isp_dev, const void * value)
|
||
|
+{
|
||
|
+ const struct module_register_info * reg_info = &mod_reg_info[imi_gmargb];
|
||
|
+ const struct jh7110_isp_gmargb_setting * setting = (const struct jh7110_isp_gmargb_setting *)value;
|
||
|
+ const struct jh7110_isp_gmargb_point * curve = setting->curve;
|
||
|
+ u32 reg_addr = reg_info->cfg_reg;
|
||
|
+ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
|
||
|
+ void __iomem *ispbase = vin->isp_base;
|
||
|
+ s32 i;
|
||
|
+
|
||
|
+ for(i = 0; i < 15; i++, curve++, reg_addr += 4)
|
||
|
+ reg_write(ispbase, reg_addr, ((u32)curve->sg_val << 16) | (curve->g_val & 0x3ff));
|
||
|
+
|
||
|
+ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static int isp_set_ctrl_lccf(struct stf_isp_dev *isp_dev, const void * value)
|
||
|
+{
|
||
|
+ const struct module_register_info * reg_info = &mod_reg_info[imi_lccf];
|
||
|
+ const struct jh7110_isp_lccf_setting * setting = (const struct jh7110_isp_lccf_setting *)value;
|
||
|
+ const s16 * params = (s16 *)(&setting->r_param);
|
||
|
+ u32 reg_addr = reg_info->cfg_reg;
|
||
|
+ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
|
||
|
+ void __iomem *ispbase = vin->isp_base;
|
||
|
+ s32 i;
|
||
|
+
|
||
|
+ reg_write(ispbase, reg_addr, ((u32)(setting->circle.center_y & 0x7fff) << 16) | (setting->circle.center_x & 0x7fff));
|
||
|
+ reg_write(ispbase, reg_addr + 8, setting->circle.radius & 0xf);
|
||
|
+ reg_addr += 0x90;
|
||
|
+ for(i = 0; i < 4; i++, reg_addr += 4, params += 2)
|
||
|
+ reg_write(ispbase, reg_addr, CREATE_REG_VALUE(u16, params, 2, 0x1fff, 16));
|
||
|
+
|
||
|
+ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static int isp_set_ctrl_obc(struct stf_isp_dev *isp_dev, const void * value)
|
||
|
+{
|
||
|
+ const struct module_register_info * reg_info = &mod_reg_info[imi_obc];
|
||
|
+ const struct jh7110_isp_blacklevel_setting * setting = (const struct jh7110_isp_blacklevel_setting *)value;
|
||
|
+ const u8 * params = (u8 *)setting->gain;
|
||
|
+ u32 reg_addr = reg_info->cfg_reg;
|
||
|
+ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
|
||
|
+ void __iomem *ispbase = vin->isp_base;
|
||
|
+ s32 i;
|
||
|
+
|
||
|
+ reg_write(ispbase, reg_addr, ((u32)(setting->win_size.height & 0xf) << 4) | (setting->win_size.width & 0xf));
|
||
|
+
|
||
|
+ reg_addr += 0x2ac; //0x2e0
|
||
|
+ for(i = 0; i < 8; i++, reg_addr += 4, params += 4)
|
||
|
+ reg_write(ispbase, reg_addr, CREATE_REG_VALUE(u8, params, 4, 0xff, 8));
|
||
|
+
|
||
|
+ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static int isp_set_ctrl_oecf(struct stf_isp_dev *isp_dev, const void * value)
|
||
|
+{
|
||
|
+ const struct module_register_info * reg_info = &mod_reg_info[imi_oecf];
|
||
|
+ const struct jh7110_isp_oecf_setting * setting = (const struct jh7110_isp_oecf_setting *)value;
|
||
|
+ const struct jh7110_isp_oecf_point * pts = (struct jh7110_isp_oecf_point *)(setting->r_curve);
|
||
|
+ u32 reg_x_addr = reg_info->cfg_reg;
|
||
|
+ u32 reg_y_addr = reg_info->cfg_reg + 0x080;
|
||
|
+ u32 reg_s_addr = reg_info->cfg_reg + 0x100;
|
||
|
+ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
|
||
|
+ void __iomem *ispbase = vin->isp_base;
|
||
|
+ u32 x, y, slope;
|
||
|
+ s32 i;
|
||
|
+
|
||
|
+ for(i = 0; i < 32; i++, reg_x_addr += 4, reg_y_addr += 4, reg_s_addr += 4) {
|
||
|
+ x = pts->x & 0x3ff;
|
||
|
+ y = pts->y & 0x3ff;
|
||
|
+ slope = pts->slope & 0x3ff;
|
||
|
+ pts++;
|
||
|
+ x |= ((pts->x & 0x3ff) << 16);
|
||
|
+ y |= ((pts->y & 0x3ff) << 16);
|
||
|
+ slope |= ((pts->slope & 0x3ff) << 16);
|
||
|
+ pts++;
|
||
|
+
|
||
|
+ reg_write(ispbase, reg_x_addr, x);
|
||
|
+ reg_write(ispbase, reg_y_addr, y);
|
||
|
+ reg_write(ispbase, reg_s_addr, slope);
|
||
|
+ }
|
||
|
+
|
||
|
+ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static int isp_set_ctrl_r2y(struct stf_isp_dev *isp_dev, const void * value)
|
||
|
+{
|
||
|
+ const struct module_register_info * reg_info = &mod_reg_info[imi_r2y];
|
||
|
+ const struct jh7110_isp_r2y_setting * setting = (const struct jh7110_isp_r2y_setting *)value;
|
||
|
+ const s16 * params = setting->matrix.m;
|
||
|
+ u32 reg_addr = reg_info->cfg_reg;
|
||
|
+ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
|
||
|
+ void __iomem *ispbase = vin->isp_base;
|
||
|
+ s32 i;
|
||
|
+
|
||
|
+ for(i = 0; i < 9; i++, reg_addr += 4)
|
||
|
+ reg_write(ispbase, reg_addr, (u32)(params[i] & 0x1ff));
|
||
|
+
|
||
|
+ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+static int isp_set_ctrl_sat(struct stf_isp_dev *isp_dev, const void * value)
|
||
|
+{
|
||
|
+ const struct module_register_info * reg_info = &mod_reg_info[imi_sat];
|
||
|
+ const struct jh7110_isp_sat_setting * setting = (const struct jh7110_isp_sat_setting *)value;
|
||
|
+ const u16 * params = (u16 *)(&setting->sat_info);
|
||
|
+ u32 reg_addr = reg_info->cfg_reg;
|
||
|
+ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
|
||
|
+ void __iomem *ispbase = vin->isp_base;
|
||
|
+ s32 i;
|
||
|
+
|
||
|
+ for(i = 0; i < 3; i++, reg_addr += 4, params += 2)
|
||
|
+ reg_write(ispbase, reg_addr, CREATE_REG_VALUE(u16, params, 2, 0xfff, 16));
|
||
|
+ reg_write(ispbase, reg_addr, CREATE_REG_VALUE(u16, &setting->hue_info.cos, 2, 0x3ff, 16));
|
||
|
+ reg_addr += 4;
|
||
|
+ reg_write(ispbase, reg_addr, setting->sat_info.cmsf & 0xf);
|
||
|
+
|
||
|
+ params = (u16 *)(&setting->curve);
|
||
|
+ reg_addr += 0x14; // 0xa54
|
||
|
+ for(i = 0; i < 2; i++, reg_addr += 4, params += 2)
|
||
|
+ reg_write(ispbase, reg_addr, CREATE_REG_VALUE(u16, params, 2, 0x3fff, 16));
|
||
|
+
|
||
|
+ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static int isp_set_ctrl_shrp(struct stf_isp_dev *isp_dev, const void * value)
|
||
|
+{
|
||
|
+ const struct module_register_info * reg_info = &mod_reg_info[imi_shrp];
|
||
|
+ const struct jh7110_isp_sharp_setting * setting = (const struct jh7110_isp_sharp_setting *)value;
|
||
|
+ u32 reg_addr = reg_info->cfg_reg;
|
||
|
+ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
|
||
|
+ void __iomem *ispbase = vin->isp_base;
|
||
|
+ s32 i;
|
||
|
+
|
||
|
+ for(i = 0; i < 4; i++, reg_addr += 4)
|
||
|
+ reg_write(ispbase, reg_addr, ((u32)(setting->strength.diff[i] & 0x3ff) << 16) | ((u32)(setting->weight.weight[i] & 0xf) << 8));
|
||
|
+ FILL_ISP_REGS(u8, ispbase, reg_addr, (u8 *)(&setting->weight.weight[4]), 15 - 4, 0xf, 8);
|
||
|
+ reg_addr += (15 - 4) * 4;
|
||
|
+
|
||
|
+ for(i = 0; i < 3; i++, reg_addr += 4)
|
||
|
+ reg_write(ispbase, reg_addr, ((u32)(setting->strength.f[i] & 0x7f) << 24) | (setting->strength.s[i] & 0x1fffff));
|
||
|
+
|
||
|
+ reg_addr += 3 * 4;
|
||
|
+ reg_write(ispbase, reg_addr, ((u32)(setting->pdirf & 0xf) << 28) | ((u32)(setting->ndirf & 0xf) << 24) | (setting->weight.recip_wei_sum & 0x3fffff));
|
||
|
+
|
||
|
+ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static int isp_set_ctrl_ycrv(struct stf_isp_dev *isp_dev, const void * value)
|
||
|
+{
|
||
|
+ const struct module_register_info * reg_info = &mod_reg_info[imi_ycrv];
|
||
|
+ const struct jh7110_isp_ycrv_setting * setting = (const struct jh7110_isp_ycrv_setting *)value;
|
||
|
+ u32 reg_addr = reg_info->cfg_reg;
|
||
|
+ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
|
||
|
+ void __iomem *ispbase = vin->isp_base;
|
||
|
+
|
||
|
+ FILL_ISP_REGS(u16, ispbase, reg_addr, (u16 *)(setting->curve.y), 64, 0x3ff, 0);
|
||
|
+
|
||
|
+ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static int isp_set_ctrl_sc(struct stf_isp_dev *isp_dev, const void * value)
|
||
|
+{
|
||
|
+ const struct module_register_info * reg_info = &mod_reg_info[imi_sc];
|
||
|
+ const struct jh7110_isp_sc_setting * setting = (const struct jh7110_isp_sc_setting *)value;
|
||
|
+ const u8 * params = setting->awb_config.awb_cw;
|
||
|
+ u32 reg_addr = 0x00;
|
||
|
+ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
|
||
|
+ void __iomem *ispbase = vin->isp_base;
|
||
|
+ u32 weight_cfg[6] = {0};
|
||
|
+ u32 * weight = weight_cfg;
|
||
|
+ u32 * w_diff = weight_cfg + 2;
|
||
|
+ s32 i;
|
||
|
+
|
||
|
+ // AF register
|
||
|
+ reg_write(ispbase, 0xc0,
|
||
|
+ ((u32)(setting->af_config.es_hor_thr & 0x1ff) << 16) |
|
||
|
+ ((u32)(setting->af_config.es_ver_thr & 0xff) << 8) |
|
||
|
+ ((setting->af_config.ver_en & 0x1) << 3) |
|
||
|
+ ((setting->af_config.hor_en & 0x1) << 2) |
|
||
|
+ ((setting->af_config.es_sum_mode & 0x1) << 1) |
|
||
|
+ (setting->af_config.es_hor_mode & 0x1));
|
||
|
+
|
||
|
+ // AWB weight sum register
|
||
|
+ reg_write(ispbase, 0x5d0, CREATE_REG_VALUE(u8, &setting->awb_config.ws_config.awb_ws_rl, 4, 0xff, 8));
|
||
|
+ reg_write(ispbase, 0x5d4, CREATE_REG_VALUE(u8, &setting->awb_config.ws_config.awb_ws_gbl, 4, 0xff, 8));
|
||
|
+
|
||
|
+ // AWB weight value point
|
||
|
+ reg_addr = 0x4d0;
|
||
|
+ for(i = 0; i < 13; i++) {
|
||
|
+ reg_write(ispbase, reg_addr, CREATE_REG_VALUE(u8, params, 8, 0xf, 4));
|
||
|
+ reg_addr += 4;
|
||
|
+ params += 8;
|
||
|
+ reg_write(ispbase, reg_addr, CREATE_REG_VALUE(u8, params, 5, 0xf, 4));
|
||
|
+ reg_addr += 4;
|
||
|
+ params += 5;
|
||
|
+ }
|
||
|
+
|
||
|
+ // AWB intensity weight curve register
|
||
|
+ reg_addr = 0x538;
|
||
|
+ for(i = 0; i < 4; i++) {
|
||
|
+ weight[0] |= (setting->awb_config.pts[i].weight & 0xf) << (i * 4);
|
||
|
+ w_diff[0] |= ((((s16)(setting->awb_config.pts[i + 1].weight & 0xf) - (s16)(setting->awb_config.pts[i].weight & 0xf)) * 2) & 0xff) << (i * 8);
|
||
|
+ }
|
||
|
+ for(w_diff++; i < 8; i++) {
|
||
|
+ weight[0] |= (setting->awb_config.pts[i].weight & 0xf) << (i * 4);
|
||
|
+ w_diff[0] |= ((((s16)(setting->awb_config.pts[i + 1].weight & 0xf) - (s16)(setting->awb_config.pts[i].weight & 0xf)) * 2) & 0xff) << (i * 8);
|
||
|
+ }
|
||
|
+ for(weight++, w_diff++; i < 12; i++) {
|
||
|
+ weight[0] |= (setting->awb_config.pts[i].weight & 0xf) << (i * 4);
|
||
|
+ w_diff[0] |= ((((s16)(setting->awb_config.pts[i + 1].weight & 0xf) - (s16)(setting->awb_config.pts[i].weight & 0xf)) * 2) & 0xff) << (i * 8);
|
||
|
+ }
|
||
|
+ for(w_diff++; i < 16; i++) {
|
||
|
+ weight[0] |= (setting->awb_config.pts[i].weight & 0xf) << (i * 4);
|
||
|
+ w_diff[0] |= ((((s16)(setting->awb_config.pts[i + 1].weight & 0xf) - (s16)(setting->awb_config.pts[i].weight & 0xf)) * 2) & 0xff) << (i * 8);
|
||
|
+ }
|
||
|
+
|
||
|
+ FILL_ISP_REGS(u32, ispbase, reg_addr, weight_cfg, 6, 0xffffffff, 0);
|
||
|
+
|
||
|
+ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
static int isp_s_ctrl(struct v4l2_ctrl *ctrl)
|
||
|
{
|
||
|
struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
|
||
|
@@ -310,10 +740,52 @@ static int isp_s_ctrl(struct v4l2_ctrl *
|
||
|
ret = isp_set_ctrl_vflip(isp_dev, ctrl->val);
|
||
|
break;
|
||
|
case V4L2_CID_USER_JH7110_ISP_WB_SETTING:
|
||
|
+ ret = isp_set_ctrl_wb(isp_dev, ctrl->p_new.p_u8);
|
||
|
break;
|
||
|
case V4L2_CID_USER_JH7110_ISP_CAR_SETTING:
|
||
|
+ ret = isp_set_ctrl_car(isp_dev, ctrl->p_new.p_u8);
|
||
|
break;
|
||
|
case V4L2_CID_USER_JH7110_ISP_CCM_SETTING:
|
||
|
+ ret = isp_set_ctrl_ccm(isp_dev, ctrl->p_new.p_u8);
|
||
|
+ break;
|
||
|
+ case V4L2_CID_USER_JH7110_ISP_CFA_SETTING:
|
||
|
+ ret = isp_set_ctrl_cfa(isp_dev, ctrl->p_new.p_u8);
|
||
|
+ break;
|
||
|
+ case V4L2_CID_USER_JH7110_ISP_CTC_SETTING:
|
||
|
+ ret = isp_set_ctrl_ctc(isp_dev, ctrl->p_new.p_u8);
|
||
|
+ break;
|
||
|
+ case V4L2_CID_USER_JH7110_ISP_DBC_SETTING:
|
||
|
+ ret = isp_set_ctrl_dbc(isp_dev, ctrl->p_new.p_u8);
|
||
|
+ break;
|
||
|
+ case V4L2_CID_USER_JH7110_ISP_DNYUV_SETTING:
|
||
|
+ ret = isp_set_ctrl_dnyuv(isp_dev, ctrl->p_new.p_u8);
|
||
|
+ break;
|
||
|
+ case V4L2_CID_USER_JH7110_ISP_GMARGB_SETTING:
|
||
|
+ ret = isp_set_ctrl_gmargb(isp_dev, ctrl->p_new.p_u8);
|
||
|
+ break;
|
||
|
+ case V4L2_CID_USER_JH7110_ISP_LCCF_SETTING:
|
||
|
+ ret = isp_set_ctrl_lccf(isp_dev, ctrl->p_new.p_u8);
|
||
|
+ break;
|
||
|
+ case V4L2_CID_USER_JH7110_ISP_OBC_SETTING:
|
||
|
+ ret = isp_set_ctrl_obc(isp_dev, ctrl->p_new.p_u8);
|
||
|
+ break;
|
||
|
+ case V4L2_CID_USER_JH7110_ISP_OECF_SETTING:
|
||
|
+ ret = isp_set_ctrl_oecf(isp_dev, ctrl->p_new.p_u8);
|
||
|
+ break;
|
||
|
+ case V4L2_CID_USER_JH7110_ISP_R2Y_SETTING:
|
||
|
+ ret = isp_set_ctrl_r2y(isp_dev, ctrl->p_new.p_u8);
|
||
|
+ break;
|
||
|
+ case V4L2_CID_USER_JH7110_ISP_SAT_SETTING:
|
||
|
+ ret = isp_set_ctrl_sat(isp_dev, ctrl->p_new.p_u8);
|
||
|
+ break;
|
||
|
+ case V4L2_CID_USER_JH7110_ISP_SHRP_SETTING:
|
||
|
+ ret = isp_set_ctrl_shrp(isp_dev, ctrl->p_new.p_u8);
|
||
|
+ break;
|
||
|
+ case V4L2_CID_USER_JH7110_ISP_YCRV_SETTING:
|
||
|
+ ret = isp_set_ctrl_ycrv(isp_dev, ctrl->p_new.p_u8);
|
||
|
+ break;
|
||
|
+ case V4L2_CID_USER_JH7110_ISP_STAT_SETTING:
|
||
|
+ ret = isp_set_ctrl_sc(isp_dev, ctrl->p_new.p_u8);
|
||
|
break;
|
||
|
default:
|
||
|
ret = -EINVAL;
|
||
|
@@ -365,6 +837,162 @@ struct v4l2_ctrl_config isp_ctrl[] = {
|
||
|
.dims[0] = sizeof(struct jh7110_isp_ccm_setting),
|
||
|
.flags = 0,
|
||
|
},
|
||
|
+ [3] = {
|
||
|
+ .ops = &isp_ctrl_ops,
|
||
|
+ .type = V4L2_CTRL_TYPE_U8,
|
||
|
+ .def = 0,
|
||
|
+ .min = 0x00,
|
||
|
+ .max = 0xff,
|
||
|
+ .step = 1,
|
||
|
+ .name = "CFA Setting",
|
||
|
+ .id = V4L2_CID_USER_JH7110_ISP_CFA_SETTING,
|
||
|
+ .dims[0] = sizeof(struct jh7110_isp_cfa_setting),
|
||
|
+ .flags = 0,
|
||
|
+ },
|
||
|
+ [4] = {
|
||
|
+ .ops = &isp_ctrl_ops,
|
||
|
+ .type = V4L2_CTRL_TYPE_U8,
|
||
|
+ .def = 0,
|
||
|
+ .min = 0x00,
|
||
|
+ .max = 0xff,
|
||
|
+ .step = 1,
|
||
|
+ .name = "CTC Setting",
|
||
|
+ .id = V4L2_CID_USER_JH7110_ISP_CTC_SETTING,
|
||
|
+ .dims[0] = sizeof(struct jh7110_isp_ctc_setting),
|
||
|
+ .flags = 0,
|
||
|
+ },
|
||
|
+ [5] = {
|
||
|
+ .ops = &isp_ctrl_ops,
|
||
|
+ .type = V4L2_CTRL_TYPE_U8,
|
||
|
+ .def = 0,
|
||
|
+ .min = 0x00,
|
||
|
+ .max = 0xff,
|
||
|
+ .step = 1,
|
||
|
+ .name = "CTC Setting",
|
||
|
+ .id = V4L2_CID_USER_JH7110_ISP_DBC_SETTING,
|
||
|
+ .dims[0] = sizeof(struct jh7110_isp_dbc_setting),
|
||
|
+ .flags = 0,
|
||
|
+ },
|
||
|
+ [6] = {
|
||
|
+ .ops = &isp_ctrl_ops,
|
||
|
+ .type = V4L2_CTRL_TYPE_U8,
|
||
|
+ .def = 0,
|
||
|
+ .min = 0x00,
|
||
|
+ .max = 0xff,
|
||
|
+ .step = 1,
|
||
|
+ .name = "DNYUV Setting",
|
||
|
+ .id = V4L2_CID_USER_JH7110_ISP_DNYUV_SETTING,
|
||
|
+ .dims[0] = sizeof(struct jh7110_isp_dnyuv_setting),
|
||
|
+ .flags = 0,
|
||
|
+ },
|
||
|
+ [7] = {
|
||
|
+ .ops = &isp_ctrl_ops,
|
||
|
+ .type = V4L2_CTRL_TYPE_U8,
|
||
|
+ .def = 0,
|
||
|
+ .min = 0x00,
|
||
|
+ .max = 0xff,
|
||
|
+ .step = 1,
|
||
|
+ .name = "DNYUV Setting",
|
||
|
+ .id = V4L2_CID_USER_JH7110_ISP_GMARGB_SETTING,
|
||
|
+ .dims[0] = sizeof(struct jh7110_isp_gmargb_setting),
|
||
|
+ .flags = 0,
|
||
|
+ },
|
||
|
+ [8] = {
|
||
|
+ .ops = &isp_ctrl_ops,
|
||
|
+ .type = V4L2_CTRL_TYPE_U8,
|
||
|
+ .def = 0,
|
||
|
+ .min = 0x00,
|
||
|
+ .max = 0xff,
|
||
|
+ .step = 1,
|
||
|
+ .name = "LCCF Setting",
|
||
|
+ .id = V4L2_CID_USER_JH7110_ISP_LCCF_SETTING,
|
||
|
+ .dims[0] = sizeof(struct jh7110_isp_lccf_setting),
|
||
|
+ .flags = 0,
|
||
|
+ },
|
||
|
+ [9] = {
|
||
|
+ .ops = &isp_ctrl_ops,
|
||
|
+ .type = V4L2_CTRL_TYPE_U8,
|
||
|
+ .def = 0,
|
||
|
+ .min = 0x00,
|
||
|
+ .max = 0xff,
|
||
|
+ .step = 1,
|
||
|
+ .name = "OBC Setting",
|
||
|
+ .id = V4L2_CID_USER_JH7110_ISP_OBC_SETTING,
|
||
|
+ .dims[0] = sizeof(struct jh7110_isp_blacklevel_setting),
|
||
|
+ .flags = 0,
|
||
|
+ },
|
||
|
+ [10] = {
|
||
|
+ .ops = &isp_ctrl_ops,
|
||
|
+ .type = V4L2_CTRL_TYPE_U8,
|
||
|
+ .def = 0,
|
||
|
+ .min = 0x00,
|
||
|
+ .max = 0xff,
|
||
|
+ .step = 1,
|
||
|
+ .name = "OECF Setting",
|
||
|
+ .id = V4L2_CID_USER_JH7110_ISP_OECF_SETTING,
|
||
|
+ .dims[0] = sizeof(struct jh7110_isp_oecf_setting),
|
||
|
+ .flags = 0,
|
||
|
+ },
|
||
|
+ [11] = {
|
||
|
+ .ops = &isp_ctrl_ops,
|
||
|
+ .type = V4L2_CTRL_TYPE_U8,
|
||
|
+ .def = 0,
|
||
|
+ .min = 0x00,
|
||
|
+ .max = 0xff,
|
||
|
+ .step = 1,
|
||
|
+ .name = "R2Y Setting",
|
||
|
+ .id = V4L2_CID_USER_JH7110_ISP_R2Y_SETTING,
|
||
|
+ .dims[0] = sizeof(struct jh7110_isp_r2y_setting),
|
||
|
+ .flags = 0,
|
||
|
+ },
|
||
|
+ [12] = {
|
||
|
+ .ops = &isp_ctrl_ops,
|
||
|
+ .type = V4L2_CTRL_TYPE_U8,
|
||
|
+ .def = 0,
|
||
|
+ .min = 0x00,
|
||
|
+ .max = 0xff,
|
||
|
+ .step = 1,
|
||
|
+ .name = "SAT Setting",
|
||
|
+ .id = V4L2_CID_USER_JH7110_ISP_SAT_SETTING,
|
||
|
+ .dims[0] = sizeof(struct jh7110_isp_sat_setting),
|
||
|
+ .flags = 0,
|
||
|
+ },
|
||
|
+ [13] = {
|
||
|
+ .ops = &isp_ctrl_ops,
|
||
|
+ .type = V4L2_CTRL_TYPE_U8,
|
||
|
+ .def = 0,
|
||
|
+ .min = 0x00,
|
||
|
+ .max = 0xff,
|
||
|
+ .step = 1,
|
||
|
+ .name = "SAT Setting",
|
||
|
+ .id = V4L2_CID_USER_JH7110_ISP_SHRP_SETTING,
|
||
|
+ .dims[0] = sizeof(struct jh7110_isp_sharp_setting),
|
||
|
+ .flags = 0,
|
||
|
+ },
|
||
|
+ [14] = {
|
||
|
+ .ops = &isp_ctrl_ops,
|
||
|
+ .type = V4L2_CTRL_TYPE_U8,
|
||
|
+ .def = 0,
|
||
|
+ .min = 0x00,
|
||
|
+ .max = 0xff,
|
||
|
+ .step = 1,
|
||
|
+ .name = "YCRV Setting",
|
||
|
+ .id = V4L2_CID_USER_JH7110_ISP_YCRV_SETTING,
|
||
|
+ .dims[0] = sizeof(struct jh7110_isp_ycrv_setting),
|
||
|
+ .flags = 0,
|
||
|
+ },
|
||
|
+ [15] = {
|
||
|
+ .ops = &isp_ctrl_ops,
|
||
|
+ .type = V4L2_CTRL_TYPE_U8,
|
||
|
+ .def = 0,
|
||
|
+ .min = 0x00,
|
||
|
+ .max = 0xff,
|
||
|
+ .step = 1,
|
||
|
+ .name = "SC Setting",
|
||
|
+ .id = V4L2_CID_USER_JH7110_ISP_STAT_SETTING,
|
||
|
+ .dims[0] = sizeof(struct jh7110_isp_sc_setting),
|
||
|
+ .flags = 0,
|
||
|
+ },
|
||
|
};
|
||
|
|
||
|
static int isp_init_controls(struct stf_isp_dev *isp_dev)
|
||
|
--- a/drivers/media/platform/starfive/v4l2_driver/stf_video.c
|
||
|
+++ b/drivers/media/platform/starfive/v4l2_driver/stf_video.c
|
||
|
@@ -1281,6 +1281,22 @@ int video_s_selection(struct file *file,
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
+static int stf_video_subscribe_event(struct v4l2_fh *fh,
|
||
|
+ const struct v4l2_event_subscription *sub)
|
||
|
+{
|
||
|
+ switch (sub->type) {
|
||
|
+ case V4L2_EVENT_FRAME_SYNC:
|
||
|
+ return v4l2_event_subscribe(fh, sub, 2, NULL);
|
||
|
+ //int ret = v4l2_event_subscribe(fh, sub, 2, NULL);
|
||
|
+ //pr_info("subscribe ret: %d\n", ret);
|
||
|
+ //return ret;
|
||
|
+ default:
|
||
|
+ return v4l2_ctrl_subscribe_event(fh, sub);
|
||
|
+ //st_debug(ST_VIN, "unsupport subscribe_event\n");
|
||
|
+ //return -EINVAL;
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
static const struct v4l2_ioctl_ops stf_vid_ioctl_ops = {
|
||
|
.vidioc_querycap = video_querycap,
|
||
|
.vidioc_enum_fmt_vid_cap = video_enum_fmt,
|
||
|
@@ -1305,6 +1321,8 @@ static const struct v4l2_ioctl_ops stf_v
|
||
|
.vidioc_s_parm = video_s_parm,
|
||
|
.vidioc_s_selection = video_s_selection,
|
||
|
.vidioc_g_selection = video_g_selection,
|
||
|
+ .vidioc_subscribe_event = stf_video_subscribe_event,
|
||
|
+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
|
||
|
};
|
||
|
|
||
|
static const struct v4l2_ioctl_ops stf_vid_ioctl_ops_mp = {
|
||
|
@@ -1331,6 +1349,8 @@ static const struct v4l2_ioctl_ops stf_v
|
||
|
.vidioc_s_parm = video_s_parm,
|
||
|
.vidioc_s_selection = video_s_selection,
|
||
|
.vidioc_g_selection = video_g_selection,
|
||
|
+ .vidioc_subscribe_event = stf_video_subscribe_event,
|
||
|
+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
|
||
|
};
|
||
|
|
||
|
static const struct v4l2_ioctl_ops stf_vid_ioctl_ops_out = {
|
||
|
@@ -1350,6 +1370,8 @@ static const struct v4l2_ioctl_ops stf_v
|
||
|
.vidioc_prepare_buf = vb2_ioctl_prepare_buf,
|
||
|
.vidioc_streamon = vb2_ioctl_streamon,
|
||
|
.vidioc_streamoff = vb2_ioctl_streamoff,
|
||
|
+ .vidioc_subscribe_event = stf_video_subscribe_event,
|
||
|
+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
|
||
|
};
|
||
|
|
||
|
static int video_open(struct file *file)
|
||
|
--- a/drivers/media/platform/starfive/v4l2_driver/stf_vin.c
|
||
|
+++ b/drivers/media/platform/starfive/v4l2_driver/stf_vin.c
|
||
|
@@ -1145,9 +1145,12 @@ static void vin_buffer_done(struct vin_l
|
||
|
spin_lock_irqsave(&line->output_lock, flags);
|
||
|
|
||
|
while ((ready_buf = vin_buf_get_ready(output))) {
|
||
|
- if (line->id >= VIN_LINE_ISP && line->id <= VIN_LINE_ISP_SS1) {
|
||
|
+ //if (line->id >= VIN_LINE_ISP && line->id <= VIN_LINE_ISP_SS1) {
|
||
|
+ if (line->id == VIN_LINE_ISP_SCD_Y) {
|
||
|
event.u.frame_sync.frame_sequence = output->sequence;
|
||
|
- v4l2_event_queue(line->subdev.devnode, &event);
|
||
|
+ v4l2_event_queue(&(line->video_out.vdev), &event);
|
||
|
+ //v4l2_event_queue(line->subdev.devnode, &event);
|
||
|
+ //pr_info("----------frame sync-----------\n");
|
||
|
}
|
||
|
|
||
|
ready_buf->vb.vb2_buf.timestamp = ts;
|
||
|
@@ -1346,7 +1349,10 @@ static int stf_vin_subscribe_event(struc
|
||
|
{
|
||
|
switch (sub->type) {
|
||
|
case V4L2_EVENT_FRAME_SYNC:
|
||
|
- return v4l2_event_subscribe(fh, sub, 0, NULL);
|
||
|
+ //return v4l2_event_subscribe(fh, sub, 2, NULL);
|
||
|
+ int ret = v4l2_event_subscribe(fh, sub, 2, NULL);
|
||
|
+ pr_info("subscribe ret: %d\n", ret);
|
||
|
+ return ret;
|
||
|
default:
|
||
|
st_debug(ST_VIN, "unsupport subscribe_event\n");
|
||
|
return -EINVAL;
|
||
|
@@ -1355,8 +1361,8 @@ static int stf_vin_subscribe_event(struc
|
||
|
|
||
|
static const struct v4l2_subdev_core_ops vin_core_ops = {
|
||
|
.s_power = vin_set_power,
|
||
|
- .subscribe_event = stf_vin_subscribe_event,
|
||
|
- .unsubscribe_event = v4l2_event_subdev_unsubscribe,
|
||
|
+ //.subscribe_event = stf_vin_subscribe_event,
|
||
|
+ //.unsubscribe_event = v4l2_event_subdev_unsubscribe,
|
||
|
};
|
||
|
|
||
|
static const struct v4l2_subdev_video_ops vin_video_ops = {
|
||
|
--- a/include/uapi/linux/jh7110-isp.h
|
||
|
+++ b/include/uapi/linux/jh7110-isp.h
|
||
|
@@ -15,6 +15,8 @@
|
||
|
|
||
|
#include <linux/v4l2-controls.h>
|
||
|
|
||
|
+#define V4L2_CID_USER_JH7110_ISP_BASE (V4L2_CID_USER_BASE + 0x1170)
|
||
|
+
|
||
|
#define V4L2_CID_USER_JH7110_ISP_WB_SETTING \
|
||
|
(V4L2_CID_USER_JH7110_ISP_BASE + 0x0001)
|
||
|
#define V4L2_CID_USER_JH7110_ISP_CAR_SETTING \
|
||
|
@@ -45,6 +47,8 @@
|
||
|
(V4L2_CID_USER_JH7110_ISP_BASE + 0x000e)
|
||
|
#define V4L2_CID_USER_JH7110_ISP_YCRV_SETTING \
|
||
|
(V4L2_CID_USER_JH7110_ISP_BASE + 0x000f)
|
||
|
+#define V4L2_CID_USER_JH7110_ISP_STAT_SETTING \
|
||
|
+ (V4L2_CID_USER_JH7110_ISP_BASE + 0x0010)
|
||
|
|
||
|
struct jh7110_isp_wb_gain {
|
||
|
__u16 gain_r;
|
||
|
@@ -202,13 +206,13 @@ struct jh7110_isp_sat_curve {
|
||
|
};
|
||
|
|
||
|
struct jh7110_isp_sat_hue_info {
|
||
|
- __s16 sin;
|
||
|
__s16 cos;
|
||
|
+ __s16 sin;
|
||
|
};
|
||
|
|
||
|
struct jh7110_isp_sat_info {
|
||
|
__s16 gain_cmab;
|
||
|
- __s16 gain_cmad;
|
||
|
+ __s16 gain_cmmd;
|
||
|
__s16 threshold_cmb;
|
||
|
__s16 threshold_cmd;
|
||
|
__s16 offset_u;
|
||
|
@@ -230,7 +234,8 @@ struct jh7110_isp_sharp_weight {
|
||
|
|
||
|
struct jh7110_isp_sharp_strength {
|
||
|
__s16 diff[4];
|
||
|
- __s16 f[4];
|
||
|
+ __s16 f[3];
|
||
|
+ __s32 s[3];
|
||
|
};
|
||
|
|
||
|
struct jh7110_isp_sharp_setting {
|
||
|
@@ -250,4 +255,41 @@ struct jh7110_isp_ycrv_setting {
|
||
|
struct jh7110_isp_ycrv_curve curve;
|
||
|
};
|
||
|
|
||
|
+struct jh7110_isp_sc_af_config {
|
||
|
+ __u8 es_hor_mode;
|
||
|
+ __u8 es_sum_mode;
|
||
|
+ __u8 hor_en;
|
||
|
+ __u8 ver_en;
|
||
|
+ __u8 es_ver_thr;
|
||
|
+ __u16 es_hor_thr;
|
||
|
+};
|
||
|
+
|
||
|
+struct jh7110_isp_sc_awb_ws {
|
||
|
+ __u8 awb_ws_rl;
|
||
|
+ __u8 awb_ws_ru;
|
||
|
+ __u8 awb_ws_grl;
|
||
|
+ __u8 awb_ws_gru;
|
||
|
+ __u8 awb_ws_gbl;
|
||
|
+ __u8 awb_ws_gbu;
|
||
|
+ __u8 awb_ws_bl;
|
||
|
+ __u8 awb_ws_bu;
|
||
|
+};
|
||
|
+
|
||
|
+struct jh7110_isp_sc_awb_point {
|
||
|
+ __u16 intensity;
|
||
|
+ __u8 weight;
|
||
|
+};
|
||
|
+
|
||
|
+struct jh7110_isp_sc_awb_config {
|
||
|
+ struct jh7110_isp_sc_awb_ws ws_config;
|
||
|
+ __u8 awb_cw[169];
|
||
|
+ struct jh7110_isp_sc_awb_point pts[17];
|
||
|
+};
|
||
|
+
|
||
|
+struct jh7110_isp_sc_setting {
|
||
|
+ __u32 enabled;
|
||
|
+ struct jh7110_isp_sc_af_config af_config;
|
||
|
+ struct jh7110_isp_sc_awb_config awb_config;
|
||
|
+};
|
||
|
+
|
||
|
#endif
|