On 12/29/17 08:52, Shunqian Zheng wrote: > From: Jacob Chen <jacob2.chen@xxxxxxxxxxxxxx> > > Add the output video driver that accept params from userspace. > > Signed-off-by: Jacob Chen <jacob2.chen@xxxxxxxxxxxxxx> > Signed-off-by: Shunqian Zheng <zhengsq@xxxxxxxxxxxxxx> > Signed-off-by: Yichong Zhong <zyc@xxxxxxxxxxxxxx> > Signed-off-by: Jacob Chen <cc@xxxxxxxxxxxxxx> > Signed-off-by: Eddie Cai <eddie.cai.linux@xxxxxxxxx> > Signed-off-by: Jeffy Chen <jeffy.chen@xxxxxxxxxxxxxx> > Signed-off-by: Allon Huang <allon.huang@xxxxxxxxxxxxxx> > Signed-off-by: Tomasz Figa <tfiga@xxxxxxxxxxxx> > --- > drivers/media/platform/rockchip/isp1/isp_params.c | 1553 +++++++++++++++++++++ > drivers/media/platform/rockchip/isp1/isp_params.h | 76 + > 2 files changed, 1629 insertions(+) > create mode 100644 drivers/media/platform/rockchip/isp1/isp_params.c > create mode 100644 drivers/media/platform/rockchip/isp1/isp_params.h > > diff --git a/drivers/media/platform/rockchip/isp1/isp_params.c b/drivers/media/platform/rockchip/isp1/isp_params.c > new file mode 100644 > index 0000000..7a90965 > --- /dev/null > +++ b/drivers/media/platform/rockchip/isp1/isp_params.c > @@ -0,0 +1,1553 @@ > +/* > + * Rockchip isp1 driver > + * > + * Copyright (C) 2017 Rockchip Electronics Co., Ltd. > + * > + * This software is available to you under a choice of one of two > + * licenses. You may choose to be licensed under the terms of the GNU > + * General Public License (GPL) Version 2, available from the file > + * COPYING in the main directory of this source tree, or the > + * OpenIB.org BSD license below: > + * > + * Redistribution and use in source and binary forms, with or > + * without modification, are permitted provided that the following > + * conditions are met: > + * > + * - Redistributions of source code must retain the above > + * copyright notice, this list of conditions and the following > + * disclaimer. > + * > + * - Redistributions in binary form must reproduce the above > + * copyright notice, this list of conditions and the following > + * disclaimer in the documentation and/or other materials > + * provided with the distribution. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, > + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF > + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND > + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS > + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN > + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN > + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE > + * SOFTWARE. > + */ > + > +#include <media/v4l2-common.h> > +#include <media/v4l2-ioctl.h> > +#include <media/videobuf2-core.h> > +#include <media/videobuf2-vmalloc.h> /* for ISP params */ > +#include "dev.h" > +#include "regs.h" > + > +#define RKISP1_ISP_PARAMS_REQ_BUFS_MIN 2 > +#define RKISP1_ISP_PARAMS_REQ_BUFS_MAX 8 > + > +#define BLS_START_H_MAX_IS_VALID(val) ((val) < CIFISP_BLS_START_H_MAX) > +#define BLS_STOP_H_MAX_IS_VALID(val) ((val) < CIFISP_BLS_STOP_H_MAX) > + > +#define BLS_START_V_MAX_IS_VALID(val) ((val) < CIFISP_BLS_START_V_MAX) > +#define BLS_STOP_V_MAX_IS_VALID(val) ((val) < CIFISP_BLS_STOP_V_MAX) > + > +#define BLS_SAMPLE_MAX_IS_VALID(val) ((val) < CIFISP_BLS_SAMPLES_MAX) > + > +#define BLS_FIX_SUB_IS_VALID(val) \ > + ((val) > (s16) CIFISP_BLS_FIX_SUB_MIN && (val) < CIFISP_BLS_FIX_SUB_MAX) > + > +#define RKISP1_ISP_DPCC_LINE_THRESH(n) (CIF_ISP_DPCC_LINE_THRESH_1 + 0x14 * (n)) > +#define RKISP1_ISP_DPCC_LINE_MAD_FAC(n) (CIF_ISP_DPCC_LINE_MAD_FAC_1 + 0x14 * (n)) > +#define RKISP1_ISP_DPCC_PG_FAC(n) (CIF_ISP_DPCC_PG_FAC_1 + 0x14 * (n)) > +#define RKISP1_ISP_DPCC_RND_THRESH(n) (CIF_ISP_DPCC_RND_THRESH_1 + 0x14 * (n)) > +#define RKISP1_ISP_DPCC_RG_FAC(n) (CIF_ISP_DPCC_RG_FAC_1 + 0x14 * (n)) > +#define RKISP1_ISP_CC_COEFF(n) (CIF_ISP_CC_COEFF_0 + (n) * 4) > + > +static inline void rkisp1_iowrite32(struct rkisp1_isp_params_vdev *params_vdev, > + u32 value, u32 addr) > +{ > + iowrite32(value, params_vdev->dev->base_addr + addr); > +} > + > +static inline u32 rkisp1_ioread32(struct rkisp1_isp_params_vdev *params_vdev, > + u32 addr) > +{ > + return ioread32(params_vdev->dev->base_addr + addr); > +} > + > +static inline void isp_param_set_bits(struct rkisp1_isp_params_vdev > + *params_vdev, > + u32 reg, u32 bit_mask) > +{ > + u32 val; > + > + val = rkisp1_ioread32(params_vdev, reg); > + rkisp1_iowrite32(params_vdev, val | bit_mask, reg); > +} > + > +static inline void isp_param_clear_bits(struct rkisp1_isp_params_vdev > + *params_vdev, > + u32 reg, u32 bit_mask) > +{ > + u32 val; > + > + val = rkisp1_ioread32(params_vdev, reg); > + rkisp1_iowrite32(params_vdev, val & ~bit_mask, reg); > +} > + > +/* ISP BP interface function */ > +static void dpcc_config(struct rkisp1_isp_params_vdev *params_vdev, > + const struct cifisp_dpcc_config *arg) > +{ > + unsigned int i; > + > + rkisp1_iowrite32(params_vdev, arg->mode, CIF_ISP_DPCC_MODE); > + rkisp1_iowrite32(params_vdev, arg->output_mode, > + CIF_ISP_DPCC_OUTPUT_MODE); > + rkisp1_iowrite32(params_vdev, arg->set_use, CIF_ISP_DPCC_SET_USE); > + > + rkisp1_iowrite32(params_vdev, arg->methods[0].method, > + CIF_ISP_DPCC_METHODS_SET_1); > + rkisp1_iowrite32(params_vdev, arg->methods[1].method, > + CIF_ISP_DPCC_METHODS_SET_2); > + rkisp1_iowrite32(params_vdev, arg->methods[2].method, > + CIF_ISP_DPCC_METHODS_SET_3); > + for (i = 0; i < CIFISP_DPCC_METHODS_MAX; i++) { > + rkisp1_iowrite32(params_vdev, arg->methods[i].line_thresh, > + RKISP1_ISP_DPCC_LINE_THRESH(i)); > + rkisp1_iowrite32(params_vdev, arg->methods[i].line_mad_fac, > + RKISP1_ISP_DPCC_LINE_MAD_FAC(i)); > + rkisp1_iowrite32(params_vdev, arg->methods[i].pg_fac, > + RKISP1_ISP_DPCC_PG_FAC(i)); > + rkisp1_iowrite32(params_vdev, arg->methods[i].rnd_thresh, > + RKISP1_ISP_DPCC_RND_THRESH(i)); > + rkisp1_iowrite32(params_vdev, arg->methods[i].rg_fac, > + RKISP1_ISP_DPCC_RG_FAC(i)); > + } > + > + rkisp1_iowrite32(params_vdev, arg->rnd_offs, CIF_ISP_DPCC_RND_OFFS); > + rkisp1_iowrite32(params_vdev, arg->ro_limits, CIF_ISP_DPCC_RO_LIMITS); > +} > + > +/* ISP black level subtraction interface function */ > +static void bls_config(struct rkisp1_isp_params_vdev *params_vdev, > + const struct cifisp_bls_config *arg) > +{ > + u32 new_control = 0; > + > + /* fixed subtraction values */ > + if (!arg->enable_auto) { > + const struct cifisp_bls_fixed_val *pval = &arg->fixed_val; > + > + switch (params_vdev->raw_type) { > + case RAW_BGGR: > + rkisp1_iowrite32(params_vdev, > + pval->r, CIF_ISP_BLS_D_FIXED); > + rkisp1_iowrite32(params_vdev, > + pval->gr, CIF_ISP_BLS_C_FIXED); > + rkisp1_iowrite32(params_vdev, > + pval->gb, CIF_ISP_BLS_B_FIXED); > + rkisp1_iowrite32(params_vdev, > + pval->b, CIF_ISP_BLS_A_FIXED); > + break; > + case RAW_GBRG: > + rkisp1_iowrite32(params_vdev, > + pval->r, CIF_ISP_BLS_C_FIXED); > + rkisp1_iowrite32(params_vdev, > + pval->gr, CIF_ISP_BLS_D_FIXED); > + rkisp1_iowrite32(params_vdev, > + pval->gb, CIF_ISP_BLS_A_FIXED); > + rkisp1_iowrite32(params_vdev, > + pval->b, CIF_ISP_BLS_B_FIXED); > + break; > + case RAW_GRBG: > + rkisp1_iowrite32(params_vdev, > + pval->r, CIF_ISP_BLS_B_FIXED); > + rkisp1_iowrite32(params_vdev, > + pval->gr, CIF_ISP_BLS_A_FIXED); > + rkisp1_iowrite32(params_vdev, > + pval->gb, CIF_ISP_BLS_D_FIXED); > + rkisp1_iowrite32(params_vdev, > + pval->b, CIF_ISP_BLS_C_FIXED); > + break; > + case RAW_RGGB: > + rkisp1_iowrite32(params_vdev, > + pval->r, CIF_ISP_BLS_A_FIXED); > + rkisp1_iowrite32(params_vdev, > + pval->gr, CIF_ISP_BLS_B_FIXED); > + rkisp1_iowrite32(params_vdev, > + pval->gb, CIF_ISP_BLS_C_FIXED); > + rkisp1_iowrite32(params_vdev, > + pval->b, CIF_ISP_BLS_D_FIXED); > + break; > + default: > + break; > + } > + > + new_control = CIF_ISP_BLS_MODE_FIXED; > + } else { > + if (arg->en_windows & BIT(1)) { > + rkisp1_iowrite32(params_vdev, arg->bls_window2.h_offs, > + CIF_ISP_BLS_H2_START); > + rkisp1_iowrite32(params_vdev, arg->bls_window2.h_size, > + CIF_ISP_BLS_H2_STOP); > + rkisp1_iowrite32(params_vdev, arg->bls_window2.v_offs, > + CIF_ISP_BLS_V2_START); > + rkisp1_iowrite32(params_vdev, arg->bls_window2.v_size, > + CIF_ISP_BLS_V2_STOP); > + new_control |= CIF_ISP_BLS_WINDOW_2; > + } > + > + if (arg->en_windows & BIT(0)) { > + rkisp1_iowrite32(params_vdev, arg->bls_window1.h_offs, > + CIF_ISP_BLS_H1_START); > + rkisp1_iowrite32(params_vdev, arg->bls_window1.h_size, > + CIF_ISP_BLS_H1_STOP); > + rkisp1_iowrite32(params_vdev, arg->bls_window1.v_offs, > + CIF_ISP_BLS_V1_START); > + rkisp1_iowrite32(params_vdev, arg->bls_window1.v_size, > + CIF_ISP_BLS_V1_STOP); > + new_control |= CIF_ISP_BLS_WINDOW_1; > + } > + > + rkisp1_iowrite32(params_vdev, arg->bls_samples, > + CIF_ISP_BLS_SAMPLES); > + > + new_control |= CIF_ISP_BLS_MODE_MEASURED; > + } > + rkisp1_iowrite32(params_vdev, new_control, CIF_ISP_BLS_CTRL); > +} > + > +/* ISP LS correction interface function */ > +static void > +__lsc_correct_matrix_config(struct rkisp1_isp_params_vdev *params_vdev, > + const struct cifisp_lsc_config *pconfig) > +{ > + int i, j; > + unsigned int isp_lsc_status, sram_addr, isp_lsc_table_sel; > + unsigned int data; > + > + isp_lsc_status = rkisp1_ioread32(params_vdev, CIF_ISP_LSC_STATUS); > + > + /* CIF_ISP_LSC_TABLE_ADDRESS_153 = ( 17 * 18 ) >> 1 */ > + sram_addr = (isp_lsc_status & CIF_ISP_LSC_ACTIVE_TABLE) ? > + CIF_ISP_LSC_TABLE_ADDRESS_0 : > + CIF_ISP_LSC_TABLE_ADDRESS_153; > + rkisp1_iowrite32(params_vdev, sram_addr, CIF_ISP_LSC_R_TABLE_ADDR); > + rkisp1_iowrite32(params_vdev, sram_addr, CIF_ISP_LSC_GR_TABLE_ADDR); > + rkisp1_iowrite32(params_vdev, sram_addr, CIF_ISP_LSC_GB_TABLE_ADDR); > + rkisp1_iowrite32(params_vdev, sram_addr, CIF_ISP_LSC_B_TABLE_ADDR); > + > + /* program data tables (table size is 9 * 17 = 153) */ > + for (i = 0; i < ((CIF_ISP_LSC_SECTORS_MAX + 1) * > + (CIF_ISP_LSC_SECTORS_MAX + 1)); > + i += CIF_ISP_LSC_SECTORS_MAX + 1) { > + /* > + * 17 sectors with 2 values in one DWORD = 9 > + * DWORDs (2nd value of last DWORD unused) > + */ > + for (j = 0; j < (CIF_ISP_LSC_SECTORS_MAX + 1); j += 2) { > + data = CIF_ISP_LSC_TABLE_DATA( > + pconfig->r_data_tbl[i + j], > + pconfig->r_data_tbl[i + j + 1]); > + rkisp1_iowrite32(params_vdev, data, > + CIF_ISP_LSC_R_TABLE_DATA); > + > + data = CIF_ISP_LSC_TABLE_DATA( > + pconfig->gr_data_tbl[i + j], > + pconfig->gr_data_tbl[i + j + 1]); > + rkisp1_iowrite32(params_vdev, data, > + CIF_ISP_LSC_GR_TABLE_DATA); > + > + data = CIF_ISP_LSC_TABLE_DATA( > + pconfig->gb_data_tbl[i + j], > + pconfig->gb_data_tbl[i + j + 1]); > + rkisp1_iowrite32(params_vdev, data, > + CIF_ISP_LSC_GB_TABLE_DATA); > + > + data = CIF_ISP_LSC_TABLE_DATA( > + pconfig->b_data_tbl[i + j], > + pconfig->b_data_tbl[i + j + 1]); > + rkisp1_iowrite32(params_vdev, data, > + CIF_ISP_LSC_B_TABLE_DATA); > + } > + } > + > + isp_lsc_table_sel = (isp_lsc_status & CIF_ISP_LSC_ACTIVE_TABLE) ? > + CIF_ISP_LSC_TABLE_0 : CIF_ISP_LSC_TABLE_1; > + rkisp1_iowrite32(params_vdev, isp_lsc_table_sel, CIF_ISP_LSC_TABLE_SEL); > +} > + > +static void lsc_config(struct rkisp1_isp_params_vdev *params_vdev, > + const struct cifisp_lsc_config *arg) > +{ > + int i; > + u32 lsc_ctrl; > + unsigned int data; > + > + /* To config must be off , store the current status firstly */ > + lsc_ctrl = rkisp1_ioread32(params_vdev, CIF_ISP_LSC_CTRL); > + isp_param_clear_bits(params_vdev, CIF_ISP_LSC_CTRL, > + CIF_ISP_LSC_CTRL_ENA); > + __lsc_correct_matrix_config(params_vdev, arg); > + > + for (i = 0; i < 4; i++) { > + /* program x size tables */ > + data = CIF_ISP_LSC_SECT_SIZE(arg->x_size_tbl[i * 2], > + arg->x_size_tbl[i * 2 + 1]); > + rkisp1_iowrite32(params_vdev, data, > + CIF_ISP_LSC_XSIZE_01 + i * 4); > + > + /* program x grad tables */ > + data = CIF_ISP_LSC_SECT_SIZE(arg->x_grad_tbl[i * 2], > + arg->x_grad_tbl[i * 2 + 1]); > + rkisp1_iowrite32(params_vdev, data, > + CIF_ISP_LSC_XGRAD_01 + i * 4); > + > + /* program y size tables */ > + data = CIF_ISP_LSC_SECT_SIZE(arg->y_size_tbl[i * 2], > + arg->y_size_tbl[i * 2 + 1]); > + rkisp1_iowrite32(params_vdev, data, > + CIF_ISP_LSC_YSIZE_01 + i * 4); > + > + /* program y grad tables */ > + data = CIF_ISP_LSC_SECT_SIZE(arg->y_grad_tbl[i * 2], > + arg->y_grad_tbl[i * 2 + 1]); > + rkisp1_iowrite32(params_vdev, data, > + CIF_ISP_LSC_YGRAD_01 + i * 4); > + } > + > + /* restore the bls ctrl status */ > + if (lsc_ctrl & CIF_ISP_LSC_CTRL_ENA) { > + isp_param_set_bits(params_vdev, > + CIF_ISP_LSC_CTRL, > + CIF_ISP_LSC_CTRL_ENA); > + } else { > + isp_param_clear_bits(params_vdev, > + CIF_ISP_LSC_CTRL, > + CIF_ISP_LSC_CTRL_ENA); > + } > +} > + > +/* ISP Filtering function */ > +static void flt_config(struct rkisp1_isp_params_vdev *params_vdev, > + const struct cifisp_flt_config *arg) > +{ > + rkisp1_iowrite32(params_vdev, arg->thresh_bl0, CIF_ISP_FILT_THRESH_BL0); > + rkisp1_iowrite32(params_vdev, arg->thresh_bl1, CIF_ISP_FILT_THRESH_BL1); > + rkisp1_iowrite32(params_vdev, arg->thresh_sh0, CIF_ISP_FILT_THRESH_SH0); > + rkisp1_iowrite32(params_vdev, arg->thresh_sh1, CIF_ISP_FILT_THRESH_SH1); > + rkisp1_iowrite32(params_vdev, arg->fac_bl0, CIF_ISP_FILT_FAC_BL0); > + rkisp1_iowrite32(params_vdev, arg->fac_bl1, CIF_ISP_FILT_FAC_BL1); > + rkisp1_iowrite32(params_vdev, arg->fac_mid, CIF_ISP_FILT_FAC_MID); > + rkisp1_iowrite32(params_vdev, arg->fac_sh0, CIF_ISP_FILT_FAC_SH0); > + rkisp1_iowrite32(params_vdev, arg->fac_sh1, CIF_ISP_FILT_FAC_SH1); > + rkisp1_iowrite32(params_vdev, arg->lum_weight, CIF_ISP_FILT_LUM_WEIGHT); > + > + rkisp1_iowrite32(params_vdev, (arg->mode ? CIF_ISP_FLT_MODE_DNR : 0) | > + CIF_ISP_FLT_CHROMA_V_MODE(arg->chr_v_mode) | > + CIF_ISP_FLT_CHROMA_H_MODE(arg->chr_h_mode) | > + CIF_ISP_FLT_GREEN_STAGE1(arg->grn_stage1), > + CIF_ISP_FILT_MODE); > +} > + > +/* ISP demosaic interface function */ > +static int bdm_config(struct rkisp1_isp_params_vdev *params_vdev, > + const struct cifisp_bdm_config *arg) > +{ > + /* set demosaic threshold */ > + rkisp1_iowrite32(params_vdev, arg->demosaic_th, CIF_ISP_DEMOSAIC); > + return 0; > +} > + > +/* ISP GAMMA correction interface function */ > +static void sdg_config(struct rkisp1_isp_params_vdev *params_vdev, > + const struct cifisp_sdg_config *arg) > +{ > + int i; > + > + rkisp1_iowrite32(params_vdev, > + arg->xa_pnts.gamma_dx0, CIF_ISP_GAMMA_DX_LO); > + rkisp1_iowrite32(params_vdev, > + arg->xa_pnts.gamma_dx1, CIF_ISP_GAMMA_DX_HI); > + > + for (i = 0; i < CIFISP_DEGAMMA_CURVE_SIZE; i++) { > + rkisp1_iowrite32(params_vdev, arg->curve_r.gamma_y[i], > + CIF_ISP_GAMMA_R_Y0 + i * 4); > + rkisp1_iowrite32(params_vdev, arg->curve_g.gamma_y[i], > + CIF_ISP_GAMMA_G_Y0 + i * 4); > + rkisp1_iowrite32(params_vdev, arg->curve_b.gamma_y[i], > + CIF_ISP_GAMMA_B_Y0 + i * 4); > + } > +} > + > +/* ISP GAMMA correction interface function */ > +static void goc_config(struct rkisp1_isp_params_vdev *params_vdev, > + const struct cifisp_goc_config *arg) > +{ > + int i; > + > + isp_param_clear_bits(params_vdev, CIF_ISP_CTRL, > + CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA); > + rkisp1_iowrite32(params_vdev, arg->mode, CIF_ISP_GAMMA_OUT_MODE); > + > + for (i = 0; i < CIFISP_GAMMA_OUT_MAX_SAMPLES; i++) > + rkisp1_iowrite32(params_vdev, arg->gamma_y[i], > + CIF_ISP_GAMMA_OUT_Y_0 + i * 4); > +} > + > +/* ISP Cross Talk */ > +static void ctk_config(struct rkisp1_isp_params_vdev *params_vdev, > + const struct cifisp_ctk_config *arg) > +{ > + rkisp1_iowrite32(params_vdev, arg->coeff0, CIF_ISP_CT_COEFF_0); > + rkisp1_iowrite32(params_vdev, arg->coeff1, CIF_ISP_CT_COEFF_1); > + rkisp1_iowrite32(params_vdev, arg->coeff2, CIF_ISP_CT_COEFF_2); > + rkisp1_iowrite32(params_vdev, arg->coeff3, CIF_ISP_CT_COEFF_3); > + rkisp1_iowrite32(params_vdev, arg->coeff4, CIF_ISP_CT_COEFF_4); > + rkisp1_iowrite32(params_vdev, arg->coeff5, CIF_ISP_CT_COEFF_5); > + rkisp1_iowrite32(params_vdev, arg->coeff6, CIF_ISP_CT_COEFF_6); > + rkisp1_iowrite32(params_vdev, arg->coeff7, CIF_ISP_CT_COEFF_7); > + rkisp1_iowrite32(params_vdev, arg->coeff8, CIF_ISP_CT_COEFF_8); > + rkisp1_iowrite32(params_vdev, arg->ct_offset_r, CIF_ISP_CT_OFFSET_R); > + rkisp1_iowrite32(params_vdev, arg->ct_offset_g, CIF_ISP_CT_OFFSET_G); > + rkisp1_iowrite32(params_vdev, arg->ct_offset_b, CIF_ISP_CT_OFFSET_B); > +} > + > +static void ctk_enable(struct rkisp1_isp_params_vdev *params_vdev, bool en) > +{ > + if (en) > + return; > + > + /* Write back the default values. */ > + rkisp1_iowrite32(params_vdev, 0x80, CIF_ISP_CT_COEFF_0); > + rkisp1_iowrite32(params_vdev, 0, CIF_ISP_CT_COEFF_1); > + rkisp1_iowrite32(params_vdev, 0, CIF_ISP_CT_COEFF_2); > + rkisp1_iowrite32(params_vdev, 0, CIF_ISP_CT_COEFF_3); > + rkisp1_iowrite32(params_vdev, 0x80, CIF_ISP_CT_COEFF_4); > + rkisp1_iowrite32(params_vdev, 0, CIF_ISP_CT_COEFF_5); > + rkisp1_iowrite32(params_vdev, 0, CIF_ISP_CT_COEFF_6); > + rkisp1_iowrite32(params_vdev, 0, CIF_ISP_CT_COEFF_7); > + rkisp1_iowrite32(params_vdev, 0x80, CIF_ISP_CT_COEFF_8); > + > + rkisp1_iowrite32(params_vdev, 0, CIF_ISP_CT_OFFSET_R); > + rkisp1_iowrite32(params_vdev, 0, CIF_ISP_CT_OFFSET_G); > + rkisp1_iowrite32(params_vdev, 0, CIF_ISP_CT_OFFSET_B); > +} > + > +/* ISP White Balance Mode */ > +static void awb_meas_config(struct rkisp1_isp_params_vdev *params_vdev, > + const struct cifisp_awb_meas_config *arg) > +{ > + u32 reg_val = 0; > + /* based on the mode,configure the awb module */ > + if (arg->awb_mode == CIFISP_AWB_MODE_YCBCR) { > + /* Reference Cb and Cr */ > + rkisp1_iowrite32(params_vdev, > + CIF_ISP_AWB_REF_CR_SET(arg->awb_ref_cr) | > + arg->awb_ref_cb, CIF_ISP_AWB_REF); > + /* Yc Threshold */ > + rkisp1_iowrite32(params_vdev, > + CIF_ISP_AWB_MAX_Y_SET(arg->max_y) | > + CIF_ISP_AWB_MIN_Y_SET(arg->min_y) | > + CIF_ISP_AWB_MAX_CS_SET(arg->max_csum) | > + arg->min_c, CIF_ISP_AWB_THRESH); > + } > + > + reg_val = rkisp1_ioread32(params_vdev, CIF_ISP_AWB_PROP); > + if (arg->enable_ymax_cmp) > + reg_val |= CIF_ISP_AWB_YMAX_CMP_EN; > + else > + reg_val &= ~CIF_ISP_AWB_YMAX_CMP_EN; > + rkisp1_iowrite32(params_vdev, reg_val, CIF_ISP_AWB_PROP); > + > + /* window offset */ > + rkisp1_iowrite32(params_vdev, > + arg->awb_wnd.v_offs, CIF_ISP_AWB_WND_V_OFFS); > + rkisp1_iowrite32(params_vdev, > + arg->awb_wnd.h_offs, CIF_ISP_AWB_WND_H_OFFS); > + /* AWB window size */ > + rkisp1_iowrite32(params_vdev, > + arg->awb_wnd.v_size, CIF_ISP_AWB_WND_V_SIZE); > + rkisp1_iowrite32(params_vdev, > + arg->awb_wnd.h_size, CIF_ISP_AWB_WND_H_SIZE); > + /* Number of frames */ > + rkisp1_iowrite32(params_vdev, > + arg->frames, CIF_ISP_AWB_FRAMES); > +} > + > +static void awb_meas_enable(struct rkisp1_isp_params_vdev *params_vdev, > + const struct cifisp_awb_meas_config *arg, bool en) > +{ > + u32 reg_val = rkisp1_ioread32(params_vdev, CIF_ISP_AWB_PROP); > + > + /* switch off */ > + reg_val &= CIF_ISP_AWB_MODE_MASK_NONE; > + > + if (en) { > + if (arg->awb_mode == CIFISP_AWB_MODE_RGB) > + reg_val |= CIF_ISP_AWB_MODE_RGB_EN; > + else > + reg_val |= CIF_ISP_AWB_MODE_YCBCR_EN; > + > + rkisp1_iowrite32(params_vdev, reg_val, CIF_ISP_AWB_PROP); > + > + /* Measurements require AWB block be active. */ > + /* TODO: need to enable here ? awb_gain_enable has done this */ > + isp_param_set_bits(params_vdev, CIF_ISP_CTRL, > + CIF_ISP_CTRL_ISP_AWB_ENA); > + } else { > + rkisp1_iowrite32(params_vdev, > + reg_val, CIF_ISP_AWB_PROP); > + isp_param_clear_bits(params_vdev, CIF_ISP_CTRL, > + CIF_ISP_CTRL_ISP_AWB_ENA); > + } > +} > + > +static void awb_gain_config(struct rkisp1_isp_params_vdev *params_vdev, > + const struct cifisp_awb_gain_config *arg) > +{ > + rkisp1_iowrite32(params_vdev, > + CIF_ISP_AWB_GAIN_R_SET(arg->gain_green_r) | > + arg->gain_green_b, CIF_ISP_AWB_GAIN_G); > + > + rkisp1_iowrite32(params_vdev, CIF_ISP_AWB_GAIN_R_SET(arg->gain_red) | > + arg->gain_blue, CIF_ISP_AWB_GAIN_RB); > +} > + > +static void aec_config(struct rkisp1_isp_params_vdev *params_vdev, > + const struct cifisp_aec_config *arg) > +{ > + unsigned int block_hsize, block_vsize; > + > + rkisp1_iowrite32(params_vdev, > + ((arg->autostop) ? CIF_ISP_EXP_CTRL_AUTOSTOP : 0) | > + ((arg->mode == CIFISP_EXP_MEASURING_MODE_1) ? > + CIF_ISP_EXP_CTRL_MEASMODE_1 : 0), CIF_ISP_EXP_CTRL); > + > + rkisp1_iowrite32(params_vdev, > + arg->meas_window.h_offs, CIF_ISP_EXP_H_OFFSET); > + rkisp1_iowrite32(params_vdev, > + arg->meas_window.v_offs, CIF_ISP_EXP_V_OFFSET); > + > + block_hsize = arg->meas_window.h_size / CIF_ISP_EXP_COLUMN_NUM - 1; > + block_vsize = arg->meas_window.v_size / CIF_ISP_EXP_ROW_NUM - 1; > + > + rkisp1_iowrite32(params_vdev, CIF_ISP_EXP_H_SIZE_SET(block_hsize), > + CIF_ISP_EXP_H_SIZE); > + rkisp1_iowrite32(params_vdev, CIF_ISP_EXP_V_SIZE_SET(block_vsize), > + CIF_ISP_EXP_V_SIZE); > +} > + > +static void cproc_config(struct rkisp1_isp_params_vdev *params_vdev, > + const struct cifisp_cproc_config *arg) > +{ > + struct cifisp_isp_other_cfg *cur_other_cfg = ¶ms_vdev->cur_params.others; > + struct cifisp_ie_config *cur_ie_config = &cur_other_cfg->ie_config; > + u32 effect = cur_ie_config->effect; > + u32 quantization = params_vdev->quantization; > + > + rkisp1_iowrite32(params_vdev, arg->contrast, CIF_C_PROC_CONTRAST); > + rkisp1_iowrite32(params_vdev, arg->hue, CIF_C_PROC_HUE); > + rkisp1_iowrite32(params_vdev, arg->sat, CIF_C_PROC_SATURATION); > + rkisp1_iowrite32(params_vdev, arg->brightness, CIF_C_PROC_BRIGHTNESS); > + > + if (quantization != V4L2_QUANTIZATION_FULL_RANGE || > + effect != V4L2_COLORFX_NONE) { > + isp_param_clear_bits(params_vdev, CIF_C_PROC_CTRL, > + CIF_C_PROC_YOUT_FULL | > + CIF_C_PROC_YIN_FULL | > + CIF_C_PROC_COUT_FULL); > + } else { > + isp_param_set_bits(params_vdev, CIF_C_PROC_CTRL, > + CIF_C_PROC_YOUT_FULL | > + CIF_C_PROC_YIN_FULL | > + CIF_C_PROC_COUT_FULL); > + } > +} > + > +static void hst_config(struct rkisp1_isp_params_vdev *params_vdev, > + const struct cifisp_hst_config *arg) > +{ > + unsigned int block_hsize, block_vsize; > + static const u32 hist_weight_regs[] = { > + CIF_ISP_HIST_WEIGHT_00TO30, CIF_ISP_HIST_WEIGHT_40TO21, > + CIF_ISP_HIST_WEIGHT_31TO12, CIF_ISP_HIST_WEIGHT_22TO03, > + CIF_ISP_HIST_WEIGHT_13TO43, CIF_ISP_HIST_WEIGHT_04TO34, > + CIF_ISP_HIST_WEIGHT_44, > + }; > + int i; > + const u8 *weight; > + > + rkisp1_iowrite32(params_vdev, > + CIF_ISP_HIST_PREDIV_SET(arg->histogram_predivider), > + CIF_ISP_HIST_PROP); > + rkisp1_iowrite32(params_vdev, > + arg->meas_window.h_offs, > + CIF_ISP_HIST_H_OFFS); > + rkisp1_iowrite32(params_vdev, > + arg->meas_window.v_offs, > + CIF_ISP_HIST_V_OFFS); > + > + block_hsize = arg->meas_window.h_size / CIF_ISP_HIST_COLUMN_NUM - 1; > + block_vsize = arg->meas_window.v_size / CIF_ISP_HIST_ROW_NUM - 1; > + > + rkisp1_iowrite32(params_vdev, block_hsize, CIF_ISP_HIST_H_SIZE); > + rkisp1_iowrite32(params_vdev, block_vsize, CIF_ISP_HIST_V_SIZE); > + > + weight = arg->hist_weight; > + for (i = 0; i < ARRAY_SIZE(hist_weight_regs); ++i, weight += 4) > + rkisp1_iowrite32(params_vdev, CIF_ISP_HIST_WEIGHT_SET( > + weight[0], weight[1], weight[2], weight[3]), > + hist_weight_regs[i]); > +} > + > +static void hst_enable(struct rkisp1_isp_params_vdev *params_vdev, > + const struct cifisp_hst_config *arg, bool en) > +{ > + if (en) { > + u32 hist_prop = rkisp1_ioread32(params_vdev, CIF_ISP_HIST_PROP); > + > + hist_prop &= ~CIF_ISP_HIST_PROP_MODE_MASK; > + hist_prop |= arg->mode; > + isp_param_set_bits(params_vdev, CIF_ISP_HIST_PROP, hist_prop); > + } else { > + isp_param_clear_bits(params_vdev, CIF_ISP_HIST_PROP, > + CIF_ISP_HIST_PROP_MODE_MASK); > + } > +} > + > +static void afm_config(struct rkisp1_isp_params_vdev *params_vdev, > + const struct cifisp_afc_config *arg) > +{ > + int i; > + size_t num_of_win = min_t(size_t, ARRAY_SIZE(arg->afm_win), > + arg->num_afm_win); > + > + /* Switch off to configure. Enabled during normal flow in frame isr. */ > + isp_param_clear_bits(params_vdev, CIF_ISP_AFM_CTRL, CIF_ISP_AFM_ENA); > + > + for (i = 0; i < num_of_win; i++) { > + rkisp1_iowrite32(params_vdev, > + CIF_ISP_AFM_WINDOW_X(arg->afm_win[i].h_offs) | > + CIF_ISP_AFM_WINDOW_Y(arg->afm_win[i].v_offs), > + CIF_ISP_AFM_LT_A + i * 8); > + rkisp1_iowrite32(params_vdev, > + CIF_ISP_AFM_WINDOW_X(arg->afm_win[i].h_size + > + arg->afm_win[i].h_offs) | > + CIF_ISP_AFM_WINDOW_Y(arg->afm_win[i].v_size + > + arg->afm_win[i].v_offs), > + CIF_ISP_AFM_RB_A + i * 8); > + } > + rkisp1_iowrite32(params_vdev, arg->thres, CIF_ISP_AFM_THRES); > + rkisp1_iowrite32(params_vdev, arg->var_shift, CIF_ISP_AFM_VAR_SHIFT); > +} > + > +static void ie_config(struct rkisp1_isp_params_vdev *params_vdev, > + const struct cifisp_ie_config *arg) > +{ > + u32 eff_ctrl; > + > + eff_ctrl = rkisp1_ioread32(params_vdev, CIF_IMG_EFF_CTRL); > + eff_ctrl &= ~CIF_IMG_EFF_CTRL_MODE_MASK; > + > + if (params_vdev->quantization == V4L2_QUANTIZATION_FULL_RANGE) > + eff_ctrl |= CIF_IMG_EFF_CTRL_YCBCR_FULL; > + > + switch (arg->effect) { > + case V4L2_COLORFX_SEPIA: > + eff_ctrl |= CIF_IMG_EFF_CTRL_MODE_SEPIA; > + break; > + case V4L2_COLORFX_SET_CBCR: > + rkisp1_iowrite32(params_vdev, arg->eff_tint, CIF_IMG_EFF_TINT); > + eff_ctrl |= CIF_IMG_EFF_CTRL_MODE_SEPIA; > + break; > + /* > + * Color selection is similar to water color(AQUA): > + * grayscale + selected color w threshold > + */ > + case V4L2_COLORFX_AQUA: > + eff_ctrl |= CIF_IMG_EFF_CTRL_MODE_COLOR_SEL; > + rkisp1_iowrite32(params_vdev, arg->color_sel, > + CIF_IMG_EFF_COLOR_SEL); > + break; > + case V4L2_COLORFX_EMBOSS: > + eff_ctrl |= CIF_IMG_EFF_CTRL_MODE_EMBOSS; > + rkisp1_iowrite32(params_vdev, arg->eff_mat_1, > + CIF_IMG_EFF_MAT_1); > + rkisp1_iowrite32(params_vdev, arg->eff_mat_2, > + CIF_IMG_EFF_MAT_2); > + rkisp1_iowrite32(params_vdev, arg->eff_mat_3, > + CIF_IMG_EFF_MAT_3); > + break; > + case V4L2_COLORFX_SKETCH: > + eff_ctrl |= CIF_IMG_EFF_CTRL_MODE_SKETCH; > + rkisp1_iowrite32(params_vdev, arg->eff_mat_3, > + CIF_IMG_EFF_MAT_3); > + rkisp1_iowrite32(params_vdev, arg->eff_mat_4, > + CIF_IMG_EFF_MAT_4); > + rkisp1_iowrite32(params_vdev, arg->eff_mat_5, > + CIF_IMG_EFF_MAT_5); > + break; > + case V4L2_COLORFX_BW: > + eff_ctrl |= CIF_IMG_EFF_CTRL_MODE_BLACKWHITE; > + break; > + case V4L2_COLORFX_NEGATIVE: > + eff_ctrl |= CIF_IMG_EFF_CTRL_MODE_NEGATIVE; > + break; > + default: > + break; > + } > + > + rkisp1_iowrite32(params_vdev, eff_ctrl, CIF_IMG_EFF_CTRL); > +} > + > +static void ie_enable(struct rkisp1_isp_params_vdev *params_vdev, bool en) > +{ > + if (en) { > + isp_param_set_bits(params_vdev, CIF_ICCL, CIF_ICCL_IE_CLK); > + rkisp1_iowrite32(params_vdev, CIF_IMG_EFF_CTRL_ENABLE, > + CIF_IMG_EFF_CTRL); > + isp_param_set_bits(params_vdev, CIF_IMG_EFF_CTRL, > + CIF_IMG_EFF_CTRL_CFG_UPD); > + } else { > + /* Disable measurement */ > + isp_param_clear_bits(params_vdev, CIF_IMG_EFF_CTRL, > + CIF_IMG_EFF_CTRL_ENABLE); > + isp_param_clear_bits(params_vdev, CIF_ICCL, CIF_ICCL_IE_CLK); > + } > +} > + > +static void csm_config(struct rkisp1_isp_params_vdev *params_vdev, > + bool full_range) > +{ > + static const u16 full_range_coeff[] = { > + 0x0026, 0x004b, 0x000f, > + 0x01ea, 0x01d6, 0x0040, > + 0x0040, 0x01ca, 0x01f6 > + }; > + static const u16 limited_range_coeff[] = { > + 0x0021, 0x0040, 0x000d, > + 0x01ed, 0x01db, 0x0038, > + 0x0038, 0x01d1, 0x01f7, > + }; > + int i; > + > + if (full_range) { > + for (i = 0; i < ARRAY_SIZE(full_range_coeff); i++) > + rkisp1_iowrite32(params_vdev, full_range_coeff[i], > + CIF_ISP_CC_COEFF_0 + i * 4); > + > + isp_param_set_bits(params_vdev, CIF_ISP_CTRL, > + CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA | > + CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA); > + } else { > + for (i = 0; i < ARRAY_SIZE(limited_range_coeff); i++) > + rkisp1_iowrite32(params_vdev, limited_range_coeff[i], > + CIF_ISP_CC_COEFF_0 + i * 4); > + > + isp_param_clear_bits(params_vdev, CIF_ISP_CTRL, > + CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA | > + CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA); > + } > +} > + > +/* ISP De-noise Pre-Filter(DPF) function */ > +static void dpf_config(struct rkisp1_isp_params_vdev *params_vdev, > + const struct cifisp_dpf_config *arg) > +{ > + unsigned int isp_dpf_mode; > + unsigned int spatial_coeff; > + unsigned int i; > + > + switch (arg->gain.mode) { > + case CIFISP_DPF_GAIN_USAGE_NF_GAINS: > + isp_dpf_mode = CIF_ISP_DPF_MODE_USE_NF_GAIN | > + CIF_ISP_DPF_MODE_AWB_GAIN_COMP; > + break; > + case CIFISP_DPF_GAIN_USAGE_LSC_GAINS: > + isp_dpf_mode = CIF_ISP_DPF_MODE_LSC_GAIN_COMP; > + break; > + case CIFISP_DPF_GAIN_USAGE_NF_LSC_GAINS: > + isp_dpf_mode = CIF_ISP_DPF_MODE_USE_NF_GAIN | > + CIF_ISP_DPF_MODE_AWB_GAIN_COMP | > + CIF_ISP_DPF_MODE_LSC_GAIN_COMP; > + break; > + case CIFISP_DPF_GAIN_USAGE_AWB_GAINS: > + isp_dpf_mode = CIF_ISP_DPF_MODE_AWB_GAIN_COMP; > + break; > + case CIFISP_DPF_GAIN_USAGE_AWB_LSC_GAINS: > + isp_dpf_mode = CIF_ISP_DPF_MODE_LSC_GAIN_COMP | > + CIF_ISP_DPF_MODE_AWB_GAIN_COMP; > + break; > + case CIFISP_DPF_GAIN_USAGE_DISABLED: > + default: > + isp_dpf_mode = 0; > + break; > + } > + > + if (arg->nll.scale_mode == CIFISP_NLL_SCALE_LOGARITHMIC) > + isp_dpf_mode |= CIF_ISP_DPF_MODE_NLL_SEGMENTATION; > + if (arg->rb_flt.fltsize == CIFISP_DPF_RB_FILTERSIZE_9x9) > + isp_dpf_mode |= CIF_ISP_DPF_MODE_RB_FLTSIZE_9x9; > + if (!arg->rb_flt.r_enable) > + isp_dpf_mode |= CIF_ISP_DPF_MODE_R_FLT_DIS; > + if (!arg->rb_flt.b_enable) > + isp_dpf_mode |= CIF_ISP_DPF_MODE_B_FLT_DIS; > + if (!arg->g_flt.gb_enable) > + isp_dpf_mode |= CIF_ISP_DPF_MODE_GB_FLT_DIS; > + if (!arg->g_flt.gr_enable) > + isp_dpf_mode |= CIF_ISP_DPF_MODE_GR_FLT_DIS; > + > + isp_param_set_bits(params_vdev, CIF_ISP_DPF_MODE, isp_dpf_mode); > + rkisp1_iowrite32(params_vdev, arg->gain.nf_b_gain, > + CIF_ISP_DPF_NF_GAIN_B); > + rkisp1_iowrite32(params_vdev, arg->gain.nf_r_gain, > + CIF_ISP_DPF_NF_GAIN_R); > + rkisp1_iowrite32(params_vdev, arg->gain.nf_gb_gain, > + CIF_ISP_DPF_NF_GAIN_GB); > + rkisp1_iowrite32(params_vdev, arg->gain.nf_gr_gain, > + CIF_ISP_DPF_NF_GAIN_GR); > + > + for (i = 0; i < CIFISP_DPF_MAX_NLF_COEFFS; i++) { > + rkisp1_iowrite32(params_vdev, arg->nll.coeff[i], > + CIF_ISP_DPF_NULL_COEFF_0 + i * 4); > + } > + > + spatial_coeff = arg->g_flt.spatial_coeff[0] | > + (arg->g_flt.spatial_coeff[1] << 8) | > + (arg->g_flt.spatial_coeff[2] << 16) | > + (arg->g_flt.spatial_coeff[3] << 24); > + rkisp1_iowrite32(params_vdev, spatial_coeff, > + CIF_ISP_DPF_S_WEIGHT_G_1_4); > + > + spatial_coeff = arg->g_flt.spatial_coeff[4] | > + (arg->g_flt.spatial_coeff[5] << 8); > + rkisp1_iowrite32(params_vdev, spatial_coeff, > + CIF_ISP_DPF_S_WEIGHT_G_5_6); > + > + spatial_coeff = arg->rb_flt.spatial_coeff[0] | > + (arg->rb_flt.spatial_coeff[1] << 8) | > + (arg->rb_flt.spatial_coeff[2] << 16) | > + (arg->rb_flt.spatial_coeff[3] << 24); > + rkisp1_iowrite32(params_vdev, spatial_coeff, > + CIF_ISP_DPF_S_WEIGHT_RB_1_4); > + > + spatial_coeff = arg->rb_flt.spatial_coeff[4] | > + (arg->rb_flt.spatial_coeff[5] << 8); > + rkisp1_iowrite32(params_vdev, spatial_coeff, > + CIF_ISP_DPF_S_WEIGHT_RB_5_6); > +} > + > +static void dpf_strength_config(struct rkisp1_isp_params_vdev *params_vdev, > + const struct cifisp_dpf_strength_config *arg) > +{ > + rkisp1_iowrite32(params_vdev, arg->b, CIF_ISP_DPF_STRENGTH_B); > + rkisp1_iowrite32(params_vdev, arg->g, CIF_ISP_DPF_STRENGTH_G); > + rkisp1_iowrite32(params_vdev, arg->r, CIF_ISP_DPF_STRENGTH_R); > +} > + > +static __maybe_unused > +void __isp_isr_other_config(struct rkisp1_isp_params_vdev *params_vdev, > + const struct rkisp1_isp_params_cfg *new_params) > +{ > + unsigned int module_en_update, module_cfg_update, module_ens; > + > + module_en_update = new_params->module_en_update; > + module_cfg_update = new_params->module_cfg_update; > + module_ens = new_params->module_ens; > + > + if ((module_en_update & CIFISP_MODULE_DPCC) || > + (module_cfg_update & CIFISP_MODULE_DPCC)) { > + /*update dpc config */ > + if ((module_cfg_update & CIFISP_MODULE_DPCC)) > + dpcc_config(params_vdev, > + &new_params->others.dpcc_config); > + > + if (module_en_update & CIFISP_MODULE_DPCC) { > + if (!!(module_ens & CIFISP_MODULE_DPCC)) > + isp_param_set_bits(params_vdev, > + CIF_ISP_DPCC_MODE, > + CIF_ISP_DPCC_ENA); > + else > + isp_param_clear_bits(params_vdev, > + CIF_ISP_DPCC_MODE, > + CIF_ISP_DPCC_ENA); > + } > + } > + > + if ((module_en_update & CIFISP_MODULE_BLS) || > + (module_cfg_update & CIFISP_MODULE_BLS)) { > + /* update bls config */ > + if ((module_cfg_update & CIFISP_MODULE_BLS)) > + bls_config(params_vdev, &new_params->others.bls_config); > + > + if (module_en_update & CIFISP_MODULE_BLS) { > + if (!!(module_ens & CIFISP_MODULE_BLS)) > + isp_param_set_bits(params_vdev, > + CIF_ISP_BLS_CTRL, > + CIF_ISP_BLS_ENA); > + else > + isp_param_clear_bits(params_vdev, > + CIF_ISP_BLS_CTRL, > + CIF_ISP_BLS_ENA); > + } > + } > + > + if ((module_en_update & CIFISP_MODULE_SDG) || > + (module_cfg_update & CIFISP_MODULE_SDG)) { > + /* update sdg config */ > + if ((module_cfg_update & CIFISP_MODULE_SDG)) > + sdg_config(params_vdev, &new_params->others.sdg_config); > + > + if (module_en_update & CIFISP_MODULE_SDG) { > + if (!!(module_ens & CIFISP_MODULE_SDG)) > + isp_param_set_bits(params_vdev, > + CIF_ISP_CTRL, > + CIF_ISP_CTRL_ISP_GAMMA_IN_ENA); > + else > + isp_param_clear_bits(params_vdev, > + CIF_ISP_CTRL, > + CIF_ISP_CTRL_ISP_GAMMA_IN_ENA); > + } > + } > + > + if ((module_en_update & CIFISP_MODULE_LSC) || > + (module_cfg_update & CIFISP_MODULE_LSC)) { > + /* update lsc config */ > + if ((module_cfg_update & CIFISP_MODULE_LSC)) > + lsc_config(params_vdev, &new_params->others.lsc_config); > + > + if (module_en_update & CIFISP_MODULE_LSC) { > + if (!!(module_ens & CIFISP_MODULE_LSC)) > + isp_param_set_bits(params_vdev, > + CIF_ISP_LSC_CTRL, > + CIF_ISP_LSC_CTRL_ENA); > + else > + isp_param_clear_bits(params_vdev, > + CIF_ISP_LSC_CTRL, > + CIF_ISP_LSC_CTRL_ENA); > + } > + } > + > + if ((module_en_update & CIFISP_MODULE_AWB_GAIN) || > + (module_cfg_update & CIFISP_MODULE_AWB_GAIN)) { > + /* update awb gains */ > + if ((module_cfg_update & CIFISP_MODULE_AWB_GAIN)) > + awb_gain_config(params_vdev, > + &new_params->others.awb_gain_config); > + > + if (module_en_update & CIFISP_MODULE_AWB_GAIN) { > + if (!!(module_ens & CIFISP_MODULE_AWB_GAIN)) > + isp_param_set_bits(params_vdev, > + CIF_ISP_CTRL, > + CIF_ISP_CTRL_ISP_AWB_ENA); > + else > + isp_param_clear_bits(params_vdev, > + CIF_ISP_CTRL, > + CIF_ISP_CTRL_ISP_AWB_ENA); > + } > + } > + > + if ((module_en_update & CIFISP_MODULE_BDM) || > + (module_cfg_update & CIFISP_MODULE_BDM)) { > + /* update bdm config */ > + if ((module_cfg_update & CIFISP_MODULE_BDM)) > + bdm_config(params_vdev, &new_params->others.bdm_config); > + > + if (module_en_update & CIFISP_MODULE_BDM) { > + if (!!(module_ens & CIFISP_MODULE_BDM)) > + isp_param_set_bits(params_vdev, > + CIF_ISP_DEMOSAIC, > + CIF_ISP_DEMOSAIC_BYPASS); > + else > + isp_param_clear_bits(params_vdev, > + CIF_ISP_DEMOSAIC, > + CIF_ISP_DEMOSAIC_BYPASS); > + } > + } > + > + if ((module_en_update & CIFISP_MODULE_FLT) || > + (module_cfg_update & CIFISP_MODULE_FLT)) { > + /* update filter config */ > + if ((module_cfg_update & CIFISP_MODULE_FLT)) > + flt_config(params_vdev, &new_params->others.flt_config); > + > + if (module_en_update & CIFISP_MODULE_FLT) { > + if (!!(module_ens & CIFISP_MODULE_FLT)) > + isp_param_set_bits(params_vdev, > + CIF_ISP_FILT_MODE, > + CIF_ISP_FLT_ENA); > + else > + isp_param_clear_bits(params_vdev, > + CIF_ISP_FILT_MODE, > + CIF_ISP_FLT_ENA); > + } > + } > + > + if ((module_en_update & CIFISP_MODULE_CTK) || > + (module_cfg_update & CIFISP_MODULE_CTK)) { > + /* update ctk config */ > + if ((module_cfg_update & CIFISP_MODULE_CTK)) > + ctk_config(params_vdev, &new_params->others.ctk_config); > + > + if (module_en_update & CIFISP_MODULE_CTK) > + ctk_enable(params_vdev, > + !!(module_ens & CIFISP_MODULE_CTK)); > + } > + > + if ((module_en_update & CIFISP_MODULE_GOC) || > + (module_cfg_update & CIFISP_MODULE_GOC)) { > + /* update goc config */ > + if ((module_cfg_update & CIFISP_MODULE_GOC)) > + goc_config(params_vdev, &new_params->others.goc_config); > + > + if (module_en_update & CIFISP_MODULE_GOC) { > + if (!!(module_ens & CIFISP_MODULE_GOC)) > + isp_param_set_bits(params_vdev, > + CIF_ISP_CTRL, > + CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA); > + else > + isp_param_clear_bits(params_vdev, > + CIF_ISP_CTRL, > + CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA); > + } > + } > + > + if ((module_en_update & CIFISP_MODULE_CPROC) || > + (module_cfg_update & CIFISP_MODULE_CPROC)) { > + /* update cproc config */ > + if ((module_cfg_update & CIFISP_MODULE_CPROC)) { > + cproc_config(params_vdev, > + &new_params->others.cproc_config); > + > + } > + > + if (module_en_update & CIFISP_MODULE_CPROC) { > + if (!!(module_ens & CIFISP_MODULE_CPROC)) > + isp_param_set_bits(params_vdev, > + CIF_C_PROC_CTRL, > + CIF_C_PROC_CTR_ENABLE); > + else > + isp_param_clear_bits(params_vdev, > + CIF_C_PROC_CTRL, > + CIF_C_PROC_CTR_ENABLE); > + } > + } > + > + > + if ((module_en_update & CIFISP_MODULE_IE) || > + (module_cfg_update & CIFISP_MODULE_IE)) { > + /* update ie config */ > + if ((module_cfg_update & CIFISP_MODULE_IE)) > + ie_config(params_vdev, &new_params->others.ie_config); > + > + if (module_en_update & CIFISP_MODULE_IE) > + ie_enable(params_vdev, > + !!(module_ens & CIFISP_MODULE_IE)); > + } > + > + if ((module_en_update & CIFISP_MODULE_DPF) || > + (module_cfg_update & CIFISP_MODULE_DPF)) { > + /* update dpf config */ > + if ((module_cfg_update & CIFISP_MODULE_DPF)) > + dpf_config(params_vdev, &new_params->others.dpf_config); > + > + if (module_en_update & CIFISP_MODULE_DPF) { > + if (!!(module_ens & CIFISP_MODULE_DPF)) > + isp_param_set_bits(params_vdev, > + CIF_ISP_DPF_MODE, > + CIF_ISP_DPF_MODE_EN); > + else > + isp_param_clear_bits(params_vdev, > + CIF_ISP_DPF_MODE, > + CIF_ISP_DPF_MODE_EN); > + } > + } > + > + if ((module_en_update & CIFISP_MODULE_DPF_STRENGTH) || > + (module_cfg_update & CIFISP_MODULE_DPF_STRENGTH)) { > + /* update dpf strength config */ > + dpf_strength_config(params_vdev, > + &new_params->others.dpf_strength_config); > + } > +} > + > +static __maybe_unused > +void __isp_isr_meas_config(struct rkisp1_isp_params_vdev *params_vdev, > + struct rkisp1_isp_params_cfg *new_params) > +{ > + unsigned int module_en_update, module_cfg_update, module_ens; > + > + module_en_update = new_params->module_en_update; > + module_cfg_update = new_params->module_cfg_update; > + module_ens = new_params->module_ens; > + > + if ((module_en_update & CIFISP_MODULE_AWB) || > + (module_cfg_update & CIFISP_MODULE_AWB)) { > + /* update awb config */ > + if ((module_cfg_update & CIFISP_MODULE_AWB)) > + awb_meas_config(params_vdev, > + &new_params->meas.awb_meas_config); > + > + if (module_en_update & CIFISP_MODULE_AWB) > + awb_meas_enable(params_vdev, > + &new_params->meas.awb_meas_config, > + !!(module_ens & CIFISP_MODULE_AWB)); > + } > + > + if ((module_en_update & CIFISP_MODULE_AFC) || > + (module_cfg_update & CIFISP_MODULE_AFC)) { > + /* update afc config */ > + if ((module_cfg_update & CIFISP_MODULE_AFC)) > + afm_config(params_vdev, &new_params->meas.afc_config); > + > + if (module_en_update & CIFISP_MODULE_AFC) { > + if (!!(module_ens & CIFISP_MODULE_AFC)) > + isp_param_set_bits(params_vdev, > + CIF_ISP_AFM_CTRL, > + CIF_ISP_AFM_ENA); > + else > + isp_param_clear_bits(params_vdev, > + CIF_ISP_AFM_CTRL, > + CIF_ISP_AFM_ENA); > + } > + } > + > + if ((module_en_update & CIFISP_MODULE_HST) || > + (module_cfg_update & CIFISP_MODULE_HST)) { > + /* update hst config */ > + if ((module_cfg_update & CIFISP_MODULE_HST)) > + hst_config(params_vdev, &new_params->meas.hst_config); > + > + if (module_en_update & CIFISP_MODULE_HST) > + hst_enable(params_vdev, > + &new_params->meas.hst_config, > + !!(module_ens & CIFISP_MODULE_HST)); > + } > + > + if ((module_en_update & CIFISP_MODULE_AEC) || > + (module_cfg_update & CIFISP_MODULE_AEC)) { > + /* update aec config */ > + if ((module_cfg_update & CIFISP_MODULE_AEC)) > + aec_config(params_vdev, &new_params->meas.aec_config); > + > + if (module_en_update & CIFISP_MODULE_AEC) { > + if (!!(module_ens & CIFISP_MODULE_AEC)) > + isp_param_set_bits(params_vdev, > + CIF_ISP_EXP_CTRL, > + CIF_ISP_EXP_ENA); > + else > + isp_param_clear_bits(params_vdev, > + CIF_ISP_EXP_CTRL, > + CIF_ISP_EXP_ENA); > + } > + } > +} > + > +void rkisp1_params_isr(struct rkisp1_isp_params_vdev *params_vdev, u32 isp_mis) > +{ > + struct rkisp1_isp_params_cfg *new_params; > + struct rkisp1_buffer *cur_buf = NULL; > + unsigned int cur_frame_id = -1; > + cur_frame_id = atomic_read(¶ms_vdev->dev->isp_sdev.frm_sync_seq) - 1; > + > + spin_lock(¶ms_vdev->config_lock); > + if (!params_vdev->streamon) { > + spin_unlock(¶ms_vdev->config_lock); > + return; > + } > + > + /* get one empty buffer */ > + if (!list_empty(¶ms_vdev->params)) > + cur_buf = list_first_entry(¶ms_vdev->params, > + struct rkisp1_buffer, queue); > + spin_unlock(¶ms_vdev->config_lock); > + > + if (!cur_buf) > + return; > + > + new_params = (struct rkisp1_isp_params_cfg *)(cur_buf->vaddr[0]); > + > + if (isp_mis & CIF_ISP_FRAME) { > + __isp_isr_other_config(params_vdev, new_params); > + __isp_isr_meas_config(params_vdev, new_params); > + spin_lock(¶ms_vdev->config_lock); > + list_del(&cur_buf->queue); > + spin_unlock(¶ms_vdev->config_lock); > + > + cur_buf->vb.sequence = cur_frame_id; > + vb2_buffer_done(&cur_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); > + } > +} > + > +static const struct cifisp_awb_meas_config awb_params_default_config = { > + { > + 0, 0, RKISP1_DEFAULT_WIDTH, RKISP1_DEFAULT_HEIGHT > + }, > + CIFISP_AWB_MODE_YCBCR, 200, 30, 20, 20, 0, 128, 128 > +}; > + > +static const struct cifisp_aec_config aec_params_default_config = { > + CIFISP_EXP_MEASURING_MODE_0, > + CIFISP_EXP_CTRL_AUTOSTOP_0, > + { > + RKISP1_DEFAULT_WIDTH >> 2, RKISP1_DEFAULT_HEIGHT >> 2, > + RKISP1_DEFAULT_WIDTH >> 1, RKISP1_DEFAULT_HEIGHT >> 1 > + } > +}; > + > +static const struct cifisp_hst_config hst_params_default_config = { > + CIFISP_HISTOGRAM_MODE_RGB_COMBINED, > + 3, > + { > + RKISP1_DEFAULT_WIDTH >> 2, RKISP1_DEFAULT_HEIGHT >> 2, > + RKISP1_DEFAULT_WIDTH >> 1, RKISP1_DEFAULT_HEIGHT >> 1 > + }, > + { > + 0, /* To be filled in with 0x01 at runtime. */ > + } > +}; > + > +static const struct cifisp_afc_config afc_params_default_config = { > + 1, > + { > + { > + 300, 225, 200, 150 > + } > + }, > + 4, > + 14 > +}; > + > +static > +void rkisp1_params_config_parameter(struct rkisp1_isp_params_vdev *params_vdev) > +{ > + struct cifisp_hst_config hst = hst_params_default_config; > + > + spin_lock(¶ms_vdev->config_lock); > + > + awb_meas_config(params_vdev, &awb_params_default_config); > + awb_meas_enable(params_vdev, &awb_params_default_config, true); > + > + aec_config(params_vdev, &aec_params_default_config); > + isp_param_set_bits(params_vdev, CIF_ISP_EXP_CTRL, CIF_ISP_EXP_ENA); > + > + afm_config(params_vdev, &afc_params_default_config); > + isp_param_set_bits(params_vdev, CIF_ISP_AFM_CTRL, CIF_ISP_AFM_ENA); > + > + memset(hst.hist_weight, 0x01, sizeof(hst.hist_weight)); > + hst_config(params_vdev, &hst); > + isp_param_set_bits(params_vdev, CIF_ISP_HIST_PROP, > + ~CIF_ISP_HIST_PROP_MODE_MASK | > + hst_params_default_config.mode); > + > + /* set the range */ > + if (params_vdev->quantization == V4L2_QUANTIZATION_FULL_RANGE) > + csm_config(params_vdev, true); > + else > + csm_config(params_vdev, false); > + > + /* override the default things */ > + __isp_isr_other_config(params_vdev, ¶ms_vdev->cur_params); > + __isp_isr_meas_config(params_vdev, ¶ms_vdev->cur_params); > + > + spin_unlock(¶ms_vdev->config_lock); > +} > + > +/* Not called when the camera active, thus not isr protection. */ > +void rkisp1_params_configure_isp(struct rkisp1_isp_params_vdev *params_vdev, > + struct ispsd_in_fmt *in_fmt, > + enum v4l2_quantization quantization) > +{ > + params_vdev->quantization = quantization; > + params_vdev->raw_type = in_fmt->bayer_pat; > + rkisp1_params_config_parameter(params_vdev); > +} > + > +/* Not called when the camera active, thus not isr protection. */ > +void rkisp1_params_disable_isp(struct rkisp1_isp_params_vdev *params_vdev) > +{ > + isp_param_clear_bits(params_vdev, CIF_ISP_DPCC_MODE, CIF_ISP_DPCC_ENA); > + isp_param_clear_bits(params_vdev, CIF_ISP_LSC_CTRL, > + CIF_ISP_LSC_CTRL_ENA); > + isp_param_clear_bits(params_vdev, CIF_ISP_BLS_CTRL, CIF_ISP_BLS_ENA); > + isp_param_clear_bits(params_vdev, CIF_ISP_CTRL, > + CIF_ISP_CTRL_ISP_GAMMA_IN_ENA); > + isp_param_clear_bits(params_vdev, CIF_ISP_CTRL, > + CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA); > + isp_param_clear_bits(params_vdev, CIF_ISP_DEMOSAIC, > + CIF_ISP_DEMOSAIC_BYPASS); > + isp_param_clear_bits(params_vdev, CIF_ISP_FILT_MODE, CIF_ISP_FLT_ENA); > + awb_meas_enable(params_vdev, NULL, false); > + isp_param_clear_bits(params_vdev, CIF_ISP_CTRL, > + CIF_ISP_CTRL_ISP_AWB_ENA); > + isp_param_clear_bits(params_vdev, CIF_ISP_EXP_CTRL, CIF_ISP_EXP_ENA); > + ctk_enable(params_vdev, false); > + isp_param_clear_bits(params_vdev, CIF_C_PROC_CTRL, > + CIF_C_PROC_CTR_ENABLE); > + hst_enable(params_vdev, NULL, false); > + isp_param_clear_bits(params_vdev, CIF_ISP_AFM_CTRL, CIF_ISP_AFM_ENA); > + ie_enable(params_vdev, false); > + isp_param_clear_bits(params_vdev, CIF_ISP_DPF_MODE, > + CIF_ISP_DPF_MODE_EN); > +} > + > +static int rkisp1_params_enum_fmt_meta_out(struct file *file, void *priv, > + struct v4l2_fmtdesc *f) > +{ > + struct video_device *video = video_devdata(file); > + struct rkisp1_isp_params_vdev *params_vdev = video_get_drvdata(video); > + > + if (f->index > 0 || f->type != video->queue->type) > + return -EINVAL; > + > + f->pixelformat = params_vdev->vdev_fmt.fmt.meta.dataformat; > + > + return 0; > +} > + > +static int rkisp1_params_g_fmt_meta_out(struct file *file, void *fh, > + struct v4l2_format *f) > +{ > + struct video_device *video = video_devdata(file); > + struct rkisp1_isp_params_vdev *params_vdev = video_get_drvdata(video); > + struct v4l2_meta_format *meta = &f->fmt.meta; > + > + if (f->type != video->queue->type) > + return -EINVAL; > + > + memset(meta, 0, sizeof(*meta)); > + meta->dataformat = params_vdev->vdev_fmt.fmt.meta.dataformat; > + meta->buffersize = params_vdev->vdev_fmt.fmt.meta.buffersize; > + > + return 0; > +} > + > +static int rkisp1_params_querycap(struct file *file, > + void *priv, struct v4l2_capability *cap) > +{ > + struct video_device *vdev = video_devdata(file); > + > + strcpy(cap->driver, DRIVER_NAME); strlcpy > + strlcpy(cap->card, vdev->name, sizeof(cap->card)); > + strlcpy(cap->bus_info, "platform: " DRIVER_NAME, sizeof(cap->bus_info)); > + > + return 0; > +} > + > +/* ISP params video device IOCTLs */ > +static const struct v4l2_ioctl_ops rkisp1_params_ioctl = { > + .vidioc_reqbufs = vb2_ioctl_reqbufs, > + .vidioc_querybuf = vb2_ioctl_querybuf, > + .vidioc_create_bufs = vb2_ioctl_create_bufs, > + .vidioc_qbuf = vb2_ioctl_qbuf, > + .vidioc_dqbuf = vb2_ioctl_dqbuf, > + .vidioc_prepare_buf = vb2_ioctl_prepare_buf, > + .vidioc_expbuf = vb2_ioctl_expbuf, > + .vidioc_streamon = vb2_ioctl_streamon, > + .vidioc_streamoff = vb2_ioctl_streamoff, > + .vidioc_enum_fmt_meta_out = rkisp1_params_enum_fmt_meta_out, > + .vidioc_g_fmt_meta_out = rkisp1_params_g_fmt_meta_out, > + .vidioc_s_fmt_meta_out = rkisp1_params_g_fmt_meta_out, > + .vidioc_try_fmt_meta_out = rkisp1_params_g_fmt_meta_out, > + .vidioc_querycap = rkisp1_params_querycap > +}; > + > +static int rkisp1_params_vb2_queue_setup(struct vb2_queue *vq, > + unsigned int *num_buffers, > + unsigned int *num_planes, > + unsigned int sizes[], > + struct device *alloc_devs[]) > +{ > + struct rkisp1_isp_params_vdev *params_vdev = vq->drv_priv; > + > + *num_buffers = clamp_t(u32, *num_buffers, > + RKISP1_ISP_PARAMS_REQ_BUFS_MIN, > + RKISP1_ISP_PARAMS_REQ_BUFS_MAX); > + > + *num_planes = 1; > + > + sizes[0] = sizeof(struct rkisp1_isp_params_cfg); > + > + INIT_LIST_HEAD(¶ms_vdev->params); > + params_vdev->first_params = true; > + > + return 0; > +} > + > +static void rkisp1_params_vb2_buf_queue(struct vb2_buffer *vb) > +{ > + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); > + struct rkisp1_buffer *params_buf = to_rkisp1_buffer(vbuf); > + struct vb2_queue *vq = vb->vb2_queue; > + struct rkisp1_isp_params_vdev *params_vdev = vq->drv_priv; > + struct rkisp1_isp_params_cfg *new_params; > + unsigned long flags; > + > + unsigned int cur_frame_id = -1; > + cur_frame_id = atomic_read(¶ms_vdev->dev->isp_sdev.frm_sync_seq) - 1; > + > + if (params_vdev->first_params) { > + new_params = (struct rkisp1_isp_params_cfg *) > + (vb2_plane_vaddr(vb, 0)); > + vbuf->sequence = cur_frame_id; > + vb2_buffer_done(¶ms_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); > + params_vdev->first_params = false; > + params_vdev->cur_params = *new_params; > + return; > + } > + > + params_buf->vaddr[0] = vb2_plane_vaddr(vb, 0); > + spin_lock_irqsave(¶ms_vdev->config_lock, flags); > + list_add_tail(¶ms_buf->queue, ¶ms_vdev->params); > + spin_unlock_irqrestore(¶ms_vdev->config_lock, flags); > +} > + > +static void rkisp1_params_vb2_stop_streaming(struct vb2_queue *vq) > +{ > + struct rkisp1_isp_params_vdev *params_vdev = vq->drv_priv; > + struct rkisp1_buffer *buf; > + unsigned long flags; > + int i; > + > + /* stop params input firstly */ > + spin_lock_irqsave(¶ms_vdev->config_lock, flags); > + params_vdev->streamon = false; > + spin_unlock_irqrestore(¶ms_vdev->config_lock, flags); > + > + for (i = 0; i < RKISP1_ISP_PARAMS_REQ_BUFS_MAX; i++) { > + spin_lock_irqsave(¶ms_vdev->config_lock, flags); > + if (!list_empty(¶ms_vdev->params)) { > + buf = list_first_entry(¶ms_vdev->params, > + struct rkisp1_buffer, queue); > + list_del(&buf->queue); > + spin_unlock_irqrestore(¶ms_vdev->config_lock, > + flags); > + } else { > + spin_unlock_irqrestore(¶ms_vdev->config_lock, > + flags); > + break; > + } > + > + if (buf) > + vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); > + buf = NULL; > + } > +} > + > +static int > +rkisp1_params_vb2_start_streaming(struct vb2_queue *queue, unsigned int count) > +{ > + struct rkisp1_isp_params_vdev *params_vdev = queue->drv_priv; > + unsigned long flags; > + > + spin_lock_irqsave(¶ms_vdev->config_lock, flags); > + params_vdev->streamon = true; > + spin_unlock_irqrestore(¶ms_vdev->config_lock, flags); > + > + return 0; > +} > + > +static struct vb2_ops rkisp1_params_vb2_ops = { > + .queue_setup = rkisp1_params_vb2_queue_setup, > + .wait_prepare = vb2_ops_wait_prepare, > + .wait_finish = vb2_ops_wait_finish, > + .buf_queue = rkisp1_params_vb2_buf_queue, > + .start_streaming = rkisp1_params_vb2_start_streaming, > + .stop_streaming = rkisp1_params_vb2_stop_streaming, > + > +}; > + > +struct v4l2_file_operations rkisp1_params_fops = { > + .mmap = vb2_fop_mmap, > + .unlocked_ioctl = video_ioctl2, > + .poll = vb2_fop_poll, > + .open = v4l2_fh_open, > + .release = vb2_fop_release > +}; > + > +static int > +rkisp1_params_init_vb2_queue(struct vb2_queue *q, > + struct rkisp1_isp_params_vdev *params_vdev) > +{ > + struct rkisp1_vdev_node *node; > + > + node = queue_to_node(q); > + > + q->type = V4L2_BUF_TYPE_META_OUTPUT; > + q->io_modes = VB2_MMAP | VB2_USERPTR; VB2_DMABUF > + q->drv_priv = params_vdev; > + q->ops = &rkisp1_params_vb2_ops; > + q->mem_ops = &vb2_vmalloc_memops; > + q->buf_struct_size = sizeof(struct rkisp1_buffer); > + q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; > + q->lock = &node->vlock; > + > + return vb2_queue_init(q); > +} > + > +static void rkisp1_init_params_vdev(struct rkisp1_isp_params_vdev *params_vdev) > +{ > + params_vdev->vdev_fmt.fmt.meta.dataformat = > + V4L2_META_FMT_RK_ISP1_PARAMS; > + params_vdev->vdev_fmt.fmt.meta.buffersize = > + sizeof(struct rkisp1_isp_params_cfg); > +} > + > +int rkisp1_register_params_vdev(struct rkisp1_isp_params_vdev *params_vdev, > + struct v4l2_device *v4l2_dev, > + struct rkisp1_device *dev) > +{ > + int ret; > + struct rkisp1_vdev_node *node = ¶ms_vdev->vnode; > + struct video_device *vdev = &node->vdev; > + > + params_vdev->dev = dev; > + mutex_init(&node->vlock); > + spin_lock_init(¶ms_vdev->config_lock); > + > + strlcpy(vdev->name, "rkisp1-input-params", sizeof(vdev->name)); > + > + video_set_drvdata(vdev, params_vdev); > + vdev->ioctl_ops = &rkisp1_params_ioctl; > + vdev->fops = &rkisp1_params_fops; > + vdev->release = video_device_release_empty; > + /* > + * Provide a mutex to v4l2 core. It will be used > + * to protect all fops and v4l2 ioctls. > + */ > + vdev->lock = &node->vlock; > + vdev->v4l2_dev = v4l2_dev; > + vdev->queue = &node->buf_queue; > + vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_META_OUTPUT; Hmm, we don't have this yet. I know it was worked on, but I'm not sure what the status is. I suggest that you add the patches adding META_OUTPUT to the patch series for the next version. > + vdev->vfl_dir = VFL_DIR_TX; > + rkisp1_params_init_vb2_queue(vdev->queue, params_vdev); > + rkisp1_init_params_vdev(params_vdev); > + video_set_drvdata(vdev, params_vdev); > + > + node->pad.flags = MEDIA_PAD_FL_SOURCE; > + vdev->entity.function = MEDIA_ENT_F_IO_V4L; Probably not needed. > + ret = media_entity_pads_init(&vdev->entity, 1, &node->pad); > + if (ret < 0) > + goto err_release_queue; > + ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); > + if (ret < 0) { > + dev_err(&vdev->dev, > + "could not register Video for Linux device\n"); > + goto err_cleanup_media_entity; > + } > + return 0; > +err_cleanup_media_entity: > + media_entity_cleanup(&vdev->entity); > +err_release_queue: > + vb2_queue_release(vdev->queue); > + return ret; > +} > + > +void rkisp1_unregister_params_vdev(struct rkisp1_isp_params_vdev *params_vdev) > +{ > + struct rkisp1_vdev_node *node = ¶ms_vdev->vnode; > + struct video_device *vdev = &node->vdev; > + > + video_unregister_device(vdev); > + media_entity_cleanup(&vdev->entity); > + vb2_queue_release(vdev->queue); > +} > diff --git a/drivers/media/platform/rockchip/isp1/isp_params.h b/drivers/media/platform/rockchip/isp1/isp_params.h > new file mode 100644 > index 0000000..9ecdcd2 > --- /dev/null > +++ b/drivers/media/platform/rockchip/isp1/isp_params.h > @@ -0,0 +1,76 @@ > +/* > + * Rockchip isp1 driver > + * > + * Copyright (C) 2017 Rockchip Electronics Co., Ltd. > + * > + * This software is available to you under a choice of one of two > + * licenses. You may choose to be licensed under the terms of the GNU > + * General Public License (GPL) Version 2, available from the file > + * COPYING in the main directory of this source tree, or the > + * OpenIB.org BSD license below: > + * > + * Redistribution and use in source and binary forms, with or > + * without modification, are permitted provided that the following > + * conditions are met: > + * > + * - Redistributions of source code must retain the above > + * copyright notice, this list of conditions and the following > + * disclaimer. > + * > + * - Redistributions in binary form must reproduce the above > + * copyright notice, this list of conditions and the following > + * disclaimer in the documentation and/or other materials > + * provided with the distribution. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, > + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF > + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND > + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS > + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN > + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN > + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE > + * SOFTWARE. > + */ > + > +#ifndef _RKISP1_ISP_H > +#define _RKISP1_ISP_H > + > +#include <linux/rkisp1-config.h> > +#include "common.h" > + > +/* > + * struct rkisp1_isp_subdev - ISP input parameters device > + * > + * @cur_params: Current ISP parameters > + * @first_params: the first params should take effect immediately > + */ > +struct rkisp1_isp_params_vdev { > + struct rkisp1_vdev_node vnode; > + struct rkisp1_device *dev; > + > + spinlock_t config_lock; > + struct list_head params; > + struct rkisp1_isp_params_cfg cur_params; > + struct v4l2_format vdev_fmt; > + bool streamon; > + bool first_params; > + > + enum v4l2_quantization quantization; > + enum rkisp1_fmt_raw_pat_type raw_type; > +}; > + > +/* config params before ISP streaming */ > +void rkisp1_params_configure_isp(struct rkisp1_isp_params_vdev *params_vdev, > + struct ispsd_in_fmt *in_fmt, > + enum v4l2_quantization quantization); > +void rkisp1_params_disable_isp(struct rkisp1_isp_params_vdev *params_vdev); > + > +int rkisp1_register_params_vdev(struct rkisp1_isp_params_vdev *params_vdev, > + struct v4l2_device *v4l2_dev, > + struct rkisp1_device *dev); > + > +void rkisp1_unregister_params_vdev(struct rkisp1_isp_params_vdev *params_vdev); > + > +void rkisp1_params_isr(struct rkisp1_isp_params_vdev *params_vdev, u32 isp_mis); > + > +#endif /* _RKISP1_ISP_H */ > Regards, Hans -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html